Codeunit 1317 Aged Inventory Chart Mgt., source in 29
Source29
src/Layers/W1/BaseApp/Inventory/Analysis/AgedInventoryChartMgt.Codeunit.al201 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.Analysis;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Ledger;
using System.Visualization;
codeunit 1317 "Aged Inventory Chart Mgt."
{
trigger OnRun()
begin
end;
var
YCaptionTxt: Label 'Inventory Value';
XCaptionTxt: Label 'Time on Inventory';
PeriodStartDate: array[6] of Date;
XFromToYearsTxt: Label '%1..%2 years', Comment = '%1=number of years,%2=number of years';
XFromToDaysTxt: Label '%1..%2 days', Comment = '%1=number of days,%2=number of days';
#pragma warning disable AA0470
XOverYearsTxt: Label 'Over %1 years';
XOverDaysTxt: Label 'Over %1 days';
#pragma warning restore AA0470
procedure UpdateChart(var BusChartBuf: Record "Business Chart Buffer")
var
ColumnIndex: Integer;
PeriodStartDate2: array[6] of Date;
InvtValue: array[5] of Decimal;
begin
BusChartBuf.Initialize();
BusChartBuf.AddDecimalMeasure(YCaptionTxt, 1, BusChartBuf."Chart Type"::StackedColumn);
BusChartBuf.SetXAxis(XCaptionTxt, BusChartBuf."Data Type"::String);
CalcPeriodStartDates(PeriodStartDate2, GetPeriodLengthInDays(BusChartBuf));
AddChartColumns(BusChartBuf);
CalcInventoryValuePerAge(InvtValue, PeriodStartDate2);
for ColumnIndex := 1 to 5 do
BusChartBuf.SetValueByIndex(0, ColumnIndex - 1, InvtValue[6 - ColumnIndex]);
end;
procedure DrillDown(var BusChartBuf: Record "Business Chart Buffer")
var
DrillDownXIndex: Integer;
begin
CalcPeriodStartDates(PeriodStartDate, GetPeriodLengthInDays(BusChartBuf));
DrillDownXIndex := BusChartBuf."Drill-Down X Index";
case BusChartBuf."Drill-Down Measure Index" + 1 of
1: // Item Ledger Entries
DrillDownItemLedgerEntries(PeriodStartDate[5 - DrillDownXIndex], PeriodStartDate[6 - DrillDownXIndex]);
end;
end;
procedure CalcInventoryValuePerAge(var InvtValue: array[5] of Decimal; PeriodStartDate: array[6] of Date)
var
Item: Record Item;
ItemLedgerEntry: Record "Item Ledger Entry";
InvtQty: array[5] of Decimal;
UnitCost: Decimal;
PeriodNo: Integer;
begin
Item.SetRange(Type, Item.Type::Inventory, Item.Type::Inventory);
if Item.FindSet() then
repeat
ItemLedgerEntry.SetCurrentKey(ItemLedgerEntry."Item No.", ItemLedgerEntry.Open);
ItemLedgerEntry.SetRange("Item No.", Item."No.");
ItemLedgerEntry.SetRange(Open, true);
if ItemLedgerEntry.Findset() then
repeat
CalcRemainingQty(ItemLedgerEntry, PeriodStartDate, InvtQty, PeriodNo);
UnitCost := CalcUnitCost(ItemLedgerEntry);
InvtValue[PeriodNo] += UnitCost * Abs(InvtQty[PeriodNo]);
until ItemLedgerEntry.Next() = 0;
until Item.Next() = 0;
end;
local procedure AddChartColumns(var BusChartBuf: Record "Business Chart Buffer")
var
I: Integer;
PeriodLengthOnXAxis: Integer;
XAxisValueTxt: Text[30];
LastXAxisValueTxt: Text[30];
begin
PeriodLengthOnXAxis := GetPeriodLengthInDays(BusChartBuf);
if PeriodLengthOnXAxis = 365 then begin
PeriodLengthOnXAxis := 1;
XAxisValueTxt := XFromToYearsTxt;
LastXAxisValueTxt := XOverYearsTxt;
end else begin
XAxisValueTxt := XFromToDaysTxt;
LastXAxisValueTxt := XOverDaysTxt;
end;
for I := 0 to 3 do
BusChartBuf.AddColumn(StrSubstNo(XAxisValueTxt, I * PeriodLengthOnXAxis, (I + 1) * PeriodLengthOnXAxis));
// X-Axis value
BusChartBuf.AddColumn(StrSubstNo(LastXAxisValueTxt, Format(4 * PeriodLengthOnXAxis))); // X-Axis value
end;
local procedure CalcPeriodStartDates(var PeriodStartDate: array[6] of Date; PeriodLength: Integer)
var
I: Integer;
begin
PeriodStartDate[6] := WorkDate();
PeriodStartDate[1] := 0D;
for I := 2 to 5 do
PeriodStartDate[I] := CalcDate('<-' + Format((6 - I) * PeriodLength) + 'D>', PeriodStartDate[6]);
end;
procedure CalcRemainingQty(ItemLedgerEntry: Record "Item Ledger Entry"; PeriodStartDate: array[6] of Date; var InvtQty: array[5] of Decimal; var PeriodNo: Integer)
begin
for PeriodNo := 1 to 5 do
InvtQty[PeriodNo] := 0;
for PeriodNo := 1 to 5 do
if (ItemLedgerEntry."Posting Date" > PeriodStartDate[PeriodNo]) and
(ItemLedgerEntry."Posting Date" <= PeriodStartDate[PeriodNo + 1])
then
if ItemLedgerEntry."Remaining Quantity" <> 0 then begin
InvtQty[PeriodNo] := ItemLedgerEntry."Remaining Quantity";
exit;
end;
end;
procedure CalcUnitCost(ItemLedgerEntry: Record "Item Ledger Entry"): Decimal
var
ValueEntry: Record "Value Entry";
UnitCost: Decimal;
begin
ValueEntry.SetRange("Item Ledger Entry No.", ItemLedgerEntry."Entry No.");
UnitCost := 0;
if ValueEntry.Find('-') then
repeat
if ValueEntry."Partial Revaluation" then
SumUnitCost(UnitCost, ValueEntry."Cost Amount (Actual)" + ValueEntry."Cost Amount (Expected)", ValueEntry."Valued Quantity")
else
SumUnitCost(UnitCost, ValueEntry."Cost Amount (Actual)" + ValueEntry."Cost Amount (Expected)", ItemLedgerEntry.Quantity);
until ValueEntry.Next() = 0;
exit(UnitCost);
end;
procedure GetPeriodLengthInDays(BusChartBuf: Record "Business Chart Buffer"): Integer
begin
case BusChartBuf."Period Length" of
BusChartBuf."Period Length"::Day:
exit(1);
BusChartBuf."Period Length"::Week:
exit(7);
BusChartBuf."Period Length"::Month:
exit(30);
BusChartBuf."Period Length"::Quarter:
exit(90);
BusChartBuf."Period Length"::Year:
exit(365);
end;
end;
local procedure SumUnitCost(var UnitCost: Decimal; CostAmount: Decimal; Quantity: Decimal)
begin
UnitCost := UnitCost + CostAmount / Abs(Quantity);
end;
local procedure DrillDownItemLedgerEntries(StartDate: Date; EndDate: Date)
var
ItemLedgerEntry: Record "Item Ledger Entry";
begin
ItemLedgerEntry.SetRange(Open, true);
// we don't want to include start date in the filter, unless it is 0D
if StartDate = 0D then
ItemLedgerEntry.SetRange("Posting Date", StartDate, EndDate)
else
ItemLedgerEntry.SetRange("Posting Date", CalcDate('<1D>', StartDate), EndDate);
ItemLedgerEntry.SetFilter("Remaining Quantity", '<>0');
PAGE.Run(PAGE::"Item Ledger Entries", ItemLedgerEntry);
end;
procedure FromToYearsTxt(): Text[30]
begin
exit(XFromToYearsTxt);
end;
procedure FromToDaysTxt(): Text[30]
begin
exit(XFromToDaysTxt);
end;
procedure OverYearsTxt(): Text[30]
begin
exit(XOverYearsTxt);
end;
procedure OverDaysTxt(): Text[30]
begin
exit(XOverDaysTxt);
end;
}