The application currently recognizes circular references in production and assembly. However, further modules cannot be added to this detection.
Circular references are identified via functions in table 339 ???Item Application Entry???. These functions are taken into account when adjusting inventory costs as well as when applying inventory.
The following is a suggestion for making the recognition of circular references expandable.
Adding integration events
table 339 "Item Application Entry"
procedure CheckIsCyclicalLoop(CheckItemLedgEntry: Record "Item Ledger Entry"; FromItemLedgEntry: Record "Item Ledger Entry"): Boolean
var
Result: Boolean; // new variable
begin
if CheckItemLedgEntry."Entry No." = FromItemLedgEntry."Entry No." then
exit(true);
[...]
if FromItemLedgEntry."Entry Type" = FromItemLedgEntry."Entry Type"::"Assembly Consumption" then
if CheckCyclicAsmCyclicalLoop(CheckItemLedgEntry, FromItemLedgEntry) then
exit(true);
// start
Result := false;
OnCheckIsCyclicalLoop(CheckItemLedgEntry, FromItemLedgEntry, MaxValuationDate, Result);
if Result then
exit(true);
// end
exit(CheckCyclicFwdToAppliedInbnds(CheckItemLedgEntry, FromItemLedgEntry."Entry No."));
end;
local procedure CheckCyclicFwdToAppliedEntries(CheckItemLedgEntry: Record "Item Ledger Entry"; var ItemApplnEntry: Record "Item Application Entry"; FromEntryNo: Integer; IsPositiveToNegativeFlow: Boolean): Boolean
var
ToEntryNo: Integer;
IsCyclicalLoop: Boolean; //new variable
begin
if EntryIsVisited(FromEntryNo) then
exit(false);
repeat
[...]
if not IsPositiveToNegativeFlow then begin
if CheckCyclicFwdToAppliedOutbnds(CheckItemLedgEntry, ToEntryNo) then
exit(true);
end else begin
if CheckCyclicFwdToAppliedInbnds(CheckItemLedgEntry, ToEntryNo) then
exit(true);
if CheckCyclicFwdToProdOutput(CheckItemLedgEntry, ToEntryNo) then
exit(true);
if CheckCyclicFwdToAsmOutput(CheckItemLedgEntry, ToEntryNo) then
exit(true);
// start
IsCyclicalLoop := false;
OnCheckCyclicFwdToAppliedEntries(CheckItemLedgEntry, ToEntryNo, IsCyclicalLoop);
if IsCyclicalLoop then
exit(true);
// end
end;
end;
until ItemApplnEntry.Next() = 0;
if IsPositiveToNegativeFlow then
exit(CheckCyclicFwdToInbndTransfers(CheckItemLedgEntry, FromEntryNo));
exit(false);
end;
Redesign existing functions for production and assembly
table 339 "Item Application Entry"
local procedure CheckCyclicProdCyclicalLoop(CheckItemLedgEntry: Record "Item Ledger Entry"; ItemLedgEntry: Record "Item Ledger Entry"): Boolean
begin
if not IsItemEverOutput(ItemLedgEntry."Item No.") then
exit(false);
[...]
ItemLedgEntry.SetRange("Entry Type", ItemLedgEntry."Entry Type"::Output);
// start
// if MaxValuationDate <> 0D then
// ItemLedgEntry.SetRange("Posting Date", 0D, MaxValuationDate);
// ItemLedgEntry.SetLoadFields(Positive);
// if ItemLedgEntry.FindSet() then
// repeat
// if TrackChain then begin
// TempItemLedgEntryInChainNo.Number := ItemLedgEntry."Entry No.";
// if TempItemLedgEntryInChainNo.Insert() then;
// if SearchedItemLedgerEntryFound(ItemLedgEntry) then
// exit(true);
// end;
// if ItemLedgEntry."Entry No." = CheckItemLedgEntry."Entry No." then
// exit(true);
// if ItemLedgEntry.Positive then
// if CheckCyclicFwdToAppliedOutbnds(CheckItemLedgEntry, ItemLedgEntry."Entry No.") then
// exit(true);
// until ItemLedgEntry.Next() = 0;
// exit(false);
exit(CheckCyclicLedgerEntryCyclicalLoop(CheckItemLedgEntry, ItemLedgEntry));
// end
end;
local procedure CheckCyclicAsmCyclicalLoop(CheckItemLedgEntry: Record "Item Ledger Entry"; ItemLedgEntry: Record "Item Ledger Entry"): Boolean
begin
if ItemLedgEntry."Order Type" <> ItemLedgEntry."Order Type"::Assembly then
exit(false);
[...]
ItemLedgEntry.SetRange("Entry Type", ItemLedgEntry."Entry Type"::"Assembly Output");
// start
// if MaxValuationDate <> 0D then
// ItemLedgEntry.SetRange("Posting Date", 0D, MaxValuationDate);
// ItemLedgEntry.SetLoadFields(Positive);
// if ItemLedgEntry.FindSet() then
// repeat
// if TrackChain then begin
// TempItemLedgEntryInChainNo.Number := ItemLedgEntry."Entry No.";
// if TempItemLedgEntryInChainNo.Insert() then;
// if SearchedItemLedgerEntryFound(ItemLedgEntry) then
// exit(true);
// end;
// if ItemLedgEntry."Entry No." = CheckItemLedgEntry."Entry No." then
// exit(true);
// if ItemLedgEntry.Positive then
// if CheckCyclicFwdToAppliedOutbnds(CheckItemLedgEntry, ItemLedgEntry."Entry No.") then
// exit(true);
// until ItemLedgEntry.Next() = 0;
// exit(false);
exit(CheckCyclicLedgerEntryCyclicalLoop(CheckItemLedgEntry, ItemLedgEntry));
// end
end;
New function
table 339 "Item Application Entry"
procedure CheckCyclicLedgerEntryCyclicalLoop(CheckItemLedgEntry: Record "Item Ledger Entry"; var ItemLedgEntry: Record "Item Ledger Entry"): Boolean
begin
if MaxValuationDate <> 0D then
ItemLedgEntry.SetRange("Posting Date", 0D, MaxValuationDate);
ItemLedgEntry.SetLoadFields(Positive);
if ItemLedgEntry.FindSet() then
repeat
if TrackChain then begin
TempItemLedgEntryInChainNo.Number := ItemLedgEntry."Entry No.";
if TempItemLedgEntryInChainNo.Insert() then;
if SearchedItemLedgerEntryFound(ItemLedgEntry) then
exit(true);
end;
if ItemLedgEntry."Entry No." = CheckItemLedgEntry."Entry No." then
exit(true);
if ItemLedgEntry.Positive then
if CheckCyclicFwdToAppliedOutbnds(CheckItemLedgEntry, ItemLedgEntry."Entry No.") then
exit(true);
until ItemLedgEntry.Next() = 0;
exit(false);
end;
New integration events
table 339 "Item Application Entry"
[IntegrationEvent(true,false)]
local procedure OnCheckIsCyclicalLoop(CheckItemLedgEntry: Record "Item Ledger Entry"; FromItemLedgEntry: Record "Item Ledger Entry"; var IsCyclicalLoop: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnCheckCyclicFwdToAppliedEntries(CheckItemLedgEntry: Record "Item Ledger Entry"; EntryNo: Integer; var IsCyclicalLoop: Boolean)
begin
end;
Important! include sender = true, so function CheckCyclicLedgerEntryCyclicalLoop can access global variables
Additional context
We are expanding Business Central with a module that enables the treatments (mixing and separating) of items. In order to correctly calculate and adjust inventory values, we need to be able to recognize and avoid circular references.
Describe the request
The application currently recognizes circular references in production and assembly. However, further modules cannot be added to this detection. Circular references are identified via functions in table 339 ???Item Application Entry???. These functions are taken into account when adjusting inventory costs as well as when applying inventory.
The following is a suggestion for making the recognition of circular references expandable.
Adding integration events
table 339 "Item Application Entry"
Redesign existing functions for production and assembly
table 339 "Item Application Entry"
New function
table 339 "Item Application Entry"
New integration events
table 339 "Item Application Entry"
Important! include sender = true, so function CheckCyclicLedgerEntryCyclicalLoop can access global variables
Additional context
We are expanding Business Central with a module that enables the treatments (mixing and separating) of items. In order to correctly calculate and adjust inventory values, we need to be able to recognize and avoid circular references.
Internal work item: AB#545884