Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Event Request] Codeunit 5790 "Available to Promise".CalcEarliestAvailabilityDate #27671

Open
fridrichovsky opened this issue Nov 22, 2024 · 1 comment
Labels
event-request Request for adding an event SCM GitHub request for SCM area

Comments

@fridrichovsky
Copy link
Contributor

fridrichovsky commented Nov 22, 2024

Describe the request

Please add new event

procedure CalcEarliestAvailabilityDate(var Item: Record Item; NeededQty: Decimal; StartDate: Date; ExcludeQty: Decimal; ExcludeOnDate: Date; var AvailableQty: Decimal; PeriodType: Enum "Analysis Period Type"; LookaheadDateFormula: DateFormula): Date
    var
        Date: Record System.Utilities.Date;
        DummyItem: Record Item;
        TempAvailabilityAtDate: Record "Availability at Date" temporary;
        CalendarManagement: Codeunit "Calendar Management";
        QtyIsAvailable: Boolean;
        ExactDateFound: Boolean;
        IsHandled: Boolean;
        ScheduledReceipt: Decimal;
        GrossRequirement: Decimal;
        AvailableQtyPeriod: Decimal;
        AvailableDate: Date;
        PeriodStart: Date;
        PeriodEnd: Date;
    begin
        AvailableQty := 0;

        Item.CopyFilter("Date Filter", DummyItem."Date Filter");
        Item.SetRange("Date Filter", 0D, GetForwardPeriodEndDate(LookaheadDateFormula, PeriodType, StartDate));
        CalculateAvailability(Item, TempAvailabilityAtDate);
        UpdateScheduledReceipt(TempAvailabilityAtDate, ExcludeOnDate, ExcludeQty);
        //-----------------------------------------------------------------------------OnCalcEarliestAvailabilityDateOnAfterUpdateScheduledReceipt:BEGIN
        OnCalcEarliestAvailabilityDateOnAfterUpdateScheduledReceipt(TempAvailabilityAtDate);
        //-----------------------------------------------------------------------------OnCalcEarliestAvailabilityDateOnAfterUpdateScheduledReceipt:END
        CalculateAvailabilityByPeriod(TempAvailabilityAtDate, PeriodType);

        IsHandled := false;
        OnCalcEarliestAvailabilityDateOnBeforeFilterDate(Item, NeededQty, StartDate, AvailableQty, PeriodType, LookaheadDateFormula, TempAvailabilityAtDate, AvailableDate, IsHandled);
        if IsHandled then
            exit(AvailableDate);

        PeriodStart := 0D;
        Date.SetRange("Period Type", PeriodType);
        Date.SetRange("Period Start", 0D, StartDate);
        if Date.FindLast() then begin
            TempAvailabilityAtDate.SetRange("Period Start", 0D, Date."Period Start");
            if TempAvailabilityAtDate.FindSet() then
                repeat
                    if PeriodStart = 0D then
                        PeriodStart := TempAvailabilityAtDate."Period Start";
                    ScheduledReceipt += TempAvailabilityAtDate."Scheduled Receipt";
                    GrossRequirement += TempAvailabilityAtDate."Gross Requirement";
                until TempAvailabilityAtDate.Next() = 0;
            AvailableQty := Item.Inventory - Item."Reserved Qty. on Inventory" + ScheduledReceipt - GrossRequirement;
            if AvailableQty >= NeededQty then begin
                QtyIsAvailable := true;
                AvailableDate := Date."Period End";
                PeriodEnd := Date."Period End";
            end else
                PeriodStart := 0D;
        end;

        if Format(LookaheadDateFormula) = '' then
            TempAvailabilityAtDate.SetRange("Period Start", StartDate + 1, CalendarManagement.GetMaxDate())
        else
            TempAvailabilityAtDate.SetRange("Period Start", StartDate + 1, CalcDate(LookaheadDateFormula, StartDate));

        TempAvailabilityAtDate."Period Start" := 0D;
        while TempAvailabilityAtDate.Next() <> 0 do begin
            AvailableQtyPeriod := TempAvailabilityAtDate."Scheduled Receipt" - TempAvailabilityAtDate."Gross Requirement";
            if TempAvailabilityAtDate."Scheduled Receipt" <= TempAvailabilityAtDate."Gross Requirement" then begin
                AvailableQty := AvailableQty + AvailableQtyPeriod;
                AvailableDate := TempAvailabilityAtDate."Period End";
                if AvailableQty < NeededQty then
                    QtyIsAvailable := false;
            end else
                if QtyIsAvailable then
                    TempAvailabilityAtDate.FindLast()
                else begin
                    AvailableQty := AvailableQty + AvailableQtyPeriod;
                    if AvailableQty >= NeededQty then begin
                        QtyIsAvailable := true;
                        AvailableDate := TempAvailabilityAtDate."Period End";
                        PeriodStart := TempAvailabilityAtDate."Period Start";
                        PeriodEnd := TempAvailabilityAtDate."Period End";
                        TempAvailabilityAtDate.FindLast();
                    end;
                end;
        end;

        if QtyIsAvailable then begin
            if PeriodType <> PeriodType::Day then begin
                Item.SetRange("Date Filter", PeriodStart, PeriodEnd);
                CalculateAvailability(Item, TempAvailabilityAtDate);
                if (ExcludeOnDate >= PeriodStart) and (ExcludeOnDate <= PeriodEnd) then
                    UpdateScheduledReceipt(TempAvailabilityAtDate, ExcludeOnDate, ExcludeQty);
            end;
            TempAvailabilityAtDate.SetRange("Period Start", PeriodStart, PeriodEnd);
            if TempAvailabilityAtDate.Find('+') then
                repeat
                    if (AvailableQty - TempAvailabilityAtDate."Scheduled Receipt") < NeededQty then begin
                        ExactDateFound := true;
                        AvailableDate := TempAvailabilityAtDate."Period Start";
                    end else
                        AvailableQty := AvailableQty - TempAvailabilityAtDate."Scheduled Receipt";
                until (TempAvailabilityAtDate.Next(-1) = 0) or ExactDateFound;
            if not ExactDateFound then begin
                AvailableDate := StartDate;
                if TempAvailabilityAtDate.Find() then
                    AvailableQty := AvailableQty + TempAvailabilityAtDate."Scheduled Receipt";
            end;
        end else
            AvailableDate := 0D;

        DummyItem.CopyFilter("Date Filter", Item."Date Filter");
        exit(AvailableDate);
    end;

    //-----------------------------------------------------------------------------OnCalcEarliestAvailabilityDateOnAfterUpdateScheduledReceipt:BEGIN
    [IntegrationEvent(true, false)]
    local procedure OnCalcEarliestAvailabilityDateOnAfterUpdateScheduledReceipt(var TempAvailabilityAtDate: Record "Availability at Date" temporary)
    begin
    end;
    //-----------------------------------------------------------------------------OnCalcEarliestAvailabilityDateOnAfterUpdateScheduledReceipt:END

Additional context

We need change temp table content after update.
Internal work item: AB#558494

@BardurKnudsen BardurKnudsen added event-request Request for adding an event SCM GitHub request for SCM area labels Nov 25, 2024
@BardurKnudsen
Copy link

Looks good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
event-request Request for adding an event SCM GitHub request for SCM area
Projects
None yet
Development

No branches or pull requests

2 participants