codeunit 50138 "SalesLineReservation"
{
[EventSubscriber(ObjectType::Table, Database::"Sales Line", 'OnAfterValidateEvent', 'Quantity', false, false)]
local procedure OnAfterQuantityValidate(var Rec: Record "Sales Line")
var
Item: Record Item;
ReservationEntry: Record "Reservation Entry";
TempReservEntry: Record "Reservation Entry" temporary;
CreateReservEntry: Codeunit "Create Reserv. Entry";
ItemLedgerEntry: Record "Item Ledger Entry";
QtyToReserve: Decimal;
QtyReserved: Decimal;
TotalReservedQty: Decimal;
ReservStatus: Enum "Reservation Status";
begin
if Rec.Type <> Rec.Type::Item then
exit;
if not Item.Get(Rec."No.") then
exit;
if Item."Assembly BOM" then
exit;
ClearExistingReservations(Rec);
ItemLedgerEntry.SetRange("Item No.", Rec."No.");
ItemLedgerEntry.SetRange("Variant Code", Rec."Variant Code");
ItemLedgerEntry.SetRange("Location Code", Rec."Location Code");
ItemLedgerEntry.SetFilter("Remaining Quantity", '>0');
if ItemLedgerEntry.FindSet() then begin
QtyToReserve := Rec.Quantity;
repeat
if QtyToReserve<ItemLedgerEntry."Remaining Quantity" then
QtyReserved :=QtyToReserve
else
QtyReserved := ItemLedgerEntry."Remaining Quantity";
if QtyReserved > 0 then begin
CreateTempReservationEntry(
TempReservEntry,
QtyReserved,
Rec,
ItemLedgerEntry."Entry No."
);
QtyToReserve -= QtyReserved;
TotalReservedQty += QtyReserved;
end;
until (ItemLedgerEntry.Next() = 0) or (QtyToReserve <= 0);
end;
if not TempReservEntry.IsEmpty() then begin
CreateReservationEntries(TempReservEntry, Rec, CreateReservEntry, ReservStatus::Reservation);
Message('Successfully reserved %1 units from Item Ledger Entries.', TotalReservedQty);
end;
end;
local procedure ClearExistingReservations(SalesLine: Record "Sales Line")
var
ReservationEntry: Record "Reservation Entry";
begin
ReservationEntry.SetRange("Source Type", Database::"Sales Line");
ReservationEntry.SetRange("Source Subtype", SalesLine."Document Type".AsInteger());
ReservationEntry.SetRange("Source ID", SalesLine."Document No.");
ReservationEntry.SetRange("Source Ref. No.", SalesLine."Line No.");
ReservationEntry.DeleteAll(true);
end;
local procedure CreateTempReservationEntry(
var TempReservEntry: Record "Reservation Entry" temporary;
QtyToReserve: Decimal;
SalesLine: Record "Sales Line";
ItemLedgerEntryNo: Integer
)
begin
TempReservEntry.Init();
TempReservEntry."Entry No." := TempReservEntry."Entry No." + 1;
TempReservEntry."Item No." := SalesLine."No.";
TempReservEntry."Variant Code" := SalesLine."Variant Code";
TempReservEntry."Location Code" := SalesLine."Location Code";
TempReservEntry.Quantity := QtyToReserve;
TempReservEntry."Reservation Status" := TempReservEntry."Reservation Status"::Reservation;
TempReservEntry."Source Type" := Database::"Sales Line";
TempReservEntry."Source Subtype" := SalesLine."Document Type".AsInteger();
TempReservEntry."Source ID" := SalesLine."Document No.";
TempReservEntry."Source Ref. No." := SalesLine."Line No.";
TempReservEntry."Item Ledger Entry No." := ItemLedgerEntryNo;
TempReservEntry.Insert();
end;
local procedure CreateReservationEntries(
var TempReservEntry: Record "Reservation Entry" temporary;
SalesLine: Record "Sales Line";
var CreateReservEntry: Codeunit "Create Reserv. Entry";
ReservStatus: Enum "Reservation Status"
)
var
QtyPerUOM: Decimal;
begin
QtyPerUOM := SalesLine."Qty. per Unit of Measure";
if QtyPerUOM = 0 then
QtyPerUOM := 1;
if TempReservEntry.FindSet() then
repeat
CreateReservEntry.SetDates(0D, TempReservEntry."Expiration Date");
CreateReservEntry.CreateReservEntryFor(
Database::"Sales Line",
SalesLine."Document Type".AsInteger(),
SalesLine."Document No.",
'',
0,
SalesLine."Line No.",
QtyPerUOM,
TempReservEntry.Quantity,
TempReservEntry.Quantity * SalesLine."Qty. per Unit of Measure",
TempReservEntry
);
CreateReservEntry.CreateEntry(
SalesLine."No.",
SalesLine."Variant Code",
SalesLine."Location Code",
'',
0D,
0D,
0,
ReservStatus
);
until TempReservEntry.Next() = 0;
end;
}