Report 719 Inv. Availability Plan, source in 29

Source29

src/Layers/W1/BaseApp/Inventory/Availability/InvAvailabilityPlan.Report.al392 lines, Copyright (c) Microsoft Corporation. MIT

// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Inventory.Reports;

using Microsoft.Inventory.Availability;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Location;

report 719 "Inv. Availability Plan"
{
    ApplicationArea = Basic, Suite;
    Caption = 'Inventory - Availability Plan (Excel)';
    ToolTip = 'View a list of the quantity of each item in customer, purchase, and transfer orders and the quantity available in inventory. The list is divided into columns that cover six periods with starting and ending dates as well as the periods before and after those periods. The list is useful when you are planning your inventory purchases.';
    DataAccessIntent = ReadOnly;
    DefaultRenderingLayout = Excel;
    UsageCategory = ReportsAndAnalysis;

    dataset
    {
        dataitem(Item; Item)
        {
            DataItemTableView = where(Type = const(Inventory));
            RequestFilterFields = "No.", "Location Filter", "Variant Filter", "Search Description", "Assembly BOM", "Inventory Posting Group", "Vendor No.";
            CalcFields = Inventory, "Planning Receipt (Qty.)", "Planning Release (Qty.)";

            dataitem("Stockkeeping Unit"; "Stockkeeping Unit")
            {
                DataItemLink = "Item No." = field("No."), "Location Code" = field("Location Filter"), "Variant Code" = field("Variant Filter");
                DataItemTableView = sorting("Item No.", "Location Code", "Variant Code");

                trigger OnAfterGetRecord()
                begin
                    CalcNeed(Item, "Location Code", "Variant Code");

                    if Print then
                        PopulateBuffer();

                    CurrReport.Skip(); // Item dataitem just for filtering and building the buffer
                end;

                trigger OnPreDataItem()
                begin
                    if not UseStockkeepingUnit then
                        CurrReport.Break();
                end;
            }

            trigger OnAfterGetRecord()
            begin
                if not UseStockkeepingUnit then begin
                    Print := false;

                    CalcNeed(Item, GetFilter("Location Filter"), GetFilter("Variant Filter"));

                    if Print then
                        PopulateBuffer();

                    CurrReport.Skip();
                end;
            end;
        }
        dataitem(AvailabilityPlanBuffer; "Availability Plan Buffer")
        {
            column(ItemNo; "Item No.")
            {
                IncludeCaption = true;
            }
            column(Description; Description)
            {
                IncludeCaption = true;
            }
            column(LocationCode; "Location Code")
            {
                IncludeCaption = true;
            }
            column(VariantCode; "Variant Code")
            {
                IncludeCaption = true;
            }
            column(CategoryName; "Category Name")
            {
                IncludeCaption = true;
            }
            column(CurrentQuantity; "Current Quantity")
            {
                IncludeCaption = true;
            }
            column(Quantity1; "Quantity 1")
            {
                IncludeCaption = true;
            }
            column(Quantity2; "Quantity 2")
            {
                IncludeCaption = true;
            }
            column(Quantity3; "Quantity 3")
            {
                IncludeCaption = true;
            }
            column(Quantity4; "Quantity 4")
            {
                IncludeCaption = true;
            }
            column(Quantity5; "Quantity 5")
            {
                IncludeCaption = true;
            }
            column(Quantity6; "Quantity 6")
            {
                IncludeCaption = true;
            }
            column(Quantity7; "Quantity 7")
            {
                IncludeCaption = true;
            }
            column(Quantity8; "Quantity 8")
            {
                IncludeCaption = true;
            }
        }
    }

    requestpage
    {
        AboutTitle = 'About Inventory - Availability Plan (Excel)';
        AboutText = 'Get an overview of specific items and stock-keeping units, and their availability.';
        SaveValues = true;

        layout
        {
            area(content)
            {
                group(Options)
                {
                    Caption = 'Options';
                    field(StartingDate; PeriodStartDate[2])
                    {
                        ApplicationArea = Basic, Suite;
                        Caption = 'Starting Date';
                        NotBlank = true;
                        ToolTip = 'Specifies the date from which the report or batch job processes information.';
                    }
                    field(PeriodLength; PeriodLength)
                    {
                        ApplicationArea = Basic, Suite;
                        Caption = 'Period Length';
                        ToolTip = 'Specifies the period for which data is shown in the report. For example, enter "1M" for one month, "30D" for thirty days, "3Q" for three quarters, or "5Y" for five years.';
                    }
                    field(UseStockkeepUnit; UseStockkeepingUnit)
                    {
                        ApplicationArea = Warehouse;
                        Caption = 'Use Stockkeeping Unit';
                        ToolTip = 'Specifies if you want the report to list the availability of items by stockkeeping unit.';
                    }
                    // ### Start Report Headers ### Used to set report headers across multiple languages
                    field(RequestItemFilterHeading; ItemFilterHeading)
                    {
                        ApplicationArea = All;
                        Caption = 'Item Filter';
                        ToolTip = 'Specifies the Item Filters applied to this report.';
                        Visible = false;
                    }
                    field(RequestPeriod1Text; Period1Text)
                    {
                        ApplicationArea = All;
                        Caption = 'Period 1';
                        ToolTip = 'Specifies Period 1 on this report.';
                        Visible = false;
                    }
                    field(RequestPeriod2Text; Period2Text)
                    {
                        ApplicationArea = All;
                        Caption = 'Period 2';
                        ToolTip = 'Specifies Period 2 on this report.';
                        Visible = false;
                    }
                    field(RequestPeriod3Text; Period3Text)
                    {
                        ApplicationArea = All;
                        Caption = 'Period 3';
                        ToolTip = 'Specifies Period 3 on this report.';
                        Visible = false;
                    }
                    field(RequestPeriod4Text; Period4Text)
                    {
                        ApplicationArea = All;
                        Caption = 'Period 4';
                        ToolTip = 'Specifies Period 4 on this report.';
                        Visible = false;
                    }
                    field(RequestPeriod5Text; Period5Text)
                    {
                        ApplicationArea = All;
                        Caption = 'Period 5';
                        ToolTip = 'Specifies Period 5 on this report.';
                        Visible = false;
                    }
                    field(RequestPeriod6Text; Period6Text)
                    {
                        ApplicationArea = All;
                        Caption = 'Period 6';
                        ToolTip = 'Specifies Period 6 on this report.';
                        Visible = false;
                    }
                    // ### End Report Headers ###
                }
            }
        }

        actions
        {
        }

        trigger OnOpenPage()
        begin
            if Format(PeriodLength) = '' then
                Evaluate(PeriodLength, '<1M>');
            if PeriodStartDate[2] = 0D then
                PeriodStartDate[2] := WorkDate();
        end;

        trigger OnClosePage()
        begin
            UpdateRequestPageFilterValues();
        end;
    }

    rendering
    {
        layout(Excel)
        {
            Caption = 'Inventory - Availability Plan (Excel)';
            Type = Excel;
            LayoutFile = './Inventory/Reports/InvAvailabilityPlan.xlsx';
            Summary = 'Built in layout for the Inventory - Availability Plan (Excel) report.';
        }
    }

    labels
    {
        InventoryAvailabilityPlanLbl = 'Inventory - Availability Plan';
        InvAvailPlanPrintLbl = 'Inv. Avail. Plan (Print)', MaxLength = 31, Comment = 'Excel worksheet name.';
        InvAvailPlanAnalysisLbl = 'Inv. Avail. Plan (Analysis)', MaxLength = 31, Comment = 'Excel worksheet name.';
        DataRetrievedLbl = 'Data retrieved:';
        BeforeLbl = '...Before';
        AfterLbl = 'After...';
        // About the report labels
        AboutTheReportLbl = 'About the report';
        EnvironmentLbl = 'Environment';
        CompanyLbl = 'Company';
        UserLbl = 'User';
        RunOnLbl = 'Run on';
        ReportNameLbl = 'Report name';
        DocumentationLbl = 'Documentation';
    }

    trigger OnPreReport()
    begin
        UpdateRequestPageFilterValues();
    end;

    var
        AvailToPromise: Codeunit "Available to Promise";
        PeriodLength: DateFormula;
        ItemFilter: Text;
        ItemFilterHeading: Text;
        SchedReceipt: array[8] of Decimal;
        PlanReceipt: array[8] of Decimal;
        PlanRelease: array[8] of Decimal;
        PeriodStartDate: array[9] of Date;
        ProjAvBalance: array[8] of Decimal;
        GrossReq: array[8] of Decimal;
        Print: Boolean;
        EntryNo: Integer;
        UseStockkeepingUnit: Boolean;
        Period1Text: Text;
        Period2Text: Text;
        Period3Text: Text;
        Period4Text: Text;
        Period5Text: Text;
        Period6Text: Text;

    local procedure CalcNeed(Item: Record Item; LocationFilter: Text[250]; VariantFilter: Text[250])
    var
        PlannedOrderReleaseQty: Decimal;
        i: Integer;
    begin
        for i := 1 to 8 do begin
            Item.SetFilter("Location Filter", LocationFilter);
            Item.SetFilter("Variant Filter", VariantFilter);
            if Item.Inventory <> 0 then
                Print := true;

            Item.SetRange("Date Filter", PeriodStartDate[i], PeriodStartDate[i + 1] - 1);

            GrossReq[i] := AvailToPromise.CalcGrossRequirement(Item);
            SchedReceipt[i] := AvailToPromise.CalcScheduledReceipt(Item);

            PlannedOrderReleaseQty := Item.CalcPlannedOrderReceiptQty();

            SchedReceipt[i] := SchedReceipt[i] - PlannedOrderReleaseQty;
            PlanReceipt[i] := Item."Planning Receipt (Qty.)" + PlannedOrderReleaseQty;
            PlanRelease[i] := Item."Planning Release (Qty.)" + PlannedOrderReleaseQty;

            if i = 1 then
                ProjAvBalance[1] :=
                  Item.Inventory - GrossReq[1] + SchedReceipt[1] + PlanReceipt[1]
            else
                ProjAvBalance[i] :=
                  ProjAvBalance[i - 1] -
                  GrossReq[i] + SchedReceipt[i] + PlanReceipt[i];

            if (GrossReq[i] <> 0) or
               (PlanReceipt[i] <> 0) or
               (SchedReceipt[i] <> 0) or
               (PlanRelease[i] <> 0)
            then
                Print := true;
        end;
    end;

    procedure InitializeRequest(NewPeriodStartDate: Date; NewPeriodLength: DateFormula; NewUseStockkeepingUnit: Boolean)
    begin
        PeriodStartDate[2] := NewPeriodStartDate;
        PeriodLength := NewPeriodLength;
        UseStockkeepingUnit := NewUseStockkeepingUnit;
    end;

    local procedure PopulateBuffer()
    var
        GrossRequirementLbl: Label 'Gross Requirement';
        ScheduledReceiptLbl: Label 'Scheduled Receipt';
        PlannedReceiptLbl: Label 'Planned Receipt';
        InventoryLbl: Label 'Inventory';
        PlannedReleasesLbl: Label 'Planned Releases';
    begin
        AddBufferEntry(GrossRequirementLbl, 0, GrossReq);
        AddBufferEntry(ScheduledReceiptLbl, 0, SchedReceipt);
        AddBufferEntry(PlannedReceiptLbl, 0, PlanReceipt);
        AddBufferEntry(InventoryLbl, Item.Inventory, ProjAvBalance);
        AddBufferEntry(PlannedReleasesLbl, 0, PlanRelease);
    end;

    local procedure AddBufferEntry(CategoryName: Text[100]; CurrentQuantity: Decimal; Quantities: array[8] of Decimal)
    begin
        AvailabilityPlanBuffer.Init();
        EntryNo += 1;
        AvailabilityPlanBuffer."Entry No." := EntryNo;
        AvailabilityPlanBuffer."Item No." := Item."No.";
        AvailabilityPlanBuffer.Description := Item.Description;
        if UseStockkeepingUnit then begin
            AvailabilityPlanBuffer."Location Code" := "Stockkeeping Unit"."Location Code";
            AvailabilityPlanBuffer."Variant Code" := "Stockkeeping Unit"."Variant Code";
        end;
        AvailabilityPlanBuffer."Category Name" := CategoryName;
        AvailabilityPlanBuffer."Current Quantity" := CurrentQuantity;
        AvailabilityPlanBuffer."Quantity 1" := Quantities[1];
        AvailabilityPlanBuffer."Quantity 2" := Quantities[2];
        AvailabilityPlanBuffer."Quantity 3" := Quantities[3];
        AvailabilityPlanBuffer."Quantity 4" := Quantities[4];
        AvailabilityPlanBuffer."Quantity 5" := Quantities[5];
        AvailabilityPlanBuffer."Quantity 6" := Quantities[6];
        AvailabilityPlanBuffer."Quantity 7" := Quantities[7];
        AvailabilityPlanBuffer."Quantity 8" := Quantities[8];
        AvailabilityPlanBuffer.Insert();
    end;

    // Ensures Layout Filter Headings are up to date
    local procedure UpdateRequestPageFilterValues()
    var
        i: Integer;
    begin
        ItemFilter := Item.GetFilters();

        ItemFilterHeading := '';
        if ItemFilter <> '' then
            ItemFilterHeading := Item.TableCaption + ': ' + ItemFilter;

        for i := 2 to 7 do
            PeriodStartDate[i + 1] := CalcDate(PeriodLength, PeriodStartDate[i]);
        PeriodStartDate[9] := DMY2Date(31, 12, 9999);

        Period1Text := Format(PeriodStartDate[2]) + ' ' + Format(PeriodStartDate[3] - 1);
        Period2Text := Format(PeriodStartDate[3]) + ' ' + Format(PeriodStartDate[4] - 1);
        Period3Text := Format(PeriodStartDate[4]) + ' ' + Format(PeriodStartDate[5] - 1);
        Period4Text := Format(PeriodStartDate[5]) + ' ' + Format(PeriodStartDate[6] - 1);
        Period5Text := Format(PeriodStartDate[6]) + ' ' + Format(PeriodStartDate[7] - 1);
        Period6Text := Format(PeriodStartDate[7]) + ' ' + Format(PeriodStartDate[8] - 1);
    end;
}