Codeunit 5895 Inventory Adjustment
- App
- Base Application
- Namespace
- Microsoft.Inventory.Costing
- Versions
- 17-28
Procedures, 21Events, 104Obsolete, 7
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Inventory/Costing/InventoryAdjustment.Codeunit.al3566 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.Costing;
using Microsoft.Finance.Currency;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Foundation.AuditCodes;
using Microsoft.Foundation.Period;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Journal;
using Microsoft.Inventory.Ledger;
using Microsoft.Inventory.Posting;
using Microsoft.Inventory.Setup;
using Microsoft.Projects.Project.Job;
using Microsoft.Projects.Project.Setup;
using Microsoft.Purchases.History;
using System.Telemetry;
using System.Utilities;
codeunit 5895 "Inventory Adjustment" implements "Inventory Adjustment", "Cost Adjustment With Params"
{
Permissions = TableData Item = rm,
TableData "Item Ledger Entry" = rm,
TableData "Item Application Entry" = rimd,
TableData "Value Entry" = rim,
TableData "Avg. Cost Adjmt. Entry Point" = rimd,
TableData "Inventory Adjmt. Entry (Order)" = rm;
trigger OnRun()
begin
end;
var
Item: Record Item;
FilterItem: Record Item;
GLSetup: Record "General Ledger Setup";
Currency: Record Currency;
InvtSetup: Record "Inventory Setup";
SourceCodeSetup: Record "Source Code Setup";
InventoryAdjmtEntryOrderToAdjust: Record "Inventory Adjmt. Entry (Order)";
AvgCostAdjmtEntryPointToAdjust: Record "Avg. Cost Adjmt. Entry Point";
TempInvtAdjmtBuf: Record "Inventory Adjustment Buffer" temporary;
TempRndgResidualBuf: Record "Rounding Residual Buffer" temporary;
TempAvgCostExceptionBuf: Record "Integer" temporary;
AvgCostBuf: Record "Cost Element Buffer";
TempAvgCostRndgBuf: Record "Rounding Residual Buffer" temporary;
TempRevaluationPoint: Record "Integer" temporary;
TempValueEntryCalcdOutbndCostBuf: Record "Value Entry" temporary;
ItemApplicationTrace: Record "Item Application Trace";
ItemJnlPostLine: Codeunit "Item Jnl.-Post Line";
CostCalcMgt: Codeunit "Cost Calculation Management";
ItemCostMgt: Codeunit ItemCostManagement;
FeatureTelemetry: Codeunit "Feature Telemetry";
CurrentCostAdjustmentParamsMgt: Codeunit "Cost Adjustment Params Mgt.";
Window: Dialog;
ItemLedgerEntryTypesUsed: Dictionary of [Enum "Item Ledger Entry Type", Boolean];
ItemLedgEntryToAdjust: Dictionary of [Code[20], List of [Integer]];
OpenOutboundEntryNos: List of [Integer];
FixedAppliedItemEntryNos: List of [Integer];
ItemsToAdjust: List of [Code[20]];
JobsToAdjust: List of [Code[20]];
ItemsBeingAdjusted: List of [Code[20]];
WindowUpdateDateTime: DateTime;
PostingDateForClosedPeriod: Date;
LevelNo: array[3] of Integer;
MaxLevels: Integer;
MaxRoundings: Integer;
LevelExceeded: Boolean;
IsOnlineAdjmt: Boolean;
PostToGL: Boolean;
CommitAdjustedItems: Boolean;
SkipUpdateJobItemCost: Boolean;
WindowIsOpen: Boolean;
WindowAdjmtLevel: Integer;
WindowItem: Code[20];
WindowAdjust: Text[20];
WindowFWLevel: Integer;
WindowEntry: Integer;
IsAvgCostCalcTypeItem: Boolean;
WindowOutbndEntry: Integer;
ConsumpAdjmtInPeriodWithOutput: Date;
AdjustTillDate: Date;
StartDateTime: DateTime;
MaxDuration: Duration;
ItemsSinceLastCommit: Integer;
AutomaticCostAdjustmentTok: Label 'Automatic cost adjustment', Locked = true;
AutomaticCostAdjustmentEnabledTok: Label 'Automatic cost adjustment was used.', Locked = true;
CostAdjustmentReachedMaxDurationErr: Label 'The cost adjustment process has reached the maximum duration of %1.', Comment = '%1=Max Duration';
CostAdjmtCommitFeatureNameTok: Label 'Cost Adjustment Item-by-Item Commit', Locked = true;
CostAdjmtCommitEventNameTok: Label 'CheckAndCommit invoked', Locked = true;
#pragma warning disable AA0074
Text009: Label 'WIP';
Text010: Label 'Assembly';
Text000: Label 'Adjusting value entries...\\';
#pragma warning disable AA0470
Text001: Label 'Adjmt. Level #2######\';
Text002: Label '%1 %2';
Text003: Label 'Adjust #3######\';
Text004: Label 'Cost FW. Level #4######\';
Text005: Label 'Entry No. #5######\';
Text006: Label 'Remaining Entries #6######';
#pragma warning restore AA0470
Text007: Label 'Applied cost';
Text008: Label 'Average cost';
#pragma warning restore AA0074
procedure SetProperties(NewIsOnlineAdjmt: Boolean; NewPostToGL: Boolean)
begin
IsOnlineAdjmt := NewIsOnlineAdjmt;
PostToGL := NewPostToGL;
end;
procedure SetFilterItem(var NewItem: Record Item)
begin
FilterItem.CopyFilters(NewItem);
end;
procedure MakeMultiLevelAdjmt(var CostAdjustmentParamsMgt: Codeunit "Cost Adjustment Params Mgt.")
var
CostAdjustmentParameter: Record "Cost Adjustment Parameter";
begin
CurrentCostAdjustmentParamsMgt := CostAdjustmentParamsMgt;
CurrentCostAdjustmentParamsMgt.GetParameters(CostAdjustmentParameter);
IsOnlineAdjmt := CostAdjustmentParameter."Online Adjustment";
PostToGL := CostAdjustmentParameter."Post to G/L";
CommitAdjustedItems := CostAdjustmentParameter."Item-By-Item Commit";
SkipUpdateJobItemCost := CostAdjustmentParameter."Skip Job Item Cost Update";
MaxDuration := CostAdjustmentParameter."Max Duration";
CurrentCostAdjustmentParamsMgt.GetInventoryAdjmtEntryOrder(InventoryAdjmtEntryOrderToAdjust);
CurrentCostAdjustmentParamsMgt.GetAvgCostAdjmtEntryPoint(AvgCostAdjmtEntryPointToAdjust);
CurrentCostAdjustmentParamsMgt.GetItemsToAdjust(ItemsToAdjust);
OnBeforeMakeMultiLevejAdjmtOnAfterGetParameters(CurrentCostAdjustmentParamsMgt);
MakeMultiLevelAdjmt();
end;
procedure MakeMultiLevelAdjmt()
var
TempItem: Record Item temporary;
TempInventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)" temporary;
TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary;
IsFirstTime: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeMakeMultiLevelAdjmt(FilterItem, IsOnlineAdjmt, PostToGL, IsHandled);
if IsHandled then
exit;
InitializeAdjmt();
IsFirstTime := true;
while (InvtToAdjustExist(TempItem) or IsFirstTime) and not LevelExceeded do begin
// items adjustment
MakeSingleLevelAdjmt(TempItem, TempAvgCostAdjmtEntryPoint);
// assembly orders adjustment
if AssemblyToAdjustExists(TempInventoryAdjmtEntryOrder) then
MakeAssemblyAdjmt(TempInventoryAdjmtEntryOrder, TempAvgCostAdjmtEntryPoint);
// production orders adjustment
if WIPToAdjustExist(TempInventoryAdjmtEntryOrder) then
MakeWIPAdjmt(TempInventoryAdjmtEntryOrder, TempAvgCostAdjmtEntryPoint);
OnMakeMultiLevelAdjmtOnAfterMakeAdjmt(
TempAvgCostAdjmtEntryPoint, FilterItem, TempRndgResidualBuf, IsOnlineAdjmt, PostToGL, ItemJnlPostLine);
IsFirstTime := false;
end;
// if any item entries remain not adjusted, mark them for the next run
SetAppliedEntryToAdjustFromBuf('');
FinalizeAdjmt();
RunUpdateJobItemCost();
OnAfterMakeMultiLevelAdjmt(TempItem, IsOnlineAdjmt, PostToGL, FilterItem);
end;
local procedure InitializeAdjmt()
begin
Clear(ItemsBeingAdjusted);
Clear(LevelNo);
MaxLevels := 100;
MaxRoundings := 20;
WindowUpdateDateTime := CurrentDateTime();
StartDateTime := CurrentDateTime();
if not IsOnlineAdjmt then
OpenWindow();
Clear(ItemJnlPostLine);
ItemJnlPostLine.SetCalledFromAdjustment(true, PostToGL);
ItemsSinceLastCommit := 0;
InvtSetup.SetLoadFields("Automatic Cost Adjustment");
InvtSetup.Get();
if InvtSetup.AutomaticCostAdjmtRequired() then
FeatureTelemetry.LogUsage('0000MEM', AutomaticCostAdjustmentTok, AutomaticCostAdjustmentEnabledTok);
CommitAdjustedItems := CommitAdjustedItems and not IsOnlineAdjmt;
GLSetup.Get();
PostingDateForClosedPeriod := GLSetup.FirstAllowedPostingDate();
OnInitializeAdjmtOnAfterGetPostingDate(PostingDateForClosedPeriod);
GetAddReportingCurrency();
SourceCodeSetup.SetLoadFields("Adjust Cost");
SourceCodeSetup.Get();
ItemCostMgt.SetProperties(true, 0);
Clear(JobsToAdjust);
end;
local procedure FinalizeAdjmt()
begin
Clear(ItemJnlPostLine);
Clear(CostCalcMgt);
Clear(ItemCostMgt);
TempAvgCostRndgBuf.DeleteAll();
ItemApplicationTrace.Reset();
ItemApplicationTrace.DeleteAll();
if WindowIsOpen then
Window.Close();
WindowIsOpen := false;
end;
local procedure GetAddReportingCurrency()
begin
if GLSetup."Additional Reporting Currency" <> '' then begin
Currency.Get(GLSetup."Additional Reporting Currency");
Currency.CheckAmountRoundingPrecision();
end;
end;
local procedure InvtToAdjustExist(var ToItem: Record Item): Boolean
var
NonAdjustedItem: Record Item;
begin
NonAdjustedItem.Reset();
NonAdjustedItem.ReadIsolation(IsolationLevel::ReadUncommitted);
NonAdjustedItem.CopyFilters(FilterItem);
NonAdjustedItem.SetRange("Cost is Adjusted", false);
if IsOnlineAdjmt then
NonAdjustedItem.SetRange("Allow Online Adjustment", true);
NonAdjustedItem.SetRange("Excluded from Cost Adjustment", false);
AdjustTillDate := FindLastDate(NonAdjustedItem.GetFilter("Date Filter"));
OnInvtToAdjustExistOnBeforeCopyItemToItem(NonAdjustedItem);
CopyItemToItem(NonAdjustedItem, ToItem);
exit(not ToItem.IsEmpty());
end;
local procedure MakeSingleLevelAdjmt(var TheItem: Record Item; var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
var
IsFirstTime: Boolean;
IsHandled: Boolean;
AnyLevelExceeded: Boolean;
begin
IsHandled := false;
OnBeforeMakeSingleLevelAdjmt(TheItem, TempAvgCostAdjmtEntryPoint, IsHandled);
if IsHandled then
exit;
if AdjustTillDate = 0D then
AdjustTillDate := FindLastDate('');
LevelNo[1] := LevelNo[1] + 1;
UpDateWindow(LevelNo[1], WindowItem, WindowAdjust, WindowFWLevel, WindowEntry, 0);
ConsumpAdjmtInPeriodWithOutput := 0D;
if TheItem.FindSet() then
repeat
OnBeforeAdjustItem(TheItem);
Item.SetBaseLoadFields();
Item.Get(TheItem."No.");
UpDateWindow(WindowAdjmtLevel, Item."No.", WindowAdjust, WindowFWLevel, WindowEntry, 0);
PushCurrentItem(Item);
IsHandled := false;
OnBeforeCollectItemLedgerEntryTypesUsed(Item, IsHandled);
if IsHandled and not IsOnlineAdjmt then
CollectItemLedgerEntryTypesUsed(Item."No.");
OnMakeSingleLevelAdjmtOnBeforeCollectAvgCostAdjmtEntryPointToUpdate(TheItem);
CollectAvgCostAdjmtEntryPointToUpdate(TempAvgCostAdjmtEntryPoint, TheItem."No.");
IsFirstTime := not AppliedEntryToAdjustBufExists(TheItem."No.");
// adjustment of applied entries
repeat
LevelExceeded := false;
OnMakeSingleLevelAdjmtOnAfterLevelExceeded(Item);
AdjustItemAppliedCost();
until not LevelExceeded;
// adjustment of average cost items
AdjustItemAvgCost();
// post new value entries
IsHandled := false;
OnMakeSingleLevelAdjmtOnBeforePostAdjmtBuf2(Item, TempAvgCostAdjmtEntryPoint, TempInvtAdjmtBuf, TempAvgCostRndgBuf, PostingDateForClosedPeriod, Currency, SkipUpdateJobItemCost, JobsToAdjust, ItemJnlPostLine, IsHandled);
if not IsHandled then
PostAdjmtBuf(TempAvgCostAdjmtEntryPoint);
// update unit cost on item card
UpdateItemUnitCost(TempAvgCostAdjmtEntryPoint, IsFirstTime);
OnMakeSingleLevelAdjmtOnAfterUpdateItemUnitCost(TheItem, TempAvgCostAdjmtEntryPoint, LevelExceeded, IsOnlineAdjmt, ItemJnlPostLine);
PopCurrentItem(Item);
CheckAndCommit();
OnAfterAdjustItem(TheItem);
if LevelExceeded then
AnyLevelExceeded := true;
LevelExceeded := false;
until TheItem.Next() = 0;
LevelExceeded := AnyLevelExceeded;
end;
local procedure AdjustItemAppliedCost()
var
ItemLedgEntry: Record "Item Ledger Entry";
AppliedQty: Decimal;
NeedsAdjustment: Boolean;
begin
UpDateWindow(WindowAdjmtLevel, WindowItem, Text007, WindowFWLevel, WindowEntry, 0);
TempValueEntryCalcdOutbndCostBuf.Reset();
TempValueEntryCalcdOutbndCostBuf.DeleteAll();
ItemLedgEntry.ReadIsolation(IsolationLevel::ReadUnCommitted);
ItemLedgEntry.SetCurrentKey("Item No.", "Applied Entry to Adjust");
ItemLedgEntry.SetRange("Item No.", Item."No.");
ItemLedgEntry.SetRange("Applied Entry to Adjust", true);
ItemLedgEntry.SetLoadFields("Item No.", "Applied Entry to Adjust", "Entry Type", "Completely Invoiced", Open, Positive, Quantity);
if not ItemLedgEntry.FindSet() then
exit;
OnBeforeCopyILEToILE(Item, ItemLedgEntry);
repeat
UpDateWindow(WindowAdjmtLevel, WindowItem, WindowAdjust, WindowFWLevel, ItemLedgEntry."Entry No.", 0);
NeedsAdjustment := true;
OnAdjustItemAppliedCostForItemLedgerEntry(ItemLedgEntry, NeedsAdjustment);
if NeedsAdjustment then begin
TempRndgResidualBuf.AddAdjustedCost(ItemLedgEntry."Entry No.", 0, 0, ItemLedgEntry."Completely Invoiced");
AppliedQty := ForwardAppliedCost(ItemLedgEntry, false);
// post value entry of "Rounding" type when the inbound entry is fully applied and its cost is not sharply equal to the cost of outbounds entries
EliminateRndgResidual(ItemLedgEntry, AppliedQty);
end;
until (ItemLedgEntry.Next() = 0) or LevelExceeded;
end;
local procedure ForwardAppliedCost(ItemLedgEntry: Record "Item Ledger Entry"; Recursion: Boolean) AppliedQty: Decimal
var
AppliedEntryToAdjust: Boolean;
begin
// Avoid stack overflow, if too many recursions
if Recursion then
LevelNo[3] := LevelNo[3] + 1
else
LevelNo[3] := 0;
if LevelNo[3] = MaxLevels then begin
ItemLedgEntry.SetAppliedEntryToAdjust(true);
LevelExceeded := true;
LevelNo[3] := 0;
exit;
end;
OnForwardAppliedCostOnBeforeUpdateWindow(ItemLedgEntry, Item);
UpDateWindow(WindowAdjmtLevel, WindowItem, WindowAdjust, LevelNo[3], WindowEntry, 0);
AppliedQty := ForwardCostToOutbndEntries(ItemLedgEntry, Recursion, AppliedEntryToAdjust);
OnForwardAppliedCostOnAfterSetAppliedQty(ItemLedgEntry, AppliedQty);
if ItemLedgEntry.Positive then
ForwardCostToInbndTransEntries(ItemLedgEntry."Entry No.", Recursion)
else
ForwardCostToInbndEntries(ItemLedgEntry."Entry No.");
ShouldSetAppliedEntryToAdjustForForwardAppliedCost(ItemLedgEntry, AppliedEntryToAdjust);
if AppliedEntryToAdjust then
if not ItemLedgEntry.IsOutbndConsump() then
UpdateAppliedEntryToAdjustBuf(ItemLedgEntry, AppliedEntryToAdjust);
ItemLedgEntry.SetAppliedEntryToAdjust(false);
end;
local procedure ShouldSetAppliedEntryToAdjustForForwardAppliedCost(ItemLedgEntry: Record "Item Ledger Entry"; var AppliedEntryToAdjust: Boolean)
begin
if AppliedEntryToAdjust then
exit;
if OutboundSalesEntryToAdjust(ItemLedgEntry) then begin
AppliedEntryToAdjust := true;
exit;
end;
if InboundTransferEntryToAdjust(ItemLedgEntry) then
AppliedEntryToAdjust := true;
end;
local procedure ForwardAppliedCostRecursion(ItemLedgEntry: Record "Item Ledger Entry")
var
ValueEntry: Record "Value Entry";
ItemApplicationEntry: Record "Item Application Entry";
ItemApplicationEntriesOutb: Query "Item Application Entries Outb.";
CostAmt: Decimal;
CostAmtACY: Decimal;
AppliedQty: Decimal;
AppliedCostAmt: Decimal;
AppliedCostAmtACY: Decimal;
begin
if not ItemLedgEntry."Applied Entry to Adjust" then begin
AppliedQty := ForwardAppliedCost(ItemLedgEntry, true);
if IsRndgAllowed(ItemLedgEntry, AppliedQty) then begin
TempInvtAdjmtBuf.CalcItemLedgEntryCost(ItemLedgEntry."Entry No.", false);
ValueEntry.CalcItemLedgEntryCost(ItemLedgEntry."Entry No.", false);
ValueEntry.AddCost(TempInvtAdjmtBuf);
CostAmt := ValueEntry."Cost Amount (Actual)";
CostAmtACY := ValueEntry."Cost Amount (Actual) (ACY)";
if ItemApplicationEntry.AppliedOutbndEntryExists(ItemApplicationEntriesOutb, ItemLedgEntry."Entry No.", true, false) then begin
repeat
TempInvtAdjmtBuf.CalcItemLedgEntryCost(ItemApplicationEntriesOutb.Item_Ledger_Entry_No, false);
ValueEntry.CalcItemLedgEntryCost(ItemApplicationEntriesOutb.Item_Ledger_Entry_No, false);
ValueEntry.AddCost(TempInvtAdjmtBuf);
AppliedCostAmt -= ValueEntry."Cost Amount (Actual)";
AppliedCostAmtACY -= ValueEntry."Cost Amount (Actual) (ACY)";
until not ItemApplicationEntriesOutb.Read();
if (Abs(CostAmt - AppliedCostAmt) = GLSetup."Amount Rounding Precision") or
(Abs(CostAmtACY - AppliedCostAmtACY) = Currency."Amount Rounding Precision")
then
UpdateAppliedEntryToAdjustBuf(ItemLedgEntry, true);
end;
end;
if LevelNo[3] > 0 then
LevelNo[3] := LevelNo[3] - 1;
end;
end;
local procedure ForwardCostToOutbndEntries(ItemLedgEntry: Record "Item Ledger Entry"; Recursion: Boolean; var AppliedEntryToAdjust: Boolean) AppliedQty: Decimal
var
ItemApplnEntry: Record "Item Application Entry";
ItemApplicationEntriesOutb: Query "Item Application Entries Outb.";
InboundCompletelyInvoiced: Boolean;
begin
AppliedQty := 0;
if ItemApplnEntry.AppliedOutbndEntryExists(ItemApplicationEntriesOutb, ItemLedgEntry."Entry No.", true, ItemLedgEntry.Open) then
repeat
if not AdjustAppliedOutbndEntries(ItemApplicationEntriesOutb.Outbound_Item_Entry_No, Recursion, InboundCompletelyInvoiced) then
AppliedEntryToAdjust :=
AppliedEntryToAdjust or
InboundCompletelyInvoiced or ItemLedgEntry.Open or not ItemLedgEntry."Completely Invoiced";
AppliedQty += ItemApplicationEntriesOutb.Quantity;
until not ItemApplicationEntriesOutb.Read();
end;
local procedure AdjustAppliedOutbndEntries(OutbndItemLedgEntryNo: Integer; Recursion: Boolean; var InboundCompletelyInvoiced: Boolean): Boolean
var
OutbndItemLedgEntry: Record "Item Ledger Entry";
OutbndValueEntry: Record "Value Entry";
TempOutbndCostElementBuf: Record "Cost Element Buffer" temporary;
TempOldCostElementBuf: Record "Cost Element Buffer" temporary;
TempAdjustedCostElementBuf: Record "Cost Element Buffer" temporary;
ItemApplnEntry: Record "Item Application Entry";
StandardCostMirroring: Boolean;
ExpectedCost: Boolean;
EntryAdjusted: Boolean;
NeedsAdjustment: Boolean;
begin
OutbndItemLedgEntry.SetLoadFields("Item No.", "Entry Type", "Document Type", "Document No.", "Document Line No.", Quantity, "Invoiced Quantity",
"Applies-to Entry", "Posting Date", "Completely Invoiced", "Applied Entry to Adjust", Positive, Open);
OutbndItemLedgEntry.Get(OutbndItemLedgEntryNo);
OnAdjustAppliedOutbndEntry(OutbndItemLedgEntry);
if Item."Costing Method" = Item."Costing Method"::Standard then
StandardCostMirroring := UseStandardCostMirroring(OutbndItemLedgEntry);
CalcOutbndCost(TempOutbndCostElementBuf, TempAdjustedCostElementBuf, OutbndItemLedgEntry, Recursion);
EntryAdjusted := false;
OutbndValueEntry.Reset();
OutbndValueEntry.SetCurrentKey("Item Ledger Entry No.", "Document No.", "Document Line No.");
OutbndValueEntry.SetRange("Item Ledger Entry No.", OutbndItemLedgEntryNo);
LoadFields(OutbndValueEntry);
for ExpectedCost := true downto false do begin
OutbndValueEntry.SetRange("Expected Cost", ExpectedCost);
if OutbndValueEntry.FindSet() then
repeat
NeedsAdjustment := not (OutbndValueEntry.Adjustment or ExpCostIsCompletelyInvoiced(OutbndItemLedgEntry, OutbndValueEntry)) and OutbndValueEntry.Inventoriable;
OnAdjustAppliedOutbndEntriesOnBeforeAdjustEntry(OutbndItemLedgEntry, OutbndValueEntry, NeedsAdjustment);
if NeedsAdjustment then begin
OutbndValueEntry.SetRange("Document No.", OutbndValueEntry."Document No.");
OutbndValueEntry.SetRange("Document Line No.", OutbndValueEntry."Document Line No.");
CalcOutbndDocOldCost(
TempOldCostElementBuf, OutbndValueEntry,
OutbndItemLedgEntry.IsExactCostReversingPurchase() or OutbndItemLedgEntry.IsExactCostReversingOutput());
CalcCostPerUnit(OutbndValueEntry, TempOutbndCostElementBuf, OutbndItemLedgEntry.Quantity);
if not OutbndValueEntry."Expected Cost" then begin
TempOldCostElementBuf.GetElement("Cost Entry Type"::"Direct Cost");
OutbndValueEntry."Invoiced Quantity" := TempOldCostElementBuf."Invoiced Quantity";
OutbndValueEntry."Valued Quantity" := TempOldCostElementBuf."Invoiced Quantity";
end;
CalcOutbndDocNewCost(
TempAdjustedCostElementBuf, TempOutbndCostElementBuf,
OutbndValueEntry, OutbndItemLedgEntry.Quantity);
if OutbndValueEntry."Expected Cost" then begin
TempOldCostElementBuf.GetElement(TempOldCostElementBuf.Type::Total);
TempAdjustedCostElementBuf."Actual Cost" := TempAdjustedCostElementBuf."Actual Cost" - TempOldCostElementBuf."Expected Cost";
TempAdjustedCostElementBuf."Actual Cost (ACY)" :=
TempAdjustedCostElementBuf."Actual Cost (ACY)" - TempOldCostElementBuf."Expected Cost (ACY)";
end else begin
TempOldCostElementBuf.GetElement(OutbndValueEntry."Entry Type"::"Direct Cost");
TempAdjustedCostElementBuf."Actual Cost" := TempAdjustedCostElementBuf."Actual Cost" - TempOldCostElementBuf."Actual Cost";
TempAdjustedCostElementBuf."Actual Cost (ACY)" :=
TempAdjustedCostElementBuf."Actual Cost (ACY)" - TempOldCostElementBuf."Actual Cost (ACY)";
end;
if StandardCostMirroring and not OutbndValueEntry."Expected Cost" then
EntryAdjusted := CreateCostAdjmtBuf(
OutbndValueEntry, TempAdjustedCostElementBuf, OutbndItemLedgEntry."Posting Date", OutbndValueEntry."Entry Type"::Variance)
else
EntryAdjusted := CreateCostAdjmtBuf(
OutbndValueEntry, TempAdjustedCostElementBuf, OutbndItemLedgEntry."Posting Date", OutbndValueEntry."Entry Type");
OnAdjustAppliedOutbndEntriesOnBeforeCheckExpectedCost(Item, OutbndValueEntry);
if not OutbndValueEntry."Expected Cost" then begin
EntryAdjusted :=
EntryAdjusted or CreateIndirectCostAdjmt(TempOldCostElementBuf, TempAdjustedCostElementBuf, OutbndValueEntry, OutbndValueEntry."Entry Type"::"Indirect Cost");
EntryAdjusted :=
EntryAdjusted or CreateIndirectCostAdjmt(TempOldCostElementBuf, TempAdjustedCostElementBuf, OutbndValueEntry, OutbndValueEntry."Entry Type"::Variance);
end;
OutbndValueEntry.FindLast();
OutbndValueEntry.SetRange("Document No.");
OutbndValueEntry.SetRange("Document Line No.");
end;
until OutbndValueEntry.Next() = 0;
end;
// Update transfers, consumptions
if IsUpdateCompletelyInvoiced(
OutbndItemLedgEntry, TempOutbndCostElementBuf."Inbound Completely Invoiced")
then
OutbndItemLedgEntry.SetCompletelyInvoiced();
ForwardAppliedCostRecursion(OutbndItemLedgEntry);
ItemApplnEntry.SetInboundToUpdated(OutbndItemLedgEntry);
InboundCompletelyInvoiced := TempOutbndCostElementBuf."Inbound Completely Invoiced";
exit(OutbndItemLedgEntry."Completely Invoiced");
end;
local procedure CalcCostPerUnit(var OutbndValueEntry: Record "Value Entry"; OutbndCostElementBuf: Record "Cost Element Buffer"; ItemLedgEntryQty: Decimal)
var
CalcCostPerUnit: Boolean;
CalcCostPerUnitACY: Boolean;
begin
CalcCostPerUnit := (OutbndValueEntry."Cost per Unit" = 0) and (OutbndCostElementBuf."Remaining Quantity" <> 0);
CalcCostPerUnitACY := (OutbndValueEntry."Cost per Unit (ACY)" = 0) and (OutbndCostElementBuf."Remaining Quantity" <> 0);
OnCalcCostPerUnitOnBeforeCalcCostPerUnit(OutbndValueEntry, OutbndCostElementBuf, CalcCostPerUnit, CalcCostPerUnitACY);
if CalcCostPerUnit then
OutbndValueEntry."Cost per Unit" := OutbndCostElementBuf."Actual Cost" / (ItemLedgEntryQty - OutbndCostElementBuf."Remaining Quantity");
if CalcCostPerUnitACY then
OutbndValueEntry."Cost per Unit (ACY)" := OutbndCostElementBuf."Actual Cost (ACY)" / (ItemLedgEntryQty - OutbndCostElementBuf."Remaining Quantity");
end;
local procedure CalcOutbndCost(var OutbndCostElementBuf: Record "Cost Element Buffer"; var AdjustedCostElementBuf: Record "Cost Element Buffer"; OutbndItemLedgEntry: Record "Item Ledger Entry"; Recursion: Boolean)
var
OutbndItemApplnEntry: Record "Item Application Entry";
TempCostElementBuf: Record "Cost Element Buffer" temporary;
begin
AdjustedCostElementBuf.DeleteAll();
OutbndCostElementBuf.DeleteAll();
if RestoreValuesFromBuffers(OutbndCostElementBuf, AdjustedCostElementBuf, OutbndItemLedgEntry."Entry No.") then begin
if not Recursion then begin
if not ItemLedgerEntryTypeIsUsed("Item Ledger Entry Type"::Transfer) then
exit;
OutbndItemApplnEntry.SetCurrentKey("Inbound Item Entry No.", "Transferred-from Entry No.", "Item Ledger Entry No.");
OutbndItemApplnEntry.SetRange("Inbound Item Entry No.", TempRndgResidualBuf."Item Ledger Entry No.");
OutbndItemApplnEntry.SetRange("Item Ledger Entry No.", OutbndItemLedgEntry."Entry No.");
OutbndItemApplnEntry.SetFilter("Transferred-from Entry No.", '<>%1', TempRndgResidualBuf."Item Ledger Entry No.");
if OutbndItemApplnEntry.FindSet() then
repeat
CalcInbndEntryAdjustedCost(
TempCostElementBuf, OutbndItemApplnEntry, OutbndItemLedgEntry."Entry No.", OutbndItemApplnEntry."Inbound Item Entry No.",
OutbndItemLedgEntry.IsExactCostReversingPurchase() or OutbndItemLedgEntry.IsExactCostReversingOutput(), false);
until OutbndItemApplnEntry.Next() = 0;
end;
exit;
end;
OutbndCostElementBuf."Remaining Quantity" := OutbndItemLedgEntry.Quantity;
OutbndCostElementBuf."Inbound Completely Invoiced" := true;
OutbndItemApplnEntry.SetRange("Item Ledger Entry No.", OutbndItemLedgEntry."Entry No.");
OutbndItemApplnEntry.FindSet();
repeat
if not
CalcInbndEntryAdjustedCost(
AdjustedCostElementBuf,
OutbndItemApplnEntry, OutbndItemLedgEntry."Entry No.",
OutbndItemApplnEntry."Inbound Item Entry No.",
OutbndItemLedgEntry.IsExactCostReversingPurchase() or OutbndItemLedgEntry.IsExactCostReversingOutput(),
Recursion)
then
OutbndCostElementBuf."Inbound Completely Invoiced" := false;
AdjustedCostElementBuf.GetElement(OutbndCostElementBuf.Type::"Direct Cost");
OutbndCostElementBuf."Actual Cost" := OutbndCostElementBuf."Actual Cost" + AdjustedCostElementBuf."Actual Cost";
OutbndCostElementBuf."Actual Cost (ACY)" := OutbndCostElementBuf."Actual Cost (ACY)" + AdjustedCostElementBuf."Actual Cost (ACY)";
OutbndCostElementBuf."Remaining Quantity" := OutbndCostElementBuf."Remaining Quantity" - OutbndItemApplnEntry.Quantity;
until OutbndItemApplnEntry.Next() = 0;
if OutbndCostElementBuf."Inbound Completely Invoiced" then
OutbndCostElementBuf."Inbound Completely Invoiced" := OutbndCostElementBuf."Remaining Quantity" = 0;
SaveValuesToBuffers(OutbndCostElementBuf, AdjustedCostElementBuf, OutbndItemLedgEntry."Entry No.");
end;
local procedure CalcOutbndDocNewCost(var NewCostElementBuf: Record "Cost Element Buffer"; OutbndCostElementBuf: Record "Cost Element Buffer"; OutbndValueEntry: Record "Value Entry"; ItemLedgEntryQty: Decimal)
var
ShareOfTotalCost: Decimal;
begin
ShareOfTotalCost := OutbndValueEntry."Valued Quantity" / ItemLedgEntryQty;
NewCostElementBuf.GetElement(OutbndCostElementBuf.Type::"Direct Cost");
OutbndCostElementBuf."Actual Cost" := OutbndCostElementBuf."Actual Cost" + OutbndValueEntry."Cost per Unit" * OutbndCostElementBuf."Remaining Quantity";
OutbndCostElementBuf."Actual Cost (ACY)" := OutbndCostElementBuf."Actual Cost (ACY)" + OutbndValueEntry."Cost per Unit (ACY)" * OutbndCostElementBuf."Remaining Quantity";
RoundCost(
NewCostElementBuf."Actual Cost", NewCostElementBuf."Rounding Residual",
OutbndCostElementBuf."Actual Cost", ShareOfTotalCost, GLSetup."Amount Rounding Precision");
RoundCost(
NewCostElementBuf."Actual Cost (ACY)", NewCostElementBuf."Rounding Residual (ACY)",
OutbndCostElementBuf."Actual Cost (ACY)", ShareOfTotalCost, Currency."Amount Rounding Precision");
if not NewCostElementBuf.Insert() then
NewCostElementBuf.Modify();
end;
local procedure CollectAvgCostAdjmtEntryPointToUpdate(var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary; ItemNo: Code[20])
var
AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point";
begin
AvgCostAdjmtEntryPoint.ReadIsolation(IsolationLevel::ReadUncommitted);
AvgCostAdjmtEntryPoint.SetRange("Item No.", ItemNo);
AvgCostAdjmtEntryPoint.SetRange("Cost Is Adjusted", false);
if AvgCostAdjmtEntryPoint.FindSet() then
repeat
InsertEntryPointToUpdate(
TempAvgCostAdjmtEntryPoint, AvgCostAdjmtEntryPoint."Item No.", AvgCostAdjmtEntryPoint."Variant Code", AvgCostAdjmtEntryPoint."Location Code");
until AvgCostAdjmtEntryPoint.Next() = 0;
end;
local procedure CreateCostAdjmtBuf(OutbndValueEntry: Record "Value Entry"; CostElementBuf: Record "Cost Element Buffer"; ItemLedgEntryPostingDate: Date; EntryType: Enum "Cost Entry Type"): Boolean
begin
if UpdateAdjmtBuf(OutbndValueEntry, CostElementBuf."Actual Cost", CostElementBuf."Actual Cost (ACY)", ItemLedgEntryPostingDate, EntryType) then begin
UpdateAvgCostAdjmtEntryPoint(OutbndValueEntry);
exit(true);
end;
exit(false);
end;
local procedure CreateIndirectCostAdjmt(var CostElementBuf: Record "Cost Element Buffer"; var AdjustedCostElementBuf: Record "Cost Element Buffer"; OutbndValueEntry: Record "Value Entry"; EntryType: Enum "Cost Entry Type"): Boolean
var
ItemJnlLine: Record "Item Journal Line";
OrigValueEntry: Record "Value Entry";
NewAdjustedCost: Decimal;
NewAdjustedCostACY: Decimal;
begin
CostElementBuf.GetElement(EntryType);
AdjustedCostElementBuf.GetElement(EntryType);
NewAdjustedCost := AdjustedCostElementBuf."Actual Cost" - CostElementBuf."Actual Cost";
NewAdjustedCostACY := AdjustedCostElementBuf."Actual Cost (ACY)" - CostElementBuf."Actual Cost (ACY)";
if HasNewCost(NewAdjustedCost, NewAdjustedCostACY) then begin
GetOrigValueEntry(OrigValueEntry, OutbndValueEntry, EntryType);
InitAdjmtJnlLine(
ItemJnlLine, OrigValueEntry, OrigValueEntry."Entry Type", OrigValueEntry."Variance Type", OrigValueEntry."Invoiced Quantity");
PostItemJnlLine(ItemJnlLine, OrigValueEntry, NewAdjustedCost, NewAdjustedCostACY);
OnCreateIndirectCostAdjmtOnAfterPostItemJnlLine(OrigValueEntry, NewAdjustedCost, NewAdjustedCostACY);
UpdateAvgCostAdjmtEntryPoint(OrigValueEntry);
exit(true);
end;
exit(false);
end;
local procedure ForwardCostToInbndTransEntries(ItemLedgEntryNo: Integer; Recursion: Boolean)
var
ItemApplnEntry: Record "Item Application Entry";
ItemApplicationEntries: Query "Item Application Entries";
begin
if not ItemLedgerEntryTypeIsUsed("Item Ledger Entry Type"::Transfer) then
exit;
if ItemApplnEntry.AppliedInbndTransEntryExists(ItemApplicationEntries, ItemLedgEntryNo, true) then
repeat
AdjustAppliedInbndTransEntries(ItemApplicationEntries, Recursion);
until not ItemApplicationEntries.Read();
end;
local procedure AdjustAppliedInbndTransEntries(ItemApplicationEntries: Query "Item Application Entries"; Recursion: Boolean)
var
TransItemApplnEntry: Record "Item Application Entry";
TransValueEntry: Record "Value Entry";
TransItemLedgEntry: Record "Item Ledger Entry";
TempCostElementBuf: Record "Cost Element Buffer" temporary;
TempAdjustedCostElementBuf: Record "Cost Element Buffer" temporary;
EntryAdjusted: Boolean;
begin
TransItemApplnEntry.Get(ItemApplicationEntries.Entry_No_);
TransItemLedgEntry.SetBaseLoadFields();
TransItemLedgEntry.Get(TransItemApplnEntry."Item Ledger Entry No.");
OnAdjustAppliedInbndTransEntry(TransItemLedgEntry);
if not TransItemLedgEntry."Completely Invoiced" then
AdjustNotInvdRevaluation(TransItemLedgEntry, TransItemApplnEntry);
CalcTransEntryOldCost(TempCostElementBuf, TransValueEntry, TransItemApplnEntry."Item Ledger Entry No.");
if CalcInbndEntryAdjustedCost(
TempAdjustedCostElementBuf,
TransItemApplnEntry, TransItemLedgEntry."Entry No.",
TransItemApplnEntry."Transferred-from Entry No.",
false, Recursion)
then
if not TransItemLedgEntry."Completely Invoiced" then begin
TransItemLedgEntry.SetCompletelyInvoiced();
EntryAdjusted := true;
end;
if UpdateAdjmtBuf(
TransValueEntry,
TempAdjustedCostElementBuf."Actual Cost" - TempCostElementBuf."Actual Cost",
TempAdjustedCostElementBuf."Actual Cost (ACY)" - TempCostElementBuf."Actual Cost (ACY)",
TransItemLedgEntry."Posting Date",
TransValueEntry."Entry Type")
then
EntryAdjusted := true;
if EntryAdjusted then begin
ClearOutboundEntryCostBuffer(TransItemLedgEntry."Entry No.");
UpdateAvgCostAdjmtEntryPoint(TransValueEntry);
ForwardAppliedCostRecursion(TransItemLedgEntry);
end;
end;
local procedure CalcTransEntryOldCost(var CostElementBuf: Record "Cost Element Buffer"; var TransValueEntry: Record "Value Entry"; ItemLedgEntryNo: Integer)
var
TransValueEntry2: Record "Value Entry";
ProcessTransValueEntry: Boolean;
begin
Clear(CostElementBuf);
TransValueEntry2 := TransValueEntry;
TransValueEntry.SetCurrentKey("Item Ledger Entry No.", "Entry Type");
TransValueEntry.SetRange("Item Ledger Entry No.", ItemLedgEntryNo);
TransValueEntry.SetRange("Entry Type", TransValueEntry."Entry Type"::"Direct Cost");
TransValueEntry.Ascending(false);
LoadFields(TransValueEntry);
TransValueEntry.FindSet();
repeat
ProcessTransValueEntry := TransValueEntry."Item Charge No." = '';
OnCalcTransEntryOldCostOnBeforeProcessTransValueEntry(TransValueEntry, ProcessTransValueEntry);
if ProcessTransValueEntry then begin
if TempInvtAdjmtBuf.Get(TransValueEntry."Entry No.") then
TransValueEntry.AddCost(TempInvtAdjmtBuf);
CostElementBuf."Actual Cost" := CostElementBuf."Actual Cost" + TransValueEntry."Cost Amount (Actual)";
CostElementBuf."Actual Cost (ACY)" := CostElementBuf."Actual Cost (ACY)" + TransValueEntry."Cost Amount (Actual) (ACY)";
TransValueEntry2 := TransValueEntry;
end;
until TransValueEntry.Next() = 0;
TransValueEntry := TransValueEntry2;
end;
local procedure ForwardCostToInbndEntries(ItemLedgEntryNo: Integer)
var
ItemApplnEntry: Record "Item Application Entry";
ItemApplicationEntriesInb: Query "Item Application Entries Inb.";
begin
if ItemApplnEntry.AppliedInbndEntryExists(ItemApplicationEntriesInb, ItemLedgEntryNo, true) then
repeat
AdjustAppliedInbndEntries(ItemApplicationEntriesInb);
until not ItemApplicationEntriesInb.Read();
end;
local procedure AdjustAppliedInbndEntries(var ItemApplicationEntriesInb: Query "Item Application Entries Inb.")
var
OutbndItemLedgEntry: Record "Item Ledger Entry";
InbndValueEntry: Record "Value Entry";
InbndItemLedgEntry: Record "Item Ledger Entry";
TempDocCostElementBuffer: Record "Cost Element Buffer" temporary;
TempOldCostElementBuf: Record "Cost Element Buffer" temporary;
EntryAdjusted: Boolean;
begin
OutbndItemLedgEntry.SetLoadFields(Quantity, "Invoiced Quantity", "Completely Invoiced");
OutbndItemLedgEntry.Get(ItemApplicationEntriesInb.Outbound_Item_Entry_No);
CalcItemApplnEntryOldCost(TempOldCostElementBuf, OutbndItemLedgEntry, ItemApplicationEntriesInb.Quantity);
InbndItemLedgEntry.SetBaseLoadFields();
InbndItemLedgEntry.Get(ItemApplicationEntriesInb.Item_Ledger_Entry_No);
OnAdjustAppliedInbndEntry(InbndItemLedgEntry);
InbndValueEntry.SetCurrentKey("Item Ledger Entry No.", "Document No.");
InbndValueEntry.SetRange("Item Ledger Entry No.", ItemApplicationEntriesInb.Item_Ledger_Entry_No);
OnAdjustAppliedInbndEntriesOnAfterSetFilter(InbndValueEntry);
LoadFields(InbndValueEntry);
InbndValueEntry.FindSet();
repeat
if (InbndValueEntry."Entry Type" = InbndValueEntry."Entry Type"::"Direct Cost") and
(InbndValueEntry."Item Charge No." = '') and
not ExpCostIsCompletelyInvoiced(InbndItemLedgEntry, InbndValueEntry)
then begin
InbndValueEntry.SetRange("Document No.", InbndValueEntry."Document No.");
InbndValueEntry.SetRange("Document Line No.", InbndValueEntry."Document Line No.");
CalcInbndDocOldCost(InbndValueEntry, TempDocCostElementBuffer);
if not InbndValueEntry."Expected Cost" then begin
TempDocCostElementBuffer.GetElement("Cost Entry Type"::"Direct Cost");
InbndValueEntry."Valued Quantity" := TempDocCostElementBuffer."Invoiced Quantity";
InbndValueEntry."Invoiced Quantity" := TempDocCostElementBuffer."Invoiced Quantity";
end;
CalcInbndDocNewCost(
TempDocCostElementBuffer, TempOldCostElementBuf, InbndValueEntry."Expected Cost",
InbndValueEntry."Valued Quantity" / InbndItemLedgEntry.Quantity);
if CreateCostAdjmtBuf(
InbndValueEntry, TempDocCostElementBuffer, InbndItemLedgEntry."Posting Date", InbndValueEntry."Entry Type")
then begin
EntryAdjusted := true;
TempValueEntryCalcdOutbndCostBuf.Reset();
TempValueEntryCalcdOutbndCostBuf.DeleteAll();
end;
InbndValueEntry.FindLast();
InbndValueEntry.SetRange("Document No.");
InbndValueEntry.SetRange("Document Line No.");
end;
until InbndValueEntry.Next() = 0;
// Update transfers, consumptions
if IsUpdateCompletelyInvoiced(
InbndItemLedgEntry, OutbndItemLedgEntry."Completely Invoiced")
then begin
InbndItemLedgEntry.SetCompletelyInvoiced();
EntryAdjusted := true;
end;
if EntryAdjusted then begin
UpdateAvgCostAdjmtEntryPoint(InbndValueEntry);
ForwardAppliedCostRecursion(InbndItemLedgEntry);
end;
end;
local procedure CalcItemApplnEntryOldCost(var OldCostElementBuf: Record "Cost Element Buffer"; OutbndItemLedgEntry: Record "Item Ledger Entry"; ItemApplnEntryQty: Decimal)
var
OutbndValueEntry: Record "Value Entry";
ShareOfExpectedCost: Decimal;
begin
ShareOfExpectedCost :=
(OutbndItemLedgEntry.Quantity - OutbndItemLedgEntry."Invoiced Quantity") / OutbndItemLedgEntry.Quantity;
Clear(OldCostElementBuf);
OutbndValueEntry.SetCurrentKey("Item Ledger Entry No.");
OutbndValueEntry.SetRange("Item Ledger Entry No.", OutbndItemLedgEntry."Entry No.");
OutbndValueEntry.SetLoadFields("Expected Cost", "Cost Amount (Actual)", "Cost Amount (Actual) (ACY)", "Cost Amount (Expected)", "Cost Amount (Expected) (ACY)");
OutbndValueEntry.FindSet();
repeat
if TempInvtAdjmtBuf.Get(OutbndValueEntry."Entry No.") then
OutbndValueEntry.AddCost(TempInvtAdjmtBuf);
if OutbndValueEntry."Expected Cost" then begin
OldCostElementBuf."Actual Cost" := OldCostElementBuf."Actual Cost" + OutbndValueEntry."Cost Amount (Expected)" * ShareOfExpectedCost;
OldCostElementBuf."Actual Cost (ACY)" := OldCostElementBuf."Actual Cost (ACY)" + OutbndValueEntry."Cost Amount (Expected) (ACY)" * ShareOfExpectedCost;
end else begin
OldCostElementBuf."Actual Cost" := OldCostElementBuf."Actual Cost" + OutbndValueEntry."Cost Amount (Actual)";
OldCostElementBuf."Actual Cost (ACY)" := OldCostElementBuf."Actual Cost (ACY)" + OutbndValueEntry."Cost Amount (Actual) (ACY)";
end;
until OutbndValueEntry.Next() = 0;
OldCostElementBuf.RoundActualCost(
ItemApplnEntryQty / OutbndItemLedgEntry.Quantity,
GLSetup."Amount Rounding Precision", Currency."Amount Rounding Precision");
end;
local procedure CalcInbndDocOldCost(InbndValueEntry: Record "Value Entry"; var CostElementBuf: Record "Cost Element Buffer")
begin
CostElementBuf.DeleteAll();
InbndValueEntry.SetCurrentKey("Item Ledger Entry No.", "Document No.");
InbndValueEntry.SetRange("Item Ledger Entry No.", InbndValueEntry."Item Ledger Entry No.");
InbndValueEntry.SetRange("Document No.", InbndValueEntry."Document No.");
InbndValueEntry.SetRange("Document Line No.", InbndValueEntry."Document Line No.");
InbndValueEntry.SetLoadFields(
"Entry Type", "Item Charge No.",
"Cost Amount (Expected)", "Cost Amount (Expected) (ACY)", "Cost Amount (Actual)", "Cost Amount (Actual) (ACY)",
"Invoiced Quantity", "Expected Cost");
if InbndValueEntry.FindSet() then
repeat
if (InbndValueEntry."Entry Type" = InbndValueEntry."Entry Type"::"Direct Cost") and
(InbndValueEntry."Item Charge No." = '')
then begin
if TempInvtAdjmtBuf.Get(InbndValueEntry."Entry No.") then
InbndValueEntry.AddCost(TempInvtAdjmtBuf);
if InbndValueEntry."Expected Cost" then
CostElementBuf.AddExpectedCostElement("Cost Entry Type"::"Direct Cost", InbndValueEntry)
else begin
CostElementBuf.AddActualCostElement("Cost Entry Type"::"Direct Cost", InbndValueEntry);
if InbndValueEntry."Invoiced Quantity" <> 0 then begin
CostElementBuf."Invoiced Quantity" := CostElementBuf."Invoiced Quantity" + InbndValueEntry."Invoiced Quantity";
if not CostElementBuf.Modify() then
CostElementBuf.Insert();
end;
end;
end;
until InbndValueEntry.Next() = 0;
end;
local procedure CalcInbndDocNewCost(var NewCostElementBuf: Record "Cost Element Buffer"; OldCostElementBuf: Record "Cost Element Buffer"; Expected: Boolean; ShareOfTotalCost: Decimal)
begin
OldCostElementBuf.RoundActualCost(
ShareOfTotalCost, GLSetup."Amount Rounding Precision", Currency."Amount Rounding Precision");
if Expected then begin
NewCostElementBuf."Actual Cost" := OldCostElementBuf."Actual Cost" - NewCostElementBuf."Expected Cost";
NewCostElementBuf."Actual Cost (ACY)" := OldCostElementBuf."Actual Cost (ACY)" - NewCostElementBuf."Expected Cost (ACY)";
end else begin
NewCostElementBuf."Actual Cost" := OldCostElementBuf."Actual Cost" - NewCostElementBuf."Actual Cost";
NewCostElementBuf."Actual Cost (ACY)" := OldCostElementBuf."Actual Cost (ACY)" - NewCostElementBuf."Actual Cost (ACY)";
end;
end;
local procedure IsUpdateCompletelyInvoiced(ItemLedgEntry: Record "Item Ledger Entry"; CompletelyInvoiced: Boolean) Result: Boolean
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeIsUpdateCompletelyInvoiced(ItemLedgEntry, CompletelyInvoiced, Result, IsHandled);
if IsHandled then
exit(Result);
exit(
(ItemLedgEntry."Entry Type" in [ItemLedgEntry."Entry Type"::Transfer, ItemLedgEntry."Entry Type"::Consumption]) and
not ItemLedgEntry."Completely Invoiced" and
CompletelyInvoiced);
end;
local procedure CalcInbndEntryAdjustedCost(var AdjustedCostElementBuf: Record "Cost Element Buffer"; ItemApplnEntry: Record "Item Application Entry"; OutbndItemLedgEntryNo: Integer; InbndItemLedgEntryNo: Integer; ExactCostReversing: Boolean; Recursion: Boolean) CompletelyInvoiced: Boolean
var
InbndValueEntry: Record "Value Entry";
InbndItemLedgEntry: Record "Item Ledger Entry";
QtyNotInvoiced: Decimal;
ShareOfTotalCost: Decimal;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCalcInbndEntryAdjustedCost(AdjustedCostElementBuf, ItemApplnEntry, OutbndItemLedgEntryNo, InbndItemLedgEntryNo, ExactCostReversing, Recursion, CompletelyInvoiced, IsHandled);
if not IsHandled then begin
AdjustedCostElementBuf.DeleteAll();
InbndItemLedgEntry.SetLoadFields(Quantity, "Invoiced Quantity", "Completely Invoiced");
InbndItemLedgEntry.Get(InbndItemLedgEntryNo);
InbndValueEntry.SetCurrentKey("Item Ledger Entry No.");
InbndValueEntry.SetRange("Item Ledger Entry No.", InbndItemLedgEntryNo);
QtyNotInvoiced := InbndItemLedgEntry.Quantity - InbndItemLedgEntry."Invoiced Quantity";
InbndValueEntry.SetLoadFields(
"Expected Cost", "Entry Type", "Applies-to Entry",
"Cost Amount (Actual)", "Cost Amount (Actual) (ACY)", "Cost Amount (Expected)", "Cost Amount (Expected) (ACY)",
"Valued Quantity", "Partial Revaluation");
InbndValueEntry.FindSet();
repeat
if not ExpCostIsCompletelyInvoiced(InbndItemLedgEntry, InbndValueEntry) then
if IncludedInCostCalculation(InbndValueEntry, OutbndItemLedgEntryNo) then begin
OnCalcInbndEntryAdjustedCostOnBeforeAddCost(Item, InbndValueEntry);
if TempInvtAdjmtBuf.Get(InbndValueEntry."Entry No.") then
InbndValueEntry.AddCost(TempInvtAdjmtBuf);
case true of
IsInterimRevaluation(InbndValueEntry):
begin
ShareOfTotalCost := InbndItemLedgEntry.Quantity / InbndValueEntry."Valued Quantity";
AdjustedCostElementBuf.AddActualCostElement(
AdjustedCostElementBuf.Type::"Direct Cost",
(InbndValueEntry."Cost Amount (Expected)" + InbndValueEntry."Cost Amount (Actual)") * ShareOfTotalCost,
(InbndValueEntry."Cost Amount (Expected) (ACY)" + InbndValueEntry."Cost Amount (Actual) (ACY)") * ShareOfTotalCost);
end;
InbndValueEntry."Expected Cost":
begin
ShareOfTotalCost := QtyNotInvoiced / InbndValueEntry."Valued Quantity";
AdjustedCostElementBuf.AddActualCostElement(
AdjustedCostElementBuf.Type::"Direct Cost",
InbndValueEntry."Cost Amount (Expected)" * ShareOfTotalCost,
InbndValueEntry."Cost Amount (Expected) (ACY)" * ShareOfTotalCost);
end;
InbndValueEntry."Partial Revaluation":
begin
ShareOfTotalCost := InbndItemLedgEntry.Quantity / InbndValueEntry."Valued Quantity";
AdjustedCostElementBuf.AddActualCostElement(
AdjustedCostElementBuf.Type::"Direct Cost",
InbndValueEntry."Cost Amount (Actual)" * ShareOfTotalCost,
InbndValueEntry."Cost Amount (Actual) (ACY)" * ShareOfTotalCost);
end;
(InbndValueEntry."Entry Type" in [InbndValueEntry."Entry Type"::"Direct Cost", InbndValueEntry."Entry Type"::Revaluation]) or not ExactCostReversing:
AdjustedCostElementBuf.AddActualCostElement(AdjustedCostElementBuf.Type::"Direct Cost", InbndValueEntry);
InbndValueEntry."Entry Type" = InbndValueEntry."Entry Type"::"Indirect Cost":
AdjustedCostElementBuf.AddActualCostElement(AdjustedCostElementBuf.Type::"Indirect Cost", InbndValueEntry);
else
AdjustedCostElementBuf.AddActualCostElement(AdjustedCostElementBuf.Type::Variance, InbndValueEntry);
end;
end;
until InbndValueEntry.Next() = 0;
IsHandled := false;
OnCalcInbndEntryAdjustedCostOnBeforeCalcNewAdjustedCost(AdjustedCostElementBuf, ItemApplnEntry, InbndItemLedgEntry, IsHandled);
if not IsHandled then
CalcNewAdjustedCost(AdjustedCostElementBuf, ItemApplnEntry.Quantity / InbndItemLedgEntry.Quantity);
if AdjustAppliedCostEntry(ItemApplnEntry, InbndItemLedgEntryNo, Recursion) then
TempRndgResidualBuf.AddAdjustedCost(
ItemApplnEntry."Inbound Item Entry No.",
AdjustedCostElementBuf."Actual Cost", AdjustedCostElementBuf."Actual Cost (ACY)",
ItemApplnEntry."Output Completely Invd. Date" <> 0D);
CompletelyInvoiced := InbndItemLedgEntry."Completely Invoiced";
end;
OnAfterCalcInbndEntryAdjustedCost(AdjustedCostElementBuf, InbndValueEntry, InbndItemLedgEntry, ItemApplnEntry, OutbndItemLedgEntryNo, CompletelyInvoiced);
end;
local procedure CalcNewAdjustedCost(var AdjustedCostElementBuf: Record "Cost Element Buffer"; ShareOfTotalCost: Decimal)
begin
if AdjustedCostElementBuf.FindSet() then
repeat
AdjustedCostElementBuf.RoundActualCost(ShareOfTotalCost, GLSetup."Amount Rounding Precision", Currency."Amount Rounding Precision");
AdjustedCostElementBuf.Modify();
until AdjustedCostElementBuf.Next() = 0;
AdjustedCostElementBuf.CalcSums("Actual Cost", "Actual Cost (ACY)");
AdjustedCostElementBuf.AddActualCostElement(AdjustedCostElementBuf.Type::Total, AdjustedCostElementBuf."Actual Cost", AdjustedCostElementBuf."Actual Cost (ACY)");
end;
local procedure AdjustAppliedCostEntry(ItemApplnEntry: Record "Item Application Entry"; ItemLedgEntryNo: Integer; Recursion: Boolean): Boolean
begin
exit(
(ItemApplnEntry."Transferred-from Entry No." <> ItemLedgEntryNo) and
(ItemApplnEntry."Inbound Item Entry No." = TempRndgResidualBuf."Item Ledger Entry No.") and
not Recursion);
end;
procedure IncludedInCostCalculation(InbndValueEntry: Record "Value Entry"; OutbndItemLedgEntryNo: Integer): Boolean
var
OutbndValueEntry: Record "Value Entry";
begin
if InbndValueEntry."Entry Type" = InbndValueEntry."Entry Type"::Revaluation then begin
if InbndValueEntry."Applies-to Entry" <> 0 then begin
InbndValueEntry.SetLoadFields("Entry Type", "Applies-to Entry", "Partial Revaluation", "Valuation Date");
InbndValueEntry.Get(InbndValueEntry."Applies-to Entry");
exit(IncludedInCostCalculation(InbndValueEntry, OutbndItemLedgEntryNo));
end;
if InbndValueEntry."Partial Revaluation" then begin
OutbndValueEntry.SetCurrentKey("Item Ledger Entry No.");
OutbndValueEntry.SetLoadFields("Valuation Date", "Posting Date");
OutbndValueEntry.SetRange("Item Ledger Entry No.", OutbndItemLedgEntryNo);
OutbndValueEntry.SetFilter("Item Ledger Entry Quantity", '<>0');
OutbndValueEntry.FindFirst();
exit(
OutbndValueEntry.EntryNoHasSameSign(InbndValueEntry."Entry No.") and ((OutbndValueEntry."Entry No." > InbndValueEntry."Entry No.")) or
not OutbndValueEntry.EntryNoHasSameSign(InbndValueEntry."Entry No.") and (OutbndValueEntry.SystemCreatedAt > InbndValueEntry.SystemCreatedAt) or
(OutbndValueEntry.GetValuationDate() > InbndValueEntry."Valuation Date") or
(OutbndValueEntry."Entry No." = 0));
end;
end;
exit(InbndValueEntry."Entry Type" <> InbndValueEntry."Entry Type"::Rounding);
end;
local procedure CalcOutbndDocOldCost(var CostElementBuf: Record "Cost Element Buffer"; OutbndValueEntry: Record "Value Entry"; ExactCostReversing: Boolean)
var
ValueEntry: Record "Value Entry";
begin
CostElementBuf.DeleteAll();
ValueEntry.SetCurrentKey("Item Ledger Entry No.", "Document No.", "Document Line No.");
ValueEntry.SetRange("Item Ledger Entry No.", OutbndValueEntry."Item Ledger Entry No.");
ValueEntry.SetRange("Document No.", OutbndValueEntry."Document No.");
ValueEntry.SetRange("Document Line No.", OutbndValueEntry."Document Line No.");
ValueEntry.SetLoadFields(
"Cost Amount (Expected)", "Cost Amount (Expected) (ACY)", "Cost Amount (Actual)", "Cost Amount (Actual) (ACY)",
"Expected Cost", "Entry Type", "Invoiced Quantity");
ValueEntry.FindSet();
repeat
if TempInvtAdjmtBuf.Get(ValueEntry."Entry No.") then
ValueEntry.AddCost(TempInvtAdjmtBuf);
CostElementBuf.AddExpectedCostElement(
CostElementBuf.Type::Total, ValueEntry."Cost Amount (Expected)", ValueEntry."Cost Amount (Expected) (ACY)");
if not ValueEntry."Expected Cost" then
case true of
(ValueEntry."Entry Type" in [ValueEntry."Entry Type"::"Direct Cost", ValueEntry."Entry Type"::Revaluation]) or not ExactCostReversing:
begin
CostElementBuf.AddActualCostElement(CostElementBuf.Type::"Direct Cost", ValueEntry);
if ValueEntry."Invoiced Quantity" <> 0 then begin
CostElementBuf."Invoiced Quantity" += ValueEntry."Invoiced Quantity";
if not CostElementBuf.Modify() then
CostElementBuf.Insert();
end;
end;
ValueEntry."Entry Type" = ValueEntry."Entry Type"::"Indirect Cost":
CostElementBuf.AddActualCostElement(CostElementBuf.Type::"Indirect Cost", ValueEntry);
else
CostElementBuf.AddActualCostElement(CostElementBuf.Type::Variance, ValueEntry);
end;
until ValueEntry.Next() = 0;
CostElementBuf.CalcSums("Actual Cost", "Actual Cost (ACY)");
CostElementBuf.AddActualCostElement(CostElementBuf.Type::Total, CostElementBuf."Actual Cost", CostElementBuf."Actual Cost (ACY)");
end;
local procedure EliminateRndgResidual(InbndItemLedgEntry: Record "Item Ledger Entry"; AppliedQty: Decimal)
var
ItemJnlLine: Record "Item Journal Line";
ValueEntry: Record "Value Entry";
RndgCost: Decimal;
RndgCostACY: Decimal;
IsHandled: Boolean;
begin
if IsRndgAllowed(InbndItemLedgEntry, AppliedQty) then begin
TempInvtAdjmtBuf.CalcItemLedgEntryCost(InbndItemLedgEntry."Entry No.", false);
ValueEntry.CalcItemLedgEntryCost(InbndItemLedgEntry."Entry No.", false);
ValueEntry.AddCost(TempInvtAdjmtBuf);
OnEliminateRndgResidualOnAfterCalcInboundCost(ValueEntry, InbndItemLedgEntry."Entry No.");
TempRndgResidualBuf.SetRange("Item Ledger Entry No.", InbndItemLedgEntry."Entry No.");
TempRndgResidualBuf.SetRange("Completely Invoiced", false);
if TempRndgResidualBuf.IsEmpty() then begin
TempRndgResidualBuf.SetRange("Completely Invoiced");
TempRndgResidualBuf.CalcSums("Adjusted Cost", "Adjusted Cost (ACY)");
RndgCost := -(ValueEntry."Cost Amount (Actual)" + TempRndgResidualBuf."Adjusted Cost");
RndgCostACY := -(ValueEntry."Cost Amount (Actual) (ACY)" + TempRndgResidualBuf."Adjusted Cost (ACY)");
IsHandled := false;
OnEliminateRndgResidualOnBeforeCheckHasNewCost(InbndItemLedgEntry, ValueEntry, RndgCost, RndgCostACY, IsHandled);
if not IsHandled then
if HasNewCost(RndgCost, RndgCostACY) then begin
ValueEntry.Reset();
ValueEntry.SetCurrentKey("Item Ledger Entry No.", "Entry Type");
ValueEntry.SetRange("Item Ledger Entry No.", InbndItemLedgEntry."Entry No.");
ValueEntry.SetRange("Entry Type", ValueEntry."Entry Type"::"Direct Cost");
ValueEntry.SetRange("Item Charge No.", '');
ValueEntry.SetRange(Adjustment, false);
ValueEntry.SetBaseLoadFields();
ValueEntry.FindLast();
InitRndgResidualItemJnlLine(ItemJnlLine, ValueEntry);
PostItemJnlLine(ItemJnlLine, ValueEntry, RndgCost, RndgCostACY);
end;
end;
end;
TempRndgResidualBuf.Reset();
TempRndgResidualBuf.DeleteAll();
end;
local procedure IsRndgAllowed(ItemLedgEntry: Record "Item Ledger Entry"; AppliedQty: Decimal): Boolean
begin
exit(
not ItemLedgEntry.Open and
ItemLedgEntry."Completely Invoiced" and
ItemLedgEntry.Positive and
(AppliedQty = -ItemLedgEntry.Quantity) and
not LevelExceeded);
end;
local procedure InitRndgResidualItemJnlLine(var ItemJnlLine: Record "Item Journal Line"; OrigValueEntry: Record "Value Entry")
begin
ItemJnlLine.Init();
ItemJnlLine."Value Entry Type" := ItemJnlLine."Value Entry Type"::Rounding;
ItemJnlLine."Quantity (Base)" := 1;
ItemJnlLine."Invoiced Qty. (Base)" := 1;
ItemJnlLine."Source No." := OrigValueEntry."Source No.";
OnAfterInitRndgResidualItemJnlLine(ItemJnlLine, OrigValueEntry);
end;
local procedure AdjustItemAvgCost()
var
TempOutbndValueEntry: Record "Value Entry" temporary;
TempExcludedValueEntry: Record "Value Entry" temporary;
TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary;
AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point";
RemainingOutbnd: Integer;
Restart: Boolean;
EndOfValuationDateReached: Boolean;
IsHandled: Boolean;
begin
if not IsAvgCostItem() then
exit;
UpDateWindow(WindowAdjmtLevel, WindowItem, Text008, WindowFWLevel, WindowEntry, 0);
DeleteAvgBuffers(TempOutbndValueEntry, TempExcludedValueEntry);
Clear(FixedAppliedItemEntryNos);
while AvgCostAdjmtEntryPointExist(TempAvgCostAdjmtEntryPoint) do begin
repeat
Restart := false;
EndOfValuationDateReached := false;
AvgCostAdjmtEntryPoint := TempAvgCostAdjmtEntryPoint;
OnBeforeAvgCostAdjmtEntryPoint(AvgCostAdjmtEntryPoint);
if (ConsumpAdjmtInPeriodWithOutput <> 0D) and
(ConsumpAdjmtInPeriodWithOutput <= AvgCostAdjmtEntryPoint."Valuation Date")
then
exit;
AvgCostAdjmtEntryPoint.SetAvgCostAjmtFilter(TempAvgCostAdjmtEntryPoint);
SetDateFilterUntilLastDate(TempAvgCostAdjmtEntryPoint);
TempAvgCostAdjmtEntryPoint.DeleteAll();
TempAvgCostAdjmtEntryPoint.Reset();
AvgCostAdjmtEntryPoint.SetAvgCostAjmtFilter(AvgCostAdjmtEntryPoint);
SetDateFilterUntilLastDate(AvgCostAdjmtEntryPoint);
AvgCostAdjmtEntryPoint.ModifyAll("Cost Is Adjusted", true);
AvgCostAdjmtEntryPoint.Reset();
OnAdjustItemAvgCostOnBeforeAdjustValueEntries();
while true do begin
if Restart or EndOfValuationDateReached then
break;
if not FindOutboundEntriesToAdjust(TempOutbndValueEntry, TempExcludedValueEntry, AvgCostAdjmtEntryPoint) then
break;
RemainingOutbnd := TempOutbndValueEntry.Count();
TempOutbndValueEntry.SetCurrentKey("Item Ledger Entry No.");
TempOutbndValueEntry.FindSet();
OnBeforeIteratingOverOutbndAvgEntries(TempOutbndValueEntry, AvgCostAdjmtEntryPoint, RemainingOutbnd);
repeat
OnAdjustItemAvgCostOnBeforeUpdateWindow(Item);
UpDateWindow(WindowAdjmtLevel, WindowItem, WindowAdjust, WindowFWLevel, WindowEntry, RemainingOutbnd);
RemainingOutbnd -= 1;
AdjustOutbndAvgEntry(TempOutbndValueEntry, TempExcludedValueEntry);
UpdateConsumpAvgEntry(TempOutbndValueEntry);
until TempOutbndValueEntry.Next() = 0;
AvgCostAdjmtEntryPoint.SetAvgCostAjmtFilter(AvgCostAdjmtEntryPoint);
SetDateFilterUntilLastDate(AvgCostAdjmtEntryPoint);
Restart := AvgCostAdjmtEntryPoint.FindFirst() and not AvgCostAdjmtEntryPoint."Cost Is Adjusted";
OnAdjustItemAvgCostOnAfterCalcRestart(TempExcludedValueEntry, Restart);
if AvgCostAdjmtEntryPoint."Valuation Date" >= AdjustTillDate then
EndOfValuationDateReached := true
else
AvgCostAdjmtEntryPoint."Valuation Date" := GetNextDate(AvgCostAdjmtEntryPoint."Valuation Date");
end;
until (TempAvgCostAdjmtEntryPoint.Next() = 0) or Restart;
IsHandled := false;
OnAdjustItemAvgCostOnAfterLastTempAvgCostAdjmtEntryPoint(TempAvgCostAdjmtEntryPoint, Restart, IsHandled);
if IsHandled then
break;
end;
end;
local procedure AvgCostAdjmtEntryPointExist(var ToAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point"): Boolean
var
AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point";
begin
AvgCostAdjmtEntryPoint.SetCurrentKey("Item No.", "Cost Is Adjusted", "Valuation Date");
AvgCostAdjmtEntryPoint.SetRange("Item No.", Item."No.");
AvgCostAdjmtEntryPoint.SetRange("Cost Is Adjusted", false);
AvgCostAdjmtEntryPoint.SetRange("Valuation Date", 0D, AdjustTillDate);
CopyAvgCostAdjmtToAvgCostAdjmt(AvgCostAdjmtEntryPoint, ToAvgCostAdjmtEntryPoint);
ToAvgCostAdjmtEntryPoint.SetCurrentKey("Item No.", "Cost Is Adjusted", "Valuation Date");
exit(ToAvgCostAdjmtEntryPoint.FindFirst())
end;
local procedure FindOutboundEntriesToAdjust(var OutbndValueEntry: Record "Value Entry"; var ExcludedValueEntry: Record "Value Entry"; var AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point") EntriesFound: Boolean
var
FindNextRange: Boolean;
begin
EntriesFound := false;
repeat
if AvgValueEntriesToAdjustExist(OutbndValueEntry, ExcludedValueEntry, AvgCostAdjmtEntryPoint, FindNextRange) then
EntriesFound := true;
if FindNextRange and (AvgCostAdjmtEntryPoint."Valuation Date" < AdjustTillDate) then begin
AvgCostAdjmtEntryPoint."Valuation Date" := GetNextDate(AvgCostAdjmtEntryPoint."Valuation Date");
OnAvgValueEntriesToAdjustExistOnFindNextRangeOnBeforeAvgValueEntriesToAdjustExist(OutbndValueEntry, ExcludedValueEntry, AvgCostAdjmtEntryPoint);
end else
FindNextRange := false;
until not FindNextRange;
end;
local procedure AvgValueEntriesToAdjustExist(var OutbndValueEntry: Record "Value Entry"; var ExcludedValueEntry: Record "Value Entry"; var AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point"; var FindNextRange: Boolean): Boolean
var
ValueEntry: Record "Value Entry";
CalendarPeriod: Record Date;
NextFiscalYearAccPeriod: Record "Accounting Period";
ItemApplicationEntry: Record "Item Application Entry";
DoInsertTempRevaluationPoint: Boolean;
begin
FindNextRange := false;
ResetAvgBuffers(OutbndValueEntry, ExcludedValueEntry);
CalendarPeriod."Period Start" := AvgCostAdjmtEntryPoint."Valuation Date";
AvgCostAdjmtEntryPoint.GetValuationPeriod(CalendarPeriod);
OnAfterGetValuationPeriod(CalendarPeriod, Item);
ValueEntry.SetCurrentKey("Item No.", "Valuation Date");
ValueEntry.SetRange("Item No.", AvgCostAdjmtEntryPoint."Item No.");
if AvgCostAdjmtEntryPoint.AvgCostCalcTypeIsChanged(CalendarPeriod."Period Start") then begin
AvgCostAdjmtEntryPoint.GetAvgCostCalcTypeIsChgPeriod(NextFiscalYearAccPeriod, CalendarPeriod."Period Start");
ValueEntry.SetRange("Valuation Date", CalendarPeriod."Period Start", Min(AdjustTillDate, CalcDate('<-1D>', NextFiscalYearAccPeriod."Starting Date")));
end else
ValueEntry.SetRange("Valuation Date", CalendarPeriod."Period Start", Min(AdjustTillDate, DMY2Date(31, 12, 9999)));
IsAvgCostCalcTypeItem := AvgCostAdjmtEntryPoint.IsAvgCostCalcTypeItem(CalendarPeriod."Period End");
if not IsAvgCostCalcTypeItem then begin
ValueEntry.SetRange("Location Code", AvgCostAdjmtEntryPoint."Location Code");
ValueEntry.SetRange("Variant Code", AvgCostAdjmtEntryPoint."Variant Code");
end;
OnAvgValueEntriesToAdjustExistOnAfterSetAvgValueEntryFilters(ValueEntry);
ValueEntry.SetLoadFields("Item No.", "Valuation Date");
if ValueEntry.FindFirst() then begin
FindNextRange := true;
if ValueEntry."Valuation Date" > CalendarPeriod."Period End" then begin
AvgCostAdjmtEntryPoint."Valuation Date" := ValueEntry."Valuation Date";
CalendarPeriod."Period Start" := ValueEntry."Valuation Date";
AvgCostAdjmtEntryPoint.GetValuationPeriod(CalendarPeriod);
end;
if not (AvgCostAdjmtEntryPoint.ValuationExists(ValueEntry) and AvgCostAdjmtEntryPoint.PrevValuationAdjusted(ValueEntry)) or
((ConsumpAdjmtInPeriodWithOutput <> 0D) and (ConsumpAdjmtInPeriodWithOutput <= AvgCostAdjmtEntryPoint."Valuation Date"))
then begin
AvgCostAdjmtEntryPoint.UpdateValuationDate(ValueEntry);
FindNextRange := false;
exit(false);
end;
ValueEntry.SetRange("Valuation Date", CalendarPeriod."Period Start", CalendarPeriod."Period End");
OnAvgValueEntriesToAdjustExistOnAfterSetChildValueEntryFilters(ValueEntry);
OutbndValueEntry.Copy(ValueEntry);
if not OutbndValueEntry.IsEmpty() then begin
OutbndValueEntry.SetCurrentKey("Item Ledger Entry No.");
FindNextRange := false;
exit(true);
end;
DeleteAvgBuffers(OutbndValueEntry, ExcludedValueEntry);
ValueEntry.SetLoadFields();
LoadFields(ValueEntry);
ValueEntry.FindSet();
repeat
if ValueEntry."Entry Type" = ValueEntry."Entry Type"::Revaluation then begin
if ValueEntry."Partial Revaluation" then
DoInsertTempRevaluationPoint := true
else
DoInsertTempRevaluationPoint := ItemApplicationEntry.AppliedFromEntryExists(ValueEntry."Item Ledger Entry No.");
if DoInsertTempRevaluationPoint then begin
TempRevaluationPoint.Number := ValueEntry."Entry No.";
if TempRevaluationPoint.Insert() then;
FillFixApplBuffer(ValueEntry."Item Ledger Entry No.");
end;
end;
if ValueEntry."Valued By Average Cost" and not ValueEntry.Adjustment and (ValueEntry."Valued Quantity" < 0) then begin
OutbndValueEntry := ValueEntry;
OutbndValueEntry.Insert();
FindNextRange := false;
end;
OnAvgValueEntriesToAdjustExistOnBeforeIsNotAdjustment(ValueEntry, OutbndValueEntry);
if not ValueEntry.Adjustment then
if IsAvgCostException(ValueEntry, IsAvgCostCalcTypeItem) then begin
TempAvgCostExceptionBuf.Number := ValueEntry."Entry No.";
if TempAvgCostExceptionBuf.Insert() then;
TempAvgCostExceptionBuf.Number += 1;
if TempAvgCostExceptionBuf.Insert() then;
end;
ExcludedValueEntry := ValueEntry;
ExcludedValueEntry.Insert();
until ValueEntry.Next() = 0;
FetchOpenOutboundItemEntriesToExclude(AvgCostAdjmtEntryPoint, ExcludedValueEntry, OpenOutboundEntryNos, CalendarPeriod);
end;
exit(not OutbndValueEntry.IsEmpty() and not ValueEntry.IsEmpty());
end;
local procedure GetNextDate(CurrentDate: Date): Date
begin
if CurrentDate = 0D then
exit(00020101D);
exit(CalcDate('<+1D>', CurrentDate));
end;
local procedure AdjustOutbndAvgEntry(var OutbndValueEntry: Record "Value Entry"; var ExcludedValueEntry: Record "Value Entry")
var
OutbndItemLedgEntry: Record "Item Ledger Entry";
TempOldCostElementBuf: Record "Cost Element Buffer" temporary;
TempNewCostElementBuf: Record "Cost Element Buffer" temporary;
EntryAdjusted: Boolean;
begin
OutbndItemLedgEntry.SetLoadFields("Applies-to Entry", "Posting Date", Quantity, "Invoiced Quantity", "Entry Type", "Completely Invoiced");
OutbndItemLedgEntry.Get(OutbndValueEntry."Item Ledger Entry No.");
if OutbndItemLedgEntry."Applies-to Entry" <> 0 then
exit;
if ExpCostIsCompletelyInvoiced(OutbndItemLedgEntry, OutbndValueEntry) then
exit;
OnAdjustOutbndAvgEntry(OutbndValueEntry);
UpDateWindow(
WindowAdjmtLevel, WindowItem, WindowAdjust, WindowFWLevel, OutbndValueEntry."Item Ledger Entry No.", WindowOutbndEntry);
EntryAdjusted := OutbndItemLedgEntry.SetAvgTransCompletelyInvoiced();
if CalcAvgCost(OutbndValueEntry, TempNewCostElementBuf, ExcludedValueEntry) then begin
CalcOutbndDocOldCost(TempOldCostElementBuf, OutbndValueEntry, false);
if OutbndValueEntry."Expected Cost" then begin
TempNewCostElementBuf."Actual Cost" -= TempOldCostElementBuf."Expected Cost";
TempNewCostElementBuf."Actual Cost (ACY)" -= TempOldCostElementBuf."Expected Cost (ACY)";
end else begin
TempNewCostElementBuf."Actual Cost" -= TempOldCostElementBuf."Actual Cost";
TempNewCostElementBuf."Actual Cost (ACY)" -= TempOldCostElementBuf."Actual Cost (ACY)";
OnAdjustOutbndAvgEntryOnNewCostElementBuf(OutbndValueEntry);
end;
if UpdateAdjmtBuf(
OutbndValueEntry,
TempNewCostElementBuf."Actual Cost", TempNewCostElementBuf."Actual Cost (ACY)",
OutbndItemLedgEntry."Posting Date", OutbndValueEntry."Entry Type")
then
EntryAdjusted := true;
end;
if EntryAdjusted then begin
if OutbndItemLedgEntry."Entry Type" = OutbndItemLedgEntry."Entry Type"::Consumption then
OutbndItemLedgEntry.SetAppliedEntryToAdjust(false);
OnAdjustOutbndAvgEntryOnBeforeForwardAvgCostToInbndEntries(OutbndItemLedgEntry);
ForwardAvgCostToInbndEntries(OutbndItemLedgEntry."Entry No.");
end;
end;
procedure ExpCostIsCompletelyInvoiced(ItemLedgEntry: Record "Item Ledger Entry"; ValueEntry: Record "Value Entry"): Boolean
begin
exit(ValueEntry."Expected Cost" and (ItemLedgEntry.Quantity = ItemLedgEntry."Invoiced Quantity"));
end;
local procedure CalcAvgCost(OutbndValueEntry: Record "Value Entry"; var CostElementBuf: Record "Cost Element Buffer"; var ExcludedValueEntry: Record "Value Entry"): Boolean
var
ValueEntry: Record "Value Entry";
RoundingError: Decimal;
RoundingErrorACY: Decimal;
CanCalcAvgCost: Boolean;
begin
if OutbndValueEntry."Entry No." >= AvgCostBuf."Last Valid Value Entry No" then begin
ValueEntry.SumCostsTillValuationDate(OutbndValueEntry);
TempInvtAdjmtBuf.SumCostsTillValuationDate(OutbndValueEntry);
CostElementBuf."Remaining Quantity" := ValueEntry."Item Ledger Entry Quantity";
CostElementBuf."Actual Cost" :=
ValueEntry."Cost Amount (Actual)" + ValueEntry."Cost Amount (Expected)" +
TempInvtAdjmtBuf."Cost Amount (Actual)" + TempInvtAdjmtBuf."Cost Amount (Expected)";
CostElementBuf."Actual Cost (ACY)" :=
ValueEntry."Cost Amount (Actual) (ACY)" + ValueEntry."Cost Amount (Expected) (ACY)" +
TempInvtAdjmtBuf."Cost Amount (Actual) (ACY)" + TempInvtAdjmtBuf."Cost Amount (Expected) (ACY)";
RoundingError := 0;
RoundingErrorACY := 0;
OnCalcAvgCostOnAfterAssignRoundingError(RoundingError, RoundingErrorACY, CostElementBuf);
ExcludeAvgCostOnValuationDate(CostElementBuf, OutbndValueEntry, ExcludedValueEntry);
AvgCostBuf.UpdateAvgCostBuffer(
CostElementBuf, GetLastValidValueEntry(OutbndValueEntry."Entry No."));
end else
CostElementBuf.UpdateCostElementBuffer(AvgCostBuf);
CanCalcAvgCost :=
(CostElementBuf."Remaining Quantity" > 0) and
(CostElementBuf."Actual Cost" >= 0) and (CostElementBuf."Actual Cost (ACY)" >= 0);
if CanCalcAvgCost then begin
AvgCostBuf."Rounding Residual" := RoundingError;
AvgCostBuf."Rounding Residual (ACY)" := RoundingErrorACY;
RoundCost(
CostElementBuf."Actual Cost", AvgCostBuf."Rounding Residual", CostElementBuf."Actual Cost",
OutbndValueEntry."Valued Quantity" / CostElementBuf."Remaining Quantity",
GLSetup."Amount Rounding Precision");
RoundCost(
CostElementBuf."Actual Cost (ACY)", AvgCostBuf."Rounding Residual (ACY)", CostElementBuf."Actual Cost (ACY)",
OutbndValueEntry."Valued Quantity" / CostElementBuf."Remaining Quantity",
Currency."Amount Rounding Precision");
AvgCostBuf.DeductOutbndValueEntryFromBuf(OutbndValueEntry, CostElementBuf, IsAvgCostCalcTypeItem);
end;
exit(CanCalcAvgCost);
end;
local procedure ExcludeAvgCostOnValuationDate(var CostElementBuf: Record "Cost Element Buffer"; OutbndValueEntry: Record "Value Entry"; var ExcludedValueEntry: Record "Value Entry")
var
OutbndItemLedgEntry: Record "Item Ledger Entry";
OutbndEntryItemApplicationTrace: Record "Item Application Trace";
ExcludeILE: Boolean;
ExcludeEntry: Boolean;
FixedApplication: Boolean;
PreviousILENo: Integer;
RevalFixedApplnQty: Decimal;
ExclusionFactor: Decimal;
begin
ExcludedValueEntry.SetCurrentKey("Item Ledger Entry No.", "Entry Type");
OutbndItemLedgEntry.SetLoadFields("Entry No.");
OutbndItemLedgEntry.Get(OutbndValueEntry."Item Ledger Entry No.");
GetChainOfAppliedEntries(ItemApplicationTrace, OutbndItemLedgEntry, true);
OutbndEntryItemApplicationTrace.AddChain(OutbndValueEntry."Item Ledger Entry No.", ItemApplicationTrace);
OnExcludeAvgCostOnValuationDateOnAfterGetItemApplicationTrace(OutbndValueEntry, OutbndEntryItemApplicationTrace);
PreviousILENo := 0;
if ExcludedValueEntry.FindSet() then
repeat
OnExcludeAvgCostOnValuationDate(ExcludedValueEntry);
// Execute this block for the first Value Entry for each ILE
if PreviousILENo <> ExcludedValueEntry."Item Ledger Entry No." then begin
// Calculate whether a Value Entry should be excluded from average cost calculation based on ILE information
// All fixed application entries (except revaluation) are included in the buffer because the inbound and outbound entries cancel each other
FixedApplication := false;
ExcludeILE := IsExcludeILEFromAvgCostCalc(ExcludedValueEntry, OutbndValueEntry, OutbndEntryItemApplicationTrace, FixedApplication);
PreviousILENo := ExcludedValueEntry."Item Ledger Entry No.";
end;
ExcludeEntry := ExcludeILE;
if FixedApplication then begin
// If a revaluation entry should normally be excluded, but has a partial fixed application to an outbound, then the fixed applied portion should still be included in the buffer
if ExcludedValueEntry."Entry Type" = ExcludedValueEntry."Entry Type"::Revaluation then
if IsExcludeFromAvgCostForRevalPoint(ExcludedValueEntry, OutbndValueEntry) then begin
RevalFixedApplnQty := CalcRevalFixedApplnQty(ExcludedValueEntry);
if RevalFixedApplnQty <> ExcludedValueEntry."Valued Quantity" then begin
ExcludeEntry := true;
ExclusionFactor := (ExcludedValueEntry."Valued Quantity" - RevalFixedApplnQty) / ExcludedValueEntry."Valued Quantity";
ExcludedValueEntry."Cost Amount (Actual)" := RoundAmt(ExclusionFactor * ExcludedValueEntry."Cost Amount (Actual)", GLSetup."Amount Rounding Precision");
ExcludedValueEntry."Cost Amount (Expected)" :=
RoundAmt(ExclusionFactor * ExcludedValueEntry."Cost Amount (Expected)", GLSetup."Amount Rounding Precision");
ExcludedValueEntry."Cost Amount (Actual) (ACY)" :=
RoundAmt(ExclusionFactor * ExcludedValueEntry."Cost Amount (Actual) (ACY)", Currency."Amount Rounding Precision");
ExcludedValueEntry."Cost Amount (Expected) (ACY)" :=
RoundAmt(ExclusionFactor * ExcludedValueEntry."Cost Amount (Expected) (ACY)", Currency."Amount Rounding Precision");
end;
end;
end else
// For non-fixed applied entries
// For each value entry, perform additional check if there has been a revaluation in the period
if not ExcludeEntry then
// For non-revaluation entries, exclusion decision is based on the date of the first posted Direct Cost entry for the ILE to ensure all cost modifiers except revaluation
// are included or excluded based on the original item posting date
ExcludeEntry := IsExcludeFromAvgCostForRevalPoint(ExcludedValueEntry, OutbndValueEntry);
if ExcludeEntry then begin
CostElementBuf.ExcludeEntryFromAvgCostCalc(ExcludedValueEntry);
if TempInvtAdjmtBuf.Get(ExcludedValueEntry."Entry No.") then
CostElementBuf.ExcludeBufFromAvgCostCalc(TempInvtAdjmtBuf);
end;
until ExcludedValueEntry.Next() = 0;
end;
local procedure IsExcludeILEFromAvgCostCalc(ValueEntry: Record "Value Entry"; OutbndValueEntry: Record "Value Entry"; var OutbndEntryItemApplicationTrace: Record "Item Application Trace"; var FixedApplication: Boolean): Boolean
var
ItemLedgEntry: Record "Item Ledger Entry";
AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point";
begin
// Return "False" if the entry is the cost source
// Return "True" if the entry is cost recipient
// outbound open entry - cost recipient
if OpenOutboundEntryNos.Contains(ValueEntry."Item Ledger Entry No.") then
exit(false);
// fixed application is taken out
if FixedAppliedItemEntryNos.Contains(ValueEntry."Item Ledger Entry No.") then begin
FixedApplication := true;
exit(false);
end;
// entry itself - cost recipient
if ValueEntry."Item Ledger Entry No." = OutbndValueEntry."Item Ledger Entry No." then
exit(true);
ItemLedgEntry.SetLoadFields(Positive);
ItemLedgEntry.Get(ValueEntry."Item Ledger Entry No.");
// output with self-consumption - cost recipient
if ItemLedgEntry.Positive then
if IsOutputWithSelfConsumption(ValueEntry, OutbndValueEntry, OutbndEntryItemApplicationTrace) then
exit(true);
// inbound entry cost-applied to outbound - cost recipient
OutbndEntryItemApplicationTrace.Reset();
OutbndEntryItemApplicationTrace.SetRange("Entry No.", ValueEntry."Item Ledger Entry No.");
if not OutbndEntryItemApplicationTrace.IsEmpty() then
exit(true);
// regular inbound entry - cost source
if not ValueEntry."Valued By Average Cost" then
exit(false);
// all other exclusions - cost recipient
OutbndEntryItemApplicationTrace.Reset();
OutbndEntryItemApplicationTrace.SetRange("Item No.", ValueEntry."Item No.");
if not AvgCostAdjmtEntryPoint.IsAvgCostCalcTypeItem(ValueEntry."Valuation Date") then begin
OutbndEntryItemApplicationTrace.SetRange("Location Code", ValueEntry."Location Code");
OutbndEntryItemApplicationTrace.SetRange("Variant Code", ValueEntry."Variant Code");
end;
OutbndEntryItemApplicationTrace.SetRange(Positive, true);
OutbndEntryItemApplicationTrace.SetFilter(Level, '>0');
if not OutbndEntryItemApplicationTrace.IsEmpty() then
exit(true);
// next outbound entries - cost recipients
if not ItemLedgEntry.Positive then
exit(ValueEntry."Item Ledger Entry No." > OutbndValueEntry."Item Ledger Entry No.");
exit(false);
end;
local procedure IsExcludeFromAvgCostForRevalPoint(RevaluationCheckValueEntry: Record "Value Entry"; var OutbndValueEntry: Record "Value Entry"): Boolean
var
FirstDirectCostValueEntry: Record "Value Entry";
begin
TempRevaluationPoint.Reset();
if TempRevaluationPoint.IsEmpty() then
exit(false);
OnBeforeIsExcludeFromAvgCostForRevalPoint(TempRevaluationPoint, RevaluationCheckValueEntry, OutbndValueEntry);
if (RevaluationCheckValueEntry."Entry Type" = RevaluationCheckValueEntry."Entry Type"::Revaluation) or
(RevaluationCheckValueEntry."Entry Type" = RevaluationCheckValueEntry."Entry Type"::"Direct Cost") and (RevaluationCheckValueEntry."Item Charge No." = '')
then begin
;
; // we are already positioned on the correct entry to check
end else begin
FirstDirectCostValueEntry.SetCurrentKey("Item Ledger Entry No.", "Entry Type");
FirstDirectCostValueEntry.SetRange("Item Ledger Entry No.", RevaluationCheckValueEntry."Item Ledger Entry No.");
FirstDirectCostValueEntry.SetRange("Entry Type", FirstDirectCostValueEntry."Entry Type"::"Direct Cost");
FirstDirectCostValueEntry.SetLoadFields("Entry Type", "Applies-to Entry", "Partial Revaluation", "Valuation Date");
FirstDirectCostValueEntry.FindFirst();
RevaluationCheckValueEntry := FirstDirectCostValueEntry;
end;
TempRevaluationPoint.SetRange(Number, RevaluationCheckValueEntry."Entry No.", OutbndValueEntry."Entry No.");
if not TempRevaluationPoint.IsEmpty() then
exit(not IncludedInCostCalculation(RevaluationCheckValueEntry, OutbndValueEntry."Item Ledger Entry No."));
TempRevaluationPoint.SetRange(Number, OutbndValueEntry."Entry No.", RevaluationCheckValueEntry."Entry No.");
if not TempRevaluationPoint.IsEmpty() then
exit(true);
end;
local procedure CalcRevalFixedApplnQty(RevaluationValueEntry: Record "Value Entry"): Decimal
var
ItemApplicationEntry: Record "Item Application Entry";
FixedApplQty: Decimal;
begin
ItemApplicationEntry.SetCurrentKey("Inbound Item Entry No.", "Outbound Item Entry No.");
ItemApplicationEntry.SetLoadFields("Outbound Item Entry No.", "Quantity");
ItemApplicationEntry.SetRange("Inbound Item Entry No.", RevaluationValueEntry."Item Ledger Entry No.");
ItemApplicationEntry.SetFilter("Outbound Item Entry No.", '<>%1', 0);
if ItemApplicationEntry.FindSet() then
repeat
if FixedAppliedItemEntryNos.Contains(ItemApplicationEntry."Outbound Item Entry No.") then
if IncludedInCostCalculation(RevaluationValueEntry, ItemApplicationEntry."Outbound Item Entry No.") then
FixedApplQty -= ItemApplicationEntry.Quantity;
until ItemApplicationEntry.Next() = 0;
exit(FixedApplQty);
end;
local procedure UpdateAvgCostAdjmtEntryPoint(ValueEntry: Record "Value Entry")
var
AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point";
begin
AvgCostAdjmtEntryPoint.UpdateValuationDate(ValueEntry);
end;
local procedure UpdateConsumpAvgEntry(ValueEntry: Record "Value Entry")
var
ItemLedgEntry: Record "Item Ledger Entry";
ConsumpItemLedgEntry: Record "Item Ledger Entry";
AvgCostAdjmtPoint: Record "Avg. Cost Adjmt. Entry Point";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeUpdateConsumpAvgEntry(ValueEntry, IsHandled);
if IsHandled then
exit;
// Determine if average costed consumption is completely invoiced
if ValueEntry."Item Ledger Entry Type" <> ValueEntry."Item Ledger Entry Type"::Consumption then
exit;
ConsumpItemLedgEntry.SetLoadFields("Completely Invoiced", "Applied Entry to Adjust");
ConsumpItemLedgEntry.Get(ValueEntry."Item Ledger Entry No.");
if not ConsumpItemLedgEntry."Completely Invoiced" then begin
ItemLedgEntry.SetRange("Item No.", ValueEntry."Item No.");
if not AvgCostAdjmtPoint.IsAvgCostCalcTypeItem(ValueEntry."Valuation Date") then begin
ItemLedgEntry.SetRange("Variant Code", ValueEntry."Variant Code");
ItemLedgEntry.SetRange("Location Code", ValueEntry."Location Code");
end;
ItemLedgEntry.SetRange("Posting Date", 0D, ValueEntry."Valuation Date");
OnUpdateConsumpAvgEntryOnAfterSetItemLedgEntryFilters(ItemLedgEntry);
ItemLedgEntry.CalcSums("Invoiced Quantity");
if ItemLedgEntry."Invoiced Quantity" >= 0 then begin
ConsumpItemLedgEntry.SetCompletelyInvoiced();
ConsumpItemLedgEntry.SetAppliedEntryToAdjust(false);
end;
end;
end;
local procedure ForwardAvgCostToInbndEntries(ItemLedgEntryNo: Integer)
var
ItemApplnEntry: Record "Item Application Entry";
ItemApplicationEntriesInb: Query "Item Application Entries Inb.";
begin
if ItemApplnEntry.AppliedInbndEntryExists(ItemApplicationEntriesInb, ItemLedgEntryNo, true) then
repeat
LevelNo[3] := 0;
AdjustAppliedInbndEntries(ItemApplicationEntriesInb);
if LevelExceeded then begin
LevelExceeded := false;
UpDateWindow(WindowAdjmtLevel, WindowItem, WindowAdjust, LevelNo[3], WindowEntry, WindowOutbndEntry);
AdjustItemAppliedCost();
UpDateWindow(WindowAdjmtLevel, WindowItem, Text008, WindowFWLevel, WindowEntry, WindowOutbndEntry);
end;
until not ItemApplicationEntriesInb.Read();
end;
local procedure WIPToAdjustExist(var ToInventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"): Boolean
var
InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)";
begin
InventoryAdjmtEntryOrder.Reset();
InventoryAdjmtEntryOrder.SetCurrentKey("Cost is Adjusted", "Allow Online Adjustment");
InventoryAdjmtEntryOrder.SetRange("Cost is Adjusted", false);
InventoryAdjmtEntryOrder.SetRange("Order Type", InventoryAdjmtEntryOrder."Order Type"::Production);
InventoryAdjmtEntryOrder.SetRange("Is Finished", true);
if IsOnlineAdjmt then
InventoryAdjmtEntryOrder.SetRange("Allow Online Adjustment", true);
OnWIPToAdjustExistOnAfterInventoryAdjmtEntryOrderSetFilters(InventoryAdjmtEntryOrder);
CopyOrderAdmtEntryToOrderAdjmt(InventoryAdjmtEntryOrder, ToInventoryAdjmtEntryOrder);
exit(ToInventoryAdjmtEntryOrder.FindFirst())
end;
local procedure MakeWIPAdjmt(var SourceInvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
var
InvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)";
CalcInventoryAdjmtOrder: Codeunit "Calc. Inventory Adjmt. - Order";
begin
if SourceInvtAdjmtEntryOrder.FindSet() then
repeat
GetItem(SourceInvtAdjmtEntryOrder."Item No.");
UpDateWindow(WindowAdjmtLevel, SourceInvtAdjmtEntryOrder."Item No.", Text009, 0, 0, 0);
OnMakeWIPAdjmt(SourceInvtAdjmtEntryOrder);
InvtAdjmtEntryOrder := SourceInvtAdjmtEntryOrder;
CalcInventoryAdjmtOrder.Calculate(SourceInvtAdjmtEntryOrder, TempInvtAdjmtBuf);
PostOutputAdjmtBuf(TempAvgCostAdjmtEntryPoint);
if not SourceInvtAdjmtEntryOrder."Completely Invoiced" then begin
InvtAdjmtEntryOrder.GetUnitCostsFromItem();
InvtAdjmtEntryOrder."Completely Invoiced" := true;
end;
InvtAdjmtEntryOrder."Cost is Adjusted" := true;
InvtAdjmtEntryOrder."Allow Online Adjustment" := true;
InvtAdjmtEntryOrder.Modify();
until SourceInvtAdjmtEntryOrder.Next() = 0;
end;
local procedure PostOutputAdjmtBuf(var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
begin
TempInvtAdjmtBuf.Reset();
if TempInvtAdjmtBuf.FindSet() then
repeat
PostOutput(TempInvtAdjmtBuf, TempAvgCostAdjmtEntryPoint);
until TempInvtAdjmtBuf.Next() = 0;
TempInvtAdjmtBuf.DeleteAll();
end;
local procedure PostOutput(InvtAdjmtBuf: Record "Inventory Adjustment Buffer"; var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
var
ItemJnlLine: Record "Item Journal Line";
OrigItemLedgEntry: Record "Item Ledger Entry";
OrigValueEntry: Record "Value Entry";
IsHandled: Boolean;
begin
OrigValueEntry.SetCurrentKey("Item Ledger Entry No.", "Entry Type", SystemCreatedAt);
OrigValueEntry.SetRange("Item Ledger Entry No.", TempInvtAdjmtBuf."Item Ledger Entry No.");
OrigValueEntry.SetBaseLoadFields();
OrigValueEntry.FindFirst();
ItemJnlLine.Init();
ItemJnlLine."Value Entry Type" := InvtAdjmtBuf."Entry Type";
ItemJnlLine."Variance Type" := InvtAdjmtBuf."Variance Type";
ItemJnlLine."Invoiced Quantity" := OrigValueEntry."Item Ledger Entry Quantity";
ItemJnlLine."Invoiced Qty. (Base)" := OrigValueEntry."Item Ledger Entry Quantity";
ItemJnlLine."Qty. per Unit of Measure" := 1;
ItemJnlLine."Source Type" := OrigValueEntry."Source Type";
ItemJnlLine."Source No." := OrigValueEntry."Source No.";
ItemJnlLine.Description := OrigValueEntry.Description;
ItemJnlLine.Adjustment := OrigValueEntry."Order Type" = OrigValueEntry."Order Type"::Assembly;
OrigItemLedgEntry.SetLoadFields("Invoiced Quantity", "Completely Invoiced");
OrigItemLedgEntry.Get(OrigValueEntry."Item Ledger Entry No.");
ItemJnlLine.Adjustment := (OrigValueEntry."Order Type" = OrigValueEntry."Order Type"::Assembly) and (OrigItemLedgEntry."Invoiced Quantity" <> 0);
IsHandled := false;
OnPostOutputOnBeforePostItemJnlLine(ItemJnlLine, OrigValueEntry, InvtAdjmtBuf, GLSetup, IsHandled);
if not IsHandled then
PostItemJnlLine(ItemJnlLine, OrigValueEntry, InvtAdjmtBuf."Cost Amount (Actual)", InvtAdjmtBuf."Cost Amount (Actual) (ACY)");
OrigItemLedgEntry.Get(OrigValueEntry."Item Ledger Entry No.");
if not OrigItemLedgEntry."Completely Invoiced" then
OrigItemLedgEntry.SetCompletelyInvoiced();
InsertEntryPointToUpdate(TempAvgCostAdjmtEntryPoint, OrigValueEntry."Item No.", OrigValueEntry."Variant Code", OrigValueEntry."Location Code");
end;
local procedure AssemblyToAdjustExists(var ToInventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"): Boolean
var
InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)";
begin
InventoryAdjmtEntryOrder.Reset();
InventoryAdjmtEntryOrder.SetCurrentKey("Cost is Adjusted", "Allow Online Adjustment");
InventoryAdjmtEntryOrder.SetRange("Cost is Adjusted", false);
InventoryAdjmtEntryOrder.SetRange("Order Type", InventoryAdjmtEntryOrder."Order Type"::Assembly);
if IsOnlineAdjmt then
InventoryAdjmtEntryOrder.SetRange("Allow Online Adjustment", true);
CopyOrderAdmtEntryToOrderAdjmt(InventoryAdjmtEntryOrder, ToInventoryAdjmtEntryOrder);
exit(ToInventoryAdjmtEntryOrder.FindFirst())
end;
local procedure MakeAssemblyAdjmt(var SourceInvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
var
InvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)";
CalcInventoryAdjmtOrder: Codeunit "Calc. Inventory Adjmt. - Order";
begin
if SourceInvtAdjmtEntryOrder.FindSet() then
repeat
GetItem(SourceInvtAdjmtEntryOrder."Item No.");
UpDateWindow(WindowAdjmtLevel, SourceInvtAdjmtEntryOrder."Item No.", Text010, 0, 0, 0);
OnMakeAssemblyAdjmt(SourceInvtAdjmtEntryOrder);
InvtAdjmtEntryOrder := SourceInvtAdjmtEntryOrder;
if not Item."Inventory Value Zero" then begin
CalcInventoryAdjmtOrder.Calculate(SourceInvtAdjmtEntryOrder, TempInvtAdjmtBuf);
PostOutputAdjmtBuf(TempAvgCostAdjmtEntryPoint);
end;
if not SourceInvtAdjmtEntryOrder."Completely Invoiced" then begin
InvtAdjmtEntryOrder.GetCostsFromItem(1);
InvtAdjmtEntryOrder."Completely Invoiced" := true;
end;
InvtAdjmtEntryOrder."Allow Online Adjustment" := true;
InvtAdjmtEntryOrder."Cost is Adjusted" := true;
InvtAdjmtEntryOrder.Modify();
until SourceInvtAdjmtEntryOrder.Next() = 0;
end;
local procedure UpdateAdjmtBuf(OrigValueEntry: Record "Value Entry"; NewAdjustedCost: Decimal; NewAdjustedCostACY: Decimal; ItemLedgEntryPostingDate: Date; EntryType: Enum "Cost Entry Type") Result: Boolean
var
ItemLedgEntry: Record "Item Ledger Entry";
ItemApplnEntry: Record "Item Application Entry";
SourceOrigValueEntry: Record "Value Entry";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeUpdateAdjmtBuf(OrigValueEntry, NewAdjustedCost, NewAdjustedCostACY, ItemLedgEntryPostingDate, EntryType, Result, IsHandled, Item);
if IsHandled then
exit(Result);
if not HasNewCost(NewAdjustedCost, NewAdjustedCostACY) then
exit(false);
if OrigValueEntry."Valued By Average Cost" then begin
TempAvgCostRndgBuf.UpdRoundingCheck(
OrigValueEntry."Item Ledger Entry No.", NewAdjustedCost, NewAdjustedCostACY,
GLSetup."Amount Rounding Precision", Currency."Amount Rounding Precision");
if TempAvgCostRndgBuf."No. of Hits" > MaxRoundings then
exit(false);
end;
UpdateValuationPeriodHasOutput(OrigValueEntry);
TempInvtAdjmtBuf.AddActualCostBuf(OrigValueEntry, NewAdjustedCost, NewAdjustedCostACY, ItemLedgEntryPostingDate);
OnUpdateAdjmtBufOnAfterAddActualCostBuf(OrigValueEntry, NewAdjustedCost, NewAdjustedCostACY, ItemLedgEntryPostingDate, TempInvtAdjmtBuf);
if EntryType = OrigValueEntry."Entry Type"::Variance then begin
GetOrigValueEntry(SourceOrigValueEntry, OrigValueEntry, EntryType);
TempInvtAdjmtBuf."Entry Type" := EntryType;
TempInvtAdjmtBuf."Variance Type" := SourceOrigValueEntry."Variance Type";
TempInvtAdjmtBuf.Modify();
end;
if not OrigValueEntry."Expected Cost" and
(OrigValueEntry."Entry Type" = OrigValueEntry."Entry Type"::"Direct Cost")
then begin
CalcExpectedCostToBalance(OrigValueEntry, NewAdjustedCost, NewAdjustedCostACY);
IsHandled := false;
OnUpdateAdjmtBufOnBeforeHasNewCost(OrigValueEntry, NewAdjustedCost, NewAdjustedCostACY, ItemLedgEntryPostingDate, EntryType, IsHandled, TempInvtAdjmtBuf, Item);
if not IsHandled then
if HasNewCost(NewAdjustedCost, NewAdjustedCostACY) then
TempInvtAdjmtBuf.AddBalanceExpectedCostBuf(OrigValueEntry, NewAdjustedCost, NewAdjustedCostACY);
end;
if OrigValueEntry."Item Ledger Entry Quantity" >= 0 then begin
ItemLedgEntry.SetLoadFields(Open, "Applied Entry to Adjust", Quantity);
ItemLedgEntry.Get(OrigValueEntry."Item Ledger Entry No.");
ItemApplnEntry.SetOutboundsNotUpdated(ItemLedgEntry);
end;
exit(true);
end;
local procedure CalcExpectedCostToBalance(OrigValueEntry: Record "Value Entry"; var ExpectedCost: Decimal; var ExpectedCostACY: Decimal)
var
ItemLedgEntry: Record "Item Ledger Entry";
ShareOfTotalCost: Decimal;
begin
ExpectedCost := 0;
ExpectedCostACY := 0;
ItemLedgEntry.SetLoadFields(Quantity, "Invoiced Quantity");
ItemLedgEntry.Get(OrigValueEntry."Item Ledger Entry No.");
TempInvtAdjmtBuf.Reset();
TempInvtAdjmtBuf.SetCurrentKey("Item Ledger Entry No.");
TempInvtAdjmtBuf.SetRange("Item Ledger Entry No.", OrigValueEntry."Item Ledger Entry No.");
if TempInvtAdjmtBuf.FindFirst() and TempInvtAdjmtBuf."Expected Cost" then begin
TempInvtAdjmtBuf.CalcSums("Cost Amount (Expected)", TempInvtAdjmtBuf."Cost Amount (Expected) (ACY)");
if ItemLedgEntry.Quantity = ItemLedgEntry."Invoiced Quantity" then begin
ExpectedCost := -TempInvtAdjmtBuf."Cost Amount (Expected)";
ExpectedCostACY := -TempInvtAdjmtBuf."Cost Amount (Expected) (ACY)";
end else begin
ShareOfTotalCost := OrigValueEntry."Invoiced Quantity" / ItemLedgEntry.Quantity;
ExpectedCost :=
-RoundAmt(TempInvtAdjmtBuf."Cost Amount (Expected)" * ShareOfTotalCost, GLSetup."Amount Rounding Precision");
ExpectedCostACY :=
-RoundAmt(TempInvtAdjmtBuf."Cost Amount (Expected) (ACY)" * ShareOfTotalCost, Currency."Amount Rounding Precision");
end;
end;
end;
local procedure PostAdjmtBuf(var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
var
ItemJnlLine: Record "Item Journal Line";
OrigValueEntry: Record "Value Entry";
begin
TempInvtAdjmtBuf.Reset();
if TempInvtAdjmtBuf.FindSet() then begin
repeat
OrigValueEntry.SetBaseLoadFields();
OrigValueEntry.Get(TempInvtAdjmtBuf."Entry No.");
InsertEntryPointToUpdate(
TempAvgCostAdjmtEntryPoint, OrigValueEntry."Item No.", OrigValueEntry."Variant Code", OrigValueEntry."Location Code");
if OrigValueEntry."Expected Cost" then begin
if HasNewCost(TempInvtAdjmtBuf."Cost Amount (Expected)", TempInvtAdjmtBuf."Cost Amount (Expected) (ACY)") then begin
InitAdjmtJnlLine(ItemJnlLine, OrigValueEntry, TempInvtAdjmtBuf."Entry Type", TempInvtAdjmtBuf."Variance Type", OrigValueEntry."Invoiced Quantity");
PostItemJnlLine(ItemJnlLine, OrigValueEntry, TempInvtAdjmtBuf."Cost Amount (Expected)", TempInvtAdjmtBuf."Cost Amount (Expected) (ACY)");
OnPostAdjmtBufOnAfterPostExpectedCost(OrigValueEntry, TempInvtAdjmtBuf);
end
end else
if HasNewCost(TempInvtAdjmtBuf."Cost Amount (Actual)", TempInvtAdjmtBuf."Cost Amount (Actual) (ACY)") then begin
if HasNewCost(TempInvtAdjmtBuf."Cost Amount (Expected)", TempInvtAdjmtBuf."Cost Amount (Expected) (ACY)") then begin
InitAdjmtJnlLine(ItemJnlLine, OrigValueEntry, TempInvtAdjmtBuf."Entry Type", TempInvtAdjmtBuf."Variance Type", 0);
PostItemJnlLine(ItemJnlLine, OrigValueEntry, TempInvtAdjmtBuf."Cost Amount (Expected)", TempInvtAdjmtBuf."Cost Amount (Expected) (ACY)");
end;
InitAdjmtJnlLine(ItemJnlLine, OrigValueEntry, TempInvtAdjmtBuf."Entry Type", TempInvtAdjmtBuf."Variance Type", OrigValueEntry."Invoiced Quantity");
OnPostAdjmtBufOnBeforePostNewCost(ItemJnlLine, OrigValueEntry, TempInvtAdjmtBuf);
PostItemJnlLine(ItemJnlLine, OrigValueEntry, TempInvtAdjmtBuf."Cost Amount (Actual)", TempInvtAdjmtBuf."Cost Amount (Actual) (ACY)");
OnPostAdjmtBufOnAfterPostNewCost(OrigValueEntry, TempInvtAdjmtBuf);
end;
until TempInvtAdjmtBuf.Next() = 0;
TempInvtAdjmtBuf.DeleteAll();
end;
end;
local procedure InitAdjmtJnlLine(var ItemJnlLine: Record "Item Journal Line"; OrigValueEntry: Record "Value Entry"; EntryType: Enum "Cost Entry Type"; VarianceType: Enum "Cost Variance Type"; InvoicedQty: Decimal)
begin
ItemJnlLine."Value Entry Type" := EntryType;
ItemJnlLine."Partial Revaluation" := OrigValueEntry."Partial Revaluation";
ItemJnlLine.Description := OrigValueEntry.Description;
ItemJnlLine."Source Posting Group" := OrigValueEntry."Source Posting Group";
ItemJnlLine."Source No." := OrigValueEntry."Source No.";
ItemJnlLine."Salespers./Purch. Code" := OrigValueEntry."Salespers./Purch. Code";
ItemJnlLine."Source Type" := OrigValueEntry."Source Type";
ItemJnlLine."Reason Code" := OrigValueEntry."Reason Code";
ItemJnlLine."Drop Shipment" := OrigValueEntry."Drop Shipment";
ItemJnlLine."Document Date" := OrigValueEntry."Document Date";
ItemJnlLine."External Document No." := OrigValueEntry."External Document No.";
ItemJnlLine."Quantity (Base)" := OrigValueEntry."Valued Quantity";
ItemJnlLine."Invoiced Qty. (Base)" := InvoicedQty;
ItemJnlLine."Item Charge No." := OrigValueEntry."Item Charge No.";
ItemJnlLine."Variance Type" := VarianceType;
ItemJnlLine.Adjustment := true;
ItemJnlLine."Applies-to Value Entry" := OrigValueEntry."Entry No.";
ItemJnlLine."Return Reason Code" := OrigValueEntry."Return Reason Code";
OnAfterInitAdjmtJnlLine(ItemJnlLine, OrigValueEntry, EntryType, VarianceType, InvoicedQty);
end;
local procedure PostItemJnlLine(ItemJnlLine: Record "Item Journal Line"; OrigValueEntry: Record "Value Entry"; NewAdjustedCost: Decimal; NewAdjustedCostACY: Decimal)
var
InventoryPeriod: Record "Inventory Period";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforePostItemJnlLine(ItemJnlLine, OrigValueEntry, NewAdjustedCost, NewAdjustedCostACY, SkipUpdateJobItemCost, IsHandled);
if IsHandled then
exit;
ItemJnlLine."Item No." := OrigValueEntry."Item No.";
ItemJnlLine."Location Code" := OrigValueEntry."Location Code";
ItemJnlLine."Variant Code" := OrigValueEntry."Variant Code";
if GLSetup.IsPostingAllowed(OrigValueEntry."Posting Date") and InventoryPeriod.IsValidDate(OrigValueEntry."Posting Date") then
ItemJnlLine."Posting Date" := OrigValueEntry."Posting Date"
else
ItemJnlLine."Posting Date" := PostingDateForClosedPeriod;
OnPostItemJnlLineOnAfterSetPostingDate(ItemJnlLine, OrigValueEntry, PostingDateForClosedPeriod, Item);
ItemJnlLine."Entry Type" := OrigValueEntry."Item Ledger Entry Type";
ItemJnlLine."Document No." := OrigValueEntry."Document No.";
ItemJnlLine."Document Type" := OrigValueEntry."Document Type";
ItemJnlLine."Document Line No." := OrigValueEntry."Document Line No.";
ItemJnlLine."Source Currency Code" := GLSetup."Additional Reporting Currency";
ItemJnlLine."Source Code" := SourceCodeSetup."Adjust Cost";
ItemJnlLine."Inventory Posting Group" := OrigValueEntry."Inventory Posting Group";
ItemJnlLine."Gen. Bus. Posting Group" := OrigValueEntry."Gen. Bus. Posting Group";
ItemJnlLine."Gen. Prod. Posting Group" := OrigValueEntry."Gen. Prod. Posting Group";
ItemJnlLine."Order Type" := OrigValueEntry."Order Type";
ItemJnlLine."Order No." := OrigValueEntry."Order No.";
ItemJnlLine."Order Line No." := OrigValueEntry."Order Line No.";
ItemJnlLine."Job No." := OrigValueEntry."Job No.";
ItemJnlLine."Job Task No." := OrigValueEntry."Job Task No.";
ItemJnlLine.Type := OrigValueEntry.Type;
if ItemJnlLine."Value Entry Type" = ItemJnlLine."Value Entry Type"::"Direct Cost" then
ItemJnlLine."Item Shpt. Entry No." := OrigValueEntry."Item Ledger Entry No."
else
ItemJnlLine."Applies-to Entry" := OrigValueEntry."Item Ledger Entry No.";
ItemJnlLine.Amount := NewAdjustedCost;
ItemJnlLine."Amount (ACY)" := NewAdjustedCostACY;
if ItemJnlLine."Quantity (Base)" <> 0 then begin
ItemJnlLine."Unit Cost" :=
RoundAmt(NewAdjustedCost / ItemJnlLine."Quantity (Base)", GLSetup."Unit-Amount Rounding Precision");
ItemJnlLine."Unit Cost (ACY)" :=
RoundAmt(NewAdjustedCostACY / ItemJnlLine."Quantity (Base)", Currency."Unit-Amount Rounding Precision");
end;
ItemJnlLine."Shortcut Dimension 1 Code" := OrigValueEntry."Global Dimension 1 Code";
ItemJnlLine."Shortcut Dimension 2 Code" := OrigValueEntry."Global Dimension 2 Code";
ItemJnlLine."Dimension Set ID" := OrigValueEntry."Dimension Set ID";
if not SkipUpdateJobItemCost and (OrigValueEntry."Job No." <> '') then
CopyJobToAdjustmentBuf(OrigValueEntry."Job No.");
OnPostItemJnlLineCopyFromValueEntry(ItemJnlLine, OrigValueEntry);
ItemJnlPostLine.RunWithCheck(ItemJnlLine);
OnPostItemJnlLineOnAfterItemJnlPostLineRunWithCheck(ItemJnlLine, OrigValueEntry);
end;
local procedure RoundCost(var Cost: Decimal; var RndgResidual: Decimal; TotalCost: Decimal; ShareOfTotalCost: Decimal; AmtRndgPrec: Decimal)
var
UnroundedCost: Decimal;
begin
UnroundedCost := TotalCost * ShareOfTotalCost + RndgResidual;
Cost := RoundAmt(UnroundedCost, AmtRndgPrec);
RndgResidual := UnroundedCost - Cost;
end;
local procedure RoundAmt(Amt: Decimal; AmtRndgPrec: Decimal): Decimal
begin
if Amt = 0 then
exit(0);
exit(Round(Amt, AmtRndgPrec))
end;
local procedure GetOrigValueEntry(var OrigValueEntry: Record "Value Entry"; ValueEntry: Record "Value Entry"; ValueEntryType: Enum "Cost Entry Type")
var
Found: Boolean;
IsLastEntry: Boolean;
begin
OrigValueEntry.SetCurrentKey("Item Ledger Entry No.", "Document No.");
OrigValueEntry.SetRange("Item Ledger Entry No.", ValueEntry."Item Ledger Entry No.");
OrigValueEntry.SetRange("Document No.", ValueEntry."Document No.");
OrigValueEntry.SetBaseLoadFields();
if OrigValueEntry.FindSet() then
repeat
if (OrigValueEntry."Expected Cost" = ValueEntry."Expected Cost") and
(OrigValueEntry."Entry Type" = ValueEntryType)
then begin
Found := true;
OrigValueEntry."Valued Quantity" := ValueEntry."Valued Quantity";
OrigValueEntry."Invoiced Quantity" := ValueEntry."Invoiced Quantity";
OnGetOrigValueEntryOnAfterOrigValueEntryFound(OrigValueEntry, ValueEntry);
end else
IsLastEntry := OrigValueEntry.Next() = 0;
until Found or IsLastEntry;
if not Found then begin
OrigValueEntry := ValueEntry;
OrigValueEntry."Entry Type" := ValueEntryType;
if ValueEntryType = OrigValueEntry."Entry Type"::Variance then
OrigValueEntry."Variance Type" := GetOrigVarianceType(ValueEntry);
end;
end;
local procedure GetOrigVarianceType(ValueEntry: Record "Value Entry"): Enum "Cost Variance Type"
begin
if ValueEntry."Item Ledger Entry Type" in
[ValueEntry."Item Ledger Entry Type"::Output, ValueEntry."Item Ledger Entry Type"::"Assembly Output"]
then
exit(ValueEntry."Variance Type"::Material);
exit(ValueEntry."Variance Type"::Purchase);
end;
local procedure UpdateAppliedEntryToAdjustBuf(ItemLedgerEntry: Record "Item Ledger Entry"; AppliedEntryToAdjust: Boolean)
var
ItemLedgEntryNos: List of [Integer];
begin
if AppliedEntryToAdjust then begin
if not ItemLedgEntryToAdjust.Get(ItemLedgerEntry."Item No.", ItemLedgEntryNos) then
ItemLedgEntryToAdjust.Add(ItemLedgerEntry."Item No.", ItemLedgEntryNos);
if not ItemLedgEntryNos.Contains(ItemLedgerEntry."Entry No.") then
ItemLedgEntryNos.Add(ItemLedgerEntry."Entry No.");
ItemLedgEntryToAdjust.Set(ItemLedgerEntry."Item No.", ItemLedgEntryNos);
end;
end;
local procedure SetAppliedEntryToAdjustFromBuf(ItemNo: Code[20])
var
ItemLedgEntry: Record "Item Ledger Entry";
ItemLedgEntryNos: List of [Integer];
EntryNo: Integer;
begin
if ItemNo <> '' then begin
if not ItemLedgEntryToAdjust.ContainsKey(ItemNo) then
exit;
ItemLedgEntryNos := ItemLedgEntryToAdjust.Get(ItemNo);
foreach EntryNo in ItemLedgEntryNos do begin
ItemLedgEntry.SetLoadFields("Applied Entry to Adjust");
ItemLedgEntry.Get(EntryNo);
ItemLedgEntry.SetAppliedEntryToAdjust(true);
end;
end else
foreach ItemLedgEntryNos in ItemLedgEntryToAdjust.Values() do
foreach EntryNo in ItemLedgEntryNos do begin
ItemLedgEntry.SetLoadFields("Applied Entry to Adjust");
ItemLedgEntry.Get(EntryNo);
ItemLedgEntry.SetAppliedEntryToAdjust(true);
end;
end;
local procedure AppliedEntryToAdjustBufExists(ItemNo: Code[20]): Boolean
begin
exit(ItemLedgEntryToAdjust.ContainsKey(ItemNo));
end;
local procedure UpdateItemUnitCost(var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary; IsFirstTime: Boolean)
var
AvgCostAdjmtPoint: Record "Avg. Cost Adjmt. Entry Point";
FilterSKU: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeUpdateItemUnitCost2(TempAvgCostAdjmtEntryPoint, IsHandled, Item, ItemLedgEntryToAdjust);
if IsHandled then
exit;
Item.ReadIsolation(IsolationLevel::UpdLock);
Item.Get(Item."No.");
OnUpdateItemUnitCostOnAfterItemGet(Item);
if not LevelExceeded then begin
Item."Allow Online Adjustment" := true;
AvgCostAdjmtPoint.SetRange("Item No.", Item."No.");
AvgCostAdjmtPoint.SetRange("Cost Is Adjusted", false);
if IsAvgCostItem() then
AvgCostAdjmtPoint.SetRange("Valuation Date", 0D, AdjustTillDate)
else
AvgCostAdjmtPoint.ModifyAll("Cost Is Adjusted", true);
Item."Cost is Adjusted" := AvgCostAdjmtPoint.IsEmpty();
if Item."Cost is Adjusted" and not IsAvgCostItem() and IsFirstTime then begin
Item."Cost is Adjusted" := not AppliedEntryToAdjustBufExists(Item."No.");
SetAppliedEntryToAdjustFromBuf(Item."No.");
end;
end;
if Item."Costing Method" <> Item."Costing Method"::Standard then begin
if TempAvgCostAdjmtEntryPoint.FindSet() then
repeat
FilterSKU := (TempAvgCostAdjmtEntryPoint."Location Code" <> '') or (TempAvgCostAdjmtEntryPoint."Variant Code" <> '');
ItemCostMgt.UpdateUnitCost(
Item, TempAvgCostAdjmtEntryPoint."Location Code", TempAvgCostAdjmtEntryPoint."Variant Code", 0, 0, true, FilterSKU, false, 0);
until TempAvgCostAdjmtEntryPoint.Next() = 0
else
Item.Modify();
end else begin
OnUpdateItemUnitCostOnBeforeModifyItemNotStandardCostingMethod(Item);
Item.Modify();
OnUpdateItemUnitCostOnAfterModifyItemNotStandardCostingMethod(Item);
end;
TempAvgCostAdjmtEntryPoint.Reset();
TempAvgCostAdjmtEntryPoint.DeleteAll();
end;
local procedure GetItem(ItemNo: Code[20])
begin
if Item."No." <> ItemNo then
Item.Get(ItemNo);
end;
local procedure IsAvgCostItem() AvgCostItem: Boolean
begin
AvgCostItem := Item."Costing Method" = Item."Costing Method"::Average;
OnAfterIsAvgCostItem(Item, AvgCostItem);
end;
local procedure HasNewCost(NewCost: Decimal; NewCostACY: Decimal): Boolean
begin
exit((NewCost <> 0) or (NewCostACY <> 0));
end;
local procedure OpenWindow()
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeOpenWindow(IsHandled, Window, WindowIsOpen);
if IsHandled then
exit;
if not GuiAllowed() then
exit;
Window.Open(
Text000 +
'#1########################\\' +
Text001 +
Text003 +
Text004 +
Text005 +
Text006);
WindowIsOpen := true;
end;
local procedure UpDateWindow(NewWindowAdjmtLevel: Integer; NewWindowItem: Code[20]; NewWindowAdjust: Text[20]; NewWindowFWLevel: Integer; NewWindowEntry: Integer; NewWindowOutbndEntry: Integer)
var
IsHandled: Boolean;
begin
WindowAdjmtLevel := NewWindowAdjmtLevel;
WindowItem := NewWindowItem;
WindowAdjust := NewWindowAdjust;
WindowFWLevel := NewWindowFWLevel;
WindowEntry := NewWindowEntry;
WindowOutbndEntry := NewWindowOutbndEntry;
if MaxDuration > 0 then
if CurrentDateTime() >= StartDateTime + MaxDuration then
Error(CostAdjustmentReachedMaxDurationErr, MaxDuration);
IsHandled := false;
OnBeforeUpdateWindow(IsHandled);
if IsHandled then
exit;
if not GuiAllowed() then
exit;
if IsTimeForUpdate() then begin
if not WindowIsOpen then
OpenWindow();
IsHandled := false;
OnUpdateWindowOnAfterOpenWindow(IsHandled);
if IsHandled then
exit;
Window.Update(1, StrSubstNo(Text002, TempInvtAdjmtBuf.FieldCaption("Item No."), WindowItem));
Window.Update(2, WindowAdjmtLevel);
Window.Update(3, WindowAdjust);
Window.Update(4, WindowFWLevel);
Window.Update(5, WindowEntry);
Window.Update(6, WindowOutbndEntry);
end;
end;
local procedure IsTimeForUpdate(): Boolean
begin
if CurrentDateTime - WindowUpdateDateTime >= 1000 then begin
WindowUpdateDateTime := CurrentDateTime;
exit(true);
end;
exit(false);
end;
local procedure CopyItemToItem(var FromItem: Record Item; var ToItem: Record Item)
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCopyItemToItem(FromItem, ToItem, IsHandled);
if IsHandled then
exit;
ToItem.Reset();
ToItem.DeleteAll();
FromItem.SetLoadFields("No.", "Low-Level Code");
FromItem.SetCurrentKey("Low-Level Code");
FromItem.Ascending(false);
if FromItem.FindSet() then
repeat
if ItemsToAdjust.Count() > 0 then
if not ItemsToAdjust.Contains(FromItem."No.") then
continue;
ToItem."No." := FromItem."No.";
ToItem."Low-Level Code" := FromItem."Low-Level Code";
ToItem.Insert();
FromItem.SetRange("Low-Level Code", FromItem."Low-Level Code");
until FromItem.Next() = 0;
end;
local procedure CopyAvgCostAdjmtToAvgCostAdjmt(var FromAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point"; var ToAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point")
begin
ToAvgCostAdjmtEntryPoint.Reset();
ToAvgCostAdjmtEntryPoint.DeleteAll();
if FromAvgCostAdjmtEntryPoint.FindSet() then
repeat
ToAvgCostAdjmtEntryPoint := FromAvgCostAdjmtEntryPoint;
ToAvgCostAdjmtEntryPoint.Insert();
OnCopyAvgCostAdjmtToAvgCostAdjmtOnAfterInsert(ToAvgCostAdjmtEntryPoint);
until FromAvgCostAdjmtEntryPoint.Next() = 0;
end;
local procedure CopyOrderAdmtEntryToOrderAdjmt(var FromInventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; var ToInventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)")
begin
ToInventoryAdjmtEntryOrder.Reset();
ToInventoryAdjmtEntryOrder.DeleteAll();
FromInventoryAdjmtEntryOrder.ReadIsolation(IsolationLevel::ReadUncommitted);
if FromInventoryAdjmtEntryOrder.FindSet() then
repeat
if CanAdjustInventoryAdjmtEntryOrder(FromInventoryAdjmtEntryOrder) then begin
ToInventoryAdjmtEntryOrder := FromInventoryAdjmtEntryOrder;
ToInventoryAdjmtEntryOrder.Insert();
end;
until FromInventoryAdjmtEntryOrder.Next() = 0;
end;
local procedure CanAdjustInventoryAdjmtEntryOrder(InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"): Boolean
begin
FilterItem.ReadIsolation(IsolationLevel::ReadUncommitted);
FilterItem.SetLoadFields("No.");
FilterItem."No." := InventoryAdjmtEntryOrder."Item No.";
if not FilterItem.Find() then
exit(false);
if ItemsToAdjust.Count() > 0 then
if not ItemsToAdjust.Contains(InventoryAdjmtEntryOrder."Item No.") then
exit(false);
InventoryAdjmtEntryOrderToAdjust.ReadIsolation(IsolationLevel::ReadUncommitted);
InventoryAdjmtEntryOrderToAdjust.SetLoadFields("Order Type", "Order No.", "Order Line No.");
InventoryAdjmtEntryOrderToAdjust."Order Type" := InventoryAdjmtEntryOrder."Order Type";
InventoryAdjmtEntryOrderToAdjust."Order No." := InventoryAdjmtEntryOrder."Order No.";
InventoryAdjmtEntryOrderToAdjust."Order Line No." := InventoryAdjmtEntryOrder."Order Line No.";
if not InventoryAdjmtEntryOrderToAdjust.Find() then
exit(false);
exit(true);
end;
local procedure AdjustNotInvdRevaluation(TransItemLedgEntry: Record "Item Ledger Entry"; TransItemApplnEntry: Record "Item Application Entry")
var
TransValueEntry: Record "Value Entry";
OrigItemLedgEntry: Record "Item Ledger Entry";
CostElementBuf: Record "Cost Element Buffer";
AdjustedCostElementBuf: Record "Cost Element Buffer";
begin
if TransValueEntry.NotInvdRevaluationExists(TransItemLedgEntry."Entry No.") then begin
GetOrigPosItemLedgEntryNo(TransItemApplnEntry);
OrigItemLedgEntry.SetLoadFields(Quantity);
OrigItemLedgEntry.Get(TransItemApplnEntry."Item Ledger Entry No.");
repeat
CalcTransEntryNewRevAmt(OrigItemLedgEntry, TransValueEntry, AdjustedCostElementBuf);
CalcTransEntryOldRevAmt(TransValueEntry, CostElementBuf);
UpdateAdjmtBuf(
TransValueEntry,
AdjustedCostElementBuf."Actual Cost" - CostElementBuf."Actual Cost",
AdjustedCostElementBuf."Actual Cost (ACY)" - CostElementBuf."Actual Cost (ACY)",
TransItemLedgEntry."Posting Date",
TransValueEntry."Entry Type");
until TransValueEntry.Next() = 0;
end;
end;
local procedure GetOrigPosItemLedgEntryNo(var ItemApplnEntry: Record "Item Application Entry")
begin
ItemApplnEntry.SetCurrentKey("Inbound Item Entry No.", "Item Ledger Entry No.");
while ItemApplnEntry."Transferred-from Entry No." <> 0 do begin
ItemApplnEntry.SetRange("Item Ledger Entry No.", ItemApplnEntry."Transferred-from Entry No.");
ItemApplnEntry.SetRange("Inbound Item Entry No.", ItemApplnEntry."Transferred-from Entry No.");
ItemApplnEntry.FindFirst();
end;
end;
local procedure CalcTransEntryNewRevAmt(ItemLedgEntry: Record "Item Ledger Entry"; TransValueEntry: Record "Value Entry"; var AdjustedCostElementBuf: Record "Cost Element Buffer")
var
ValueEntry: Record "Value Entry";
InvdQty: Decimal;
OrigInvdQty: Decimal;
ShareOfRevExpAmt: Decimal;
OrigShareOfRevExpAmt: Decimal;
begin
ValueEntry.SetCurrentKey("Item Ledger Entry No.", "Entry Type");
ValueEntry.SetRange("Item Ledger Entry No.", ItemLedgEntry."Entry No.");
ValueEntry.SetRange("Entry Type", ValueEntry."Entry Type"::"Direct Cost");
ValueEntry.SetRange("Item Charge No.", '');
ValueEntry.SetLoadFields("Invoiced Quantity");
if ValueEntry.FindSet() then
repeat
InvdQty := InvdQty + ValueEntry."Invoiced Quantity";
if ValueEntry.EntryNoHasSameSign(TransValueEntry."Entry No.") and (ValueEntry."Entry No." < TransValueEntry."Entry No.") or
not ValueEntry.EntryNoHasSameSign(TransValueEntry."Entry No.") and ((ValueEntry.SystemCreatedAt < TransValueEntry.SystemCreatedAt) or (TransValueEntry.SystemCreatedAt = 0DT)) then
OrigInvdQty := OrigInvdQty + ValueEntry."Invoiced Quantity";
until ValueEntry.Next() = 0;
ShareOfRevExpAmt := (ItemLedgEntry.Quantity - InvdQty) / ItemLedgEntry.Quantity;
OrigShareOfRevExpAmt := (ItemLedgEntry.Quantity - OrigInvdQty) / ItemLedgEntry.Quantity;
if TempInvtAdjmtBuf.Get(TransValueEntry."Entry No.") then
TransValueEntry.AddCost(TempInvtAdjmtBuf);
AdjustedCostElementBuf."Actual Cost" := Round(
(ShareOfRevExpAmt - OrigShareOfRevExpAmt) * TransValueEntry."Cost Amount (Actual)", GLSetup."Amount Rounding Precision");
AdjustedCostElementBuf."Actual Cost (ACY)" := Round(
(ShareOfRevExpAmt - OrigShareOfRevExpAmt) *
TransValueEntry."Cost Amount (Actual) (ACY)", Currency."Amount Rounding Precision");
end;
local procedure CalcTransEntryOldRevAmt(TransValueEntry: Record "Value Entry"; var CostElementBuf: Record "Cost Element Buffer")
begin
Clear(CostElementBuf);
TransValueEntry.SetCurrentKey("Item Ledger Entry No.", "Entry Type");
TransValueEntry.SetRange("Item Ledger Entry No.", TransValueEntry."Item Ledger Entry No.");
TransValueEntry.SetRange("Entry Type", TransValueEntry."Entry Type"::Revaluation);
TransValueEntry.SetRange("Applies-to Entry", TransValueEntry."Entry No.");
TransValueEntry.SetLoadFields("Cost Amount (Expected)", "Cost Amount (Expected) (ACY)", "Cost Amount (Actual)", "Cost Amount (Actual) (ACY)");
if TransValueEntry.FindSet() then
repeat
if TempInvtAdjmtBuf.Get(TransValueEntry."Entry No.") then
TransValueEntry.AddCost(TempInvtAdjmtBuf);
CostElementBuf."Actual Cost" := CostElementBuf."Actual Cost" + TransValueEntry."Cost Amount (Actual)";
CostElementBuf."Actual Cost (ACY)" := CostElementBuf."Actual Cost (ACY)" + TransValueEntry."Cost Amount (Actual) (ACY)";
until TransValueEntry.Next() = 0;
end;
local procedure IsInterimRevaluation(InbndValueEntry: Record "Value Entry"): Boolean
begin
exit(
(InbndValueEntry."Entry Type" = InbndValueEntry."Entry Type"::Revaluation) and
((InbndValueEntry."Cost Amount (Expected)" <> 0) or (InbndValueEntry."Cost Amount (Expected) (ACY)" <> 0)));
end;
local procedure OutboundSalesEntryToAdjust(ItemLedgerEntry: Record "Item Ledger Entry"): Boolean
var
ItemApplicationEntry: Record "Item Application Entry";
InbndItemLedgerEntry: Record "Item Ledger Entry";
begin
if not ItemLedgerEntry.IsOutbndSale() then
exit(false);
ItemApplicationEntry.SetCurrentKey("Outbound Item Entry No.", "Item Ledger Entry No.", "Cost Application", "Transferred-from Entry No.");
ItemApplicationEntry.SetLoadFields("Inbound Item Entry No.");
ItemApplicationEntry.SetRange("Outbound Item Entry No.", ItemLedgerEntry."Entry No.");
ItemApplicationEntry.SetFilter("Item Ledger Entry No.", '<>%1', ItemLedgerEntry."Entry No.");
ItemApplicationEntry.SetRange("Transferred-from Entry No.", 0);
if ItemApplicationEntry.FindSet() then
repeat
InbndItemLedgerEntry.SetLoadFields("Completely Invoiced");
if InbndItemLedgerEntry.Get(ItemApplicationEntry."Inbound Item Entry No.") then
if not InbndItemLedgerEntry."Completely Invoiced" then
exit(true);
until ItemApplicationEntry.Next() = 0;
exit(false);
end;
local procedure InboundTransferEntryToAdjust(ItemLedgerEntry: Record "Item Ledger Entry"): Boolean
var
ItemApplicationEntry: Record "Item Application Entry";
begin
if (ItemLedgerEntry."Entry Type" <> ItemLedgerEntry."Entry Type"::Transfer) or not ItemLedgerEntry.Positive or
ItemLedgerEntry."Completely Invoiced"
then
exit(false);
ItemApplicationEntry.SetRange("Inbound Item Entry No.", ItemLedgerEntry."Entry No.");
ItemApplicationEntry.SetFilter("Item Ledger Entry No.", '<>%1', ItemLedgerEntry."Entry No.");
ItemApplicationEntry.SetRange("Transferred-from Entry No.", 0);
exit(not ItemApplicationEntry.IsEmpty());
end;
procedure SetJobUpdateProperties(SkipJobUpdate: Boolean)
begin
SkipUpdateJobItemCost := SkipJobUpdate;
end;
local procedure GetLastValidValueEntry(ValueEntryNo: Integer): Integer
var
MaxInteger: Integer;
begin
MaxInteger := Power(2, 31) - 1;
TempAvgCostExceptionBuf.SetFilter(TempAvgCostExceptionBuf.Number, '>%1', ValueEntryNo);
if not TempAvgCostExceptionBuf.FindFirst() then begin
TempAvgCostExceptionBuf.SetRange(TempAvgCostExceptionBuf.Number);
exit(MaxInteger);
end;
exit(TempAvgCostExceptionBuf.Number);
end;
local procedure FillFixApplBuffer(ItemLedgerEntryNo: Integer)
var
ItemApplnEntry: Record "Item Application Entry";
ItemApplicationEntriesOutb: Query "Item Application Entries Outb.";
begin
if not FixedAppliedItemEntryNos.Contains(ItemLedgerEntryNo) then
if ItemApplnEntry.AppliedOutbndEntryExists(ItemApplicationEntriesOutb, ItemLedgerEntryNo, true, false) then begin
FixedAppliedItemEntryNos.Add(ItemLedgerEntryNo);
repeat
// buffer is filled with couple of entries which are applied and contains revaluation
FixedAppliedItemEntryNos.Add(ItemApplicationEntriesOutb.Item_Ledger_Entry_No);
until not ItemApplicationEntriesOutb.Read();
end;
end;
local procedure RunUpdateJobItemCost()
var
JobsSetup: Record "Jobs Setup";
Job: Record Job;
UpdateJobItemCost: Report "Update Job Item Cost";
JobNo: Code[20];
begin
OnBeforeRunUpdateJobItemCost(JobsToAdjust);
JobsSetup.SetLoadFields("Automatic Update Job Item Cost");
if JobsSetup.Get() then
if JobsSetup."Automatic Update Job Item Cost" then
foreach JobNo in JobsToAdjust do begin
Job.SetRange("No.", JobNo);
Clear(UpdateJobItemCost);
UpdateJobItemCost.SetTableView(Job);
UpdateJobItemCost.UseRequestPage := false;
UpdateJobItemCost.SetProperties(true);
UpdateJobItemCost.RunModal();
end;
end;
local procedure FetchOpenOutboundItemEntriesToExclude(AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point"; var ExcludedValueEntry: Record "Value Entry"; var OpenOutbndEntries: List of [Integer]; CalendarPeriod: Record Date)
var
OpenItemLedgEntry: Record "Item Ledger Entry";
ItemApplicationTraceAllPeriods: Record "Item Application Trace";
begin
Clear(OpenOutbndEntries);
if OpenOutbndItemLedgEntriesExist(OpenItemLedgEntry, AvgCostAdjmtEntryPoint, CalendarPeriod) then
repeat
CopyOpenItemLedgEntryToBuf(OpenOutbndEntries, ExcludedValueEntry, OpenItemLedgEntry."Entry No.", CalendarPeriod."Period Start");
if GetChainOfAppliedEntries(ItemApplicationTraceAllPeriods, OpenItemLedgEntry, false) then
repeat
CopyOpenItemLedgEntryToBuf(
OpenOutbndEntries, ExcludedValueEntry, ItemApplicationTraceAllPeriods."Entry No.", CalendarPeriod."Period Start");
until ItemApplicationTraceAllPeriods.Next() = 0;
until OpenItemLedgEntry.Next() = 0;
end;
local procedure OpenOutbndItemLedgEntriesExist(var OpenItemLedgEntry: Record "Item Ledger Entry"; AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point"; CalendarPeriod: Record Date): Boolean
begin
OpenItemLedgEntry.SetCurrentKey("Item No.", Open, "Variant Code", Positive, "Location Code", "Posting Date", "Entry No.");
OpenItemLedgEntry.SetRange("Item No.", AvgCostAdjmtEntryPoint."Item No.");
OpenItemLedgEntry.SetRange(Open, true);
OpenItemLedgEntry.SetRange(Positive, false);
OpenItemLedgEntry.SetRange("Posting Date", 0D, CalendarPeriod."Period Start" - 1);
if not AvgCostAdjmtEntryPoint.IsAvgCostCalcTypeItem(CalendarPeriod."Period End") then begin
OpenItemLedgEntry.SetRange("Location Code", AvgCostAdjmtEntryPoint."Location Code");
OpenItemLedgEntry.SetRange("Variant Code", AvgCostAdjmtEntryPoint."Variant Code");
end;
OnOpenOutbndItemLedgEntriesExistOnAfterSetOpenItemLedgEntryFilters(OpenItemLedgEntry);
OpenItemLedgEntry.SetBaseLoadFields();
exit(OpenItemLedgEntry.FindSet());
end;
local procedure ResetAvgBuffers(var OutbndValueEntry: Record "Value Entry"; var ExcludedValueEntry: Record "Value Entry")
begin
OutbndValueEntry.Reset();
ExcludedValueEntry.Reset();
TempAvgCostExceptionBuf.Reset();
TempRevaluationPoint.Reset();
TempValueEntryCalcdOutbndCostBuf.Reset();
AvgCostBuf.Initialize(true);
end;
local procedure DeleteAvgBuffers(var OutbndValueEntry: Record "Value Entry"; var ExcludedValueEntry: Record "Value Entry")
begin
ResetAvgBuffers(OutbndValueEntry, ExcludedValueEntry);
AvgCostBuf.Initialize(false);
OutbndValueEntry.DeleteAll();
ExcludedValueEntry.DeleteAll();
TempAvgCostExceptionBuf.DeleteAll();
TempRevaluationPoint.DeleteAll();
TempValueEntryCalcdOutbndCostBuf.DeleteAll();
end;
local procedure InsertEntryPointToUpdate(var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary; ItemNo: Code[20]; VariantCode: Code[10]; LocationCode: Code[10])
begin
TempAvgCostAdjmtEntryPoint."Item No." := ItemNo;
TempAvgCostAdjmtEntryPoint."Variant Code" := VariantCode;
TempAvgCostAdjmtEntryPoint."Location Code" := LocationCode;
TempAvgCostAdjmtEntryPoint."Valuation Date" := 0D;
if TempAvgCostAdjmtEntryPoint.Insert() then;
end;
local procedure UpdateValuationPeriodHasOutput(ValueEntry: Record "Value Entry")
var
AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point";
OutputValueEntry: Record "Value Entry";
CalendarPeriod: Record Date;
begin
if ValueEntry."Item Ledger Entry Type" in
[ValueEntry."Item Ledger Entry Type"::Consumption,
ValueEntry."Item Ledger Entry Type"::"Assembly Consumption"]
then
if AvgCostAdjmtEntryPoint.ValuationExists(ValueEntry) then begin
if (ConsumpAdjmtInPeriodWithOutput <> 0D) and
(ConsumpAdjmtInPeriodWithOutput <= AvgCostAdjmtEntryPoint."Valuation Date")
then
exit;
CalendarPeriod."Period Start" := AvgCostAdjmtEntryPoint."Valuation Date";
AvgCostAdjmtEntryPoint.GetValuationPeriod(CalendarPeriod);
OutputValueEntry.SetCurrentKey("Item No.", "Valuation Date");
OutputValueEntry.SetRange("Item No.", ValueEntry."Item No.");
OutputValueEntry.SetRange("Valuation Date", AvgCostAdjmtEntryPoint."Valuation Date", CalendarPeriod."Period End");
OutputValueEntry.SetFilter(
OutputValueEntry."Item Ledger Entry Type", '%1|%2',
OutputValueEntry."Item Ledger Entry Type"::Output,
OutputValueEntry."Item Ledger Entry Type"::"Assembly Output");
if not OutputValueEntry.IsEmpty() then
ConsumpAdjmtInPeriodWithOutput := AvgCostAdjmtEntryPoint."Valuation Date";
end;
end;
local procedure CopyOpenItemLedgEntryToBuf(var OpenOutbndEntries: List of [Integer]; var ExcludedValueEntry: Record "Value Entry"; OpenItemLedgEntryNo: Integer; PeriodStart: Date)
begin
if CollectOpenValueEntries(ExcludedValueEntry, OpenItemLedgEntryNo, PeriodStart) then
if not OpenOutbndEntries.Contains(OpenItemLedgEntryNo) then
OpenOutbndEntries.Add(OpenItemLedgEntryNo);
end;
local procedure CollectOpenValueEntries(var ExcludedValueEntry: Record "Value Entry"; ItemLedgerEntryNo: Integer; PeriodStart: Date) FoundEntries: Boolean
var
OpenValueEntry: Record "Value Entry";
begin
OpenValueEntry.SetCurrentKey("Item Ledger Entry No.", "Valuation Date");
OpenValueEntry.SetRange("Item Ledger Entry No.", ItemLedgerEntryNo);
OpenValueEntry.SetFilter("Valuation Date", '<%1', PeriodStart);
LoadFields(OpenValueEntry);
FoundEntries := OpenValueEntry.FindSet();
if FoundEntries then
repeat
ExcludedValueEntry := OpenValueEntry;
if ExcludedValueEntry.Insert() then;
until OpenValueEntry.Next() = 0;
end;
local procedure CopyJobToAdjustmentBuf(JobNo: Code[20])
begin
if not JobsToAdjust.Contains(JobNo) then
JobsToAdjust.Add(JobNo);
end;
local procedure UseStandardCostMirroring(ItemLedgEntry: Record "Item Ledger Entry"): Boolean
var
ReturnShipmentLine: Record "Return Shipment Line";
EntryNo: Integer;
begin
if (ItemLedgEntry."Entry Type" <> ItemLedgEntry."Entry Type"::Purchase) or
(ItemLedgEntry."Document Type" <> ItemLedgEntry."Document Type"::"Purchase Return Shipment")
then
exit(false);
EntryNo := ItemLedgEntry."Entry No.";
ItemLedgEntry.Reset();
ItemLedgEntry.SetCurrentKey("Document No.", "Document Type", "Document Line No.");
ItemLedgEntry.SetRange("Document Type", ItemLedgEntry."Document Type");
ItemLedgEntry.SetRange("Document No.", ItemLedgEntry."Document No.");
ItemLedgEntry.SetFilter("Document Line No.", '<>%1', ItemLedgEntry."Document Line No.");
ItemLedgEntry.SetRange("Item No.", ItemLedgEntry."Item No.");
ItemLedgEntry.SetRange(Correction, true);
ItemLedgEntry.SetLoadFields("Document No.", "Document Line No.");
if ItemLedgEntry.FindSet() then
repeat
ReturnShipmentLine.SetLoadFields("Appl.-to Item Entry");
ReturnShipmentLine.Get(ItemLedgEntry."Document No.", ItemLedgEntry."Document Line No.");
if ReturnShipmentLine."Appl.-to Item Entry" = EntryNo then
exit(true);
until ItemLedgEntry.Next() = 0;
exit(false);
end;
local procedure IsOutputWithSelfConsumption(InbndValueEntry: Record "Value Entry"; OutbndValueEntry: Record "Value Entry"; var OutbndEntryItemApplicationTrace: Record "Item Application Trace"): Boolean
var
ConsumpItemLedgEntry: Record "Item Ledger Entry";
ConsumpValueEntry: Record "Value Entry";
AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point";
AvgCostValuePeriodDate: Record Date;
begin
if not (InbndValueEntry."Item Ledger Entry Type" in
[InbndValueEntry."Item Ledger Entry Type"::Output,
InbndValueEntry."Item Ledger Entry Type"::"Assembly Output"])
then
exit(false);
if not (OutbndValueEntry."Item Ledger Entry Type" in
[OutbndValueEntry."Item Ledger Entry Type"::Consumption,
OutbndValueEntry."Item Ledger Entry Type"::"Assembly Consumption"])
then
exit(false);
if not AvgCostAdjmtEntryPoint.ValuationExists(InbndValueEntry) then
exit(false);
AvgCostValuePeriodDate."Period Start" := AvgCostAdjmtEntryPoint."Valuation Date";
AvgCostAdjmtEntryPoint.GetValuationPeriod(AvgCostValuePeriodDate);
ConsumpValueEntry.SetCurrentKey("Order Type", "Order No.", "Order Line No.");
ConsumpValueEntry.SetRange("Order Type", InbndValueEntry."Order Type");
ConsumpValueEntry.SetRange("Order No.", InbndValueEntry."Order No.");
if InbndValueEntry."Order Type" = InbndValueEntry."Order Type"::Production then
ConsumpValueEntry.SetRange("Order Line No.", InbndValueEntry."Order Line No.");
ConsumpValueEntry.SetRange("Item No.", InbndValueEntry."Item No."); // self-consumption
ConsumpValueEntry.SetRange("Valuation Date", AvgCostAdjmtEntryPoint."Valuation Date", AvgCostValuePeriodDate."Period End");
ConsumpValueEntry.SetFilter(
ConsumpValueEntry."Item Ledger Entry Type", '%1|%2',
ConsumpValueEntry."Item Ledger Entry Type"::Consumption, ConsumpValueEntry."Item Ledger Entry Type"::"Assembly Consumption");
if not AvgCostAdjmtEntryPoint.IsAvgCostCalcTypeItem(InbndValueEntry."Valuation Date") then begin
ConsumpValueEntry.SetRange("Variant Code", InbndValueEntry."Variant Code");
ConsumpValueEntry.SetRange("Location Code", InbndValueEntry."Location Code");
end;
OnIsOutputWithSelfConsumptionOnAfterSetConsumpValueEntryFilters(ConsumpValueEntry);
ConsumpValueEntry.SetLoadFields("Item Ledger Entry No.");
if ConsumpValueEntry.FindFirst() then begin
ConsumpItemLedgEntry.SetBaseLoadFields();
ConsumpItemLedgEntry.Get(ConsumpValueEntry."Item Ledger Entry No.");
if GetChainOfAppliedEntries(ItemApplicationTrace, ConsumpItemLedgEntry, true) then begin
OnIsOutputWithSelfConsumptionOnAfterGetItemApplicationTrace(ItemApplicationTrace);
ConsumpValueEntry.CopyFilter("Item No.", ItemApplicationTrace."Item No.");
ConsumpValueEntry.CopyFilter("Variant Code", ItemApplicationTrace."Variant Code");
ConsumpValueEntry.CopyFilter("Location Code", ItemApplicationTrace."Location Code");
OutbndEntryItemApplicationTrace.AddChain(OutbndValueEntry."Item Ledger Entry No.", ItemApplicationTrace);
end;
exit(true);
end;
exit(false);
end;
local procedure RestoreValuesFromBuffers(var OutbndCostElementBuf: Record "Cost Element Buffer"; var AdjustedCostElementBuf: Record "Cost Element Buffer"; OutbndItemLedgEntryNo: Integer): Boolean
begin
TempValueEntryCalcdOutbndCostBuf.Reset();
TempValueEntryCalcdOutbndCostBuf.SetRange("Item Ledger Entry No.", OutbndItemLedgEntryNo);
if TempValueEntryCalcdOutbndCostBuf.IsEmpty() then
exit(false);
TempValueEntryCalcdOutbndCostBuf.FindSet();
CopyValueEntryBufToCostElementBuf(OutbndCostElementBuf, TempValueEntryCalcdOutbndCostBuf);
TempValueEntryCalcdOutbndCostBuf.Next();
repeat
CopyValueEntryBufToCostElementBuf(AdjustedCostElementBuf, TempValueEntryCalcdOutbndCostBuf);
until TempValueEntryCalcdOutbndCostBuf.Next() = 0;
exit(true);
end;
local procedure SaveValuesToBuffers(var OutbndCostElementBuf: Record "Cost Element Buffer"; var AdjustedCostElementBuf: Record "Cost Element Buffer"; OutbndItemLedgEntryNo: Integer)
begin
if AdjustedCostElementBuf.IsEmpty() then
exit;
CopyCostElementBufToValueEntryBuf(TempValueEntryCalcdOutbndCostBuf, OutbndCostElementBuf, OutbndItemLedgEntryNo);
AdjustedCostElementBuf.FindSet();
repeat
CopyCostElementBufToValueEntryBuf(TempValueEntryCalcdOutbndCostBuf, AdjustedCostElementBuf, OutbndItemLedgEntryNo);
until AdjustedCostElementBuf.Next() = 0;
end;
local procedure CopyCostElementBufToValueEntryBuf(var ValueEntryBuf: Record "Value Entry"; CostElementBuffer: Record "Cost Element Buffer"; ItemLedgEntryNo: Integer)
var
EntryNo: Integer;
begin
ValueEntryBuf.Reset();
if ValueEntryBuf.FindLast() then
EntryNo := ValueEntryBuf."Entry No.";
ValueEntryBuf.Init();
ValueEntryBuf."Entry No." := EntryNo + 1;
ValueEntryBuf."Entry Type" := CostElementBuffer.Type;
ValueEntryBuf."Variance Type" := CostElementBuffer."Variance Type";
ValueEntryBuf."Item Ledger Entry No." := ItemLedgEntryNo;
ValueEntryBuf."Cost Amount (Actual)" := CostElementBuffer."Actual Cost";
ValueEntryBuf."Cost Amount (Actual) (ACY)" := CostElementBuffer."Actual Cost (ACY)";
ValueEntryBuf."Cost Amount (Expected)" := CostElementBuffer."Expected Cost";
ValueEntryBuf."Cost Amount (Expected) (ACY)" := CostElementBuffer."Expected Cost (ACY)";
ValueEntryBuf."Cost Amount (Non-Invtbl.)" := CostElementBuffer."Rounding Residual";
ValueEntryBuf."Cost Amount (Non-Invtbl.)(ACY)" := CostElementBuffer."Rounding Residual (ACY)";
ValueEntryBuf."Invoiced Quantity" := CostElementBuffer."Invoiced Quantity";
ValueEntryBuf."Valued Quantity" := CostElementBuffer."Remaining Quantity";
ValueEntryBuf."Expected Cost" := CostElementBuffer."Inbound Completely Invoiced";
OnCopyCostElementBufToValueEntryBufOnBeforeValueEntryBufInsert(ValueEntryBuf, CostElementBuffer);
ValueEntryBuf.Insert();
end;
local procedure CopyValueEntryBufToCostElementBuf(var CostElementBuffer: Record "Cost Element Buffer"; ValueEntryBuf: Record "Value Entry")
begin
CostElementBuffer.Init();
CostElementBuffer.Type := ValueEntryBuf."Entry Type";
CostElementBuffer."Variance Type" := ValueEntryBuf."Variance Type";
CostElementBuffer."Actual Cost" := ValueEntryBuf."Cost Amount (Actual)";
CostElementBuffer."Actual Cost (ACY)" := ValueEntryBuf."Cost Amount (Actual) (ACY)";
CostElementBuffer."Expected Cost" := ValueEntryBuf."Cost Amount (Expected)";
CostElementBuffer."Expected Cost (ACY)" := ValueEntryBuf."Cost Amount (Expected) (ACY)";
CostElementBuffer."Rounding Residual" := ValueEntryBuf."Cost Amount (Non-Invtbl.)";
CostElementBuffer."Rounding Residual (ACY)" := ValueEntryBuf."Cost Amount (Non-Invtbl.)(ACY)";
CostElementBuffer."Invoiced Quantity" := ValueEntryBuf."Invoiced Quantity";
CostElementBuffer."Remaining Quantity" := ValueEntryBuf."Valued Quantity";
CostElementBuffer."Inbound Completely Invoiced" := ValueEntryBuf."Expected Cost";
OnCopyValueEntryBufToCostElementBufOnBeforeCostElementBufferInsert(CostElementBuffer, ValueEntryBuf);
CostElementBuffer.Insert();
end;
local procedure ClearOutboundEntryCostBuffer(InboundEntryNo: Integer)
var
ItemApplicationEntry: Record "Item Application Entry";
ItemApplicationEntriesOutb: Query "Item Application Entries Outb.";
begin
if ItemApplicationEntry.AppliedOutbndEntryExists(ItemApplicationEntriesOutb, InboundEntryNo, false, false) then
repeat
TempValueEntryCalcdOutbndCostBuf.Reset();
TempValueEntryCalcdOutbndCostBuf.SetRange("Item Ledger Entry No.", ItemApplicationEntriesOutb.Outbound_Item_Entry_No);
if not TempValueEntryCalcdOutbndCostBuf.IsEmpty() then
TempValueEntryCalcdOutbndCostBuf.DeleteAll();
until not ItemApplicationEntriesOutb.Read();
end;
local procedure GetChainOfAppliedEntries(var CurrentItemApplicationTrace: Record "Item Application Trace"; FromItemLedgerEntry: Record "Item Ledger Entry"; WithinValuationDate: Boolean): Boolean
var
ItemApplicationEntry: Record "Item Application Entry";
TempItemLedgerEntryChain: Record "Item Ledger Entry" temporary;
begin
CurrentItemApplicationTrace.Reset();
CurrentItemApplicationTrace.SetRange("From Entry No.", FromItemLedgerEntry."Entry No.");
if CurrentItemApplicationTrace.IsEmpty() then begin
ItemApplicationEntry.GetVisitedEntries(FromItemLedgerEntry, TempItemLedgerEntryChain, WithinValuationDate);
CurrentItemApplicationTrace.CreateChain(FromItemLedgerEntry, TempItemLedgerEntryChain);
end;
CurrentItemApplicationTrace.SetFilter(Level, '>0');
exit(CurrentItemApplicationTrace.FindSet());
end;
local procedure IsAvgCostException(ValueEntry: Record "Value Entry"; AvgCostByItem: Boolean): Boolean
var
ItemLedgerEntry: Record "Item Ledger Entry";
begin
if ValueEntry."Partial Revaluation" then
exit(true);
if ValueEntry."Item Charge No." <> '' then
exit(true);
ItemLedgerEntry.SetLoadFields(Positive);
ItemLedgerEntry.Get(ValueEntry."Item Ledger Entry No.");
if ItemLedgerEntry.Positive then
exit(false);
if not GetChainOfAppliedEntries(ItemApplicationTrace, ItemLedgerEntry, true) then
exit(false);
ItemApplicationTrace.SetRange("Item No.", ValueEntry."Item No.");
if not AvgCostByItem then begin
ItemApplicationTrace.SetRange("Location Code", ValueEntry."Location Code");
ItemApplicationTrace.SetRange("Variant Code", ValueEntry."Variant Code");
end;
ItemApplicationTrace.SetRange(Positive, true);
exit(not ItemApplicationTrace.IsEmpty());
end;
local procedure CollectItemLedgerEntryTypesUsed(ItemNo: Code[20])
var
ItemLedgerEntry: Record "Item Ledger Entry";
begin
ItemLedgerEntry.CollectItemLedgerEntryTypesUsed(ItemLedgerEntryTypesUsed, StrSubstNo('''%1''', ItemNo));
end;
local procedure ItemLedgerEntryTypeIsUsed(ItemLedgerEntryType: Enum "Item Ledger Entry Type"): Boolean
begin
if not ItemLedgerEntryTypesUsed.ContainsKey(ItemLedgerEntryType) then
exit(true);
exit(ItemLedgerEntryTypesUsed.Get(ItemLedgerEntryType));
end;
local procedure PushCurrentItem(var CurrentItem: Record Item)
begin
if not ItemsBeingAdjusted.Contains(CurrentItem."No.") then
ItemsBeingAdjusted.Add(CurrentItem."No.");
end;
local procedure PopCurrentItem(var CurrentItem: Record Item)
begin
if not CurrentItem."Cost is Adjusted" then
exit;
if ItemsBeingAdjusted.Contains(CurrentItem."No.") then
ItemsBeingAdjusted.Remove(CurrentItem."No.");
end;
local procedure CheckAndCommit()
begin
ItemsSinceLastCommit += 1;
if ItemsBeingAdjusted.Count() > 0 then
exit;
if CommitAdjustedItems then begin
Commit();
ItemJnlPostLine.ResetGLPostingState();
EmitCheckAndCommitTelemetry();
ItemsSinceLastCommit := 0;
end;
ItemApplicationTrace.Reset();
ItemApplicationTrace.DeleteAll();
end;
local procedure EmitCheckAndCommitTelemetry()
var
TelemetryDimensions: Dictionary of [Text, Text];
begin
TelemetryDimensions.Add('ItemsSinceLastCommit', Format(ItemsSinceLastCommit));
TelemetryDimensions.Add('IsOnlineAdjmt', Format(IsOnlineAdjmt, 0, 9));
TelemetryDimensions.Add('PostToGL', Format(PostToGL, 0, 9));
TelemetryDimensions.Add('ItemByItemCommit', Format(CommitAdjustedItems, 0, 9));
FeatureTelemetry.LogUsage('0000MEQ', CostAdjmtCommitFeatureNameTok, CostAdjmtCommitEventNameTok, TelemetryDimensions);
end;
local procedure FindLastDate(DateFilter: Text): Date
var
Calendar: Record Date;
PeriodPageMgt: Codeunit PeriodPageManagement;
begin
if DateFilter = '' then
exit(PeriodPageMgt.EndOfPeriod());
Calendar.SetRange("Period Type", Calendar."Period Type"::Date);
Calendar.SetFilter("Period Start", DateFilter);
Calendar.FindLast();
exit(Calendar."Period Start");
end;
local procedure SetDateFilterUntilLastDate(var AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point")
var
Calendar: Record Date;
PeriodPageMgt: Codeunit PeriodPageManagement;
FromDate, ToDate : Date;
begin
if AdjustTillDate = PeriodPageMgt.EndOfPeriod() then
exit;
Calendar.SetRange("Period Type", Calendar."Period Type"::Date);
Calendar.SetFilter("Period Start", AvgCostAdjmtEntryPoint.GetFilter("Valuation Date"));
Calendar.FilterGroup(2);
Calendar.SetRange("Period Start", 0D, AdjustTillDate);
Calendar.FindFirst();
FromDate := Calendar."Period Start";
Calendar.FindLast();
ToDate := Calendar."Period Start";
AvgCostAdjmtEntryPoint.SetRange("Valuation Date", FromDate, ToDate);
end;
local procedure LoadFields(var ValueEntry: Record "Value Entry")
begin
ValueEntry.SetLoadFields("Entry No.", "Item No.", "Item Ledger Entry Type", "Document No.", "Location Code",
"Item Ledger Entry No.", "Valued Quantity", "Item Ledger Entry Quantity", "Invoiced Quantity",
"Cost per Unit", "Applies-to Entry", "Cost Amount (Actual)", "Cost Amount (Actual) (ACY)", "Cost per Unit (ACY)",
"Document Line No.", "Order Type", "Order No.", "Order Line No.", "Expected Cost",
"Item Charge No.", "Valued By Average Cost", "Partial Revaluation", Inventoriable, "Valuation Date",
"Entry Type", "Cost Amount (Expected)", "Cost Amount (Expected) (ACY)", "Variant Code", Adjustment)
end;
local procedure Min(Date1: Date; Date2: Date): Date
begin
if Date1 < Date2 then
exit(Date1);
exit(Date2);
end;
// Extension interface for local procedures
procedure CallInitializeAdjmt()
begin
InitializeAdjmt();
end;
procedure CallFinalizeAdjmt()
begin
FinalizeAdjmt();
end;
procedure CallInvtToAdjustExist(var ToItem: Record Item): Boolean
begin
exit(InvtToAdjustExist(ToItem));
end;
procedure CallMakeSingleLevelAdjmt(var TheItem: Record Item; var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
begin
MakeSingleLevelAdjmt(TheItem, TempAvgCostAdjmtEntryPoint);
end;
procedure CallWIPToAdjustExist(var ToInventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"): Boolean
begin
exit(WIPToAdjustExist(ToInventoryAdjmtEntryOrder));
end;
procedure CallMakeWIPAdjmt(var SourceInvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
begin
MakeWIPAdjmt(SourceInvtAdjmtEntryOrder, TempAvgCostAdjmtEntryPoint);
end;
procedure CallAssemblyToAdjustExists(var ToInventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"): Boolean
begin
exit(AssemblyToAdjustExists(ToInventoryAdjmtEntryOrder));
end;
procedure CallMakeAssemblyAdjmt(var SourceInvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)"; var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
begin
MakeAssemblyAdjmt(SourceInvtAdjmtEntryOrder, TempAvgCostAdjmtEntryPoint);
end;
procedure CallUpdateAdjmtBuf(OrigValueEntry: Record "Value Entry"; NewAdjustedCost: Decimal; NewAdjustedCostACY: Decimal; ItemLedgEntryPostingDate: Date; EntryType: Enum "Cost Entry Type"): Boolean
begin
exit(UpdateAdjmtBuf(OrigValueEntry, NewAdjustedCost, NewAdjustedCostACY, ItemLedgEntryPostingDate, EntryType));
end;
procedure CallPostAdjmtBuf(var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
begin
PostAdjmtBuf(TempAvgCostAdjmtEntryPoint);
end;
procedure CallPostOutputAdjmtBuf(var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary)
begin
PostOutputAdjmtBuf(TempAvgCostAdjmtEntryPoint);
end;
procedure CallSetAppliedEntryToAdjustFromBuf(ItemNo: Code[20])
begin
SetAppliedEntryToAdjustFromBuf(ItemNo);
end;
procedure CallAppliedEntryToAdjustBufExists(ItemNo: Code[20]): Boolean
begin
exit(AppliedEntryToAdjustBufExists((ItemNo)));
end;
procedure CallUpdateJobItemCost()
begin
RunUpdateJobItemCost();
end;
[IntegrationEvent(true, false)]
local procedure OnAfterCalcInbndEntryAdjustedCost(var AdjustedCostElementBuf: Record "Cost Element Buffer"; var InbndValueEntry: Record "Value Entry"; InbndItemLedgEntry: Record "Item Ledger Entry"; ItemApplnEntry: Record "Item Application Entry"; OutbndItemLedgEntryNo: Integer; var CompletelyInvoiced: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustOutbndAvgEntryOnBeforeForwardAvgCostToInbndEntries(var OutbndItemLedgEntry: Record "Item Ledger Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustItemAvgCostOnAfterLastTempAvgCostAdjmtEntryPoint(var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary; var Restart: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustItemAvgCostOnAfterCalcRestart(var TempExcludedValueEntry: Record "Value Entry" temporary; var Restart: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAvgValueEntriesToAdjustExistOnAfterSetAvgValueEntryFilters(var ValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAvgValueEntriesToAdjustExistOnAfterSetChildValueEntryFilters(var ValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAvgValueEntriesToAdjustExistOnFindNextRangeOnBeforeAvgValueEntriesToAdjustExist(var OutbndValueEntry: Record "Value Entry"; var ExcludedValueEntry: Record "Value Entry"; var AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterGetValuationPeriod(var CalendarPeriod: Record Date; Item: record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterIsAvgCostItem(var Item: Record Item; var AvgCostItem: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterMakeMultiLevelAdjmt(var Item: Record Item; IsOnlineAdjmt: Boolean; PostToGL: Boolean; var FilterItem: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCalcInbndEntryAdjustedCost(var AdjustedCostElementBuf: Record "Cost Element Buffer"; ItemApplnEntry: Record "Item Application Entry"; OutbndItemLedgEntryNo: Integer; InbndItemLedgEntryNo: Integer; ExactCostReversing: Boolean; Recursion: Boolean; var CompletelyInvoiced: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCopyILEToILE(var Item: Record Item; ItemLedgEntry: Record "Item Ledger Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCopyItemToItem(var FromItem: Record Item; var ToItem: Record Item; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeIsUpdateCompletelyInvoiced(ItemLedgEntry: Record "Item Ledger Entry"; CompletelyInvoiced: Boolean; var Result: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeMakeMultiLevelAdjmt(var Item: Record Item; IsOnlineAdjmt: Boolean; var PostToGL: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeMakeMultiLevejAdjmtOnAfterGetParameters(var CostAdjustmentParamsMgt: Codeunit "Cost Adjustment Params Mgt.")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforePostItemJnlLine(var ItemJournalLine: Record "Item Journal Line"; OrigValueEntry: Record "Value Entry"; NewAdjustedCost: Decimal; NewAdjustedCostACY: Decimal; SkipUpdateJobItemCost: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeOpenWindow(var IsHandled: Boolean; var WindowDialog: Dialog; var WindowIsOpen: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateAdjmtBuf(OrigValueEntry: Record "Value Entry"; NewAdjustedCost: Decimal; NewAdjustedCostACY: Decimal; ItemLedgEntryPostingDate: Date; EntryType: Enum "Cost Entry Type"; var Result: Boolean; var IsHandled: Boolean; var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateWindow(var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateItemUnitCost2(var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary; var IsHandled: Boolean; var Item: Record Item; var ItemLedgEntryToAdjust: Dictionary of [Code[20], List of [Integer]])
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateConsumpAvgEntry(ValueEntry: Record "Value Entry"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCopyAvgCostAdjmtToAvgCostAdjmtOnAfterInsert(var AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCopyCostElementBufToValueEntryBufOnBeforeValueEntryBufInsert(var ValueEntryBuf: Record "Value Entry"; CostElementBuffer: Record "Cost Element Buffer")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCopyValueEntryBufToCostElementBufOnBeforeCostElementBufferInsert(var CostElementBuffer: Record "Cost Element Buffer"; ValueEntryBuf: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnForwardAppliedCostOnAfterSetAppliedQty(ItemLedgerEntry: Record "Item Ledger Entry"; var AppliedQty: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnGetOrigValueEntryOnAfterOrigValueEntryFound(var OrigValueEntry: Record "Value Entry"; ValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnIsOutputWithSelfConsumptionOnAfterSetConsumpValueEntryFilters(var ConsumpValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnOpenOutbndItemLedgEntriesExistOnAfterSetOpenItemLedgEntryFilters(var OpenItemLedgerEntry: Record "Item Ledger Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostItemJnlLineCopyFromValueEntry(var ItemJournalLine: Record "Item Journal Line"; ValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostItemJnlLineOnAfterItemJnlPostLineRunWithCheck(var ItemJournalLine: Record "Item Journal Line"; ValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostItemJnlLineOnAfterSetPostingDate(var ItemJournalLine: Record "Item Journal Line"; ValueEntry: Record "Value Entry"; PostingDateForClosedPeriod: Date; var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnMakeMultiLevelAdjmtOnAfterMakeAdjmt(var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary; var FilterItem: Record Item; var RndgResidualBuf: Record "Rounding Residual Buffer"; IsOnlineAdjmt: Boolean; PostToGL: Boolean; var ItemJnlPostLine: Codeunit "Item Jnl.-Post Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnMakeSingleLevelAdjmtOnAfterUpdateItemUnitCost(var TheItem: Record Item; var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary; var LevelExceeded: Boolean; IsOnlineAdjmt: Boolean; var ItemJnlPostLine: Codeunit "Item Jnl.-Post Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInvtToAdjustExistOnBeforeCopyItemToItem(var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRunUpdateJobItemCost(var JobsToAdjust: List of [Code[20]])
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateItemUnitCostOnAfterItemGet(var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateItemUnitCostOnAfterModifyItemNotStandardCostingMethod(var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateItemUnitCostOnBeforeModifyItemNotStandardCostingMethod(var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateConsumpAvgEntryOnAfterSetItemLedgEntryFilters(var ItemLedgerEntry: Record "Item Ledger Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostOutputOnBeforePostItemJnlLine(var ItemJnlLine: Record "Item Journal Line"; OrigValueEntry: Record "Value Entry"; var InvtAdjmtBuf: Record "Inventory Adjustment Buffer"; var GLSetup: Record "General Ledger Setup"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInitAdjmtJnlLine(var ItemJnlLine: Record "Item Journal Line"; OrigValueEntry: Record "Value Entry"; EntryType: Enum "Cost Entry Type"; VarianceType: Enum "Cost Variance Type"; InvoicedQty: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnWIPToAdjustExistOnAfterInventoryAdjmtEntryOrderSetFilters(var InventoryAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeMakeSingleLevelAdjmt(var TheItem: Record Item; var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustItemAvgCostOnBeforeAdjustValueEntries()
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAvgValueEntriesToAdjustExistOnBeforeIsNotAdjustment(var ValueEntry: Record "Value Entry"; var OutbndValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnMakeSingleLevelAdjmtOnBeforeCollectAvgCostAdjmtEntryPointToUpdate(var TheItem: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInitializeAdjmtOnAfterGetPostingDate(var PostingDateForClosedPeriod: Date)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustAppliedInbndEntriesOnAfterSetFilter(var InbndValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateIndirectCostAdjmtOnAfterPostItemJnlLine(ValueEntry: Record "Value Entry"; NewAdjustedCost: Decimal; NewAdjustedCostACY: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostAdjmtBufOnAfterPostExpectedCost(ValueEntry: Record "Value Entry"; TempInventoryAdjustmentBuffer: Record "Inventory Adjustment Buffer" temporary)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostAdjmtBufOnBeforePostNewCost(var ItemJournalLine: Record "Item Journal Line"; OrigValueEntry: Record "Value Entry"; TempInventoryAdjustmentBuffer: Record "Inventory Adjustment Buffer" temporary)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostAdjmtBufOnAfterPostNewCost(ValueEntry: Record "Value Entry"; TempInventoryAdjustmentBuffer: Record "Inventory Adjustment Buffer" temporary)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnMakeSingleLevelAdjmtOnAfterLevelExceeded(var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnMakeSingleLevelAdjmtOnBeforePostAdjmtBuf2(var Item: Record Item; var TempAvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point" temporary; var TempInventoryAdjustmentBuffer: Record "Inventory Adjustment Buffer" temporary; var TempRoundingResidualBuffer: Record "Rounding Residual Buffer" temporary; PostingDateForClosedPeriod: Date; Currency: Record Currency; SkipUpdateJobItemCost: Boolean; var JobsToAdjust: List of [Code[20]]; ItemJnlPostLine: Codeunit "Item Jnl.-Post Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnForwardAppliedCostOnBeforeUpdateWindow(var ItemLedgerEntry: Record "Item Ledger Entry"; var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustAppliedOutbndEntriesOnBeforeCheckExpectedCost(var Item: Record Item; var OutbndValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalcInbndEntryAdjustedCostOnBeforeAddCost(var Item: Record Item; var InbndValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustItemAvgCostOnBeforeUpdateWindow(var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateAdjmtBufOnBeforeHasNewCost(OrigValueEntry: Record "Value Entry"; NewAdjustedCost: Decimal; NewAdjustedCostACY: Decimal; ItemLedgEntryPostingDate: Date; EntryType: Enum "Cost Entry Type"; var IsHandled: Boolean; var TempInvtAdjmtBuf: Record "Inventory Adjustment Buffer" temporary; var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateWindowOnAfterOpenWindow(var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalcAvgCostOnAfterAssignRoundingError(var RoundingError: Decimal; var RoundingErrorACY: Decimal; var CostElementBuffer: Record "Cost Element Buffer")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustOutbndAvgEntryOnNewCostElementBuf(var OutbndValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateAdjmtBufOnAfterAddActualCostBuf(OrigValueEntry: Record "Value Entry"; NewAdjustedCost: Decimal; NewAdjustedCostACY: Decimal; ItemLedgEntryPostingDate: Date; TempInventoryAdjustmentBuffer: Record "Inventory Adjustment Buffer" temporary)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnEliminateRndgResidualOnBeforeCheckHasNewCost(InbndItemLedgerEntry: Record "Item Ledger Entry"; ValueEntry: Record "Value Entry"; RndgCost: Decimal; RndgCostACY: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAdjustItem(var TheItem: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterAdjustItem(var TheItem: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnEliminateRndgResidualOnAfterCalcInboundCost(var ValueEntry: Record "Value Entry"; InbndItemLedgEntryNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCollectItemLedgerEntryTypesUsed(var Item: Record Item; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustItemAppliedCostForItemLedgerEntry(var ItemLedgEntry: Record "Item Ledger Entry"; var NeedsAdjustment: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalcCostPerUnitOnBeforeCalcCostPerUnit(var OutbndValueEntry: Record "Value Entry"; OutbndCostElementBuffer: Record "Cost Element Buffer"; var CalcCostPerUnit: Boolean; var CalcCostPerUnitACY: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalcTransEntryOldCostOnBeforeProcessTransValueEntry(var TransValueEntry: Record "Value Entry"; var ProcessTransValueEntry: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustAppliedOutbndEntry(var OutbndItemLedgEntry: Record "Item Ledger Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustAppliedOutbndEntriesOnBeforeAdjustEntry(var OutbndItemLedgEntry: Record "Item Ledger Entry"; var OutbndValueEntry: Record "Value Entry"; var NeedsAdjustment: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustAppliedInbndEntry(var InbndItemLedgEntry: Record "Item Ledger Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustAppliedInbndTransEntry(var TransItemLedgEntry: Record "Item Ledger Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAvgCostAdjmtEntryPoint(var AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeIteratingOverOutbndAvgEntries(var OutbndValueEntry: Record "Value Entry"; var AvgCostAdjmtEntryPoint: Record "Avg. Cost Adjmt. Entry Point"; RemainingOutbnd: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAdjustOutbndAvgEntry(var OutbndValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnExcludeAvgCostOnValuationDate(var ExcludedValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeIsExcludeFromAvgCostForRevalPoint(var RevaluationPoint: Record "Integer"; var RevaluationCheckValueEntry: Record "Value Entry"; var OutbndValueEntry: Record "Value Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnMakeWIPAdjmt(var SourceInvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnMakeAssemblyAdjmt(var SourceInvtAdjmtEntryOrder: Record "Inventory Adjmt. Entry (Order)")
begin
end;
#if not CLEAN27
[Obsolete('This event is never raised.', '27.0')]
[IntegrationEvent(false, false)]
local procedure OnAfterSetParameters(var CostAdjustmentParameter: Record "Cost Adjustment Parameter")
begin
end;
#endif
[IntegrationEvent(false, false)]
local procedure OnExcludeAvgCostOnValuationDateOnAfterGetItemApplicationTrace(var OutbndValueEntry: Record "Value Entry"; var OutbndEntryItemApplicationTrace: Record "Item Application Trace")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnIsOutputWithSelfConsumptionOnAfterGetItemApplicationTrace(var ItemApplicationTrace: Record "Item Application Trace")
begin
end;
[IntegrationEvent(true, false)]
local procedure OnCalcInbndEntryAdjustedCostOnBeforeCalcNewAdjustedCost(var CostElementBuffer: Record "Cost Element Buffer"; ItemApplicationEntry: Record "Item Application Entry"; ItemLedgerEntry: Record "Item Ledger Entry"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInitRndgResidualItemJnlLine(var ItemJournalLine: Record "Item Journal Line"; ValueEntry: Record "Value Entry")
begin
end;
}