Codeunit 99000845 Reservation Management
- App
- Base Application
- Namespace
- Microsoft.Inventory.Tracking
- Versions
- 17-28
Procedures, 97Events, 125Obsolete, 47
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Inventory/Tracking/ReservationManagement.Codeunit.al2842 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.Tracking;
using Microsoft.Foundation.Enums;
using Microsoft.Foundation.Navigate;
using Microsoft.Foundation.UOM;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Journal;
using Microsoft.Inventory.Ledger;
using Microsoft.Inventory.Location;
using Microsoft.Inventory.Planning;
using Microsoft.Inventory.Requisition;
using Microsoft.Inventory.Transfer;
using Microsoft.Purchases.Document;
using Microsoft.Purchases.History;
using Microsoft.Sales.Document;
using Microsoft.Warehouse.Activity;
using Microsoft.Warehouse.Availability;
using Microsoft.Warehouse.Ledger;
using Microsoft.Warehouse.Structure;
using System.Utilities;
codeunit 99000845 "Reservation Management"
{
Permissions = TableData "Item Ledger Entry" = rm,
TableData "Reservation Entry" = rimd,
TableData "Action Message Entry" = rimd;
trigger OnRun()
begin
end;
var
#pragma warning disable AA0074
Text007: Label 'CU99000845 DeleteReservEntries2: Surplus order tracking double record detected.';
#pragma warning restore AA0074
CalcReservEntry: Record "Reservation Entry";
CalcReservEntry2: Record "Reservation Entry";
CalcItemLedgEntry: Record "Item Ledger Entry";
Item: Record Item;
Location: Record Location;
SKU: Record "Stockkeeping Unit";
ItemTrackingCode: Record "Item Tracking Code";
TempTrackingSpecification: Record "Tracking Specification" temporary;
CallTrackingSpecification: Record "Tracking Specification";
CreateReservEntry: Codeunit "Create Reserv. Entry";
ReservEngineMgt: Codeunit "Reservation Engine Mgt.";
CreatePick: Codeunit "Create Pick";
UOMMgt: Codeunit "Unit of Measure Management";
LateBindingMgt: Codeunit "Late Binding Management";
SourceRecRef: RecordRef;
RefOrderType: Enum "Requisition Ref. Order Type";
PlanningLineOrigin: Enum "Planning Line Origin Type";
Positive: Boolean;
CurrentBindingIsSet: Boolean;
HandleItemTracking: Boolean;
InvSearch: Text[1];
InvNextStep: Integer;
ValueArray: array[30] of Integer;
CurrentBinding: Enum "Reservation Binding";
ItemTrackingHandling: Option "None","Allow deletion",Match;
#pragma warning disable AA0074
#pragma warning disable AA0470
Text008: Label 'Item tracking defined for item %1 in the %2 accounts for more than the quantity you have entered.\You must adjust the existing item tracking and then reenter the new quantity.';
#pragma warning restore AA0470
#pragma warning restore AA0074
#pragma warning disable AA0470
ItemTrackingCannotBeFullyMatchedErr: Label 'Item Tracking cannot be fully matched.\Serial No.: %1, Lot No.: %2, outstanding quantity: %3.';
#pragma warning restore AA0470
#pragma warning disable AA0074
#pragma warning disable AA0470
Text010: Label 'Item tracking is defined for item %1 in the %2.\You must delete the existing item tracking before modifying or deleting the %2.';
#pragma warning restore AA0470
#pragma warning restore AA0074
TotalAvailQty: Decimal;
QtyAllocInWhse: Decimal;
QtyOnOutBound: Decimal;
#pragma warning disable AA0074
#pragma warning disable AA0470
Text011: Label 'Item tracking is defined for item %1 in the %2.\Do you want to delete the %2 and the item tracking lines?';
#pragma warning restore AA0470
#pragma warning restore AA0074
QtyReservedOnPickShip: Decimal;
DeleteDocLineWithItemReservQst: Label '%1 %2 has item reservation. Do you want to delete it anyway?', Comment = '%1 = Document Type, %2 = Document No.';
DeleteTransLineWithItemReservQst: Label 'Transfer order %1 has item reservation. Do you want to delete it anyway?', Comment = '%1 = Document No.';
SkipUntrackedSurplus: Boolean;
procedure IsPositive(): Boolean
begin
exit(Positive);
end;
procedure FormatQty(Quantity: Decimal): Decimal
begin
if Positive then
exit(Quantity);
exit(-Quantity);
end;
procedure SetCalcReservEntry(TrackingSpecification: Record "Tracking Specification"; var ReservEntry: Record "Reservation Entry")
begin
// Late Binding
CalcReservEntry.TransferFields(TrackingSpecification);
SourceQuantity(CalcReservEntry, true);
CalcReservEntry.CopyTrackingFromSpec(TrackingSpecification);
ReservEntry := CalcReservEntry;
HandleItemTracking := true;
end;
procedure SetOrderTrackingSurplusEntries(var TempReservEntry: Record "Reservation Entry" temporary)
begin
// Late Binding
LateBindingMgt.SetOrderTrackingSurplusEntries(TempReservEntry);
end;
procedure SetReservSource(NewRecordVar: Variant)
begin
SourceRecRef.GetTable(NewRecordVar);
SetReservSource(SourceRecRef, Enum::"Transfer Direction"::Outbound);
end;
procedure SetReservSource(NewRecordVar: Variant; Direction: Enum "Transfer Direction")
begin
SourceRecRef.GetTable(NewRecordVar);
SetReservSource(SourceRecRef, Direction);
end;
procedure SetReservSource(NewSourceRecRef: RecordRef)
begin
SetReservSource(NewSourceRecRef, Enum::"Transfer Direction"::Outbound);
end;
procedure SetReservSource(NewSourceRecRef: RecordRef; Direction: Enum "Transfer Direction")
begin
ClearAll();
TempTrackingSpecification.DeleteAll();
SourceRecRef := NewSourceRecRef;
// Use this event to subscribe from any source table included in reservation
OnSetReservSource(SourceRecRef, CalcReservEntry, Direction, RefOrderType, PlanningLineOrigin, Positive);
case SourceRecRef.Number of
Database::"Sales Line":
SetSourceForSalesLine();
Database::"Requisition Line":
SetSourceForReqLine();
Database::"Purchase Line":
SetSourceForPurchLine();
Database::"Item Journal Line":
SetSourceForItemJnlLine();
Database::"Item Ledger Entry":
SetSourceForItemLedgerEntry();
5406: // Database::"Prod. Order Line":
SetSourceForProdOrderLine();
5407: // Database::"Prod. Order Component":
SetSourceForProdOrderComp();
Database::"Planning Component":
SetSourceForPlanningComp();
Database::"Transfer Line":
SetSourceForTransferLine(Direction);
5902: // Database::"Service Line":
SetSourceForServiceLine();
Database::Microsoft.Projects.Project.Journal."Job Journal Line":
SetSourceForJobJournalLine();
Database::Microsoft.Projects.Project.Planning."Job Planning Line":
SetSourceForJobPlanningLine();
900: // Database::"Assembly Header":
SetSourceForAssemblyHeader();
901: // Database::"Assembly Line":
SetSourceForAssemblyLine();
Database::Microsoft.Inventory.Document."Invt. Document Line":
SetSourceForInvtDocLine();
end;
OnAfterSetReservSource(SourceRecRef, CalcReservEntry, Direction);
end;
local procedure SetSourceForAssemblyHeader()
var
EntryIsPositive: Boolean;
begin
OnSetSourceForAssemblyHeader(SourceRecRef, CalcReservEntry, EntryIsPositive);
UpdateReservation(EntryIsPositive);
end;
local procedure SetSourceForAssemblyLine()
var
EntryIsPositive: Boolean;
begin
OnSetSourceForAssemblyLine(SourceRecRef, CalcReservEntry, EntryIsPositive);
UpdateReservation(EntryIsPositive);
end;
local procedure SetSourceForInvtDocLine()
var
InvtDocLine: Record Microsoft.Inventory.Document."Invt. Document Line";
begin
SourceRecRef.SetTable(InvtDocLine);
InvtDocLine.SetReservationEntry(CalcReservEntry);
UpdateReservation((CreateReservEntry.SignFactor(CalcReservEntry) * InvtDocLine."Quantity (Base)") < 0);
end;
local procedure SetSourceForItemJnlLine()
var
ItemJnlLine: Record "Item Journal Line";
begin
SourceRecRef.SetTable(ItemJnlLine);
ItemJnlLine.SetReservationEntry(CalcReservEntry);
OnSetItemJnlLineOnBeforeUpdateReservation(CalcReservEntry, ItemJnlLine);
UpdateReservation((CreateReservEntry.SignFactor(CalcReservEntry) * ItemJnlLine."Quantity (Base)") < 0);
end;
local procedure SetSourceForItemLedgerEntry()
var
ItemLedgerEntry: Record "Item Ledger Entry";
begin
SourceRecRef.SetTable(ItemLedgerEntry);
ItemLedgerEntry.SetReservationEntry(CalcReservEntry);
CalcReservEntry.CopyTrackingFromItemLedgEntry(ItemLedgerEntry);
OnSetItemLedgEntryOnBeforeUpdateReservation(CalcReservEntry, ItemLedgerEntry);
UpdateReservation(Positive);
end;
local procedure SetSourceForJobJournalLine()
var
JobJournalLine: Record Microsoft.Projects.Project.Journal."Job Journal Line";
begin
SourceRecRef.SetTable(JobJournalLine);
JobJournalLine.SetReservationEntry(CalcReservEntry);
OnSetJobJnlLineOnBeforeUpdateReservation(CalcReservEntry, JobJournalLine);
UpdateReservation((CreateReservEntry.SignFactor(CalcReservEntry) * JobJournalLine."Quantity (Base)") < 0);
end;
local procedure SetSourceForJobPlanningLine()
var
JobPlanningLine: Record Microsoft.Projects.Project.Planning."Job Planning Line";
begin
SourceRecRef.SetTable(JobPlanningLine);
JobPlanningLine.SetReservationEntry(CalcReservEntry);
OnSetJobPlanningLineOnBeforeUpdateReservation(CalcReservEntry, JobPlanningLine);
UpdateReservation((CreateReservEntry.SignFactor(CalcReservEntry) * JobPlanningLine."Remaining Qty. (Base)") <= 0);
end;
local procedure SetSourceForReqLine()
var
ReqLine: Record "Requisition Line";
begin
SourceRecRef.SetTable(ReqLine);
ReqLine.SetReservationEntry(CalcReservEntry);
RefOrderType := ReqLine."Ref. Order Type";
PlanningLineOrigin := ReqLine."Planning Line Origin";
OnSetReqLineOnBeforeUpdateReservation(CalcReservEntry, ReqLine);
UpdateReservation(ReqLine."Net Quantity (Base)" < 0);
end;
local procedure SetSourceForProdOrderLine()
var
EntryIsPositive: Boolean;
begin
OnSetSourceForProdOrderLine(SourceRecRef, CalcReservEntry, EntryIsPositive);
UpdateReservation(EntryIsPositive);
end;
local procedure SetSourceForProdOrderComp()
var
EntryIsPositive: Boolean;
begin
OnSetSourceForProdOrderComp(SourceRecRef, CalcReservEntry, EntryIsPositive);
UpdateReservation(EntryIsPositive);
end;
local procedure SetSourceForPlanningComp()
var
PlanningComponent: Record "Planning Component";
begin
SourceRecRef.SetTable(PlanningComponent);
PlanningComponent.SetReservationEntry(CalcReservEntry);
OnSetPlanningCompOnBeforeUpdateReservation(CalcReservEntry, PlanningComponent);
UpdateReservation(PlanningComponent."Net Quantity (Base)" > 0);
end;
local procedure SetSourceForPurchLine()
var
PurchLine: Record "Purchase Line";
begin
SourceRecRef.SetTable(PurchLine);
PurchLine.SetReservationEntry(CalcReservEntry);
OnSetPurchLineOnBeforeUpdateReservation(CalcReservEntry, PurchLine);
UpdateReservation((CreateReservEntry.SignFactor(CalcReservEntry) * PurchLine."Outstanding Qty. (Base)") < 0);
end;
local procedure SetSourceForTransferLine(Direction: Enum "Transfer Direction")
var
TransferLine: Record "Transfer Line";
begin
SourceRecRef.SetTable(TransferLine);
TransferLine.SetReservationEntry(CalcReservEntry, Direction);
OnSetTransLineOnBeforeUpdateReservation(CalcReservEntry, TransferLine);
UpdateReservation((CreateReservEntry.SignFactor(CalcReservEntry) * TransferLine."Outstanding Qty. (Base)") <= 0);
end;
local procedure SetSourceForSalesLine()
var
SalesLine: Record "Sales Line";
begin
SourceRecRef.SetTable(SalesLine);
SalesLine.SetReservationEntry(CalcReservEntry);
OnSetSalesLineOnBeforeUpdateReservation(CalcReservEntry, SalesLine);
UpdateReservation((CreateReservEntry.SignFactor(CalcReservEntry) * SalesLine."Outstanding Qty. (Base)") <= 0);
OnAfterSetSourceForSalesLine(CalcReservEntry, SalesLine);
end;
local procedure SetSourceForServiceLine()
var
EntryIsPositive: Boolean;
begin
OnSetSourceForServiceLine(SourceRecRef, CalcReservEntry, EntryIsPositive);
UpdateReservation(EntryIsPositive);
end;
procedure SetExternalDocumentResEntry(ReservEntry: Record "Reservation Entry"; UpdReservation: Boolean)
begin
ClearAll();
TempTrackingSpecification.DeleteAll();
CalcReservEntry := ReservEntry;
UpdateReservation(UpdReservation);
end;
procedure UpdateReservation(EntryIsPositive: Boolean)
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeUpdateReservation(SourceRecRef, CalcReservEntry, IsHandled);
if IsHandled then
exit;
CalcReservEntry2 := CalcReservEntry;
GetItemSetup(CalcReservEntry);
Positive := EntryIsPositive;
CalcReservEntry2.SetPointerFilter();
OnUpdateReservationOnAfterSetPointerFilter(CalcReservEntry2);
CallCalcReservedQtyOnPick();
end;
procedure UpdateStatistics(var TempEntrySummary: Record "Entry Summary" temporary; AvailabilityDate: Date; HandleItemTracking2: Boolean)
var
i: Integer;
CurrentEntryNo: Integer;
ValueArrayNo: Integer;
TotalQuantity: Decimal;
begin
OnBeforeUpdateStatistics(AvailabilityDate);
CurrentEntryNo := TempEntrySummary."Entry No.";
CalcReservEntry.TestField("Source Type");
TempEntrySummary.DeleteAll();
HandleItemTracking := HandleItemTracking2;
if HandleItemTracking2 then
ValueArrayNo := 3;
for i := 1 to SetValueArray(ValueArrayNo) do begin
TotalQuantity := 0;
TempEntrySummary.Init();
TempEntrySummary."Entry No." := ValueArray[i];
case ValueArray[i] of
Enum::"Reservation Summary Type"::"Item Ledger Entry".AsInteger():
UpdateItemLedgEntryStats(CalcReservEntry, TempEntrySummary, TotalQuantity, HandleItemTracking2);
Enum::"Reservation Summary Type"::"Item Tracking Line".AsInteger():
UpdateItemTrackingLineStats(CalcReservEntry, TempEntrySummary, AvailabilityDate);
end;
OnUpdateStatistics(CalcReservEntry, TempEntrySummary, AvailabilityDate, Positive, TotalQuantity, HandleItemTracking2, QtyOnOutBound, ValueArray[i]);
end;
OnAfterUpdateStatistics(TempEntrySummary, AvailabilityDate, TotalQuantity);
if not TempEntrySummary.Get(CurrentEntryNo) then
if TempEntrySummary.IsEmpty() then
Clear(TempEntrySummary);
end;
local procedure UpdateItemLedgEntryStats(CalcReservEntry: Record "Reservation Entry"; var TempEntrySummary: Record "Entry Summary" temporary; var CalcSumValue: Decimal; HandleItemTracking2: Boolean)
var
ReservForm: Page Reservation;
CurrReservedQtyBase: Decimal;
IsHandled: Boolean;
begin
OnBeforeUpdateItemLedgEntryStats(CalcReservEntry);
if CalcItemLedgEntry.ReadPermission then begin
CalcItemLedgEntry.FilterLinesForReservation(CalcReservEntry, Positive);
CalcItemLedgEntry.FilterLinesForTracking(CalcReservEntry, Positive);
OnAfterInitFilter(CalcReservEntry, 1);
if CalcItemLedgEntry.FindSet() then
repeat
CalcItemLedgEntry.CalcFields("Reserved Quantity");
IsHandled := false;
OnUpdateItemLedgEntryStatsUpdateTotals(CalcReservEntry, CalcItemLedgEntry, TotalAvailQty, QtyOnOutBound, CalcSumValue, TempEntrySummary, IsHandled);
if not IsHandled then begin
TempEntrySummary."Total Reserved Quantity" += CalcItemLedgEntry."Reserved Quantity";
CalcSumValue += CalcItemLedgEntry."Remaining Quantity";
end;
until CalcItemLedgEntry.Next() = 0;
if HandleItemTracking2 then
if TempEntrySummary."Total Reserved Quantity" > 0 then
TempEntrySummary."Non-specific Reserved Qty." := LateBindingMgt.NonspecificReservedQty(CalcItemLedgEntry);
OnUpdateItemLedgEntryStatsOnBeforePrepareTempEntrySummary(CalcReservEntry, TempEntrySummary);
if CalcSumValue <> 0 then
if (CalcSumValue > 0) = Positive then begin
if Location.Get(CalcItemLedgEntry."Location Code") and
(Location."Bin Mandatory" or Location."Require Pick")
then begin
CalcReservedQtyOnPick(TotalAvailQty, QtyAllocInWhse);
QtyOnOutBound :=
CreatePick.CheckOutBound(
CalcReservEntry."Source Type", CalcReservEntry."Source Subtype",
CalcReservEntry."Source ID", CalcReservEntry."Source Ref. No.",
CalcReservEntry."Source Prod. Order Line");
end else begin
QtyAllocInWhse := 0;
QtyOnOutBound := 0;
end;
if QtyAllocInWhse < 0 then
QtyAllocInWhse := 0;
TempEntrySummary."Table ID" := Database::"Item Ledger Entry";
TempEntrySummary."Summary Type" :=
CopyStr(CalcItemLedgEntry.TableCaption(), 1, MaxStrLen(TempEntrySummary."Summary Type"));
TempEntrySummary."Total Quantity" := CalcSumValue;
TempEntrySummary."Total Available Quantity" :=
TempEntrySummary."Total Quantity" - TempEntrySummary."Total Reserved Quantity";
Clear(ReservForm);
ReservForm.SetReservEntry(CalcReservEntry);
CurrReservedQtyBase := ReservForm.ReservedThisLine(TempEntrySummary);
if (CurrReservedQtyBase <> 0) and (QtyOnOutBound <> 0) then
if QtyOnOutBound > CurrReservedQtyBase then
QtyOnOutBound := QtyOnOutBound - CurrReservedQtyBase
else
QtyOnOutBound := 0;
if Location."Bin Mandatory" and Location."Require Pick" then begin
if TotalAvailQty + QtyOnOutBound < TempEntrySummary."Total Available Quantity" then
TempEntrySummary."Total Available Quantity" := TotalAvailQty + QtyOnOutBound;
TempEntrySummary."Qty. Alloc. in Warehouse" := QtyAllocInWhse;
TempEntrySummary."Res. Qty. on Picks & Shipmts." := QtyReservedOnPickShip
end else begin
TempEntrySummary."Qty. Alloc. in Warehouse" := 0;
TempEntrySummary."Res. Qty. on Picks & Shipmts." := 0
end;
if not TempEntrySummary.Insert() then
TempEntrySummary.Modify();
end;
end;
end;
local procedure UpdateItemTrackingLineStats(CalcReservEntry: Record "Reservation Entry"; var TempEntrySummary: Record "Entry Summary"; AvailabilityDate: Date)
var
ReservEntry: Record "Reservation Entry";
begin
ReservEntry.Reset();
ReservEntry.SetCurrentKey(
"Item No.", "Source Type", "Source Subtype", "Reservation Status", "Location Code",
"Variant Code", "Shipment Date", "Expected Receipt Date", "Serial No.", "Lot No.");
ReservEntry.SetRange("Item No.", CalcReservEntry."Item No.");
ReservEntry.SetFilter("Source Type", '<> %1', Database::"Item Ledger Entry");
ReservEntry.SetRange("Reservation Status",
ReservEntry."Reservation Status"::Reservation, ReservEntry."Reservation Status"::Surplus);
ReservEntry.SetRange("Location Code", CalcReservEntry."Location Code");
ReservEntry.SetRange("Variant Code", CalcReservEntry."Variant Code");
if Positive then
ReservEntry.SetFilter("Expected Receipt Date", '..%1', AvailabilityDate)
else
ReservEntry.SetFilter("Shipment Date", '>=%1', AvailabilityDate);
ReservEntry.SetTrackingFilterFromReservEntry(CalcReservEntry);
ReservEntry.SetRange(Positive, Positive);
OnUpdateItemTrackingLineStatsOnAfterReservEntrySetFilters(ReservEntry, CalcReservEntry);
if ReservEntry.FindSet() then
repeat
ReservEntry.SetRange("Source Type", ReservEntry."Source Type");
ReservEntry.SetRange("Source Subtype", ReservEntry."Source Subtype");
TempEntrySummary.Init();
TempEntrySummary."Entry No." := ReservEntry.SummEntryNo();
TempEntrySummary."Table ID" := ReservEntry."Source Type";
TempEntrySummary."Summary Type" :=
CopyStr(ReservEntry.TextCaption(), 1, MaxStrLen(TempEntrySummary."Summary Type"));
TempEntrySummary."Source Subtype" := ReservEntry."Source Subtype";
TempEntrySummary.CopyTrackingFromReservEntry(ReservEntry);
if ReservEntry.FindSet() then
repeat
TempEntrySummary."Total Quantity" += ReservEntry."Quantity (Base)";
if ReservEntry."Reservation Status" = ReservEntry."Reservation Status"::Reservation then
TempEntrySummary."Total Reserved Quantity" += ReservEntry."Quantity (Base)";
if CalcReservEntry.HasSamePointer(ReservEntry) then
TempEntrySummary."Current Reserved Quantity" += ReservEntry."Quantity (Base)";
until ReservEntry.Next() = 0;
TempEntrySummary."Total Available Quantity" :=
TempEntrySummary."Total Quantity" - TempEntrySummary."Total Reserved Quantity";
OnUpdateItemTrackingLineStatsOnBeforeReservEntrySummaryInsert(TempEntrySummary, ReservEntry);
TempEntrySummary.Insert();
ReservEntry.SetRange("Source Type");
ReservEntry.SetRange("Source Subtype");
until ReservEntry.Next() = 0;
end;
procedure AutoReserve(var FullAutoReservation: Boolean; Description: Text[100]; AvailabilityDate: Date; MaxQtyToReserve: Decimal; MaxQtyToReserveBase: Decimal)
var
RemainingQtyToReserve: Decimal;
RemainingQtyToReserveBase: Decimal;
i: Integer;
ValueArrayNo: Integer;
StopReservation: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeAutoReserve(CalcReservEntry, FullAutoReservation, Description, AvailabilityDate, MaxQtyToReserve, MaxQtyToReserveBase, IsHandled);
if IsHandled then
exit;
CalcReservEntry.TestField("Source Type");
OnAutoReserveOnBeforeStopReservation(CalcReservEntry, FullAutoReservation, AvailabilityDate, MaxQtyToReserve, MaxQtyToReserveBase, StopReservation, SourceRecRef);
if StopReservation then begin
FullAutoReservation := true;
exit;
end;
CalculateRemainingQty(RemainingQtyToReserve, RemainingQtyToReserveBase);
if (MaxQtyToReserveBase <> 0) and (Abs(MaxQtyToReserveBase) < Abs(RemainingQtyToReserveBase)) then begin
RemainingQtyToReserve := MaxQtyToReserve;
RemainingQtyToReserveBase := MaxQtyToReserveBase;
end;
if (RemainingQtyToReserveBase <> 0) and
HandleItemTracking and
ItemTrackingCode."SN Specific Tracking"
then
RemainingQtyToReserveBase := 1;
FullAutoReservation := false;
if RemainingQtyToReserveBase = 0 then begin
FullAutoReservation := true;
exit;
end;
OnAutoReserveOnBeforeSetValueArray(ValueArrayNo, AvailabilityDate);
for i := 1 to SetValueArray(ValueArrayNo) do
AutoReserveOneLine(ValueArray[i], RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate);
FullAutoReservation := (RemainingQtyToReserveBase = 0);
OnAfterAutoReserve(CalcReservEntry, FullAutoReservation);
end;
procedure AutoReserveOneLine(ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date)
var
Item: Record Item;
ReservSummaryType: Enum "Reservation Summary Type";
Search: Text[1];
NextStep: Integer;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeAutoReserveOneLine(IsHandled, AvailabilityDate, CalcReservEntry);
if IsHandled then
exit;
CalcReservEntry.TestField("Source Type");
if RemainingQtyToReserveBase = 0 then
exit;
if not Item.Get(CalcReservEntry."Item No.") then
Clear(Item);
CalcReservEntry.Lock();
if Positive then begin
Search := '+';
NextStep := -1;
if Item."Costing Method" = Item."Costing Method"::LIFO then begin
InvSearch := '+';
InvNextStep := -1;
end else begin
InvSearch := '-';
InvNextStep := 1;
end;
end else begin
Search := '-';
NextStep := 1;
InvSearch := '-';
InvNextStep := 1;
end;
ReservSummaryType := Enum::"Reservation Summary Type".FromInteger(ReservSummEntryNo);
OnAutoReserveOneLineOnAfterUpdateSearchNextStep(Item, Positive, Search, NextStep, InvSearch, InvNextStep, RemainingQtyToReserve);
case ReservSummaryType of
Enum::"Reservation Summary Type"::"Item Ledger Entry":
AutoManageReservationItemLedgerEntry(
ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate);
else
OnAfterAutoReserveOneLine(
ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate, Search, NextStep, CalcReservEntry, CalcReservEntry2, Positive);
end;
OnAfterFinishedAutoReserveOneLine(ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate);
end;
local procedure AutoReserveItemLedgEntry(ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date)
var
Location: Record Location;
AllocationsChanged: Boolean;
QtyThisLine: Decimal;
QtyThisLineBase: Decimal;
IsReserved: Boolean;
IsHandled: Boolean;
IsFound: Boolean;
begin
IsReserved := false;
OnBeforeAutoReserveItemLedgEntry(ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate, IsReserved, CalcReservEntry, CalcItemLedgEntry, ItemTrackingCode, Positive);
if IsReserved then
exit;
if not Location.Get(CalcReservEntry."Location Code") then
Clear(Location);
CalcItemLedgEntry.FilterLinesForReservation(CalcReservEntry, Positive);
CalcItemLedgEntry.FilterLinesForTracking(CalcReservEntry, Positive);
// Late Binding
if HandleItemTracking then
AllocationsChanged :=
LateBindingMgt.ReleaseForReservation(CalcItemLedgEntry, CalcReservEntry, RemainingQtyToReserveBase);
IsFound := false;
IsHandled := false;
OnAutoReserveItemLedgEntryOnFindFirstItemLedgEntry(CalcReservEntry, CalcItemLedgEntry, InvSearch, IsHandled, IsFound);
if not IsHandled then
IsFound := CalcItemLedgEntry.Find(InvSearch);
if IsFound then begin
if Location."Bin Mandatory" or Location."Require Pick" then begin
QtyOnOutBound :=
CreatePick.CheckOutBound(
CalcReservEntry."Source Type", CalcReservEntry."Source Subtype",
CalcReservEntry."Source ID", CalcReservEntry."Source Ref. No.",
CalcReservEntry."Source Prod. Order Line") -
CalcCurrLineReservQtyOnPicksShips(CalcReservEntry);
if AllocationsChanged then
CalcReservedQtyOnPick(TotalAvailQty, QtyAllocInWhse); // If allocations have changed we must recalculate
end;
repeat
CalcItemLedgEntry.CalcFields("Reserved Quantity");
if (CalcItemLedgEntry."Remaining Quantity" -
CalcItemLedgEntry."Reserved Quantity") <> 0
then begin
if Abs(CalcItemLedgEntry."Remaining Quantity" -
CalcItemLedgEntry."Reserved Quantity") > Abs(RemainingQtyToReserveBase)
then begin
QtyThisLine := Abs(RemainingQtyToReserve);
QtyThisLineBase := Abs(RemainingQtyToReserveBase);
end else begin
QtyThisLineBase :=
CalcItemLedgEntry."Remaining Quantity" - CalcItemLedgEntry."Reserved Quantity";
QtyThisLine := 0;
end;
if (FindUnfinishedSpecialOrderSalesNo(CalcItemLedgEntry) <> '') or (Positive = (QtyThisLineBase < 0)) then begin
QtyThisLineBase := 0;
QtyThisLine := 0;
end;
OnAutoReserveItemLedgEntryOnAfterCalcReservQty(CalcItemLedgEntry, QtyThisLine, QtyThisLineBase);
if (Location."Bin Mandatory" or Location."Require Pick") and
(TotalAvailQty + QtyOnOutBound < QtyThisLineBase)
then
if (TotalAvailQty + QtyOnOutBound) < 0 then begin
QtyThisLineBase := 0;
QtyThisLine := 0
end else begin
QtyThisLineBase := TotalAvailQty + QtyOnOutBound;
QtyThisLine := Round(QtyThisLineBase, UOMMgt.QtyRndPrecision());
end;
OnAfterCalcReservation(CalcReservEntry, CalcItemLedgEntry, ReservSummEntryNo, QtyThisLine, QtyThisLineBase, TotalAvailQty);
CallTrackingSpecification.InitTrackingSpecification(
Database::"Item Ledger Entry", 0, '', '', 0, CalcItemLedgEntry."Entry No.",
CalcItemLedgEntry."Variant Code", CalcItemLedgEntry."Location Code", CalcItemLedgEntry."Qty. per Unit of Measure");
CallTrackingSpecification.CopyTrackingFromItemLedgEntry(CalcItemLedgEntry);
if InsertReservationEntries(
RemainingQtyToReserve, RemainingQtyToReserveBase, 0,
Description, 0D, QtyThisLine, QtyThisLineBase, CallTrackingSpecification)
then
if Location."Bin Mandatory" or Location."Require Pick" then
TotalAvailQty := TotalAvailQty - QtyThisLineBase;
end;
IsHandled := false;
IsFound := false;
OnAutoReserveItemLedgEntryOnFindNextItemLedgEntry(CalcReservEntry, CalcItemLedgEntry, InvSearch, IsHandled, IsFound);
if not IsHandled then
IsFound := CalcItemLedgEntry.Next(InvNextStep) <> 0;
until not IsFound or (RemainingQtyToReserveBase = 0);
end;
OnAfterAutoReserveItemLedgEntry(CalcItemLedgEntry, RemainingQtyToReserveBase);
end;
procedure InsertReservationEntries(var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; ReservQty: Decimal; Description: Text[100]; ExpectedDate: Date; QtyThisLine: Decimal; QtyThisLineBase: Decimal; TrackingSpecification: Record "Tracking Specification") ReservationCreated: Boolean
begin
if QtyThisLineBase = 0 then
exit;
if Abs(QtyThisLineBase - ReservQty) > 0 then begin
if Abs(QtyThisLineBase - ReservQty) > Abs(RemainingQtyToReserveBase) then begin
QtyThisLine := RemainingQtyToReserve;
QtyThisLineBase := RemainingQtyToReserveBase;
end else begin
QtyThisLineBase := QtyThisLineBase - ReservQty;
QtyThisLine := Round(RemainingQtyToReserve / RemainingQtyToReserveBase * QtyThisLineBase, UOMMgt.QtyRndPrecision());
end;
CopySign(RemainingQtyToReserveBase, QtyThisLineBase);
CopySign(RemainingQtyToReserve, QtyThisLine);
OnInsertReservationEntriesOnBeforeCreateReservation(TrackingSpecification, CalcReservEntry);
CreateReservation(Description, ExpectedDate, QtyThisLine, QtyThisLineBase, TrackingSpecification);
RemainingQtyToReserve := RemainingQtyToReserve - QtyThisLine;
RemainingQtyToReserveBase := RemainingQtyToReserveBase - QtyThisLineBase;
ReservationCreated := true;
end;
OnAfterInsertReservationEntries(TrackingSpecification, CalcReservEntry, RemainingQtyToReserve, RemainingQtyToReserveBase, QtyThisLine, QtyThisLineBase, ReservationCreated);
end;
procedure CreateReservation(Description: Text[100]; ExpectedDate: Date; Quantity: Decimal; QuantityBase: Decimal; TrackingSpecification: Record "Tracking Specification")
begin
CalcReservEntry.TestField("Source Type");
OnBeforeCreateReservation(TrackingSpecification, CalcReservEntry, CalcItemLedgEntry);
OnCreateReservation(SourceRecRef, TrackingSpecification, CalcReservEntry, Description, ExpectedDate, Quantity, QuantityBase);
end;
procedure DeleteReservEntries(DeleteAll: Boolean; DownToQuantity: Decimal)
var
CalcReservEntry4: Record "Reservation Entry";
ReqLine: Record "Requisition Line";
TrackingMgt: Codeunit OrderTrackingManagement;
ReservMgt: Codeunit "Reservation Management";
QtyToReTrack: Decimal;
QtyTracked: Decimal;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeDeleteReservEntries2(CalcReservEntry, CalcReservEntry2, IsHandled, Item, ItemTrackingCode, SKU, Positive, Location, TotalAvailQty, QtyAllocInWhse, QtyReservedOnPickShip);
if IsHandled then
exit;
DeleteReservEntries(DeleteAll, DownToQuantity, CalcReservEntry2);
// Handle both sides of a req. line related to a transfer line:
if ((CalcReservEntry."Source Type" = Database::"Requisition Line") and
(RefOrderType = ReqLine."Ref. Order Type"::Transfer))
then begin
CalcReservEntry4 := CalcReservEntry;
CalcReservEntry4."Source Subtype" := 1;
CalcReservEntry4.SetPointerFilter();
DeleteReservEntries(DeleteAll, DownToQuantity, CalcReservEntry4);
end;
if DeleteAll then
if ((CalcReservEntry."Source Type" = Database::"Requisition Line") and
(PlanningLineOrigin <> ReqLine."Planning Line Origin"::" ")) or
(CalcReservEntry."Source Type" = Database::"Planning Component")
then begin
CalcReservEntry4.Reset();
if TrackingMgt.DerivePlanningFilter(CalcReservEntry2, CalcReservEntry4) then
if CalcReservEntry4.FindFirst() then begin
QtyToReTrack := ReservMgt.SourceQuantity(CalcReservEntry4, true);
CalcReservEntry4.SetRange("Reservation Status", CalcReservEntry4."Reservation Status"::Reservation);
if not CalcReservEntry4.IsEmpty() then begin
CalcReservEntry4.CalcSums("Quantity (Base)");
QtyTracked += CalcReservEntry4."Quantity (Base)";
end;
CalcReservEntry4.SetFilter("Reservation Status", '<>%1', CalcReservEntry4."Reservation Status"::Reservation);
CalcReservEntry4.SetFilter("Item Tracking", '<>%1', CalcReservEntry4."Item Tracking"::None);
if not CalcReservEntry4.IsEmpty() then begin
CalcReservEntry4.CalcSums("Quantity (Base)");
QtyTracked += CalcReservEntry4."Quantity (Base)";
end;
if CalcReservEntry."Source Type" = Database::"Planning Component" then
QtyTracked := -QtyTracked;
ReservMgt.DeleteReservEntries(QtyTracked = 0, QtyTracked);
ReservMgt.AutoTrack(QtyToReTrack);
end;
end;
end;
procedure DeleteReservEntries(DeleteAll: Boolean; DownToQuantity: Decimal; var ReservEntry: Record "Reservation Entry")
var
CalcReservEntry4: Record "Reservation Entry";
SurplusEntry: Record "Reservation Entry";
DummyEntry: Record "Reservation Entry";
CurrentItemTrackingSetup: Record "Item Tracking Setup";
ReservStatus: Enum "Reservation Status";
QtyToRelease: Decimal;
QtyTracked: Decimal;
QtyToReleaseForLotSN: Decimal;
CurrentQty: Decimal;
AvailabilityDate: Date;
Release: Option "Non-Inventory",Inventory;
HandleItemTracking2: Boolean;
SignFactor: Integer;
QuantityIsValidated: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeDeleteReservEntries(ReservEntry, DownToQuantity, CalcReservEntry, CalcReservEntry2, IsHandled, ItemTrackingHandling);
if IsHandled then
exit;
ReservEntry.SetRange("Reservation Status");
if ReservEntry.IsEmpty() then
exit;
CurrentItemTrackingSetup.CopyTrackingFromReservEntry(ReservEntry);
CurrentQty := ReservEntry."Quantity (Base)";
GetItemSetup(ReservEntry);
IsHandled := false;
OnDeleteReservEntriesOnBeforeReservEntryTestField(ReservEntry, IsHandled);
if not IsHandled then
ReservEntry.TestField("Source Type");
ReservEntry.Lock();
SignFactor := CreateReservEntry.SignFactor(ReservEntry);
QtyTracked := QuantityTracked(ReservEntry);
CurrentBinding := ReservEntry.Binding;
CurrentBindingIsSet := true;
// Item Tracking:
if ItemTrackingCode.IsSpecific() or CurrentItemTrackingSetup.TrackingExists() then begin
ReservEntry.SetFilter("Item Tracking", '<>%1', ReservEntry."Item Tracking"::None);
HandleItemTracking2 := not ReservEntry.IsEmpty();
ReservEntry.SetRange("Item Tracking");
OnDeleteReservEntriesOnAfterReservEntrySetFilters(ReservEntry, ItemTrackingHandling);
case ItemTrackingHandling of
ItemTrackingHandling::None:
ReservEntry.SetTrackingFilterBlank();
ItemTrackingHandling::Match:
if CurrentItemTrackingSetup.TrackingExists() then begin
QtyToReleaseForLotSN := QuantityTracked2(ReservEntry);
if Abs(QtyToReleaseForLotSN) > Abs(CurrentQty) then
QtyToReleaseForLotSN := CurrentQty;
DownToQuantity := (QtyTracked - QtyToReleaseForLotSN) * SignFactor;
ReservEntry.SetTrackingFilterFromItemTrackingSetup(CurrentItemTrackingSetup);
end else
DownToQuantity += CalcDownToQtySyncingToAssembly(ReservEntry);
end;
OnDeleteReservEntriesOnAfterItemTrackingHandling(ReservEntry, ItemTrackingHandling);
end;
if SignFactor * QtyTracked * DownToQuantity < 0 then
DeleteAll := true
else
if Abs(QtyTracked) < Abs(DownToQuantity) then
exit;
QtyToRelease := QtyTracked - (DownToQuantity * SignFactor);
for ReservStatus := ReservStatus::Prospect downto ReservStatus::Reservation do begin
ReservEntry.SetRange("Reservation Status", ReservStatus);
if ReservEntry.FindSet() and (QtyToRelease <> 0) then
case ReservStatus of
Enum::"Reservation Status"::Prospect:
repeat
if (Abs(ReservEntry."Quantity (Base)") <= Abs(QtyToRelease)) or DeleteAll then begin
ReservEntry.Delete();
SaveTrackingSpecification(ReservEntry, ReservEntry."Quantity (Base)");
QtyToRelease := QtyToRelease - ReservEntry."Quantity (Base)";
end else begin
ReservEntry.Validate("Quantity (Base)", ReservEntry."Quantity (Base)" - QtyToRelease);
ReservEntry.Modify();
SaveTrackingSpecification(ReservEntry, QtyToRelease);
QtyToRelease := 0;
end;
until (ReservEntry.Next() = 0) or ((not DeleteAll) and (QtyToRelease = 0));
Enum::"Reservation Status"::Surplus:
repeat
if CalcReservEntry4.Get(ReservEntry."Entry No.", not ReservEntry.Positive) then // Find related entry
Error(Text007);
if (Abs(ReservEntry."Quantity (Base)") <= Abs(QtyToRelease)) or DeleteAll then begin
ReservEngineMgt.CloseReservEntry(ReservEntry, false, DeleteAll);
SaveTrackingSpecification(ReservEntry, ReservEntry."Quantity (Base)");
QtyToRelease := QtyToRelease - ReservEntry."Quantity (Base)";
if not DeleteAll and CalcReservEntry4.TrackingExists() then begin
CalcReservEntry4."Reservation Status" := CalcReservEntry4."Reservation Status"::Surplus;
CalcReservEntry4.Insert();
end;
ModifyActionMessage(ReservEntry."Entry No.", 0, true); // Delete action messages
end else begin
ReservEntry.Validate("Quantity (Base)", ReservEntry."Quantity (Base)" - QtyToRelease);
ReservEntry.Modify();
OnDeleteReservEntriesOnAfterModifyReservEntryReservationStatusSurplus(ReservEntry, QtyToRelease);
SaveTrackingSpecification(ReservEntry, QtyToRelease);
ModifyActionMessage(ReservEntry."Entry No.", QtyToRelease, false); // Modify action messages
QtyToRelease := 0;
end;
until (ReservEntry.Next() = 0) or ((not DeleteAll) and (QtyToRelease = 0));
Enum::"Reservation Status"::Tracking,
Enum::"Reservation Status"::Reservation:
for Release := Release::"Non-Inventory" to Release::Inventory do begin
// Release non-inventory reservations in first cycle
repeat
CalcReservEntry4.Get(ReservEntry."Entry No.", not ReservEntry.Positive); // Find related entry
OnDeleteReservEntriesOnReservationOnAfterCalcReservEntry4Get(CalcReservEntry4, ReservEntry);
if (Release = Release::Inventory) = (CalcReservEntry4."Source Type" = Database::"Item Ledger Entry") then
if (Abs(ReservEntry."Quantity (Base)") <= Abs(QtyToRelease)) or DeleteAll then begin
ReservEngineMgt.CloseReservEntry(ReservEntry, false, DeleteAll);
SaveTrackingSpecification(ReservEntry, ReservEntry."Quantity (Base)");
QtyToRelease := QtyToRelease - ReservEntry."Quantity (Base)";
end else begin
ReservEntry.Validate("Quantity (Base)", ReservEntry."Quantity (Base)" - QtyToRelease);
ReservEntry.Modify();
SaveTrackingSpecification(ReservEntry, QtyToRelease);
if Item."Order Tracking Policy" <> Item."Order Tracking Policy"::None then begin
if CalcReservEntry4."Quantity (Base)" > 0 then
AvailabilityDate := CalcReservEntry4."Shipment Date"
else
AvailabilityDate := CalcReservEntry4."Expected Receipt Date";
QtyToRelease := -MatchSurplus(CalcReservEntry4, SurplusEntry, -QtyToRelease,
CalcReservEntry4."Quantity (Base)" < 0, AvailabilityDate, Item."Order Tracking Policy");
// Make residual surplus record:
if QtyToRelease <> 0 then begin
MakeConnection(
CalcReservEntry4, CalcReservEntry4, -QtyToRelease, CalcReservEntry4."Reservation Status"::Surplus,
AvailabilityDate, CalcReservEntry4.Binding);
if Item."Order Tracking Policy" = Item."Order Tracking Policy"::"Tracking & Action Msg." then begin
CreateReservEntry.GetLastEntry(SurplusEntry); // Get the surplus-entry just inserted
IssueActionMessage(SurplusEntry, false, DummyEntry);
end;
end;
end else
if ItemTrackingHandling = ItemTrackingHandling::None then
QuantityIsValidated :=
SaveItemTrackingAsSurplus(CalcReservEntry4, -ReservEntry.Quantity, -ReservEntry."Quantity (Base)");
if not QuantityIsValidated then
CalcReservEntry4.Validate("Quantity (Base)", -ReservEntry."Quantity (Base)");
CalcReservEntry4.Modify();
QtyToRelease := 0;
QuantityIsValidated := false;
end;
until (ReservEntry.Next() = 0) or ((not DeleteAll) and (QtyToRelease = 0));
if not ReservEntry.FindFirst() then // Rewind for second cycle
Release := Release::Inventory;
end;
end;
end;
if HandleItemTracking2 then
CheckQuantityIsCompletelyReleased(QtyToRelease, DeleteAll, CurrentItemTrackingSetup, ReservEntry);
end;
procedure CalculateRemainingQty(var RemainingQty: Decimal; var RemainingQtyBase: Decimal)
begin
CalcReservEntry.TestField("Source Type");
OnCalculateRemainingQty(SourceRecRef, CalcReservEntry, RemainingQty, RemainingQtyBase);
end;
procedure GetAvailabilityFilter(AvailabilityDate: Date): Text[80]
begin
exit(GetAvailabilityFilter2(AvailabilityDate, Positive));
end;
local procedure GetAvailabilityFilter2(AvailabilityDate: Date; SearchForSupply: Boolean) Result: Text[80]
var
ReservEntry2: Record "Reservation Entry";
begin
if SearchForSupply then
ReservEntry2.SetFilter("Expected Receipt Date", '..%1', AvailabilityDate)
else
ReservEntry2.SetFilter("Expected Receipt Date", '>=%1', AvailabilityDate);
Result := ReservEntry2.GetFilter("Expected Receipt Date");
OnAfterGetAvailabilityFilter2(ReservEntry2, AvailabilityDate, SearchForSupply, Result);
end;
procedure CopySign(FromValue: Decimal; var ToValue: Decimal)
begin
if FromValue * ToValue < 0 then
ToValue := -ToValue;
end;
local procedure SetValueArray(EntryStatus: Option Reservation,Tracking,Simulation) ArrayCounter: Integer
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeSetValueArray(EntryStatus, ValueArray, ArrayCounter, IsHandled, CalcReservEntry);
if not IsHandled then begin
Clear(ValueArray);
case EntryStatus of
0:
begin // Reservation
ValueArray[1] := Enum::"Reservation Summary Type"::"Item Ledger Entry".AsInteger();
ValueArray[2] := Enum::"Reservation Summary Type"::"Sales Order".AsInteger();
ValueArray[3] := Enum::"Reservation Summary Type"::"Sales Return Order".AsInteger();
ValueArray[4] := Enum::"Reservation Summary Type"::"Purchase Order".AsInteger();
ValueArray[5] := Enum::"Reservation Summary Type"::"Purchase Return Order".AsInteger();
ValueArray[6] := Enum::"Reservation Summary Type"::"Firm Planned Production Order".AsInteger();
ValueArray[7] := Enum::"Reservation Summary Type"::"Released Production Order".AsInteger();
ValueArray[8] := Enum::"Reservation Summary Type"::"Firm Planned Prod. Order Comp.".AsInteger();
ValueArray[9] := Enum::"Reservation Summary Type"::"Released Prod. Order Comp.".AsInteger();
ValueArray[10] := Enum::"Reservation Summary Type"::"Transfer Shipment".AsInteger();
ValueArray[11] := Enum::"Reservation Summary Type"::"Transfer Receipt".AsInteger();
ValueArray[12] := Enum::"Reservation Summary Type"::"Job Planning Order".AsInteger();
ValueArray[13] := Enum::"Reservation Summary Type"::"Assembly Order Header".AsInteger();
ValueArray[14] := Enum::"Reservation Summary Type"::"Assembly Order Line".AsInteger();
ValueArray[15] := Enum::"Reservation Summary Type"::"Inventory Receipt".AsInteger();
ValueArray[16] := Enum::"Reservation Summary Type"::"Inventory Shipment".AsInteger();
ArrayCounter := 16;
OnAfterSetValueArrayForReservation(ValueArray, ArrayCounter);
end;
1:
begin // Order Tracking
ValueArray[1] := Enum::"Reservation Summary Type"::"Item Ledger Entry".AsInteger();
ValueArray[2] := Enum::"Reservation Summary Type"::"Sales Order".AsInteger();
ValueArray[3] := Enum::"Reservation Summary Type"::"Sales Return Order".AsInteger();
ValueArray[4] := Enum::"Reservation Summary Type"::"Requisition Line".AsInteger();
ValueArray[5] := Enum::"Reservation Summary Type"::"Purchase Order".AsInteger();
ValueArray[6] := Enum::"Reservation Summary Type"::"Purchase Return Order".AsInteger();
ValueArray[7] := Enum::"Reservation Summary Type"::"Planned Production Order".AsInteger();
ValueArray[8] := Enum::"Reservation Summary Type"::"Firm Planned Production Order".AsInteger();
ValueArray[9] := Enum::"Reservation Summary Type"::"Released Production Order".AsInteger();
ValueArray[10] := Enum::"Reservation Summary Type"::"Planned Prod. Order Comp.".AsInteger();
ValueArray[11] := Enum::"Reservation Summary Type"::"Firm Planned Prod. Order Comp.".AsInteger();
ValueArray[12] := Enum::"Reservation Summary Type"::"Released Prod. Order Comp.".AsInteger();
ValueArray[13] := Enum::"Reservation Summary Type"::"Transfer Shipment".AsInteger();
ValueArray[14] := Enum::"Reservation Summary Type"::"Transfer Receipt".AsInteger();
ValueArray[15] := Enum::"Reservation Summary Type"::"Job Planning Order".AsInteger();
ValueArray[16] := Enum::"Reservation Summary Type"::"Assembly Order Header".AsInteger();
ValueArray[17] := Enum::"Reservation Summary Type"::"Assembly Order Line".AsInteger();
ValueArray[18] := Enum::"Reservation Summary Type"::"Inventory Receipt".AsInteger();
ValueArray[19] := Enum::"Reservation Summary Type"::"Inventory Shipment".AsInteger();
ArrayCounter := 19;
OnAfterSetValueArrayForOrderTracking(ValueArray, ArrayCounter);
end;
2:
begin // Simulation order tracking
ValueArray[1] := Enum::"Reservation Summary Type"::"Sales Quote".AsInteger();
ValueArray[2] := Enum::"Reservation Summary Type"::"Simulated Production Order".AsInteger();
ValueArray[3] := Enum::"Reservation Summary Type"::"Simulated Prod. Order Comp.".AsInteger();
ArrayCounter := 3;
end;
3:
begin // Item Tracking
ValueArray[1] := Enum::"Reservation Summary Type"::"Item Ledger Entry".AsInteger();
ValueArray[2] := Enum::"Reservation Summary Type"::"Item Tracking Line".AsInteger();
ArrayCounter := 2;
end;
end;
end;
OnAfterSetValueArray(EntryStatus, ValueArray, ArrayCounter);
end;
procedure ClearSurplus()
var
ReservEntry2: Record "Reservation Entry";
ActionMessageEntry: Record "Action Message Entry";
begin
CalcReservEntry.TestField("Source Type");
ReservEntry2 := CalcReservEntry;
ReservEntry2.SetPointerFilter();
ReservEntry2.SetRange("Reservation Status", ReservEntry2."Reservation Status"::Surplus);
// Item Tracking
if ItemTrackingHandling = ItemTrackingHandling::None then
ReservEntry2.SetTrackingFilterBlank();
OnClearSurplusOnAfterReservEntry2SetFilters(ReservEntry2, ItemTrackingHandling);
if Item."Order Tracking Policy" = Item."Order Tracking Policy"::"Tracking & Action Msg." then begin
ReservEntry2.Lock();
ReservEntry2.SetLoadFields("Entry No.");
OnClearSurplusOnBeforeReservEntry2FindSet(ReservEntry2);
if not ReservEntry2.FindSet() then
exit;
ActionMessageEntry.Reset();
ActionMessageEntry.SetCurrentKey("Reservation Entry");
repeat
ActionMessageEntry.SetRange("Reservation Entry", ReservEntry2."Entry No.");
ActionMessageEntry.DeleteAll();
until ReservEntry2.Next() = 0;
end;
ReservEntry2.SetRange(
"Reservation Status", ReservEntry2."Reservation Status"::Surplus, ReservEntry2."Reservation Status"::Prospect);
if not ReservEntry2.IsEmpty() then
ReservEntry2.DeleteAll();
end;
local procedure QuantityTracked(var ReservEntry: Record "Reservation Entry"): Decimal
var
ReservEntry2: Record "Reservation Entry";
QtyTracked: Decimal;
begin
ReservEntry2 := ReservEntry;
ReservEntry2.SetPointerFilter();
ReservEntry.CopyTrackingFiltersToReservEntry(ReservEntry2);
if ReservEntry.GetFilter("Item Ledger Entry No.") <> '' then
ReservEntry2.SetRange("Item Ledger Entry No.", ReservEntry."Item Ledger Entry No.");
if ReservEntry2.FindFirst() then begin
ReservEntry.Binding := ReservEntry2.Binding;
ReservEntry2.CalcSums("Quantity (Base)");
QtyTracked := ReservEntry2."Quantity (Base)";
end;
exit(QtyTracked);
end;
local procedure QuantityTracked2(var ReservEntry: Record "Reservation Entry"): Decimal
var
ReservEntry2: Record "Reservation Entry";
QtyTracked: Decimal;
begin
ReservEntry2 := ReservEntry;
ReservEntry2.SetPointerFilter();
ReservEntry2.SetTrackingFilterFromReservEntry(ReservEntry);
ReservEntry2.SetRange("Reservation Status",
ReservEntry2."Reservation Status"::Tracking, ReservEntry2."Reservation Status"::Prospect);
if not ReservEntry2.IsEmpty() then begin
ReservEntry2.CalcSums("Quantity (Base)");
QtyTracked := ReservEntry2."Quantity (Base)";
end;
exit(QtyTracked);
end;
procedure AutoTrack(TotalQty: Decimal)
var
SurplusEntry: Record "Reservation Entry";
DummyEntry: Record "Reservation Entry";
AvailabilityDate: Date;
QtyToTrack: Decimal;
ShouldExit: Boolean;
begin
CalcReservEntry.TestField("Source Type");
OnAutoTrackOnCheckSourceType(CalcReservEntry, ShouldExit);
if ShouldExit then
exit;
if CalcReservEntry."Source Type" = Database::"Item Journal Line" then
exit;
if CalcReservEntry."Item No." = '' then
exit;
GetItemSetup(CalcReservEntry);
OnAutoTrackOnAfterGetItemSetup(CalcReservEntry, Item);
if Item."Order Tracking Policy" = Item."Order Tracking Policy"::None then
exit;
CalcReservEntry.Lock();
QtyToTrack := CreateReservEntry.SignFactor(CalcReservEntry) * TotalQty - QuantityTracked(CalcReservEntry);
if QtyToTrack = 0 then begin
UpdateDating();
exit;
end;
QtyToTrack := MatchSurplus(CalcReservEntry, SurplusEntry, QtyToTrack, Positive, AvailabilityDate, Item."Order Tracking Policy");
// Make residual surplus record:
if QtyToTrack <> 0 then begin
if CurrentBindingIsSet then
MakeConnection(
CalcReservEntry, SurplusEntry, QtyToTrack, CalcReservEntry."Reservation Status"::Surplus, AvailabilityDate, CurrentBinding)
else
MakeConnection(
CalcReservEntry, SurplusEntry, QtyToTrack, CalcReservEntry."Reservation Status"::Surplus, AvailabilityDate, CalcReservEntry.Binding);
CreateReservEntry.GetLastEntry(SurplusEntry); // Get the surplus-entry just inserted
if SurplusEntry.IsResidualSurplus() then begin
SurplusEntry."Untracked Surplus" := true;
SurplusEntry.Modify();
end;
if Item."Order Tracking Policy" = Item."Order Tracking Policy"::"Tracking & Action Msg." then // Issue Action Message
IssueActionMessage(SurplusEntry, true, DummyEntry);
end else
UpdateDating();
end;
procedure MatchSurplus(var ReservEntry: Record "Reservation Entry"; var SurplusEntry: Record "Reservation Entry"; QtyToTrack: Decimal; SearchForSupply: Boolean; var AvailabilityDate: Date; TrackingPolicy: Enum "Order Tracking Policy"): Decimal
var
ReservEntry2: Record "Reservation Entry";
Search: Text[1];
NextStep: Integer;
ReservationStatus: Enum "Reservation Status";
begin
if QtyToTrack = 0 then
exit;
ReservEntry.Lock();
SurplusEntry.SetCurrentKey(
"Item No.", "Variant Code", "Location Code", "Reservation Status",
"Shipment Date", "Expected Receipt Date", "Serial No.", "Lot No.");
SurplusEntry.SetRange("Item No.", ReservEntry."Item No.");
SurplusEntry.SetRange("Variant Code", ReservEntry."Variant Code");
SurplusEntry.SetRange("Location Code", ReservEntry."Location Code");
SurplusEntry.SetRange("Reservation Status", SurplusEntry."Reservation Status"::Surplus);
SurplusEntry.SetRange(Positive, SearchForSupply);
if SkipUntrackedSurplus then
SurplusEntry.SetRange("Untracked Surplus", false);
if SearchForSupply then begin
AvailabilityDate := ReservEntry."Shipment Date";
Search := '+';
NextStep := -1;
SurplusEntry.SetFilter("Expected Receipt Date", GetAvailabilityFilter2(AvailabilityDate, SearchForSupply));
SurplusEntry.SetFilter("Quantity (Base)", '>0');
end else begin
AvailabilityDate := ReservEntry."Expected Receipt Date";
Search := '-';
NextStep := 1;
SurplusEntry.SetFilter("Shipment Date", GetAvailabilityFilter2(AvailabilityDate, SearchForSupply));
SurplusEntry.SetFilter("Quantity (Base)", '<0')
end;
SurplusEntry.FilterLinesForTracking(ReservEntry, SearchForSupply);
if SurplusEntry.Find(Search) then
repeat
if not IsSpecialOrderOrDropShipment(SurplusEntry) then begin
ReservationStatus := ReservationStatus::Tracking;
if Abs(SurplusEntry."Quantity (Base)") <= Abs(QtyToTrack) then begin
ReservEntry2 := SurplusEntry;
MakeConnection(
ReservEntry, SurplusEntry, -SurplusEntry."Quantity (Base)", ReservationStatus, AvailabilityDate, SurplusEntry.Binding);
QtyToTrack := QtyToTrack + SurplusEntry."Quantity (Base)";
SurplusEntry := ReservEntry2;
SurplusEntry.Delete();
if TrackingPolicy = TrackingPolicy::"Tracking & Action Msg." then
ModifyActionMessage(SurplusEntry."Entry No.", 0, true); // Delete related Action Message
end else begin
SurplusEntry.Validate("Quantity (Base)", SurplusEntry."Quantity (Base)" + QtyToTrack);
SurplusEntry.Modify();
MakeConnection(
ReservEntry, SurplusEntry, QtyToTrack, ReservationStatus, AvailabilityDate, SurplusEntry.Binding);
if TrackingPolicy = TrackingPolicy::"Tracking & Action Msg." then
ModifyActionMessage(SurplusEntry."Entry No.", QtyToTrack, false); // Modify related Action Message
QtyToTrack := 0;
end;
end;
until (SurplusEntry.Next(NextStep) = 0) or (QtyToTrack = 0);
SurplusEntry.SetRange(Positive);
exit(QtyToTrack);
end;
local procedure MakeConnection(var FromReservEntry: Record "Reservation Entry"; var ToReservEntry: Record "Reservation Entry"; Quantity: Decimal; ReservationStatus: Enum "Reservation Status"; AvailabilityDate: Date; Binding: Enum "Reservation Binding")
var
FromTrackingSpecification: Record "Tracking Specification";
Sign: Integer;
IsHandled: Boolean;
begin
if Quantity < 0 then
ToReservEntry."Shipment Date" := AvailabilityDate
else
ToReservEntry."Expected Receipt Date" := AvailabilityDate;
CreateReservEntry.SetBinding(Binding);
if FromReservEntry."Planning Flexibility" <> FromReservEntry."Planning Flexibility"::Unlimited then
CreateReservEntry.SetPlanningFlexibility(FromReservEntry."Planning Flexibility");
IsHandled := false;
OnMakeConnectionOnBeforeCreateReservEntry(FromReservEntry, ToReservEntry, Quantity, ReservationStatus, AvailabilityDate, Binding, FromTrackingSpecification, Sign, IsHandled);
if not IsHandled then begin
Sign := CreateReservEntry.SignFactor(FromReservEntry);
CreateReservEntry.CreateReservEntryFor(
FromReservEntry."Source Type", FromReservEntry."Source Subtype", FromReservEntry."Source ID",
FromReservEntry."Source Batch Name", FromReservEntry."Source Prod. Order Line", FromReservEntry."Source Ref. No.",
FromReservEntry."Qty. per Unit of Measure", 0, Sign * Quantity,
FromReservEntry);
FromTrackingSpecification.SetSourceFromReservEntry(ToReservEntry);
FromTrackingSpecification."Qty. per Unit of Measure" := ToReservEntry."Qty. per Unit of Measure";
FromTrackingSpecification.CopyTrackingFromReservEntry(ToReservEntry);
FromTrackingSpecification."Expiration Date" := ToReservEntry."Expiration Date";
CreateReservEntry.CreateReservEntryFrom(FromTrackingSpecification);
CreateReservEntry.SetApplyFromEntryNo(FromReservEntry."Appl.-from Item Entry");
CreateReservEntry.SetApplyToEntryNo(FromReservEntry."Appl.-to Item Entry");
CreateReservEntry.SetUntrackedSurplus(ToReservEntry."Untracked Surplus");
end;
if IsSpecialOrderOrDropShipment(ToReservEntry) then begin
if FromReservEntry."Source Type" = Database::"Purchase Line" then
ToReservEntry."Shipment Date" := 0D;
if FromReservEntry."Source Type" = Database::"Sales Line" then
ToReservEntry."Expected Receipt Date" := 0D;
end;
CreateReservEntry.CreateEntry(
FromReservEntry."Item No.", FromReservEntry."Variant Code", FromReservEntry."Location Code",
FromReservEntry.Description, ToReservEntry."Expected Receipt Date", ToReservEntry."Shipment Date", 0, ReservationStatus);
end;
procedure ModifyUnitOfMeasure()
begin
ReservEngineMgt.ModifyUnitOfMeasure(CalcReservEntry, CalcReservEntry."Qty. per Unit of Measure");
end;
procedure MakeRoomForReservation(var ReservEntry: Record "Reservation Entry")
var
ReservEntry2: Record "Reservation Entry";
TotalQuantity: Decimal;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeMakeRoomForReservation(ReservEntry, IsHandled);
if IsHandled then
exit;
TotalQuantity := SourceQuantity(ReservEntry, false);
ReservEntry2 := ReservEntry;
ReservEntry2.SetPointerFilter();
ItemTrackingHandling := ItemTrackingHandling::Match;
DeleteReservEntries(false, TotalQuantity - (ReservEntry."Quantity (Base)" * CreateReservEntry.SignFactor(ReservEntry)),
ReservEntry2);
end;
local procedure SaveTrackingSpecification(var ReservEntry: Record "Reservation Entry"; QtyReleased: Decimal)
begin
// Used when creating reservations.
if ItemTrackingHandling = ItemTrackingHandling::None then
exit;
if not ReservEntry.TrackingExists() then
exit;
TempTrackingSpecification.SetTrackingFilterFromReservEntry(ReservEntry);
if TempTrackingSpecification.FindSet() then begin
TempTrackingSpecification.Validate("Quantity (Base)",
TempTrackingSpecification."Quantity (Base)" + QtyReleased);
TempTrackingSpecification.Modify();
end else begin
TempTrackingSpecification.TransferFields(ReservEntry);
TempTrackingSpecification.Validate("Quantity (Base)", QtyReleased);
TempTrackingSpecification.Insert();
end;
TempTrackingSpecification.Reset();
OnAfterSaveTrackingSpecification(ReservEntry, TempTrackingSpecification, QtyReleased);
end;
procedure CollectTrackingSpecification(var TargetTrackingSpecification: Record "Tracking Specification" temporary): Boolean
begin
// Used when creating reservations.
TempTrackingSpecification.Reset();
TargetTrackingSpecification.Reset();
if not TempTrackingSpecification.FindSet() then
exit(false);
repeat
TargetTrackingSpecification := TempTrackingSpecification;
TargetTrackingSpecification.Insert();
until TempTrackingSpecification.Next() = 0;
TempTrackingSpecification.DeleteAll();
exit(true);
end;
procedure SourceQuantity(var ReservEntry: Record "Reservation Entry"; SetAsCurrent: Boolean): Decimal
begin
exit(GetSourceRecordValue(ReservEntry, SetAsCurrent, 0));
end;
procedure FilterReservFor(SourceRecRef: RecordRef; var ReservEntry: Record "Reservation Entry"; Direction: Enum "Transfer Direction") CaptionText: Text
begin
ReservEntry.InitSortingAndFilters(true);
OnFilterReservFor(SourceRecRef, ReservEntry, Direction.AsInteger(), CaptionText);
end;
procedure GetSourceRecordValue(var ReservEntry: Record "Reservation Entry"; SetAsCurrent: Boolean; ReturnOption: Option "Net Qty. (Base)","Gross Qty. (Base)") SourceQty: Decimal
var
IsHandled: Boolean;
begin
IsHandled := false;
OnGetSourceRecordValue(ReservEntry, SetAsCurrent, ReturnOption, SourceQty, SourceRecRef, IsHandled);
if IsHandled then
exit;
if SetAsCurrent then
SetReservSource(SourceRecRef, ReservEntry.GetTransferDirection());
end;
local procedure GetItemSetup(var ReservEntry: Record "Reservation Entry")
var
PlanningGetParameters: Codeunit "Planning-Get Parameters";
begin
if ReservEntry."Item No." <> Item."No." then begin
Item.Get(ReservEntry."Item No.");
if Item."Item Tracking Code" <> '' then
ItemTrackingCode.Get(Item."Item Tracking Code")
else
ItemTrackingCode.Init();
PlanningGetParameters.AtSKU(
SKU, ReservEntry."Item No.", ReservEntry."Variant Code", ReservEntry."Location Code");
OnAfterGetItemSetup(ReservEntry, Item);
end;
end;
procedure MarkReservConnection(var ReservEntry: Record "Reservation Entry"; TargetReservEntry: Record "Reservation Entry") ReservedQuantity: Decimal
var
ReservEntry2: Record "Reservation Entry";
SignFactor: Integer;
IsHandled: Boolean;
begin
if not ReservEntry.FindSet() then
exit;
SignFactor := CreateReservEntry.SignFactor(ReservEntry);
repeat
if ReservEntry2.Get(ReservEntry."Entry No.", not ReservEntry.Positive) then
if ReservEntry2.HasSamePointer(TargetReservEntry) then begin
ReservEntry.Mark(true);
IsHandled := false;
OnBeforeReservedQuantityAssign(ReservEntry, ReservedQuantity, SignFactor, IsHandled);
if not IsHandled then
ReservedQuantity += ReservEntry."Quantity (Base)" * SignFactor;
end;
until ReservEntry.Next() = 0;
ReservEntry.MarkedOnly(true);
end;
procedure IssueActionMessage(var SurplusEntry: Record "Reservation Entry"; UseGlobalSettings: Boolean; AllDeletedEntry: Record "Reservation Entry")
var
ReservEntry: Record "Reservation Entry";
ReservEntry2: Record "Reservation Entry";
ReservEntry3: Record "Reservation Entry";
ActionMessageEntry: Record "Action Message Entry";
ActionMessageEntry2: Record "Action Message Entry";
DateFormula: DateFormula;
DampenerPeriod: DateFormula;
NextEntryNo: Integer;
FirstDate: Date;
Found: Boolean;
FreeBinding: Boolean;
NoMoreData: Boolean;
begin
SurplusEntry.TestField("Quantity (Base)");
if SurplusEntry.IsReservationOrTracking() then
SurplusEntry.FieldError("Reservation Status");
SurplusEntry.CalcFields("Action Message Adjustment");
if SurplusEntry."Quantity (Base)" + SurplusEntry."Action Message Adjustment" = 0 then
exit;
ActionMessageEntry.Reset();
NextEntryNo := ActionMessageEntry.GetLastEntryNo() + 1;
ActionMessageEntry.Init();
ActionMessageEntry."Entry No." := NextEntryNo;
if SurplusEntry."Quantity (Base)" > 0 then begin // Supply: Issue AM directly
if SurplusEntry."Planning Flexibility" = SurplusEntry."Planning Flexibility"::None then
exit;
if not (SurplusEntry."Source Type" in [5406, Database::"Purchase Line"]) then // Database::"Prod. Order Line"
exit;
ActionMessageEntry.TransferFromReservEntry(SurplusEntry);
ActionMessageEntry.Quantity := -(SurplusEntry."Quantity (Base)" + SurplusEntry."Action Message Adjustment");
ActionMessageEntry.Type := ActionMessageEntry.Type::New;
ReservEntry2 := SurplusEntry;
end else begin // Demand: Find supply and issue AM
case SurplusEntry.Binding of
SurplusEntry.Binding::" ":
begin
if UseGlobalSettings then begin
ReservEntry.Copy(SurplusEntry); // Copy filter and sorting
ReservEntry.SetRange("Reservation Status"); // Remove filter on Reservation Status
end else begin
GetItemSetup(SurplusEntry);
Positive := true;
ReservEntry.SetCurrentKey(
"Item No.", "Variant Code", "Location Code", "Reservation Status",
"Shipment Date", "Expected Receipt Date", "Serial No.", "Lot No.");
ReservEntry.SetRange("Item No.", SurplusEntry."Item No.");
ReservEntry.SetRange("Variant Code", SurplusEntry."Variant Code");
ReservEntry.SetRange("Location Code", SurplusEntry."Location Code");
ReservEntry.SetFilter("Expected Receipt Date", GetAvailabilityFilter(SurplusEntry."Shipment Date"));
ReservEntry.FilterLinesForTracking(SurplusEntry, Positive);
ReservEntry.SetRange(Positive, true);
end;
ReservEntry.SetRange(Binding, ReservEntry.Binding::" ");
ReservEntry.SetRange("Planning Flexibility", ReservEntry."Planning Flexibility"::Unlimited);
ReservEntry.SetFilter("Source Type", '=%1|=%2', Database::"Purchase Line", 5406); // Database::"Prod. Order Line"
end;
SurplusEntry.Binding::"Order-to-Order":
begin
ReservEntry3 := SurplusEntry;
ReservEntry3.SetPointerFilter();
ReservEntry3.SetRange(
"Reservation Status", ReservEntry3."Reservation Status"::Reservation, ReservEntry3."Reservation Status"::Tracking);
ReservEntry3.SetRange(Binding, ReservEntry3.Binding::"Order-to-Order");
if ReservEntry3.FindFirst() then begin
ReservEntry3.Get(ReservEntry3."Entry No.", not ReservEntry3.Positive);
ReservEntry := ReservEntry3;
ReservEntry.SetRecFilter();
Found := true;
end else begin
Found := false;
FreeBinding := true;
end;
end;
end;
ActionMessageEntry.Quantity := -(SurplusEntry."Quantity (Base)" + SurplusEntry."Action Message Adjustment");
if not FreeBinding then begin
ReservEntry.SetLoadFields(
"Source Type", "Source Subtype", "Source ID", "Source Batch Name", "Source Prod. Order Line", "Source Ref. No.");
if ReservEntry.Find('+') then
if AllDeletedEntry."Entry No." > 0 then // The supply record has been deleted and cannot be reused.
repeat
Found := not AllDeletedEntry.HasSamePointer(ReservEntry);
if not Found then
NoMoreData := ReservEntry.Next(-1) = 0;
until Found or NoMoreData
else
Found := true;
end;
if Found then begin
ActionMessageEntry.TransferFromReservEntry(ReservEntry);
ActionMessageEntry.Type := ActionMessageEntry.Type::"Change Qty.";
ReservEntry2 := ReservEntry;
end else begin
ActionMessageEntry."Location Code" := SurplusEntry."Location Code";
ActionMessageEntry."Variant Code" := SurplusEntry."Variant Code";
ActionMessageEntry."Item No." := SurplusEntry."Item No.";
OnIssueActionMessageOnSetSourceTypeFromSKU(ActionMessageEntry, SKU);
ActionMessageEntry.Type := ActionMessageEntry.Type::New;
end;
ActionMessageEntry."Reservation Entry" := SurplusEntry."Entry No.";
end;
ReservEntry2.SetPointerFilter();
ReservEntry2.SetRange(
"Reservation Status", ReservEntry2."Reservation Status"::Reservation, ReservEntry2."Reservation Status"::Tracking);
if ReservEntry2."Source Type" <> Database::"Item Ledger Entry" then
if ReservEntry2.FindFirst() then begin
FirstDate := FindDate(ReservEntry2, 0, true);
if FirstDate <> 0D then begin
DampenerPeriod := GetDefaultDampenerPeriod();
if (Format(DampenerPeriod) = '') or
((ReservEntry2.Binding = ReservEntry2.Binding::"Order-to-Order") and
(ReservEntry2."Reservation Status" = ReservEntry2."Reservation Status"::Reservation))
then
Evaluate(DampenerPeriod, '<0D>');
Evaluate(DateFormula, StrSubstNo('%1%2', '-', Format(DampenerPeriod)));
if CalcDate(DateFormula, FirstDate) > ReservEntry2."Expected Receipt Date" then begin
ActionMessageEntry2.SetCurrentKey(
"Source Type", "Source Subtype", "Source ID", "Source Batch Name", "Source Prod. Order Line", "Source Ref. No.");
ActionMessageEntry2.SetSourceFilterFromActionEntry(ActionMessageEntry);
ActionMessageEntry2.SetRange(Quantity, 0);
ActionMessageEntry2.DeleteAll();
ActionMessageEntry2.Reset();
ActionMessageEntry2 := ActionMessageEntry;
ActionMessageEntry2.Quantity := 0;
ActionMessageEntry2."New Date" := FirstDate;
ActionMessageEntry2.Type := ActionMessageEntry.Type::Reschedule;
ActionMessageEntry2."Reservation Entry" := ReservEntry2."Entry No.";
while not ActionMessageEntry2.Insert() do
ActionMessageEntry2."Entry No." += 1;
ActionMessageEntry."Entry No." := ActionMessageEntry2."Entry No." + 1;
end;
end;
end;
while not ActionMessageEntry.Insert() do
ActionMessageEntry."Entry No." += 1;
end;
procedure ModifyActionMessage(RelatedToEntryNo: Integer; Quantity: Decimal; DoDelete: Boolean)
var
ActionMessageEntry: Record "Action Message Entry";
begin
ActionMessageEntry.Reset();
ActionMessageEntry.SetCurrentKey("Reservation Entry");
ActionMessageEntry.SetRange("Reservation Entry", RelatedToEntryNo);
if DoDelete then begin
ActionMessageEntry.DeleteAll();
exit;
end;
ActionMessageEntry.SetRange("New Date", 0D);
if ActionMessageEntry.FindFirst() then begin
ActionMessageEntry.Quantity -= Quantity;
if ActionMessageEntry.Quantity = 0 then
ActionMessageEntry.Delete()
else
ActionMessageEntry.Modify();
end;
end;
procedure FindDate(var ReservEntry: Record "Reservation Entry"; Which: Option "Earliest Shipment","Latest Receipt"; ReturnRecord: Boolean): Date
var
ReservEntry2: Record "Reservation Entry";
LastDate: Date;
begin
ReservEntry2.Copy(ReservEntry); // Copy filter and sorting
if not ReservEntry2.FindSet() then
exit;
case Which of
0:
begin
LastDate := DMY2Date(31, 12, 9999);
repeat
if ReservEntry2."Shipment Date" < LastDate then begin
LastDate := ReservEntry2."Shipment Date";
if ReturnRecord then
ReservEntry := ReservEntry2;
end;
until ReservEntry2.Next() = 0;
end;
1:
begin
LastDate := 0D;
repeat
if ReservEntry2."Expected Receipt Date" > LastDate then begin
LastDate := ReservEntry2."Expected Receipt Date";
if ReturnRecord then
ReservEntry := ReservEntry2;
end;
until ReservEntry2.Next() = 0;
end;
end;
exit(LastDate);
end;
local procedure UpdateDating()
var
FilterReservEntry: Record "Reservation Entry";
ReservEntry2: Record "Reservation Entry";
ReqLine: Record "Requisition Line";
begin
if CalcReservEntry2."Source Type" = Database::"Planning Component" then
exit;
if Item."Order Tracking Policy" <> Item."Order Tracking Policy"::"Tracking & Action Msg." then
exit;
if CalcReservEntry2."Source Type" = Database::"Requisition Line" then
if PlanningLineOrigin <> ReqLine."Planning Line Origin"::" " then
exit;
FilterReservEntry := CalcReservEntry2;
FilterReservEntry.SetPointerFilter();
if not FilterReservEntry.FindFirst() then
exit;
if CalcReservEntry2."Source Type" in [5406, Database::"Purchase Line"] then // Database::"Prod. Order Line"
ReservEngineMgt.ModifyActionMessageDating(FilterReservEntry)
else begin
if FilterReservEntry.Positive then
exit;
FilterReservEntry.SetRange("Reservation Status", FilterReservEntry."Reservation Status"::Reservation,
FilterReservEntry."Reservation Status"::Tracking);
if not FilterReservEntry.FindSet() then
exit;
repeat
if ReservEntry2.Get(FilterReservEntry."Entry No.", not FilterReservEntry.Positive) then
ReservEngineMgt.ModifyActionMessageDating(ReservEntry2);
until FilterReservEntry.Next() = 0;
end;
end;
procedure ClearActionMessageReferences()
var
ActionMessageEntry: Record "Action Message Entry";
ActionMessageEntry2: Record "Action Message Entry";
begin
ActionMessageEntry.Reset();
ActionMessageEntry.FilterFromReservEntry(CalcReservEntry);
if ActionMessageEntry.FindSet() then
repeat
ActionMessageEntry2 := ActionMessageEntry;
if ActionMessageEntry2.Quantity = 0 then
ActionMessageEntry2.Delete()
else begin
ActionMessageEntry2."Source Subtype" := 0;
ActionMessageEntry2."Source ID" := '';
ActionMessageEntry2."Source Batch Name" := '';
ActionMessageEntry2."Source Prod. Order Line" := 0;
ActionMessageEntry2."Source Ref. No." := 0;
ActionMessageEntry2."New Date" := 0D;
ActionMessageEntry2.Modify();
end;
until ActionMessageEntry.Next() = 0;
end;
procedure SetItemTrackingHandling(Mode: Option "None","Allow deletion",Match)
begin
ItemTrackingHandling := Mode;
end;
procedure DeleteItemTrackingConfirm() Result: Boolean
var
ConfirmManagement: Codeunit "Confirm Management";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeDeleteItemTrackingConfirm(CalcReservEntry2, IsHandled, Result);
if IsHandled then
exit(Result);
if not ItemTrackingExist(CalcReservEntry2) then
exit(true);
if ConfirmManagement.GetResponseOrDefault(
StrSubstNo(Text011, CalcReservEntry2."Item No.", CalcReservEntry2.TextCaption()), true)
then
exit(true);
exit(false);
end;
local procedure ItemTrackingExist(var ReservEntry: Record "Reservation Entry"): Boolean
var
ReservEntry2: Record "Reservation Entry";
begin
ReservEntry2.Copy(ReservEntry);
ReservEntry2.SetFilter("Item Tracking", '> %1', ReservEntry2."Item Tracking"::None);
exit(not ReservEntry2.IsEmpty);
end;
procedure SetTrackingFromReservEntry(ReservEntry: Record "Reservation Entry")
begin
CalcReservEntry.CopyTrackingFromReservEntry(ReservEntry);
end;
procedure SetTrackingFromWhseActivityLine(WhseActivityLine: Record "Warehouse Activity Line")
begin
CalcReservEntry.CopyTrackingFromWhseActivLine(WhseActivityLine);
end;
procedure SetMatchFilter(var ReservEntry: Record "Reservation Entry"; var FilterReservEntry: Record "Reservation Entry"; SearchForSupply: Boolean; AvailabilityDate: Date)
begin
FilterReservEntry.Reset();
FilterReservEntry.SetCurrentKey(
"Item No.", "Variant Code", "Location Code", "Reservation Status",
"Shipment Date", "Expected Receipt Date", "Serial No.", "Lot No.");
FilterReservEntry.SetRange("Item No.", ReservEntry."Item No.");
FilterReservEntry.SetRange("Variant Code", ReservEntry."Variant Code");
FilterReservEntry.SetRange("Location Code", ReservEntry."Location Code");
FilterReservEntry.SetRange("Reservation Status",
FilterReservEntry."Reservation Status"::Reservation, FilterReservEntry."Reservation Status"::Surplus);
if SearchForSupply then
FilterReservEntry.SetFilter("Expected Receipt Date", '..%1', AvailabilityDate)
else
FilterReservEntry.SetFilter("Shipment Date", '>=%1', AvailabilityDate);
FilterReservEntry.FilterLinesForTracking(ReservEntry, SearchForSupply);
FilterReservEntry.SetRange(Positive, SearchForSupply);
end;
procedure LookupLine(SourceType: Integer; SourceSubtype: Integer; SourceID: Code[20]; SourceBatchName: Code[10]; SourceProdOrderLine: Integer; SourceRefNo: Integer)
begin
OnLookupLine(SourceType, SourceSubtype, SourceID, SourceBatchName, SourceProdOrderLine, SourceRefNo);
end;
procedure LookupDocument(SourceType: Integer; SourceSubtype: Integer; SourceID: Code[20]; SourceBatchName: Code[10]; SourceProdOrderLine: Integer; SourceRefNo: Integer)
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeLookupDocument(SourceType, SourceSubtype, SourceID, SourceBatchName, SourceProdOrderLine, SourceRefNo, IsHandled);
if IsHandled then
exit;
OnLookupDocument(SourceType, SourceSubtype, SourceID, SourceBatchName, SourceProdOrderLine, SourceRefNo);
end;
local procedure CallCalcReservedQtyOnPick()
var
ShouldCalsReservedQtyOnPick: Boolean;
begin
ShouldCalsReservedQtyOnPick :=
Positive and (CalcReservEntry."Location Code" <> '') and
Location.Get(CalcReservEntry."Location Code") and (Location."Bin Mandatory" or Location."Require Pick");
OnBeforeCallCalcReservedQtyOnPick(CalcReservEntry, Positive, ShouldCalsReservedQtyOnPick);
if ShouldCalsReservedQtyOnPick then
CalcReservedQtyOnPick(TotalAvailQty, QtyAllocInWhse);
end;
local procedure CalcReservedQtyOnPick(var AvailQty: Decimal; var AllocQty: Decimal)
var
WhseActivLine: Record "Warehouse Activity Line";
WhseItemTrackingSetup: Record "Item Tracking Setup";
TempWhseActivLine2: Record "Warehouse Activity Line" temporary;
TempBinContentBuffer: Record "Bin Content Buffer" temporary;
TempTrackingSpecification: Record "Tracking Specification" temporary;
WhseAvailMgt: Codeunit "Warehouse Availability Mgt.";
QtyOnOutboundBins: Decimal;
QtyOnInvtMovement: Decimal;
QtyOnSpecialBins: Decimal;
IsHandled: Boolean;
begin
GetItemSetup(CalcReservEntry);
Item.SetRange("Location Filter", CalcReservEntry."Location Code");
IsHandled := false;
OnCalcReservedQtyOnPickOnbeforeSetItemVariantCodeFilter(Item, CalcReservEntry, IsHandled);
if not IsHandled then
Item.SetRange("Variant Filter", CalcReservEntry."Variant Code");
CalcReservEntry.SetTrackingFilterToItemIfRequired(Item);
Item.CalcFields(Inventory, "Reserved Qty. on Inventory");
WhseActivLine.SetCurrentKey(
"Item No.", "Bin Code", "Location Code", "Action Type", "Variant Code",
"Unit of Measure Code", "Breakbulk No.", "Activity Type", "Lot No.", "Serial No.");
WhseActivLine.SetRange("Item No.", CalcReservEntry."Item No.");
if Location."Bin Mandatory" then
WhseActivLine.SetFilter("Bin Code", '<>%1', '');
WhseActivLine.SetRange("Location Code", CalcReservEntry."Location Code");
WhseActivLine.SetFilter(
"Action Type", '%1|%2', WhseActivLine."Action Type"::" ", WhseActivLine."Action Type"::Take);
IsHandled := false;
OnCalcReservedQtyOnPickOnBeforeSetWhseActivLineVariantCodeFilter(WhseActivLine, CalcReservEntry, IsHandled);
if not IsHandled then
WhseActivLine.SetRange("Variant Code", CalcReservEntry."Variant Code");
WhseActivLine.SetRange("Breakbulk No.", 0);
WhseActivLine.SetFilter(
"Activity Type", '%1|%2', WhseActivLine."Activity Type"::Pick, WhseActivLine."Activity Type"::"Invt. Pick");
WhseActivLine.SetTrackingFilterFromReservEntryIfRequired(CalcReservEntry);
WhseActivLine.CalcSums("Qty. Outstanding (Base)");
if Location."Require Pick" then begin
WhseItemTrackingSetup.CopyTrackingFromItemTrackingCodeSpecificTracking(ItemTrackingCode);
WhseItemTrackingSetup.CopyTrackingFromReservEntry(CalcReservEntry);
if Location."Bin Mandatory" and not Location."Directed Put-away and Pick" and
WhseItemTrackingSetup.TrackingExists()
then begin
WhseAvailMgt.GetOutboundBinsOnBasicWarehouseLocation(
TempBinContentBuffer, CalcReservEntry."Location Code", CalcReservEntry."Item No.", CalcReservEntry."Variant Code", WhseItemTrackingSetup);
TempBinContentBuffer.CalcSums("Qty. Outstanding (Base)");
QtyOnOutboundBins := TempBinContentBuffer."Qty. Outstanding (Base)";
end else
QtyOnOutboundBins :=
WhseAvailMgt.CalcQtyOnOutboundBins(CalcReservEntry."Location Code", CalcReservEntry."Item No.", CalcReservEntry."Variant Code", WhseItemTrackingSetup, true);
if WhseItemTrackingSetup.TrackingExists() then begin
TempTrackingSpecification.CopyTrackingFromItemTrackingSetup(WhseItemTrackingSetup);
QtyReservedOnPickShip :=
WhseAvailMgt.CalcReservQtyOnPicksShipsWithItemTracking(
TempWhseActivLine2, TempTrackingSpecification, CalcReservEntry."Location Code", CalcReservEntry."Item No.", CalcReservEntry."Variant Code");
end else
QtyReservedOnPickShip :=
WhseAvailMgt.CalcReservQtyOnPicksShips(
CalcReservEntry."Location Code", CalcReservEntry."Item No.", CalcReservEntry."Variant Code", TempWhseActivLine2);
QtyOnInvtMovement := CalcQtyOnInvtMovement(WhseActivLine);
QtyOnSpecialBins :=
WhseAvailMgt.CalcQtyOnSpecialBinsOnLocation(
CalcReservEntry."Location Code", CalcReservEntry."Item No.", CalcReservEntry."Variant Code", WhseItemTrackingSetup, TempBinContentBuffer);
end;
CalcAvailAllocQuantities(
Item, WhseActivLine, QtyOnOutboundBins, QtyOnInvtMovement, QtyOnSpecialBins, AvailQty, AllocQty);
OnAfterCalcReservedQtyOnPick(Item, WhseActivLine, CalcReservEntry, AvailQty, AllocQty);
end;
local procedure CalcAvailAllocQuantities(
Item: Record Item; WhseActivLine: Record "Warehouse Activity Line";
QtyOnOutboundBins: Decimal; QtyOnInvtMovement: Decimal; QtyOnSpecialBins: Decimal;
var AvailQty: Decimal; var AllocQty: Decimal)
var
IsHandled: Boolean;
PickQty: Decimal;
begin
IsHandled := false;
OnBeforeCalcAvailAllocQuantities(
Item, WhseActivLine, QtyOnOutboundBins, QtyOnInvtMovement, QtyOnSpecialBins,
AvailQty, AllocQty, IsHandled);
if IsHandled then
exit;
AllocQty :=
WhseActivLine."Qty. Outstanding (Base)" + QtyOnInvtMovement +
QtyOnOutboundBins + QtyOnSpecialBins;
PickQty := WhseActivLine."Qty. Outstanding (Base)" + QtyOnInvtMovement;
AvailQty :=
Item.Inventory - PickQty - QtyOnOutboundBins - QtyOnSpecialBins -
Item."Reserved Qty. on Inventory" + QtyReservedOnPickShip;
end;
local procedure SaveItemTrackingAsSurplus(var ReservEntry: Record "Reservation Entry"; NewQty: Decimal; NewQtyBase: Decimal) QuantityIsValidated: Boolean
var
SurplusEntry: Record "Reservation Entry";
CreateReservEntry2: Codeunit "Create Reserv. Entry";
QtyToSave: Decimal;
QtyToSaveBase: Decimal;
QtyToHandleThisLine: Decimal;
QtyToInvoiceThisLine: Decimal;
SignFactor: Integer;
begin
QtyToSave := ReservEntry.Quantity - NewQty;
QtyToSaveBase := ReservEntry."Quantity (Base)" - NewQtyBase;
if QtyToSaveBase = 0 then
exit;
if ReservEntry."Item Tracking" = ReservEntry."Item Tracking"::None then
exit;
if ReservEntry."Source Type" = Database::"Item Ledger Entry" then
exit;
if QtyToSaveBase * ReservEntry."Quantity (Base)" < 0 then
ReservEntry.FieldError("Quantity (Base)");
SignFactor := ReservEntry."Quantity (Base)" / Abs(ReservEntry."Quantity (Base)");
if SignFactor * QtyToSaveBase > SignFactor * ReservEntry."Quantity (Base)" then
ReservEntry.FieldError("Quantity (Base)");
QtyToHandleThisLine := ReservEntry."Qty. to Handle (Base)" - NewQtyBase;
QtyToInvoiceThisLine := ReservEntry."Qty. to Invoice (Base)" - NewQtyBase;
ReservEntry.Validate("Quantity (Base)", NewQtyBase);
if SignFactor * QtyToHandleThisLine < 0 then begin
ReservEntry.Validate("Qty. to Handle (Base)", ReservEntry."Qty. to Handle (Base)" + QtyToHandleThisLine);
QtyToHandleThisLine := 0;
end;
if SignFactor * QtyToInvoiceThisLine < 0 then begin
ReservEntry.Validate("Qty. to Invoice (Base)", ReservEntry."Qty. to Invoice (Base)" + QtyToInvoiceThisLine);
QtyToInvoiceThisLine := 0;
end;
QuantityIsValidated := true;
SurplusEntry := ReservEntry;
SurplusEntry."Reservation Status" := SurplusEntry."Reservation Status"::Surplus;
if SurplusEntry.Positive then
SurplusEntry."Shipment Date" := 0D
else
SurplusEntry."Expected Receipt Date" := 0D;
CreateReservEntry2.SetQtyToHandleAndInvoice(QtyToHandleThisLine, QtyToInvoiceThisLine);
CreateReservEntry2.CreateRemainingReservEntry(SurplusEntry, QtyToSave, QtyToSaveBase);
end;
procedure CalcIsAvailTrackedQtyInBin(ItemNo: Code[20]; BinCode: Code[20]; LocationCode: Code[10]; VariantCode: Code[10]; SourceType: Integer; SourceSubtype: Integer; SourceID: Code[20]; SourceBatchName: Code[10]; SourceProdOrderLine: Integer; SourceRefNo: Integer) Result: Boolean
var
ReservationEntry: Record "Reservation Entry";
WarehouseEntry: Record "Warehouse Entry";
ItemTrackingMgt: Codeunit "Item Tracking Management";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCalcIsAvailTrackedQtyInBin(ItemNo, BinCode, LocationCode, VariantCode, Result, IsHandled);
if IsHandled then
exit(Result);
if not ItemTrackingMgt.GetWhseItemTrkgSetup(ItemNo) or (BinCode = '') then
exit(true);
ReservationEntry.SetSourceFilter(SourceType, SourceSubtype, SourceID, SourceRefNo, false);
ReservationEntry.SetSourceFilter(SourceBatchName, SourceProdOrderLine);
ReservationEntry.SetRange(Positive, false);
if ReservationEntry.FindSet() then
repeat
if ReservEntryPositiveTypeIsItemLedgerEntry(ReservationEntry."Entry No.") then begin
WarehouseEntry.SetRange("Item No.", ItemNo);
WarehouseEntry.SetRange("Location Code", LocationCode);
WarehouseEntry.SetRange("Bin Code", BinCode);
WarehouseEntry.SetRange("Variant Code", VariantCode);
WarehouseEntry.SetTrackingFilterFromReservEntryIfNotBlank(ReservationEntry);
WarehouseEntry.CalcSums("Qty. (Base)");
if WarehouseEntry."Qty. (Base)" < Abs(ReservationEntry."Quantity (Base)") then
exit(false);
end;
until ReservationEntry.Next() = 0;
exit(true);
end;
local procedure CalcQtyOnInvtMovement(var WarehouseActivityLine: Record "Warehouse Activity Line"): Decimal
var
xWarehouseActivityLine: Record "Warehouse Activity Line";
OutstandingQty: Decimal;
begin
xWarehouseActivityLine.Copy(WarehouseActivityLine);
WarehouseActivityLine.SetRange("Activity Type", WarehouseActivityLine."Activity Type"::"Invt. Movement");
if WarehouseActivityLine.Find('-') then
repeat
if WarehouseActivityLine."Source Type" <> 0 then
OutstandingQty += WarehouseActivityLine."Qty. Outstanding (Base)"
until WarehouseActivityLine.Next() = 0;
WarehouseActivityLine.Copy(xWarehouseActivityLine);
exit(OutstandingQty);
end;
local procedure ProdJnlLineEntry(ReservationEntry: Record "Reservation Entry"): Boolean
begin
exit((ReservationEntry."Source Type" = Database::"Item Journal Line") and (ReservationEntry."Source Subtype" = 6));
end;
local procedure CalcDownToQtySyncingToAssembly(ReservEntry: Record "Reservation Entry"): Decimal
var
SynchronizingSalesLine: Record "Sales Line";
begin
if ReservEntry."Source Type" = Database::"Sales Line" then begin
SynchronizingSalesLine.Get(ReservEntry."Source Subtype", ReservEntry."Source ID", ReservEntry."Source Ref. No.");
if (Item."Order Tracking Policy" <> Item."Order Tracking Policy"::None) and
(Item."Assembly Policy" = Item."Assembly Policy"::"Assemble-to-Order") and Item.IsAssemblyItem() and
(SynchronizingSalesLine."Quantity (Base)" = 0)
then
exit(ReservEntry."Quantity (Base)" * CreateReservEntry.SignFactor(ReservEntry));
end;
end;
procedure AutoReserveToShip(var FullAutoReservation: Boolean; Description: Text[100]; AvailabilityDate: Date; QuantityToShip: Decimal; QuantityToShipBase: Decimal)
var
RemainingQtyToReserve: Decimal;
RemainingQtyToReserveBase: Decimal;
StopReservation: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeAutoReserveToShip(IsHandled, FullAutoReservation, Description, AvailabilityDate, QuantityToShip, QuantityToShipBase);
if not IsHandled then begin
CalcReservEntry.TestField("Source Type");
if CalcReservEntry."Source Type" in [1 /*Sales*/, 3 /* Purchase*/]
then
StopReservation := not (CalcReservEntry."Source Subtype" in [1, 2, 5]); // Only invoice, order and return order
if CalcReservEntry."Source Type" in [7 /*Prod. Order Line"*/, 8 /* Prod. Order Component */]
then
StopReservation := CalcReservEntry."Source Subtype" < 2; // Not simulated or planned
if StopReservation then begin
FullAutoReservation := true;
exit;
end;
RemainingQtyToReserve := QuantityToShip;
RemainingQtyToReserveBase := QuantityToShipBase;
FullAutoReservation := false;
if RemainingQtyToReserve = 0 then begin
FullAutoReservation := true;
exit;
end;
SetValueArray(0);
AutoReserveOneLine(ValueArray[1], RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate);
FullAutoReservation := (RemainingQtyToReserve = 0);
end;
OnAfterAutoReserveToShip(FullAutoReservation, Description, AvailabilityDate, QuantityToShip, QuantityToShipBase);
end;
local procedure CalcCurrLineReservQtyOnPicksShips(ReservationEntry: Record "Reservation Entry"): Decimal
var
ReservEntry: Record "Reservation Entry";
TempWhseActivLine: Record "Warehouse Activity Line" temporary;
WhseAvailMgt: Codeunit "Warehouse Availability Mgt.";
PickQty: Decimal;
begin
PickQty := WhseAvailMgt.CalcRegisteredAndOutstandingPickQty(ReservationEntry, TempWhseActivLine);
ReservEntry.SetSourceFilter(
ReservationEntry."Source Type", ReservationEntry."Source Subtype",
ReservationEntry."Source ID", ReservationEntry."Source Ref. No.", false);
ReservEntry.SetRange("Source Prod. Order Line", ReservationEntry."Source Prod. Order Line");
ReservEntry.SetRange("Reservation Status", ReservEntry."Reservation Status"::Reservation);
ReservEntry.CalcSums("Quantity (Base)");
if -ReservEntry."Quantity (Base)" > PickQty then
exit(PickQty);
exit(-ReservEntry."Quantity (Base)");
end;
local procedure CheckQuantityIsCompletelyReleased(QtyToRelease: Decimal; DeleteAll: Boolean; CurrentItemTrackingSetup: Record "Item Tracking Setup"; ReservEntry: Record "Reservation Entry")
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCheckQuantityIsCompletelyReleased(ItemTrackingHandling, QtyToRelease, DeleteAll, CurrentItemTrackingSetup, ReservEntry, IsHandled);
if IsHandled then
exit;
if QtyToRelease = 0 then
exit;
if ItemTrackingHandling = ItemTrackingHandling::None then begin
if DeleteAll then
Error(Text010, ReservEntry."Item No.", ReservEntry.TextCaption());
if not ProdJnlLineEntry(ReservEntry) then
Error(Text008, ReservEntry."Item No.", ReservEntry.TextCaption());
end;
if ItemTrackingHandling = ItemTrackingHandling::Match then
Error(
ItemTrackingCannotBeFullyMatchedErr,
CurrentItemTrackingSetup."Serial No.", CurrentItemTrackingSetup."Lot No.", Abs(QtyToRelease));
end;
[Scope('OnPrem')]
procedure ReservEntryPositiveTypeIsItemLedgerEntry(ReservationEntryNo: Integer): Boolean
var
ReservationEntryPositive: Record "Reservation Entry";
begin
if ReservationEntryPositive.Get(ReservationEntryNo, true) then
exit(ReservationEntryPositive."Source Type" = Database::"Item Ledger Entry");
exit(true);
end;
procedure DeleteDocumentReservation(TableID: Integer; DocType: Option; DocNo: Code[20]; HideValidationDialog: Boolean)
var
ReservEntry: Record "Reservation Entry";
ReservEntry2: Record "Reservation Entry";
ConfirmManagement: Codeunit "Confirm Management";
DocTypeCaption: Text;
Confirmed: Boolean;
begin
OnBeforeDeleteDocumentReservation(TableID, DocType, DocNo, HideValidationDialog);
ReservEntry.Reset();
ReservEntry.SetCurrentKey(
"Source ID", "Source Ref. No.", "Source Type", "Source Subtype",
"Source Batch Name", "Source Prod. Order Line", "Reservation Status");
if TableID <> 5406 then begin // Database::"Prod. Order Line"
ReservEntry.SetRange("Source Type", TableID);
ReservEntry.SetRange("Source Prod. Order Line", 0);
end else
ReservEntry.SetFilter("Source Type", '%1|%2', 5406, 5407); // Database::"Prod. Order Component"
case TableID of
Database::"Transfer Line":
ReservEntry.SetRange("Source Subtype");
else
ReservEntry.SetRange("Source Subtype", DocType);
end;
ReservEntry.SetRange("Source ID", DocNo);
ReservEntry.SetRange("Source Batch Name", '');
ReservEntry.SetFilter("Item Tracking", '> %1', Enum::"Item Tracking Entry Type"::None);
if ReservEntry.IsEmpty() then
exit;
if HideValidationDialog then
Confirmed := true
else begin
DocTypeCaption := GetDocumentReservationDeleteQst(TableID, DocType, DocNo);
Confirmed := ConfirmManagement.GetResponseOrDefault(DocTypeCaption, true);
end;
if not Confirmed then
Error('');
if ReservEntry.FindSet() then
repeat
ReservEntry2 := ReservEntry;
ReservEntry2.ClearItemTrackingFields();
ReservEntry2.Modify();
OnDeleteDocumentReservationOnAfterReservEntry2Modify(ReservEntry);
until ReservEntry.Next() = 0;
end;
local procedure GetDocumentReservationDeleteQst(TableID: Integer; DocType: Option; DocNo: Code[20]) Question: Text
var
RecRef: RecordRef;
FldRef: FieldRef;
DocTypeCaption: Text;
IsHandled: Boolean;
begin
case TableID of
Database::"Transfer Line":
exit(StrSubstNo(DeleteTransLineWithItemReservQst, DocNo));
else begin
RecRef.Open(TableID);
FldRef := RecRef.FieldIndex(1);
OnGetDocumentReservationDeleteQstOnElseCase(RecRef, FldRef, DocType, DocTypeCaption, IsHandled, DocNo, Question);
if IsHandled then
exit(Question)
else
exit(StrSubstNo(DeleteDocLineWithItemReservQst, SelectStr(DocType + 1, FldRef.OptionCaption), DocNo));
end;
end;
end;
[Scope('OnPrem')]
procedure SetSkipUntrackedSurplus(NewSkipUntrackedSurplus: Boolean)
begin
SkipUntrackedSurplus := NewSkipUntrackedSurplus;
end;
procedure SetQtyToReserveDownToTrackedQuantity(ReservEntry: Record "Reservation Entry"; RowID: Text[250]; var QtyThisLine: Decimal; var QtyThisLineBase: Decimal)
var
FilterReservEntry: Record "Reservation Entry";
TempTrackingSpec: Record "Tracking Specification" temporary;
ItemTrackingMgt: Codeunit "Item Tracking Management";
MaxReservQtyPerLotOrSerial: Decimal;
MaxReservQtyBasePerLotOrSerial: Decimal;
begin
if not ReservEntry.TrackingExists() then
exit;
FilterReservEntry.SetPointer(RowID);
FilterReservEntry.SetPointerFilter();
FilterReservEntry.SetTrackingFilterFromReservEntry(ReservEntry);
ItemTrackingMgt.SumUpItemTracking(FilterReservEntry, TempTrackingSpec, true, true);
MaxReservQtyBasePerLotOrSerial := TempTrackingSpec."Quantity (Base)";
MaxReservQtyPerLotOrSerial :=
UOMMgt.CalcQtyFromBase(
FilterReservEntry."Item No.", FilterReservEntry."Variant Code", '',
MaxReservQtyBasePerLotOrSerial, TempTrackingSpec."Qty. per Unit of Measure");
QtyThisLine := GetMinAbs(QtyThisLine, MaxReservQtyPerLotOrSerial) * GetSign(QtyThisLine);
QtyThisLineBase := GetMinAbs(QtyThisLineBase, MaxReservQtyBasePerLotOrSerial) * GetSign(QtyThisLineBase);
end;
procedure SetReservedQtyDownToTrackedQuantity(ReservEntry: Record "Reservation Entry"; RowID: Text[250]; var ReserveQty: Decimal)
var
FilterReservEntry: Record "Reservation Entry";
TempTrackingSpec: Record "Tracking Specification" temporary;
ItemTrackingMgt: Codeunit "Item Tracking Management";
begin
if not ReservEntry.TrackingExists() then
exit;
FilterReservEntry.SetPointer(RowID);
FilterReservEntry.SetPointerFilter();
FilterReservEntry.SetTrackingFilterFromReservEntry(ReservEntry);
FilterReservEntry.SetRange("Reservation Status", FilterReservEntry."Reservation Status"::Reservation);
ItemTrackingMgt.SumUpItemTracking(FilterReservEntry, TempTrackingSpec, true, true);
if TempTrackingSpec.IsEmpty then
ReserveQty := 0
else
ReserveQty := TempTrackingSpec."Quantity (Base)";
end;
local procedure IsSpecialOrderOrDropShipment(ReservationEntry: Record "Reservation Entry"): Boolean
var
SalesLine: Record "Sales Line";
PurchaseLine: Record "Purchase Line";
begin
if ReservationEntry."Source Type" = Database::"Sales Line" then
if SalesLine.Get(ReservationEntry."Source Subtype", ReservationEntry."Source ID", ReservationEntry."Source Ref. No.") then
if SalesLine."Special Order" or SalesLine."Drop Shipment" then
exit(true);
if ReservationEntry."Source Type" = Database::"Purchase Line" then
if PurchaseLine.Get(ReservationEntry."Source Subtype", ReservationEntry."Source ID", ReservationEntry."Source Ref. No.") then
if PurchaseLine."Special Order" or PurchaseLine."Drop Shipment" then
exit(true);
exit(false);
end;
procedure FindUnfinishedSpecialOrderSalesNo(ItemLedgerEntry: Record "Item Ledger Entry") Result: Code[20]
var
PurchRcptLine: Record "Purch. Rcpt. Line";
SalesLine: Record "Sales Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeFindUnfinishedSpecialOrderSalesNo(ItemLedgerEntry, Result, IsHandled);
if IsHandled then
exit(Result);
if ItemLedgerEntry."Document Type" = ItemLedgerEntry."Document Type"::"Purchase Receipt" then
if PurchRcptLine.Get(ItemLedgerEntry."Document No.", ItemLedgerEntry."Document Line No.") then
if SalesLine.Get(
SalesLine."Document Type"::Order, PurchRcptLine."Special Order Sales No.", PurchRcptLine."Special Order Sales Line No.")
then
if SalesLine.Quantity <> SalesLine."Quantity Shipped" then
exit(SalesLine."Document No.");
exit('');
end;
procedure GetMinAbs(Value1: Decimal; Value2: Decimal): Decimal
begin
Value1 := Abs(Value1);
Value2 := Abs(Value2);
if Value1 <= Value2 then
exit(Value1);
exit(Value2);
end;
procedure GetSign(Value: Decimal): Integer
begin
if Value >= 0 then
exit(1);
exit(-1);
end;
local procedure GetDefaultDampenerPeriod() DampenerPeriod: DateFormula
begin
OnGetDefaultDampenerPeriod(DampenerPeriod);
end;
procedure TestItemType(SourceRecRef: RecordRef)
begin
OnTestItemType(SourceRecRef);
end;
local procedure AutoManageReservationItemLedgerEntry(ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date)
begin
if not HandleItemTracking then
AutoReserveItemLedgerEntryFromSurplus(ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate);
if RemainingQtyToReserveBase <> 0 then
AutoReserveItemLedgEntry(ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate);
end;
local procedure AutoReserveItemLedgerEntryFromSurplus(ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date)
var
ReservationEntry: Record "Reservation Entry";
begin
if CalcReservEntry.TrackingExists() then
exit;
ReservationEntry.SetSourceFilterFromReservEntry(CalcReservEntry);
ReservationEntry.SetRange("Reservation Status", ReservationEntry."Reservation Status"::Surplus);
if ReservationEntry.FindSet() then
repeat
AutoReserveFromSpecificReservEntry(ReservationEntry, ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate)
until ReservationEntry.Next() = 0;
end;
local procedure AutoReserveFromSpecificReservEntry(ReservationEntry: Record "Reservation Entry"; ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date)
var
QtyToReserve: Decimal;
QtyToReserveBase: Decimal;
begin
if not ReservationEntry.TrackingExists() then
exit;
CalcReservEntry.CopyTrackingFromReservEntry(ReservationEntry);
QtyToReserve := Abs(ReservationEntry.Quantity);
QtyToReserveBase := Abs(ReservationEntry."Qty. to Handle (Base)");
AutoReserveItemLedgEntry(ReservSummEntryNo, QtyToReserve, QtyToReserveBase, Description, AvailabilityDate);
if Abs(ReservationEntry."Qty. to Handle (Base)") = QtyToReserveBase then begin
CalcReservEntry.ClearTracking();
exit;
end;
RemainingQtyToReserve -= Abs(ReservationEntry.Quantity);
RemainingQtyToReserveBase -= Abs(ReservationEntry."Qty. to Handle (Base)");
end;
[IntegrationEvent(false, false)]
local procedure OnAfterAutoReserve(var ReservationEntry: Record "Reservation Entry"; var FullAutoReservation: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnAfterAutoReserveOneLine(ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date; Search: Text[1]; NextStep: Integer; CalcReservEntry: Record "Reservation Entry"; CalcReservEntry2: Record "Reservation Entry"; Positive: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCalcReservation(var ReservEntry: Record "Reservation Entry"; var ItemLedgEntry: Record "Item Ledger Entry"; var ResSummEntryNo: Integer; var QtyThisLine: Decimal; var QtyThisLineBase: Decimal; TotalAvailQty: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterAutoReserveItemLedgEntry(var CalcItemLedgEntry: Record "Item Ledger Entry"; var RemainingQtyToReserveBase: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterGetAvailabilityFilter2(var ReservationEntry: Record "Reservation Entry"; AvailabilityDate: Date; SearchForSupply: Boolean; var Result: Text[80])
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInsertReservationEntries(var TrackingSpecification: Record "Tracking Specification"; var CalcReservEntry: Record "Reservation Entry"; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; var QtyThisLine: Decimal; var QtyThisLineBase: Decimal; var ReservationCreated: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAutoReserveOneLine(var IsHandled: Boolean; var AvailabilityDate: Date; var CalcReservEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCalcIsAvailTrackedQtyInBin(ItemNo: Code[20]; BinCode: Code[20]; LocationCode: Code[10]; VariantCode: Code[10]; var Result: Boolean; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeDeleteDocumentReservation(TableID: Integer; DocType: Option; DocNo: Code[20]; var HideValidationDialog: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeMakeRoomForReservation(var ReservationEntry: Record "Reservation Entry"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeSetValueArray(EntryStatus: Option; var ValueArray: array[30] of Integer; var ArrayCounter: Integer; var IsHandled: Boolean; var CalcReservationEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateStatistics(var AvailabilityDate: Date)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnAfterInitFilter(var CalcReservEntry: Record "Reservation Entry"; EntryID: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSaveTrackingSpecification(var ReservationEntry: Record "Reservation Entry"; var TrackingSpecification: Record "Tracking Specification"; QtyReleased: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSetReservSource(var SourceRecRef: RecordRef; var CalcReservEntry: Record "Reservation Entry"; var Direction: Enum "Transfer Direction")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSetValueArray(EntryStatus: Option Reservation,Tracking,Simulation; var ValueArray: array[30] of Integer; var ArrayCounter: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterUpdateStatistics(var ReservEntrySummary: Record "Entry Summary"; AvailabilityDate: Date; var CalcSumValue: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAutoReserveItemLedgEntryOnFindFirstItemLedgEntry(CalcReservEntry: Record "Reservation Entry"; var CalcItemLedgEntry: Record "Item Ledger Entry"; var InvSearch: Text[1]; var IsHandled: Boolean; var IsFound: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAutoReserveOnBeforeStopReservation(var CalcReservEntry: Record "Reservation Entry"; var FullAutoReservation: Boolean; var AvailabilityDate: Date; var MaxQtyToReserve: Decimal; var MaxQtyToReserveBase: Decimal; var StopReservation: Boolean; SourceRecRef: RecordRef)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAutoReserveOnBeforeSetValueArray(var ValueArrayNo: Integer; AvailabilityDate: Date)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAutoReserveOneLineOnAfterUpdateSearchNextStep(var Item: Record Item; var Positive: Boolean; var Search: Text[1]; var NextStep: Integer; var InvSearch: Text[1]; InvNextStep: Integer; var RemainingQtyToReserve: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAutoReserveItemLedgEntryOnFindNextItemLedgEntry(CalcReservEntry: Record "Reservation Entry"; var CalcItemLedgEntry: Record "Item Ledger Entry"; var InvSearch: Text[1]; var IsHandled: Boolean; var IsFound: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSetSourceForSalesLine(var CalcReservEntry: Record "Reservation Entry"; SalesLine: Record "Sales Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAutoReserve(var CalcReservEntry: Record "Reservation Entry"; var FullAutoReservation: Boolean; var Description: Text[100]; var AvailabilityDate: Date; var MaxQtyToReserve: Decimal; var MaxQtyToReserveBase: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeAutoReserveItemLedgEntry(ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date; var IsReserved: Boolean; CalcReservEntry: Record "Reservation Entry"; var CalcItemLedgerEntry: Record "Item Ledger Entry"; var ItemTrackingCode: Record "Item Tracking Code"; Positive: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCalcAvailAllocQuantities(
Item: Record Item; WhseActivLine: Record "Warehouse Activity Line";
QtyOnOutboundBins: Decimal; QtyOnInvtMovement: Decimal; QtyOnSpecialBins: Decimal;
var AvailQty: Decimal; var AllocQty: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCreateReservation(var TrkgSpec: Record "Tracking Specification"; var ReservEntry: Record "Reservation Entry"; var ItemLedgEntry: Record "Item Ledger Entry")
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeDeleteItemTrackingConfirm(var CalcReservEntry2: Record "Reservation Entry"; var IsHandled: Boolean; var Result: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeDeleteReservEntries(var ReservationEntry: Record "Reservation Entry"; var DownToQuantity: Decimal; CalcReservEntry: Record "Reservation Entry"; var CalcReservEntry2: Record "Reservation Entry"; var IsHandled: Boolean; var ItemTrackingHandling: Option "None","Allow deletion",Match)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeFindUnfinishedSpecialOrderSalesNo(ItemLedgerEntry: Record "Item Ledger Entry"; var Result: Code[20]; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeLookupDocument(SourceType: Integer; SourceSubtype: Integer; SourceID: Code[20]; SourceBatchName: Code[10]; SourceProdOrderLine: Integer; SourceRefNo: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateItemLedgEntryStats(var CalcReservEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateReservation(var SourceRecRef: RecordRef; var ReservEntry: Record "Reservation Entry"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalculateRemainingQty(SourceRecRef: RecordRef; var ReservEntry: Record "Reservation Entry"; var RemainingQty: Decimal; var RemainingQtyBase: Decimal);
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalcReservedQtyOnPickOnBeforeSetItemVariantCodeFilter(var Item: Record Item; var ReservationEntry: Record "Reservation Entry"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCalcReservedQtyOnPickOnBeforeSetWhseActivLineVariantCodeFilter(var WnseActivLine: Record "Warehouse Activity Line"; var ReservationEntry: Record "Reservation Entry"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnClearSurplusOnAfterReservEntry2SetFilters(var ReservationEntry: Record "Reservation Entry"; ItemTrackingHandling: Option "None","Allow deletion",Match)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnClearSurplusOnBeforeReservEntry2FindSet(var ReservationEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateReservation(SourceRecRef: RecordRef; TrackingSpecification: Record "Tracking Specification"; ForReservEntry: Record "Reservation Entry"; Description: Text[100]; ExpectedDate: Date; Quantity: Decimal; QuantityBase: Decimal);
begin
end;
[IntegrationEvent(false, false)]
local procedure OnGetDocumentReservationDeleteQstOnElseCase(RecRef: RecordRef; FldRef: FieldRef; DocType: Integer; var DocTypeCaption: Text; var IsHandled: Boolean; DocNo: Code[20]; var Question: Text)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteReservEntriesOnAfterReservEntrySetFilters(var ReservEntry: Record "Reservation Entry"; var ItemTrackingHandling: Option "None","Allow deletion",Match)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteDocumentReservationOnAfterReservEntry2Modify(var ReservEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnGetSourceRecordValue(var ReservEntry: Record "Reservation Entry"; SetAsCurrent: Boolean; ReturnOption: Option "Net Qty. (Base)","Gross Qty. (Base)"; var ReturnQty: Decimal; var SourceRecRef: RecordRef; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnFilterReservFor(SourceRecRef: RecordRef; var ReservEntry: Record "Reservation Entry"; Direction: Integer; var CaptionText: Text);
begin
end;
[IntegrationEvent(false, false)]
local procedure OnInsertReservationEntriesOnBeforeCreateReservation(var TrackingSpecification: Record "Tracking Specification"; var CalcReservEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnLookupDocument(SourceType: Integer; SourceSubtype: Integer; SourceID: Code[20]; SourceBatchName: Code[10]; SourceProdOrderLine: Integer; SourceRefNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnLookupLine(SourceType: Integer; SourceSubtype: Integer; SourceID: Code[20]; SourceBatchName: Code[10]; SourceProdOrderLine: Integer; SourceRefNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetItemJnlLineOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; ItemJnlLine: Record "Item Journal Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetItemLedgEntryOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; ItemLedgerEntry: Record "Item Ledger Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetJobPlanningLineOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; JobPlanningLine: Record Microsoft.Projects.Project.Planning."Job Planning Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetJobJnlLineOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; JobJnlLine: Record Microsoft.Projects.Project.Journal."Job Journal Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetSalesLineOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; SalesLine: Record "Sales Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetPlanningCompOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; PlanningComponent: Record "Planning Component")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetPurchLineOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; PurchLine: Record "Purchase Line")
begin
end;
[IntegrationEvent(true, false)]
local procedure OnSetReservSource(SourceRecRef: RecordRef; var ReservEntry: Record "Reservation Entry"; Direction: Enum "Transfer Direction"; var RefOrderType: Enum "Requisition Ref. Order Type"; var PlanningLineOrigin: Enum "Planning Line Origin Type"; Positive: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetReqLineOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; ReqLine: Record "Requisition Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetTransLineOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; TransferLine: Record "Transfer Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateItemLedgEntryStatsOnBeforePrepareTempEntrySummary(CalcReservationEntry: Record "Reservation Entry"; var TempEntrySummary: Record "Entry Summary")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateItemLedgEntryStatsUpdateTotals(CalcReservEntry: Record "Reservation Entry"; var CalcItemLedgEntry: Record "Item Ledger Entry"; TotalAvailQty: Decimal; QtyOnOutBound: Decimal; var CalcSumValue: Decimal; var TempEntrySummary: Record "Entry Summary"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateItemTrackingLineStatsOnBeforeReservEntrySummaryInsert(var ReservEntrySummary: Record "Entry Summary"; ReservationEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateItemTrackingLineStatsOnAfterReservEntrySetFilters(var ReservEntry: Record "Reservation Entry"; CalcReservEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateStatistics(CalcReservEntry: Record "Reservation Entry"; var ReservSummEntry: Record "Entry Summary"; AvailabilityDate: Date; Positive: Boolean; var TotalQuantity: Decimal; HandleItemTracking2: Boolean; var QtyOnOutBound: Decimal; ReservationSummaryType: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCalcReservedQtyOnPick(var Item: Record Item; var WhseActivLine: Record "Warehouse Activity Line"; var CalcReservEntry: Record "Reservation Entry"; var AvailQty: Decimal; var AllocQty: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCallCalcReservedQtyOnPick(CalcReservEntry: Record "Reservation Entry"; Positive: Boolean; var ShouldCalsReservedQtyOnPick: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCheckQuantityIsCompletelyReleased(ItemTrackingHandling: Option "None","Allow deletion",Match; QtyToRelease: Decimal; DeleteAll: Boolean; CurrentItemTrackingSetup: Record "Item Tracking Setup"; ReservEntry: Record "Reservation Entry"; var IsHandled: boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeReservedQuantityAssign(ReservationEntry: Record "Reservation Entry"; var ReservedQuantity: Decimal; SignFactor: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeDeleteReservEntries2(CalcReservEntry: Record "Reservation Entry"; var CalcReservEntry2: Record "Reservation Entry"; var IsHandled: Boolean; var Item: record Item; var ItemTrackingCode: Record "Item Tracking Code"; var SKU: Record "Stockkeeping Unit"; var Positive: Boolean; var Location: Record Location; var TotalAvailQty: Decimal; var QtyAllocInWhse: Decimal; var QtyReservedOnPickShip: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteReservEntriesOnReservationOnAfterCalcReservEntry4Get(var CalcReservEntry4: Record "Reservation Entry"; var ReservEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteReservEntriesOnBeforeReservEntryTestField(var ReservEntry: Record "Reservation Entry"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterFinishedAutoReserveOneLine(ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteReservEntriesOnAfterItemTrackingHandling(var ReservationEntry: Record "Reservation Entry"; var ItemTrackingHandling: Option "None","Allow deletion",Match)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAutoTrackOnCheckSourceType(var ReservationEntry: Record "Reservation Entry"; var ShouldExit: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAutoTrackOnAfterGetItemSetup(var ReservationEntry: Record "Reservation Entry"; var Item: Record Item)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTestItemType(SourceRecRef: RecordRef);
begin
end;
[IntegrationEvent(false, false)]
local procedure OnIssueActionMessageOnSetSourceTypeFromSKU(var ActionMessageEntry: Record "Action Message Entry"; SKU: Record "Stockkeeping Unit")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnMakeConnectionOnBeforeCreateReservEntry(var FromReservationEntry: Record "Reservation Entry"; var ToReservationEntry: Record "Reservation Entry"; var Quantity: Decimal; ReservationStatus: Enum "Reservation Status"; var AvailabilityDate: Date; ReservationBinding: Enum "Reservation Binding"; var FromTrackingSpecification: Record "Tracking Specification"; var Sign: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnDeleteReservEntriesOnAfterModifyReservEntryReservationStatusSurplus(var ReservationEntry: Record "Reservation Entry"; QtyToRelease: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSetValueArrayForReservation(var ValueArray: array[30] of Integer; var ArrayCounter: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterSetValueArrayForOrderTracking(var ValueArray: array[30] of Integer; var ArrayCounter: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetSourceForAssemblyHeader(SourceRecRef: RecordRef; var CalcReservEntry: Record "Reservation Entry"; var EntryIsPositive: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetSourceForAssemblyLine(SourceRecRef: RecordRef; var CalcReservEntry: Record "Reservation Entry"; var EntryIsPositive: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetSourceForProdOrderLine(SourceRecRef: RecordRef; var CalcReservEntry: Record "Reservation Entry"; var EntryIsPositive: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetSourceForProdOrderComp(SourceRecRef: RecordRef; var CalcReservEntry: Record "Reservation Entry"; var EntryIsPositive: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnSetSourceForServiceLine(SourceRecRef: RecordRef; var CalcReservEntry: Record "Reservation Entry"; var EntryIsPositive: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnGetDefaultDampenerPeriod(var DampenerPeriod: DateFormula)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAutoReserveItemLedgEntryOnAfterCalcReservQty(CalcItemLedgerEntry: Record "Item Ledger Entry"; QtyThisLine: Decimal; QtyThisLineBase: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateReservationOnAfterSetPointerFilter(var CalcReservationEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAutoReserveToShip(var IsHandled: Boolean; var FullAutoReservation: Boolean; Description: Text[100]; AvailabilityDate: Date; QuantityToShip: Decimal; QuantityToShipBase: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterAutoReserveToShip(var FullAutoReservation: Boolean; Description: Text[100]; AvailabilityDate: Date; QuantityToShip: Decimal; QuantityToShipBase: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterGetItemSetup(var ReservationEntry: Record "Reservation Entry"; var Item: Record Item)
begin
end;
}