Codeunit 99000834 Purch. Line-Reserve
- App
- Base Application
- Namespace
- Microsoft.Purchases.Document
- Versions
- 17-28
Procedures, 29Events, 32Obsolete, 3
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Purchases/Document/PurchLineReserve.Codeunit.al1330 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.Purchases.Document;
using Microsoft.Foundation.Navigate;
using Microsoft.Foundation.UOM;
using Microsoft.Inventory.Journal;
using Microsoft.Inventory.Ledger;
using Microsoft.Inventory.Location;
using Microsoft.Inventory.Planning;
using Microsoft.Inventory.Tracking;
using Microsoft.Purchases.History;
using Microsoft.Sales.Document;
codeunit 99000834 "Purch. Line-Reserve"
{
Permissions = TableData "Reservation Entry" = rimd;
trigger OnRun()
begin
end;
var
FromTrackingSpecification: Record "Tracking Specification";
CreateReservEntry: Codeunit "Create Reserv. Entry";
ReservationEngineMgt: Codeunit "Reservation Engine Mgt.";
ReservationManagement: Codeunit "Reservation Management";
ItemTrackingManagement: Codeunit "Item Tracking Management";
UnitOfMeasureManagement: Codeunit "Unit of Measure Management";
Blocked: Boolean;
ApplySpecificItemTracking: Boolean;
OverruleItemTracking: Boolean;
DeleteItemTracking: Boolean;
Text000Err: Label 'Reserved quantity cannot be greater than %1', Comment = '%1 - quantity';
Text001Err: Label 'must be filled in when a quantity is reserved';
Text002Err: Label 'must not be filled in when a quantity is reserved';
Text003Err: Label 'must not be changed when a quantity is reserved';
Text004Err: Label 'Codeunit is not initialized correctly.';
PurchaseTxt: Label 'Purchase';
SummaryTypeTxt: Label '%1, %2', Locked = true;
SourceDoc3Txt: Label '%1 %2 %3', Locked = true;
procedure CreateReservation(var PurchaseLine: Record "Purchase Line"; Description: Text[100]; ExpectedReceiptDate: Date; Quantity: Decimal; QuantityBase: Decimal; ForReservationEntry: Record "Reservation Entry")
var
ShipmentDate: Date;
SignFactor: Integer;
IsHandled: Boolean;
begin
if FromTrackingSpecification."Source Type" = 0 then
Error(Text004Err);
OnBeforeCreateReservation(PurchaseLine);
PurchaseLine.TestField(Type, PurchaseLine.Type::Item);
PurchaseLine.TestField("No.");
PurchaseLine.TestField("Expected Receipt Date");
PurchaseLine.CalcFields("Reserved Qty. (Base)");
if Abs(PurchaseLine."Outstanding Qty. (Base)") < Abs(PurchaseLine."Reserved Qty. (Base)") + QuantityBase then
Error(
Text000Err,
Abs(PurchaseLine."Outstanding Qty. (Base)") - Abs(PurchaseLine."Reserved Qty. (Base)"));
PurchaseLine.TestField("Variant Code", FromTrackingSpecification."Variant Code");
PurchaseLine.TestField("Location Code", FromTrackingSpecification."Location Code");
if PurchaseLine."Document Type" = PurchaseLine."Document Type"::"Return Order" then
SignFactor := -1
else
SignFactor := 1;
if QuantityBase * SignFactor < 0 then
ShipmentDate := PurchaseLine."Expected Receipt Date"
else begin
ShipmentDate := ExpectedReceiptDate;
ExpectedReceiptDate := PurchaseLine."Expected Receipt Date";
end;
if PurchaseLine."Planning Flexibility" <> PurchaseLine."Planning Flexibility"::Unlimited then
CreateReservEntry.SetPlanningFlexibility(PurchaseLine."Planning Flexibility");
IsHandled := false;
OnCreateReservationOnBeforeCreateReservEntry(PurchaseLine, Quantity, QuantityBase, ForReservationEntry, IsHandled, FromTrackingSpecification, ExpectedReceiptDate, Description, ShipmentDate);
if not IsHandled then begin
CreateReservEntry.CreateReservEntryFor(
Database::"Purchase Line", PurchaseLine."Document Type".AsInteger(),
PurchaseLine."Document No.", '', 0, PurchaseLine."Line No.", PurchaseLine."Qty. per Unit of Measure",
Quantity, QuantityBase, ForReservationEntry);
CreateReservEntry.CreateReservEntryFrom(FromTrackingSpecification);
end;
CreateReservEntry.CreateReservEntry(
PurchaseLine."No.", PurchaseLine."Variant Code", PurchaseLine."Location Code",
Description, ExpectedReceiptDate, ShipmentDate, 0);
FromTrackingSpecification."Source Type" := 0;
OnAfterCreateReservation(PurchaseLine);
end;
procedure CreateReservationSetFrom(TrackingSpecification: Record "Tracking Specification")
begin
FromTrackingSpecification := TrackingSpecification;
end;
procedure ReservQuantity(PurchaseLine: Record "Purchase Line") QtyToReserve: Decimal
begin
case PurchaseLine."Document Type" of
PurchaseLine."Document Type"::Quote,
PurchaseLine."Document Type"::Order,
PurchaseLine."Document Type"::Invoice,
PurchaseLine."Document Type"::"Blanket Order":
QtyToReserve := -PurchaseLine."Outstanding Qty. (Base)";
PurchaseLine."Document Type"::"Return Order",
PurchaseLine."Document Type"::"Credit Memo":
QtyToReserve := PurchaseLine."Outstanding Qty. (Base)";
end;
OnAfterReservQuantity(PurchaseLine, QtyToReserve);
end;
procedure Caption(PurchaseLine: Record "Purchase Line") CaptionText: Text
begin
CaptionText := PurchaseLine.GetSourceCaption();
end;
procedure FindReservEntry(PurchaseLine: Record "Purchase Line"; var ReservationEntry: Record "Reservation Entry"): Boolean
begin
ReservationEntry.InitSortingAndFilters(false);
PurchaseLine.SetReservationFilters(ReservationEntry);
exit(ReservationEntry.FindLast());
end;
procedure GetReservedQtyFromInventory(PurchaseLine: Record "Purchase Line"): Decimal
var
ReservationEntry: Record "Reservation Entry";
QtyReservedFromItemLedger: Query "Qty. Reserved From Item Ledger";
begin
PurchaseLine.SetReservationEntry(ReservationEntry);
QtyReservedFromItemLedger.SetSourceFilter(ReservationEntry);
QtyReservedFromItemLedger.Open();
if QtyReservedFromItemLedger.Read() then
exit(QtyReservedFromItemLedger.Quantity__Base_);
exit(0);
end;
procedure GetReservedQtyFromInventory(PurchaseHeader: Record "Purchase Header"): Decimal
var
ReservationEntry: Record "Reservation Entry";
QtyReservedFromItemLedger: Query "Qty. Reserved From Item Ledger";
begin
ReservationEntry.SetSource(Database::"Purchase Line", PurchaseHeader."Document Type".AsInteger(), PurchaseHeader."No.", 0, '', 0);
QtyReservedFromItemLedger.SetSourceFilter(ReservationEntry);
QtyReservedFromItemLedger.Open();
if QtyReservedFromItemLedger.Read() then
exit(QtyReservedFromItemLedger.Quantity__Base_);
exit(0);
end;
procedure ReservEntryExist(PurchaseLine: Record "Purchase Line"): Boolean
begin
exit(PurchaseLine.ReservEntryExist());
end;
procedure VerifyChange(var NewPurchaseLine: Record "Purchase Line"; var OldPurchaseLine: Record "Purchase Line")
var
PurchaseLine: Record "Purchase Line";
ShowError: Boolean;
HasError: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeVerifyChange(NewPurchaseLine, OldPurchaseLine, IsHandled);
if IsHandled then
exit;
if (NewPurchaseLine.Type <> NewPurchaseLine.Type::Item) and (OldPurchaseLine.Type <> OldPurchaseLine.Type::Item) then
exit;
if Blocked then
exit;
if NewPurchaseLine."Line No." = 0 then
if not PurchaseLine.Get(
NewPurchaseLine."Document Type",
NewPurchaseLine."Document No.",
NewPurchaseLine."Line No.")
then
exit;
NewPurchaseLine.CalcFields("Reserved Qty. (Base)");
ShowError := NewPurchaseLine."Reserved Qty. (Base)" <> 0;
if (NewPurchaseLine."Expected Receipt Date" = 0D) and (OldPurchaseLine."Expected Receipt Date" <> 0D) then
if ShowError then
NewPurchaseLine.FieldError("Expected Receipt Date", Text001Err)
else
HasError := true;
if NewPurchaseLine."Sales Order No." <> '' then
if ShowError then
NewPurchaseLine.FieldError("Sales Order No.", Text002Err)
else
HasError := NewPurchaseLine."Sales Order No." <> OldPurchaseLine."Sales Order No.";
if NewPurchaseLine."Sales Order Line No." <> 0 then
if ShowError then
NewPurchaseLine.FieldError(
"Sales Order Line No.", Text002Err)
else
HasError := NewPurchaseLine."Sales Order Line No." <> OldPurchaseLine."Sales Order Line No.";
if NewPurchaseLine."Drop Shipment" <> OldPurchaseLine."Drop Shipment" then
if ShowError and NewPurchaseLine."Drop Shipment" then
NewPurchaseLine.FieldError("Drop Shipment", Text002Err)
else
HasError := true;
if NewPurchaseLine."No." <> OldPurchaseLine."No." then
if ShowError then
NewPurchaseLine.FieldError("No.", Text003Err)
else
HasError := true;
IsHandled := false;
OnVerifyChangeOnBeforeTestVariantCode(NewPurchaseLine, OldPurchaseLine, IsHandled);
if not IsHandled then
if NewPurchaseLine."Variant Code" <> OldPurchaseLine."Variant Code" then
if ShowError then
NewPurchaseLine.FieldError("Variant Code", Text003Err)
else
HasError := true;
if NewPurchaseLine."Location Code" <> OldPurchaseLine."Location Code" then
if ShowError then
NewPurchaseLine.FieldError("Location Code", Text003Err)
else
HasError := true;
VerifyPurchLine(NewPurchaseLine, OldPurchaseLine, HasError);
OnVerifyChangeOnBeforeHasError(NewPurchaseLine, OldPurchaseLine, HasError, ShowError);
if HasError then
if (NewPurchaseLine."No." <> OldPurchaseLine."No.") or NewPurchaseLine.ReservEntryExist() then begin
if (NewPurchaseLine."No." <> OldPurchaseLine."No.") or (NewPurchaseLine.Type <> OldPurchaseLine.Type) then begin
ReservationManagement.SetReservSource(OldPurchaseLine);
ReservationManagement.DeleteReservEntries(true, 0);
ReservationManagement.SetReservSource(NewPurchaseLine);
end else begin
ReservationManagement.SetReservSource(NewPurchaseLine);
ReservationManagement.DeleteReservEntries(true, 0);
end;
ReservationManagement.AutoTrack(NewPurchaseLine."Outstanding Qty. (Base)");
end;
if HasError or (NewPurchaseLine."Expected Receipt Date" <> OldPurchaseLine."Expected Receipt Date") then begin
AssignForPlanning(NewPurchaseLine);
if (NewPurchaseLine."No." <> OldPurchaseLine."No.") or
(NewPurchaseLine."Variant Code" <> OldPurchaseLine."Variant Code") or
(NewPurchaseLine."Location Code" <> OldPurchaseLine."Location Code")
then
AssignForPlanning(OldPurchaseLine);
end;
end;
procedure VerifyQuantity(var NewPurchaseLine: Record "Purchase Line"; var OldPurchaseLine: Record "Purchase Line")
var
PurchaseLine: Record "Purchase Line";
IsHandled: Boolean;
begin
if Blocked then
exit;
IsHandled := false;
OnBeforeVerifyQuantity(NewPurchaseLine, IsHandled, OldPurchaseLine);
if IsHandled then
exit;
if NewPurchaseLine.Type <> NewPurchaseLine.Type::Item then
exit;
if NewPurchaseLine."Document Type" = OldPurchaseLine."Document Type" then
if NewPurchaseLine."Line No." = OldPurchaseLine."Line No." then
if NewPurchaseLine."Quantity (Base)" = OldPurchaseLine."Quantity (Base)" then
exit;
if NewPurchaseLine."Line No." = 0 then
if not PurchaseLine.Get(NewPurchaseLine."Document Type", NewPurchaseLine."Document No.", NewPurchaseLine."Line No.") then
exit;
ReservationManagement.SetReservSource(NewPurchaseLine);
if NewPurchaseLine."Qty. per Unit of Measure" <> OldPurchaseLine."Qty. per Unit of Measure" then
ReservationManagement.ModifyUnitOfMeasure();
if NewPurchaseLine."Outstanding Qty. (Base)" * OldPurchaseLine."Outstanding Qty. (Base)" < 0 then
ReservationManagement.DeleteReservEntries(true, 0)
else
ReservationManagement.DeleteReservEntries(false, NewPurchaseLine."Outstanding Qty. (Base)");
ReservationManagement.ClearSurplus();
ReservationManagement.AutoTrack(NewPurchaseLine."Outstanding Qty. (Base)");
AssignForPlanning(NewPurchaseLine);
end;
procedure UpdatePlanningFlexibility(var PurchaseLine: Record "Purchase Line")
var
ReservationEntry: Record "Reservation Entry";
begin
if FindReservEntry(PurchaseLine, ReservationEntry) then
ReservationEntry.ModifyAll("Planning Flexibility", PurchaseLine."Planning Flexibility");
end;
procedure TransferPurchLineToItemJnlLine(var PurchaseLine: Record "Purchase Line"; var ItemJournalLine: Record "Item Journal Line"; TransferQty: Decimal; var CheckApplToItemEntry: Boolean) Result: Decimal
var
OldReservationEntry: Record "Reservation Entry";
OppositeReservationEntry: Record "Reservation Entry";
ApplyToItemEntryNo: Integer;
NotFullyReserved: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeTransferPurchLineToItemJnlLine(PurchaseLine, ItemJournalLine, TransferQty, CheckApplToItemEntry, Result, IsHandled);
if IsHandled then
exit;
if not FindReservEntry(PurchaseLine, OldReservationEntry) then
exit(TransferQty);
OldReservationEntry.LockTable();
OldReservationEntry.FindLast();
// Handle Item Tracking on drop shipment:
Clear(CreateReservEntry);
if ApplySpecificItemTracking and (ItemJournalLine."Applies-to Entry" <> 0) then
CreateReservEntry.SetItemLedgEntryNo(ItemJournalLine."Applies-to Entry");
if OverruleItemTracking then
if ItemJournalLine.TrackingExists() then begin
CreateReservEntry.SetNewTrackingFromItemJnlLine(ItemJournalLine);
CreateReservEntry.SetOverruleItemTracking(true);
// Try to match against Item Tracking on the purchase order line:
OldReservationEntry.SetTrackingFilterFromItemJnlLine(ItemJournalLine);
if OldReservationEntry.IsEmpty() then
exit(TransferQty);
end;
ItemJournalLine.TestItemFields(PurchaseLine."No.", PurchaseLine."Variant Code", PurchaseLine."Location Code");
if TransferQty = 0 then
exit;
if ItemJournalLine."Invoiced Quantity" <> 0 then
CreateReservEntry.SetUseQtyToInvoice(true);
OnTransferPurchLineToItemJnlLineOnBeforeInitRecordSet(OldReservationEntry);
if ReservationEngineMgt.InitRecordSet(OldReservationEntry) then begin
repeat
OldReservationEntry.TestItemFields(PurchaseLine."No.", PurchaseLine."Variant Code", PurchaseLine."Location Code");
if CheckApplToItemEntry then begin
ApplyToItemEntryNo := OldReservationEntry."Appl.-to Item Entry";
if OldReservationEntry."Reservation Status" = OldReservationEntry."Reservation Status"::Reservation then begin
OppositeReservationEntry.Get(OldReservationEntry."Entry No.", not OldReservationEntry.Positive);
if OppositeReservationEntry."Source Type" <> Database::"Item Ledger Entry" then
NotFullyReserved := true
else
if ApplyToItemEntryNo = 0 then
ApplyToItemEntryNo := OppositeReservationEntry."Source Ref. No.";
end else
NotFullyReserved := true;
if OldReservationEntry."Item Tracking" <> OldReservationEntry."Item Tracking"::None then begin
if ApplyToItemEntryNo = 0 then
OldReservationEntry.TestField("Appl.-to Item Entry");
CreateReservEntry.SetApplyToEntryNo(ApplyToItemEntryNo);
CheckApplToItemEntry := false;
end;
end;
TransferPurchLineToItemJnlLineReservEntry(PurchaseLine, ItemJournalLine, OldReservationEntry, TransferQty);
until (ReservationEngineMgt.NEXTRecord(OldReservationEntry) = 0) or (TransferQty = 0);
CheckApplToItemEntry := CheckApplToItemEntry and NotFullyReserved;
end;
exit(TransferQty);
end;
local procedure TransferPurchLineToItemJnlLineReservEntry(PurchaseLine: Record "Purchase Line"; ItemJournalLine: Record "Item Journal Line"; OldReservationEntry: Record "Reservation Entry"; var TransferQty: Decimal);
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeTransferPurchLineToItemJnlLineReservEntry(OldReservationEntry, PurchaseLine, ItemJournalLine, TransferQty, IsHandled);
if IsHandled then
exit;
TransferQty :=
CreateReservEntry.TransferReservEntry(
Database::"Item Journal Line",
ItemJournalLine."Entry Type".AsInteger(), ItemJournalLine."Journal Template Name",
ItemJournalLine."Journal Batch Name", 0, ItemJournalLine."Line No.",
ItemJournalLine."Qty. per Unit of Measure", OldReservationEntry, TransferQty);
end;
procedure TransferPurchLineToPurchLine(var OldPurchaseLine: Record "Purchase Line"; var NewPurchaseLine: Record "Purchase Line"; TransferQty: Decimal)
var
OldReservationEntry: Record "Reservation Entry";
ReservStatus: Enum "Reservation Status";
begin
if not FindReservEntry(OldPurchaseLine, OldReservationEntry) then
exit;
OldReservationEntry.Lock();
NewPurchaseLine.TestItemFields(OldPurchaseLine."No.", OldPurchaseLine."Variant Code", OldPurchaseLine."Location Code");
for ReservStatus := ReservStatus::Reservation to ReservStatus::Prospect do begin
if TransferQty = 0 then
exit;
OldReservationEntry.SetRange("Reservation Status", ReservStatus);
OnTransferPurchLineToPurchLineOnAfterOldReservEntrySetFilters(OldPurchaseLine, NewPurchaseLine);
if OldReservationEntry.FindSet() then
repeat
OldReservationEntry.TestItemFields(OldPurchaseLine."No.", OldPurchaseLine."Variant Code", OldPurchaseLine."Location Code");
TransferQty :=
CreateReservEntry.TransferReservEntry(
Database::"Purchase Line",
NewPurchaseLine."Document Type".AsInteger(), NewPurchaseLine."Document No.", '', 0, NewPurchaseLine."Line No.",
NewPurchaseLine."Qty. per Unit of Measure", OldReservationEntry, TransferQty);
until (OldReservationEntry.Next() = 0) or (TransferQty = 0);
end; // DO
end;
procedure DeleteLineConfirm(var PurchaseLine: Record "Purchase Line"): Boolean
begin
if not PurchaseLine.ReservEntryExist() then
exit(true);
ReservationManagement.SetReservSource(PurchaseLine);
if ReservationManagement.DeleteItemTrackingConfirm() then
DeleteItemTracking := true;
exit(DeleteItemTracking);
end;
procedure DeleteLine(var PurchaseLine: Record "Purchase Line")
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeDeleteLine(PurchaseLine, IsHandled);
if IsHandled then
exit;
if Blocked then
exit;
ReservationManagement.SetReservSource(PurchaseLine);
if DeleteItemTracking then
ReservationManagement.SetItemTrackingHandling(1); // Allow Deletion
ReservationManagement.DeleteReservEntries(true, 0);
DeleteInvoiceSpecFromLine(PurchaseLine);
ReservationManagement.ClearActionMessageReferences();
PurchaseLine.CalcFields("Reserved Qty. (Base)");
AssignForPlanning(PurchaseLine);
end;
local procedure AssignForPlanning(var PurchaseLine: Record "Purchase Line")
var
PlanningAssignment: Record "Planning Assignment";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeAssignForPlanning(PurchaseLine, IsHandled);
if IsHandled then
exit;
if PurchaseLine."Document Type" <> PurchaseLine."Document Type"::Order then
exit;
if PurchaseLine.Type <> PurchaseLine.Type::Item then
exit;
if PurchaseLine."No." <> '' then
PlanningAssignment.ChkAssignOne(PurchaseLine."No.", PurchaseLine."Variant Code", PurchaseLine."Location Code", WorkDate());
end;
procedure Block(SetBlocked: Boolean)
begin
Blocked := SetBlocked;
end;
procedure CallItemTracking(var PurchaseLine: Record "Purchase Line")
var
TrackingSpecification: Record "Tracking Specification";
ItemTrackingLines: Page "Item Tracking Lines";
ShouldProcessDropShipment: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCallItemTracking(PurchaseLine, IsHandled);
if not IsHandled then begin
InitFromPurchLine(TrackingSpecification, PurchaseLine);
if ((PurchaseLine."Document Type" = PurchaseLine."Document Type"::Invoice) and
PurchaseLine.IsMatchedToReceiptOrOrder()) or
((PurchaseLine."Document Type" = PurchaseLine."Document Type"::"Credit Memo") and
(PurchaseLine."Return Shipment No." <> ''))
then
ItemTrackingLines.SetRunMode(Enum::"Item Tracking Run Mode"::"Combined Ship/Rcpt");
ShouldProcessDropShipment := PurchaseLine."Drop Shipment";
OnCallItemTrackingOnAfterCalcShouldProcessDropShipment(PurchaseLine, ShouldProcessDropShipment, ItemTrackingLines);
if ShouldProcessDropShipment then begin
ItemTrackingLines.SetRunMode(Enum::"Item Tracking Run Mode"::"Drop Shipment");
if PurchaseLine."Sales Order No." <> '' then
ItemTrackingLines.SetSecondSourceRowID(
ItemTrackingManagement.ComposeRowID(
Database::"Sales Line", 1, PurchaseLine."Sales Order No.", '', 0, PurchaseLine."Sales Order Line No."));
end;
ItemTrackingLines.SetSourceSpec(TrackingSpecification, PurchaseLine."Expected Receipt Date");
ItemTrackingLines.SetInbound(PurchaseLine.IsInbound());
OnCallItemTrackingOnBeforeItemTrackingFormRunModal(PurchaseLine, ItemTrackingLines);
RunItemTrackingLinesPage(ItemTrackingLines);
end;
end;
procedure CallItemTracking(var PurchaseLine: Record "Purchase Line"; SecondSourceQuantityArray: array[3] of Decimal)
var
TrackingSpecification: Record "Tracking Specification";
ItemTrackingLines: Page "Item Tracking Lines";
begin
InitFromPurchLine(TrackingSpecification, PurchaseLine);
ItemTrackingLines.SetSourceSpec(TrackingSpecification, PurchaseLine."Expected Receipt Date");
ItemTrackingLines.SetSecondSourceQuantity(SecondSourceQuantityArray);
OnCallItemTrackingOnBeforeItemTrackingFormRunModal(PurchaseLine, ItemTrackingLines);
RunItemTrackingLinesPage(ItemTrackingLines);
end;
procedure CallItemTracking(var PurchaseLine: Record "Purchase Line"; ItemLedgerEntryFilter: Text)
var
TrackingSpecification: Record "Tracking Specification";
ItemTrackingLines: Page "Item Tracking Lines";
ShouldProcessDropShipment: Boolean;
begin
InitFromPurchLine(TrackingSpecification, PurchaseLine);
ItemTrackingLines.SetRunMode(Enum::"Item Tracking Run Mode"::"Combined Ship/Rcpt");
ShouldProcessDropShipment := PurchaseLine."Drop Shipment";
if ShouldProcessDropShipment then begin
ItemTrackingLines.SetRunMode(Enum::"Item Tracking Run Mode"::"Drop Shipment");
if PurchaseLine."Sales Order No." <> '' then
ItemTrackingLines.SetSecondSourceRowID(
ItemTrackingManagement.ComposeRowID(
Database::"Sales Line", 1, PurchaseLine."Sales Order No.", '', 0, PurchaseLine."Sales Order Line No."));
end;
ItemTrackingLines.SetItemLedgerEntryFilter(ItemLedgerEntryFilter);
ItemTrackingLines.SetSourceSpec(TrackingSpecification, PurchaseLine."Expected Receipt Date");
ItemTrackingLines.SetInbound(PurchaseLine.IsInbound());
RunItemTrackingLinesPage(ItemTrackingLines);
end;
local procedure RunItemTrackingLinesPage(var ItemTrackingLines: Page "Item Tracking Lines")
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeRunItemTrackingLinesPage(ItemTrackingLines, IsHandled);
if IsHandled then
exit;
ItemTrackingLines.RunModal();
end;
procedure RetrieveInvoiceSpecification(var PurchaseLine: Record "Purchase Line"; var TempInvoicingTrackingSpecification: Record "Tracking Specification" temporary) OK: Boolean
var
SourceTrackingSpecification: Record "Tracking Specification";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeRetrieveInvoiceSpecification(PurchaseLine, IsHandled, OK, TempInvoicingTrackingSpecification);
if IsHandled then
exit;
Clear(TempInvoicingTrackingSpecification);
if PurchaseLine.Type <> PurchaseLine.Type::Item then
exit;
if ((PurchaseLine."Document Type" = PurchaseLine."Document Type"::Invoice) and
PurchaseLine.IsMatchedToReceiptOrOrder()) or
((PurchaseLine."Document Type" = PurchaseLine."Document Type"::"Credit Memo") and
(PurchaseLine."Return Shipment No." <> ''))
then
OK := RetrieveInvoiceSpecification2(PurchaseLine, TempInvoicingTrackingSpecification)
else begin
InitFromPurchLine(SourceTrackingSpecification, PurchaseLine);
OK := ItemTrackingManagement.RetrieveInvoiceSpecification(SourceTrackingSpecification, TempInvoicingTrackingSpecification);
end;
end;
procedure RetrieveInvoiceSpecification2(var PurchaseLine: Record "Purchase Line"; var TempInvoicingTrackingSpecification: Record "Tracking Specification" temporary) OK: Boolean
var
TrackingSpecification: Record "Tracking Specification";
ReservationEntry: Record "Reservation Entry";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeRetrieveInvoiceSpecification2(PurchaseLine, IsHandled);
if IsHandled then
exit;
// Used for combined receipt/return:
if PurchaseLine.Type <> PurchaseLine.Type::Item then
exit;
if not FindReservEntry(PurchaseLine, ReservationEntry) then
exit;
ReservationEntry.FindSet();
repeat
ReservationEntry.TestField("Reservation Status", ReservationEntry."Reservation Status"::Prospect);
ReservationEntry.TestField("Item Ledger Entry No.");
TrackingSpecification.Get(ReservationEntry."Item Ledger Entry No.");
TempInvoicingTrackingSpecification := TrackingSpecification;
TempInvoicingTrackingSpecification."Qty. to Invoice (Base)" := ReservationEntry."Qty. to Invoice (Base)";
TempInvoicingTrackingSpecification."Qty. to Invoice" :=
Round(ReservationEntry."Qty. to Invoice (Base)" / ReservationEntry."Qty. per Unit of Measure", UnitOfMeasureManagement.QtyRndPrecision());
TempInvoicingTrackingSpecification."Buffer Status" := TempInvoicingTrackingSpecification."Buffer Status"::MODIFY;
OnRetrieveInvoiceSpecification2OnBeforeInsert(TempInvoicingTrackingSpecification, ReservationEntry);
TempInvoicingTrackingSpecification.Insert();
ReservationEntry.Delete();
until ReservationEntry.Next() = 0;
OK := TempInvoicingTrackingSpecification.FindFirst();
end;
procedure DeleteInvoiceSpecFromHeader(PurchaseHeader: Record "Purchase Header")
begin
ItemTrackingManagement.DeleteInvoiceSpecFromHeader(
Database::"Purchase Line", PurchaseHeader."Document Type".AsInteger(), PurchaseHeader."No.");
end;
procedure DeleteInvoiceSpecFromLine(PurchaseLine: Record "Purchase Line")
begin
ItemTrackingManagement.DeleteInvoiceSpecFromLine(
Database::"Purchase Line", PurchaseLine."Document Type".AsInteger(), PurchaseLine."Document No.", PurchaseLine."Line No.");
end;
procedure UpdateItemTrackingAfterPosting(PurchaseHeader: Record "Purchase Header")
var
ReservationEntry: Record "Reservation Entry";
begin
// Used for updating Quantity to Handle and Quantity to Invoice after posting
ReservationEntry.SetSourceFilter(Database::"Purchase Line", PurchaseHeader."Document Type".AsInteger(), PurchaseHeader."No.", -1, true);
ReservationEntry.SetSourceFilter('', 0);
CreateReservEntry.UpdateItemTrackingAfterPosting(ReservationEntry);
OnAfterUpdateItemTrackingAfterPosting(PurchaseHeader);
end;
procedure SetApplySpecificItemTracking(ApplySpecific: Boolean)
begin
ApplySpecificItemTracking := ApplySpecific;
end;
procedure SetOverruleItemTracking(Overrule: Boolean)
begin
OverruleItemTracking := Overrule;
end;
local procedure VerifyPurchLine(var NewPurchaseLine: Record "Purchase Line"; var OldPurchaseLine: Record "Purchase Line"; var HasError: Boolean)
begin
if (NewPurchaseLine.Type = NewPurchaseLine.Type::Item) and (OldPurchaseLine.Type = OldPurchaseLine.Type::Item) then
if (NewPurchaseLine."Bin Code" <> OldPurchaseLine."Bin Code") and
(not ReservationManagement.CalcIsAvailTrackedQtyInBin(
NewPurchaseLine."No.", NewPurchaseLine."Bin Code",
NewPurchaseLine."Location Code", NewPurchaseLine."Variant Code",
Database::"Purchase Line", NewPurchaseLine."Document Type".AsInteger(),
NewPurchaseLine."Document No.", '', 0, NewPurchaseLine."Line No."))
then
HasError := true;
if NewPurchaseLine."Line No." <> OldPurchaseLine."Line No." then
HasError := true;
if NewPurchaseLine.Type <> OldPurchaseLine.Type then
HasError := true;
end;
[EventSubscriber(ObjectType::Page, PAGE::Reservation, 'OnGetQtyPerUOMFromSourceRecRef', '', false, false)]
local procedure OnGetQtyPerUOMFromSourceRecRef(SourceRecRef: RecordRef; var QtyPerUOM: Decimal; var QtyReserved: Decimal; var QtyReservedBase: Decimal; var QtyToReserve: Decimal; var QtyToReserveBase: Decimal)
var
PurchaseLine: Record "Purchase Line";
begin
if MatchThisTable(SourceRecRef.Number) then begin
SourceRecRef.SetTable(PurchaseLine);
PurchaseLine.Find();
QtyPerUOM := PurchaseLine.GetReservationQty(QtyReserved, QtyReservedBase, QtyToReserve, QtyToReserveBase);
end;
end;
local procedure SetReservSourceFor(SourceRecordRef: RecordRef; var ReservationEntry: Record "Reservation Entry"; var CaptionText: Text)
var
PurchaseLine: Record "Purchase Line";
begin
SourceRecordRef.SetTable(PurchaseLine);
PurchaseLine.TestField("Job No.", '');
PurchaseLine.TestField("Drop Shipment", false);
PurchaseLine.TestField(Type, PurchaseLine.Type::Item);
PurchaseLine.TestField("Expected Receipt Date");
PurchaseLine.SetReservationEntry(ReservationEntry);
CaptionText := PurchaseLine.GetSourceCaption();
end;
local procedure EntryStartNo(): Integer
begin
exit(Enum::"Reservation Summary Type"::"Purchase Quote".AsInteger());
end;
local procedure MatchThisEntry(EntryNo: Integer): Boolean
begin
exit(EntryNo in [Enum::"Reservation Summary Type"::"Purchase Quote".AsInteger() ..
Enum::"Reservation Summary Type"::"Purchase Return Order".AsInteger()]);
end;
local procedure MatchThisTable(TableID: Integer): Boolean
begin
exit(TableID = Database::"Purchase Line");
end;
[EventSubscriber(ObjectType::Page, Page::Reservation, 'OnSetReservSource', '', false, false)]
local procedure ReservationOnSetReservSource(SourceRecRef: RecordRef; var ReservEntry: Record "Reservation Entry"; var CaptionText: Text)
begin
if MatchThisTable(SourceRecRef.Number) then
SetReservSourceFor(SourceRecRef, ReservEntry, CaptionText);
end;
[EventSubscriber(ObjectType::Page, Page::Reservation, 'OnDrillDownTotalQuantity', '', false, false)]
local procedure ReservationOnDrillDownTotalQuantity(SourceRecRef: RecordRef; ReservEntry: Record "Reservation Entry"; EntrySummary: Record "Entry Summary"; Location: Record Location; MaxQtyToReserve: Decimal)
var
AvailablePurchaseLines: page "Available - Purchase Lines";
begin
if MatchThisEntry(EntrySummary."Entry No.") then begin
Clear(AvailablePurchaseLines);
AvailablePurchaseLines.SetCurrentSubType(EntrySummary."Entry No." - EntryStartNo());
AvailablePurchaseLines.SetSource(SourceRecRef, ReservEntry, ReservEntry.GetTransferDirection());
AvailablePurchaseLines.RunModal();
end;
end;
[EventSubscriber(ObjectType::Page, Page::Reservation, 'OnFilterReservEntry', '', false, false)]
local procedure ReservationOnFilterReservEntry(var FilterReservEntry: Record "Reservation Entry"; ReservEntrySummary: Record "Entry Summary")
begin
if MatchThisEntry(ReservEntrySummary."Entry No.") then begin
FilterReservEntry.SetRange("Source Type", Database::"Purchase Line");
FilterReservEntry.SetRange("Source Subtype", ReservEntrySummary."Entry No." - EntryStartNo());
end;
end;
[EventSubscriber(ObjectType::Page, Page::Reservation, 'OnAfterRelatesToSummEntry', '', false, false)]
local procedure ReservationOnRelatesToEntrySummary(var FilterReservEntry: Record "Reservation Entry"; FromEntrySummary: Record "Entry Summary"; var IsHandled: Boolean)
begin
if MatchThisEntry(FromEntrySummary."Entry No.") then
IsHandled :=
(FilterReservEntry."Source Type" = Database::"Purchase Line") and
(FilterReservEntry."Source Subtype" = FromEntrySummary."Entry No." - EntryStartNo());
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Item Ledger Entry-Reserve", 'OnDrillDownTotalQuantity', '', false, false)]
local procedure ItemLedgerEntryOnDrillDownTotalQuantity(SourceRecRef: RecordRef; EntrySummary: Record "Entry Summary" temporary; ReservEntry: Record "Reservation Entry"; Location: Record Location; MaxQtyToReserve: Decimal; var IsHandled: Boolean; sender: Codeunit "Item Ledger Entry-Reserve")
var
PurchaseLine: Record "Purchase Line";
CheckOutbound: Boolean;
begin
if MatchThisTable(ReservEntry."Source Type") then begin
SourceRecRef.SetTable(PurchaseLine);
CheckOutbound := Location."Bin Mandatory" or Location."Require Pick" and (PurchaseLine."Document Type" = PurchaseLine."Document Type"::"Return Order");
sender.DrillDownTotalQuantity(SourceRecRef, EntrySummary, ReservEntry, MaxQtyToReserve, CheckOutbound, false);
IsHandled := true;
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnCreateReservation', '', false, false)]
local procedure OnCreateReservation(SourceRecRef: RecordRef; TrackingSpecification: Record "Tracking Specification"; ForReservEntry: Record "Reservation Entry"; Description: Text[100]; ExpectedDate: Date; Quantity: Decimal; QuantityBase: Decimal)
var
PurchaseLine: Record "Purchase Line";
begin
if MatchThisTable(ForReservEntry."Source Type") then begin
CreateReservationSetFrom(TrackingSpecification);
SourceRecRef.SetTable(PurchaseLine);
CreateReservation(PurchaseLine, Description, ExpectedDate, Quantity, QuantityBase, ForReservEntry);
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnLookupDocument', '', false, false)]
local procedure OnLookupDocument(SourceType: Integer; SourceSubtype: Integer; SourceID: Code[20]; SourceRefNo: Integer)
var
PurchHeader: Record "Purchase Header";
begin
if MatchThisTable(SourceType) then begin
PurchHeader.Reset();
PurchHeader.SetRange("Document Type", SourceSubtype);
PurchHeader.SetRange("No.", SourceID);
case SourceSubtype of
0:
PAGE.RunModal(PAGE::"Purchase Quote", PurchHeader);
1:
PAGE.RunModal(PAGE::"Purchase Order", PurchHeader);
2:
PAGE.RunModal(PAGE::"Purchase Invoice", PurchHeader);
3:
PAGE.RunModal(PAGE::"Purchase Credit Memo", PurchHeader);
5:
PAGE.RunModal(PAGE::"Purchase Return Order", PurchHeader);
end;
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnLookupLine', '', false, false)]
local procedure OnLookupLine(SourceType: Integer; SourceSubtype: Integer; SourceID: Code[20]; SourceRefNo: Integer)
var
PurchaseLine: Record "Purchase Line";
begin
if MatchThisTable(SourceType) then begin
PurchaseLine.Reset();
PurchaseLine.SetRange("Document Type", SourceSubtype);
PurchaseLine.SetRange("Document No.", SourceID);
PurchaseLine.SetRange("Line No.", SourceRefNo);
PAGE.Run(PAGE::"Purchase Lines", PurchaseLine);
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnFilterReservFor', '', false, false)]
local procedure OnFilterReservFor(SourceRecRef: RecordRef; var ReservEntry: Record "Reservation Entry"; var CaptionText: Text)
var
PurchaseLine: Record "Purchase Line";
begin
if MatchThisTable(SourceRecRef.Number) then begin
SourceRecRef.SetTable(PurchaseLine);
PurchaseLine.SetReservationFilters(ReservEntry);
CaptionText := PurchaseLine.GetSourceCaption();
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnCalculateRemainingQty', '', false, false)]
local procedure OnCalculateRemainingQty(SourceRecRef: RecordRef; var ReservEntry: Record "Reservation Entry"; var RemainingQty: Decimal; var RemainingQtyBase: Decimal)
var
PurchaseLine: Record "Purchase Line";
begin
if MatchThisTable(ReservEntry."Source Type") then begin
SourceRecRef.SetTable(PurchaseLine);
PurchaseLine.GetRemainingQty(RemainingQty, RemainingQtyBase);
end;
end;
local procedure GetSourceValue(ReservationEntry: Record "Reservation Entry"; var SourceRecordRef: RecordRef; ReturnOption: Option "Net Qty. (Base)","Gross Qty. (Base)"): Decimal
var
PurchaseLine: Record "Purchase Line";
begin
PurchaseLine.Get(ReservationEntry."Source Subtype", ReservationEntry."Source ID", ReservationEntry."Source Ref. No.");
SourceRecordRef.GetTable(PurchaseLine);
case ReturnOption of
ReturnOption::"Net Qty. (Base)":
exit(PurchaseLine."Outstanding Qty. (Base)");
ReturnOption::"Gross Qty. (Base)":
exit(PurchaseLine."Quantity (Base)");
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnGetSourceRecordValue', '', false, false)]
local procedure OnGetSourceRecordValue(var ReservEntry: Record "Reservation Entry"; ReturnOption: Option; var ReturnQty: Decimal; var SourceRecRef: RecordRef)
begin
if MatchThisTable(ReservEntry."Source Type") then
ReturnQty := GetSourceValue(ReservEntry, SourceRecRef, ReturnOption);
end;
[IntegrationEvent(false, false)]
local procedure OnVerifyChangeOnBeforeHasError(NewPurchLine: Record "Purchase Line"; OldPurchLine: Record "Purchase Line"; var HasError: Boolean; var ShowError: Boolean)
begin
end;
local procedure UpdateStatistics(ReservationEntry: Record "Reservation Entry"; var TempEntrySummary: Record "Entry Summary" temporary; AvailabilityDate: Date; DocumentType: Enum "Purchase Document Type"; Positive: Boolean; var TotalQuantity: Decimal)
var
PurchaseLine: Record "Purchase Line";
AvailabilityFilter: Text;
begin
if not PurchaseLine.ReadPermission then
exit;
PurchaseLine.SetAutoCalcFields("Reserved Qty. (Base)");
AvailabilityFilter := ReservationEntry.GetAvailabilityFilter(AvailabilityDate, Positive);
PurchaseLine.FilterLinesForReservation(ReservationEntry, DocumentType, AvailabilityFilter, Positive);
if PurchaseLine.FindSet() then
repeat
OnUpdateStatisticsOnBeforeCheckSpecialOrder(PurchaseLine);
if not PurchaseLine."Special Order" then begin
TempEntrySummary."Total Reserved Quantity" += PurchaseLine."Reserved Qty. (Base)";
TotalQuantity += PurchaseLine."Outstanding Qty. (Base)";
end;
until PurchaseLine.Next() = 0;
if TotalQuantity = 0 then
exit;
if (Positive = (TotalQuantity > 0)) and (DocumentType <> PurchaseLine."Document Type"::"Return Order") or
(Positive = (TotalQuantity < 0)) and (DocumentType = PurchaseLine."Document Type"::"Return Order")
then begin
TempEntrySummary."Table ID" := Database::"Purchase Line";
TempEntrySummary."Summary Type" :=
CopyStr(StrSubstNo(SummaryTypeTxt, PurchaseLine.TableCaption(), PurchaseLine."Document Type"), 1, MaxStrLen(TempEntrySummary."Summary Type"));
if DocumentType = PurchaseLine."Document Type"::"Return Order" then
TempEntrySummary."Total Quantity" := -TotalQuantity
else
TempEntrySummary."Total Quantity" := TotalQuantity;
TempEntrySummary."Total Available Quantity" := TempEntrySummary."Total Quantity" - TempEntrySummary."Total Reserved Quantity";
if not TempEntrySummary.Insert() then
TempEntrySummary.Modify();
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnUpdateStatistics', '', false, false)]
local procedure OnUpdateStatistics(CalcReservEntry: Record "Reservation Entry"; var ReservSummEntry: Record "Entry Summary"; AvailabilityDate: Date; Positive: Boolean; var TotalQuantity: Decimal)
begin
if ReservSummEntry."Entry No." in [Enum::"Reservation Summary Type"::"Purchase Order".AsInteger(),
Enum::"Reservation Summary Type"::"Purchase Return Order".AsInteger()]
then
UpdateStatistics(
CalcReservEntry, ReservSummEntry, AvailabilityDate, Enum::"Purchase Document Type".FromInteger(ReservSummEntry."Entry No." - 11), Positive, TotalQuantity);
end;
[EventSubscriber(ObjectType::Page, Page::"Reservation Entries", 'OnLookupReserved', '', false, false)]
local procedure OnLookupReserved(var ReservationEntry: Record "Reservation Entry")
begin
if MatchThisTable(ReservationEntry."Source Type") then
ShowSourceLines(ReservationEntry);
end;
local procedure ShowSourceLines(var ReservationEntry: Record "Reservation Entry")
var
PurchaseLine: Record "Purchase Line";
begin
PurchaseLine.Reset();
PurchaseLine.SetRange("Document Type", ReservationEntry."Source Subtype");
PurchaseLine.SetRange("Document No.", ReservationEntry."Source ID");
PurchaseLine.SetRange("Line No.", ReservationEntry."Source Ref. No.");
PAGE.RunModal(PAGE::"Purchase Lines", PurchaseLine);
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnAfterAutoReserveOneLine', '', false, 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; var sender: Codeunit "Reservation Management")
begin
if MatchThisEntry(ReservSummEntryNo) then
AutoReservePurchLine(
CalcReservEntry, sender, ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase,
Description, AvailabilityDate, Search, NextStep, Positive);
end;
local procedure AutoReservePurchLine(var CalcReservEntry: Record "Reservation Entry"; var sender: Codeunit "Reservation Management"; ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date; Search: Text[1]; NextStep: Integer; Positive: Boolean)
var
CallTrackingSpecification: Record "Tracking Specification";
PurchLine: Record "Purchase Line";
QtyThisLine: Decimal;
QtyThisLineBase: Decimal;
ReservQty: Decimal;
IsReserved: Boolean;
begin
IsReserved := false;
OnBeforeAutoReservePurchLine(
ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate, IsReserved, Search, NextStep, CalcReservEntry);
if IsReserved then
exit;
PurchLine.SetAutoCalcFields("Reserved Qty. (Base)");
PurchLine.FilterLinesForReservation(
CalcReservEntry, Enum::"Purchase Document Type".FromInteger(ReservSummEntryNo - Enum::"Reservation Summary Type"::"Purchase Quote".AsInteger()),
sender.GetAvailabilityFilter(AvailabilityDate), Positive);
if PurchLine.Find(Search) then
repeat
if not PurchLine."Special Order" then begin
QtyThisLine := PurchLine."Outstanding Quantity";
QtyThisLineBase := PurchLine."Outstanding Qty. (Base)";
end;
if ReservSummEntryNo = Enum::"Reservation Summary Type"::"Purchase Return Order".AsInteger() then
ReservQty := -PurchLine."Reserved Qty. (Base)"
else
ReservQty := PurchLine."Reserved Qty. (Base)";
if (Positive = (QtyThisLineBase < 0)) and (ReservSummEntryNo <> Enum::"Reservation Summary Type"::"Purchase Return Order".AsInteger()) or
(Positive = (QtyThisLineBase > 0)) and (ReservSummEntryNo = Enum::"Reservation Summary Type"::"Purchase Return Order".AsInteger())
then begin
QtyThisLine := 0;
QtyThisLineBase := 0;
end;
OnAutoReservePurchLineOnBeforeSetQtyToReserveDownToTrackedQuantity(
PurchLine, CalcReservEntry, ReservQty, QtyThisLine, QtyThisLineBase);
sender.SetQtyToReserveDownToTrackedQuantity(CalcReservEntry, PurchLine.RowID1(), QtyThisLine, QtyThisLineBase);
CallTrackingSpecification.InitTrackingSpecification(
Database::"Purchase Line", PurchLine."Document Type".AsInteger(), PurchLine."Document No.", '', 0, PurchLine."Line No.",
PurchLine."Variant Code", PurchLine."Location Code", PurchLine."Qty. per Unit of Measure");
CallTrackingSpecification.CopyTrackingFromReservEntry(CalcReservEntry);
sender.InsertReservationEntries(
RemainingQtyToReserve, RemainingQtyToReserveBase, ReservQty,
Description, PurchLine."Expected Receipt Date", QtyThisLine, QtyThisLineBase, CallTrackingSpecification);
until (PurchLine.Next(NextStep) = 0) or (RemainingQtyToReserveBase = 0);
OnAfterAutoReservePurchLine(PurchLine, ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase, Description, AvailabilityDate);
end;
[IntegrationEvent(false, false)]
local procedure OnAfterUpdateItemTrackingAfterPosting(var PurchHeader: Record "Purchase Header")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCreateReservation(var PurchLine: Record "Purchase Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeDeleteLine(var PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeTransferPurchLineToItemJnlLine(var PurchaseLine: Record "Purchase Line"; var ItemJournalLine: Record "Item Journal Line"; TransferQty: Decimal; var CheckApplToItemEntry: Boolean; var Result: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeTransferPurchLineToItemJnlLineReservEntry(var OldReservEntry: Record "Reservation Entry"; PurchLine: Record "Purchase Line"; ItemJnlLine: Record "Item Journal Line"; var TransferQty: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRunItemTrackingLinesPage(var ItemTrackingLines: Page "Item Tracking Lines"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeVerifyQuantity(PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean; OldPurchaseLine: Record "Purchase Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferPurchLineToPurchLineOnAfterOldReservEntrySetFilters(var OldPurchLine: record "Purchase Line"; var NewPurchLine: Record "Purchase Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransferPurchLineToItemJnlLineOnBeforeInitRecordSet(var OldReservationEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnVerifyChangeOnBeforeTestVariantCode(var NewPurchaseLine: Record "Purchase Line"; var OldPurchaseLine: Record "Purchase Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCallItemTrackingOnBeforeItemTrackingFormRunModal(var PurchLine: Record "Purchase Line"; var ItemTrackingForm: Page "Item Tracking Lines")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnRetrieveInvoiceSpecification2OnBeforeInsert(var TempInvoicingSpecification: Record "Tracking Specification" temporary; ReservEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateStatisticsOnBeforeCheckSpecialOrder(var PurchLine: Record "Purchase Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAssignForPlanning(PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeRetrieveInvoiceSpecification(PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean; var OK: Boolean; var TempInvoicingSpecification: Record "Tracking Specification" temporary)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeRetrieveInvoiceSpecification2(PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateReservationOnBeforeCreateReservEntry(var PurchLine: Record "Purchase Line"; var Quantity: Decimal; var QuantityBase: Decimal; var ForReservEntry: Record "Reservation Entry"; var IsHandled: Boolean; var FromTrackingSpecification: Record "Tracking Specification"; ExpectedReceiptDate: Date; var Description: Text[100]; ShipmentDate: Date)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCallItemTrackingOnAfterCalcShouldProcessDropShipment(var PurchLine: Record "Purchase Line"; var ShouldProcessDropShipment: Boolean; var ItemTrackingLinesPage: Page "Item Tracking Lines")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCreateReservation(var PurchaseLine: Record "Purchase Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCallItemTracking(var PurchaseLine: Record "Purchase Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterReservQuantity(PurchaseLine: Record "Purchase Line"; var QtyToReserve: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeVerifyChange(var NewPurchaseLine: Record "Purchase Line"; var OldPurchaseLine: Record "Purchase Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAutoReservePurchLine(ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date; var IsReserved: Boolean; var Search: Text[1]; var NextStep: Integer; CalcReservEntry: Record "Reservation Entry")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAutoReservePurchLineOnBeforeSetQtyToReserveDownToTrackedQuantity(PurchLine: Record "Purchase Line"; CalcReservEntry: Record "Reservation Entry"; var ReservQty: Decimal; var QtyThisLine: Decimal; var QtyThisLineBase: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterAutoReservePurchLine(var PurchLine: Record "Purchase Line"; ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date)
begin
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnAutoReserveOnBeforeStopReservation', '', false, false)]
local procedure OnAutoReserveOnBeforeStopReservation(var CalcReservEntry: Record "Reservation Entry"; var StopReservation: Boolean; SourceRecRef: RecordRef);
begin
if MatchThisTable(CalcReservEntry."Source Type") then
StopReservation := not (CalcReservEntry."Source Subtype" in [1, 5]); // Only order and return order
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnAutoTrackOnCheckSourceType', '', false, false)]
local procedure OnAutoTrackOnCheckSourceType(var ReservationEntry: Record "Reservation Entry"; var ShouldExit: Boolean)
begin
if ReservationEntry."Source Type" = Database::"Purchase Line" then
if not (ReservationEntry."Source Subtype" in [1, 5]) then
ShouldExit := true; // Only order, return order
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnTestItemType', '', false, false)]
local procedure OnTestItemType(SourceRecRef: RecordRef)
var
PurchaseLine: Record "Purchase Line";
begin
if SourceRecRef.Number = Database::"Purchase Line" then begin
SourceRecRef.SetTable(PurchaseLine);
PurchaseLine.TestField(Type, PurchaseLine.Type::Item);
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnIssueActionMessageOnSetSourceTypeFromSKU', '', false, false)]
local procedure OnIssueActionMessageOnSetSourceTypeFromSKU(var ActionMessageEntry: Record "Action Message Entry"; SKU: Record "Stockkeeping Unit")
begin
if SKU."Replenishment System" = SKU."Replenishment System"::Purchase then
ActionMessageEntry."Source Type" := Database::"Purchase Line";
end;
#if not CLEAN27
[Obsolete('This event is never raised.', '27.0')]
[IntegrationEvent(false, false)]
local procedure OnSetSourceForReservationOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; PurchLine: Record "Purchase Line")
begin
end;
#endif
// codeunit Create Reserv. Entry
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Create Reserv. Entry", 'OnCheckSourceTypeSubtype', '', false, false)]
local procedure CheckSourceTypeSubtype(var ReservationEntry: Record "Reservation Entry"; var IsError: Boolean)
begin
if MatchThisTable(ReservationEntry."Source Type") then
IsError := not (ReservationEntry."Source Subtype" in [1, 5]);
end;
// codeunit Reservation Engine Mgt. subscribers
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Engine Mgt.", 'OnRevertDateToSourceDate', '', false, false)]
local procedure OnRevertDateToSourceDate(var ReservEntry: Record "Reservation Entry")
var
PurchaseLine: Record "Purchase Line";
begin
if ReservEntry."Source Type" = Database::"Purchase Line" then begin
PurchaseLine.Get(ReservEntry."Source Subtype", ReservEntry."Source ID", ReservEntry."Source Ref. No.");
if ReservEntry.Positive then begin
ReservEntry."Expected Receipt Date" := PurchaseLine."Expected Receipt Date";
ReservEntry."Shipment Date" := 0D;
end else
ReservEntry."Expected Receipt Date" := 0D;
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Engine Mgt.", 'OnGetActivePointerFieldsOnBeforeAssignArrayValues', '', false, false)]
local procedure OnGetActivePointerFieldsOnBeforeAssignArrayValues(TableID: Integer; var PointerFieldIsActive: array[6] of Boolean; var IsHandled: Boolean)
begin
if TableID = Database::"Purchase Line" then begin
PointerFieldIsActive[1] := true; // Type
PointerFieldIsActive[2] := true; // SubType
PointerFieldIsActive[3] := true; // ID
PointerFieldIsActive[6] := true; // RefNo
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Engine Mgt.", 'OnCreateText', '', false, false)]
local procedure OnAfterCreateText(ReservationEntry: Record "Reservation Entry"; var Description: Text[80])
begin
if ReservationEntry."Source Type" = Database::"Purchase Line" then
Description :=
StrSubstNo(
SourceDoc3Txt, PurchaseTxt,
Enum::"Purchase Document Type".FromInteger(ReservationEntry."Source Subtype"), ReservationEntry."Source ID");
end;
procedure InitFromPurchLine(var TransactionSpecification: Record "Tracking Specification"; PurchLine: Record "Purchase Line")
begin
TransactionSpecification.Init();
TransactionSpecification.SetItemData(
PurchLine."No.", PurchLine.Description, PurchLine."Location Code", PurchLine."Variant Code", PurchLine."Bin Code",
PurchLine."Qty. per Unit of Measure", PurchLine."Qty. Rounding Precision (Base)");
TransactionSpecification.SetSource(
Database::"Purchase Line", PurchLine."Document Type".AsInteger(), PurchLine."Document No.", PurchLine."Line No.", '', 0);
if PurchLine.IsCreditDocType() then
TransactionSpecification.SetQuantities(
PurchLine."Quantity (Base)", PurchLine."Return Qty. to Ship", PurchLine."Return Qty. to Ship (Base)",
PurchLine."Qty. to Invoice", PurchLine."Qty. to Invoice (Base)", PurchLine."Return Qty. Shipped (Base)",
PurchLine."Qty. Invoiced (Base)")
else
TransactionSpecification.SetQuantities(
PurchLine."Quantity (Base)", PurchLine."Qty. to Receive", PurchLine."Qty. to Receive (Base)",
PurchLine."Qty. to Invoice", PurchLine."Qty. to Invoice (Base)", PurchLine."Qty. Received (Base)",
PurchLine."Qty. Invoiced (Base)");
OnAfterInitFromPurchLine(TransactionSpecification, PurchLine);
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInitFromPurchLine(var TrackingSpecification: Record "Tracking Specification"; PurchaseLine: Record "Purchase Line")
begin
end;
[EventSubscriber(ObjectType::Table, Database::"Reservation Entry", 'OnAfterSummEntryNo', '', false, false)]
local procedure OnBeforeSummEntryNo(ReservationEntry: Record "Reservation Entry"; var ReturnValue: Integer)
begin
if MatchThisTable(ReservationEntry."Source Type") then
ReturnValue := Enum::"Reservation Summary Type"::"Purchase Quote".AsInteger() + ReservationEntry."Source Subtype";
end;
[EventSubscriber(ObjectType::Table, Database::"Reservation Entry", 'OnUpdateSourceCost', '', false, false)]
local procedure ReservationEntryOnUpdateSourceCost(ReservationEntry: Record "Reservation Entry"; UnitCost: Decimal)
var
PurchLine: Record "Purchase Line";
QtyReserved: Decimal;
begin
if MatchThisTable(ReservationEntry."Source Type") then begin
PurchLine.Get(ReservationEntry."Source Subtype", ReservationEntry."Source ID", ReservationEntry."Source Ref. No.");
if PurchLine."Qty. per Unit of Measure" <> 0 then
PurchLine."Unit Cost (LCY)" :=
Round(PurchLine."Unit Cost (LCY)" / PurchLine."Qty. per Unit of Measure");
if PurchLine."Quantity (Base)" <> 0 then
PurchLine."Unit Cost (LCY)" :=
Round(
(PurchLine."Unit Cost (LCY)" *
(PurchLine."Quantity (Base)" - QtyReserved) +
UnitCost * QtyReserved) / PurchLine."Quantity (Base)", 0.00001);
if PurchLine."Qty. per Unit of Measure" <> 0 then
PurchLine."Unit Cost (LCY)" :=
Round(PurchLine."Unit Cost (LCY)" * PurchLine."Qty. per Unit of Measure");
PurchLine.Validate("Unit Cost (LCY)");
PurchLine.Modify();
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::OrderTrackingManagement, 'OnSetSourceRecord', '', false, false)]
local procedure OrderTrackingManagementOnSetSourceRecord(var SourceRecordVar: Variant; var ReservationEntry: Record "Reservation Entry"; var CaptionText: Text; var ItemLedgerEntry2: Record "Item Ledger Entry")
var
PurchaseLine: Record "Purchase Line";
SourceRecRef: RecordRef;
begin
SourceRecRef.GetTable(SourceRecordVar);
if MatchThisTable(SourceRecRef.Number) then begin
PurchaseLine := SourceRecordVar;
SetPurchaseLine(PurchaseLine, ReservationEntry, ItemLedgerEntry2);
end;
end;
local procedure SetPurchaseLine(var PurchaseLine: Record "Purchase Line"; var ReservEntry: Record "Reservation Entry"; var ItemLedgerEntry: Record "Item Ledger Entry")
var
PurchRcptLine: Record "Purch. Rcpt. Line";
begin
PurchaseLine.TestField(Type, PurchaseLine.Type::Item);
ReservEntry.InitSortingAndFilters(false);
PurchaseLine.SetReservationFilters(ReservEntry);
if PurchaseLine."Qty. Received (Base)" <> 0 then begin
PurchRcptLine.SetCurrentKey("Order No.", "Order Line No.");
PurchRcptLine.SetRange("Order No.", PurchaseLine."Document No.");
PurchRcptLine.SetRange("Order Line No.", PurchaseLine."Line No.");
if PurchRcptLine.Find('-') then
repeat
if ItemLedgerEntry.Get(PurchRcptLine."Item Rcpt. Entry No.") then
ItemLedgerEntry.Mark(true);
until PurchRcptLine.Next() = 0;
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::OrderTrackingManagement, 'OnInsertOrderTrackingEntry', '', false, false)]
local procedure OnInsertOrderTrackingEntry(var OrderTrackingEntry: Record "Order Tracking Entry")
var
PurchaseLine: Record "Purchase Line";
begin
if OrderTrackingEntry."For Type" = DATABASE::"Purchase Line" then
if PurchaseLine.Get(OrderTrackingEntry."For Subtype", OrderTrackingEntry."For ID", OrderTrackingEntry."For Ref. No.") then begin
OrderTrackingEntry."Starting Date" := PurchaseLine."Expected Receipt Date";
OrderTrackingEntry."Ending Date" := PurchaseLine."Expected Receipt Date";
end;
end;
[EventSubscriber(ObjectType::Table, Database::"Tracking Specification", 'OnGetSourceShipmentDate', '', false, false)]
local procedure OnGetSourceShipmentDate(var TrackingSpecification: Record "Tracking Specification"; var ShipmentDate: Date);
var
PurchaseLine: Record "Purchase Line";
begin
if TrackingSpecification."Source Type" = Database::"Purchase Line" then begin
PurchaseLine.Get(TrackingSpecification."Source Subtype", TrackingSpecification."Source ID", TrackingSpecification."Source Ref. No.");
ShipmentDate := PurchaseLine."Expected Receipt Date";
end;
end;
}