Codeunit 99000842 Service Line-Reserve
- App
- Base Application
- Namespace
- Microsoft.Service.Document
- Versions
- 17-28
Procedures, 29Events, 13Obsolete, 8
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Service/Document/ServiceLineReserve.Codeunit.al1144 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.Service.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.Requisition;
using Microsoft.Inventory.Tracking;
using Microsoft.Purchases.Document;
codeunit 99000842 "Service 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";
DeleteItemTracking: Boolean;
Text000Err: Label 'Codeunit is not initialized correctly.';
Text001Err: Label 'Reserved quantity cannot be greater than %1', Comment = '%1 - quantity';
Text002Err: Label 'must be filled in when a quantity is reserved';
Text003Err: Label 'must not be changed when a quantity is reserved';
Text004Err: Label 'must not be filled in when a quantity is reserved';
SummaryTypeTxt: Label '%1', Locked = true;
SourceDoc2Txt: Label '%1 %2', Locked = true;
procedure CreateReservation(ServiceLine: Record "Service Line"; Description: Text[100]; ExpectedReceiptDate: Date; Quantity: Decimal; QuantityBase: Decimal; ForReservationEntry: Record "Reservation Entry")
var
ShipmentDate: Date;
IsHandled: Boolean;
begin
if FromTrackingSpecification."Source Type" = 0 then
Error(Text000Err);
ServiceLine.TestField(Type, ServiceLine.Type::Item);
ServiceLine.TestField("No.");
ServiceLine.TestField("Needed by Date");
ServiceLine.CalcFields("Reserved Qty. (Base)");
if Abs(ServiceLine."Outstanding Qty. (Base)") < Abs(ServiceLine."Reserved Qty. (Base)") + QuantityBase then
Error(
Text001Err,
Abs(ServiceLine."Outstanding Qty. (Base)") - Abs(ServiceLine."Reserved Qty. (Base)"));
ServiceLine.TestField("Variant Code", FromTrackingSpecification."Variant Code");
ServiceLine.TestField("Location Code", FromTrackingSpecification."Location Code");
if QuantityBase > 0 then
ShipmentDate := ServiceLine."Needed by Date"
else begin
ShipmentDate := ExpectedReceiptDate;
ExpectedReceiptDate := ServiceLine."Needed by Date";
end;
IsHandled := false;
OnCreateReservationOnBeforeCreateReservEntry(ServiceLine, Quantity, QuantityBase, ForReservationEntry, IsHandled, FromTrackingSpecification, ExpectedReceiptDate, Description, ShipmentDate);
if not IsHandled then begin
CreateReservEntry.CreateReservEntryFor(
DATABASE::"Service Line", ServiceLine."Document Type".AsInteger(),
ServiceLine."Document No.", '', 0, ServiceLine."Line No.",
ServiceLine."Qty. per Unit of Measure", Quantity, QuantityBase, ForReservationEntry);
CreateReservEntry.CreateReservEntryFrom(FromTrackingSpecification);
end;
CreateReservEntry.CreateReservEntry(
ServiceLine."No.", ServiceLine."Variant Code", ServiceLine."Location Code",
Description, ExpectedReceiptDate, ShipmentDate, 0);
FromTrackingSpecification."Source Type" := 0;
OnAfterCreateReservation(ServiceLine);
end;
procedure CreateBindingReservation(ServiceLine: Record "Service Line"; Description: Text[100]; ExpectedReceiptDate: Date; Quantity: Decimal; QuantityBase: Decimal)
var
DummyReservationEntry: Record "Reservation Entry";
begin
CreateReservation(ServiceLine, Description, ExpectedReceiptDate, Quantity, QuantityBase, DummyReservationEntry);
end;
procedure CreateReservationSetFrom(TrackingSpecification: Record "Tracking Specification")
begin
FromTrackingSpecification := TrackingSpecification;
end;
procedure SetBinding(Binding: Enum "Reservation Binding")
begin
CreateReservEntry.SetBinding(Binding);
end;
procedure Caption(ServiceLine: Record "Service Line") CaptionText: Text
begin
CaptionText := ServiceLine.GetSourceCaption();
end;
procedure FindReservEntry(ServiceLine: Record "Service Line"; var ReservationEntry: Record "Reservation Entry"): Boolean
begin
ReservationEntry.InitSortingAndFilters(false);
ServiceLine.SetReservationFilters(ReservationEntry);
exit(ReservationEntry.FindLast());
end;
procedure ReservQuantity(ServiceLine: Record "Service Line"; var QtyToReserve: Decimal; var QtyToReserveBase: Decimal)
begin
case ServiceLine."Document Type" of
ServiceLine."Document Type"::Quote,
ServiceLine."Document Type"::Order,
ServiceLine."Document Type"::Invoice:
begin
QtyToReserve := ServiceLine."Outstanding Quantity";
QtyToReserveBase := ServiceLine."Outstanding Qty. (Base)";
end;
ServiceLine."Document Type"::"Credit Memo":
begin
QtyToReserve := -ServiceLine."Outstanding Quantity";
QtyToReserveBase := -ServiceLine."Outstanding Qty. (Base)"
end;
end;
OnAfterReservQuantity(ServiceLine, QtyToReserve, QtyToReserveBase);
end;
procedure GetReservedQtyFromInventory(ServiceLine: Record "Service Line"): Decimal
var
ReservationEntry: Record "Reservation Entry";
QtyReservedFromItemLedger: Query "Qty. Reserved From Item Ledger";
begin
ServiceLine.SetReservationEntry(ReservationEntry);
QtyReservedFromItemLedger.SetSourceFilter(ReservationEntry);
QtyReservedFromItemLedger.Open();
if QtyReservedFromItemLedger.Read() then
exit(QtyReservedFromItemLedger.Quantity__Base_);
exit(0);
end;
procedure GetReservedQtyFromInventory(ServiceHeader: Record "Service Header"): Decimal
var
ReservationEntry: Record "Reservation Entry";
QtyReservedFromItemLedger: Query "Qty. Reserved From Item Ledger";
begin
ReservationEntry.SetSource(DATABASE::"Service Line", ServiceHeader."Document Type".AsInteger(), ServiceHeader."No.", 0, '', 0);
QtyReservedFromItemLedger.SetSourceFilter(ReservationEntry);
QtyReservedFromItemLedger.Open();
if QtyReservedFromItemLedger.Read() then
exit(QtyReservedFromItemLedger.Quantity__Base_);
exit(0);
end;
procedure VerifyChange(var NewServiceLine: Record "Service Line"; var OldServiceLine: Record "Service Line")
var
ServiceLine: Record "Service Line";
ShowError: Boolean;
HasError: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeVerifyChange(NewServiceLine, OldServiceLine, IsHandled);
if IsHandled then
exit;
if (NewServiceLine.Type <> NewServiceLine.Type::Item) and (OldServiceLine.Type <> OldServiceLine.Type::Item) then
exit;
if NewServiceLine."Line No." = 0 then
if not ServiceLine.Get(NewServiceLine."Document Type", NewServiceLine."Document No.", NewServiceLine."Line No.") then
exit;
NewServiceLine.CalcFields("Reserved Qty. (Base)");
ShowError := NewServiceLine."Reserved Qty. (Base)" <> 0;
if NewServiceLine.Type <> OldServiceLine.Type then
if ShowError then
NewServiceLine.FieldError(Type, Text003Err)
else
HasError := true;
if NewServiceLine."No." <> OldServiceLine."No." then
if ShowError then
NewServiceLine.FieldError("No.", Text003Err)
else
HasError := true;
if (NewServiceLine."Needed by Date" = 0D) and (OldServiceLine."Needed by Date" <> 0D) then
if ShowError then
NewServiceLine.FieldError("Needed by Date", Text002Err)
else
HasError := true;
if NewServiceLine."Variant Code" <> OldServiceLine."Variant Code" then
if ShowError then
NewServiceLine.FieldError("Variant Code", Text003Err)
else
HasError := true;
if NewServiceLine."Location Code" <> OldServiceLine."Location Code" then
if ShowError then
NewServiceLine.FieldError("Location Code", Text003Err)
else
HasError := true;
if (NewServiceLine.Type = NewServiceLine.Type::Item) and (OldServiceLine.Type = OldServiceLine.Type::Item) then
if (NewServiceLine."Bin Code" <> OldServiceLine."Bin Code") and
(not ReservationManagement.CalcIsAvailTrackedQtyInBin(
NewServiceLine."No.", NewServiceLine."Bin Code",
NewServiceLine."Location Code", NewServiceLine."Variant Code",
DATABASE::"Service Line", NewServiceLine."Document Type".AsInteger(),
NewServiceLine."Document No.", '', 0, NewServiceLine."Line No."))
then begin
if ShowError then
NewServiceLine.FieldError("Bin Code", Text004Err);
HasError := true;
end;
if NewServiceLine."Line No." <> OldServiceLine."Line No." then
HasError := true;
OnVerifyChangeOnBeforeHasError(NewServiceLine, OldServiceLine, HasError, ShowError);
if HasError then
if (NewServiceLine."No." <> OldServiceLine."No.") or NewServiceLine.ReservEntryExist() then begin
if NewServiceLine."No." <> OldServiceLine."No." then begin
ReservationManagement.SetReservSource(OldServiceLine);
ReservationManagement.DeleteReservEntries(true, 0);
ReservationManagement.SetReservSource(NewServiceLine);
end else begin
ReservationManagement.SetReservSource(NewServiceLine);
ReservationManagement.DeleteReservEntries(true, 0);
end;
ReservationManagement.AutoTrack(NewServiceLine."Outstanding Qty. (Base)");
end;
if HasError or (NewServiceLine."Needed by Date" <> OldServiceLine."Needed by Date")
then begin
AssignForPlanning(NewServiceLine);
if (NewServiceLine."No." <> OldServiceLine."No.") or
(NewServiceLine."Variant Code" <> OldServiceLine."Variant Code") or
(NewServiceLine."Location Code" <> OldServiceLine."Location Code")
then
AssignForPlanning(OldServiceLine);
end;
end;
procedure VerifyQuantity(var NewServiceLine: Record "Service Line"; var OldServiceLine: Record "Service Line")
var
ServiceLine: Record "Service Line";
begin
if not (NewServiceLine."Document Type" in
[NewServiceLine."Document Type"::Quote, NewServiceLine."Document Type"::Order])
then
if NewServiceLine."Shipment No." = '' then
exit;
if NewServiceLine.Type <> NewServiceLine.Type::Item then
exit;
if NewServiceLine."Line No." = OldServiceLine."Line No." then
if NewServiceLine."Quantity (Base)" = OldServiceLine."Quantity (Base)" then
exit;
if NewServiceLine."Line No." = 0 then
if not ServiceLine.Get(NewServiceLine."Document Type", NewServiceLine."Document No.", NewServiceLine."Line No.") then
exit;
ReservationManagement.SetReservSource(NewServiceLine);
if NewServiceLine."Qty. per Unit of Measure" <> OldServiceLine."Qty. per Unit of Measure" then
ReservationManagement.ModifyUnitOfMeasure();
if NewServiceLine."Outstanding Qty. (Base)" * OldServiceLine."Outstanding Qty. (Base)" < 0 then
ReservationManagement.DeleteReservEntries(false, 0)
else
ReservationManagement.DeleteReservEntries(false, NewServiceLine."Outstanding Qty. (Base)");
ReservationManagement.ClearSurplus();
ReservationManagement.AutoTrack(NewServiceLine."Outstanding Qty. (Base)");
AssignForPlanning(NewServiceLine);
end;
local procedure AssignForPlanning(var ServiceLine: Record "Service Line")
var
PlanningAssignment: Record "Planning Assignment";
begin
if ServiceLine."Document Type" <> ServiceLine."Document Type"::Order then
exit;
if ServiceLine.Type <> ServiceLine.Type::Item then
exit;
if ServiceLine."No." <> '' then
PlanningAssignment.ChkAssignOne(ServiceLine."No.", ServiceLine."Variant Code", ServiceLine."Location Code", ServiceLine."Needed by Date");
end;
procedure DeleteLineConfirm(var ServiceLine: Record "Service Line"): Boolean
begin
if not ServiceLine.ReservEntryExist() then
exit(true);
ReservationManagement.SetReservSource(ServiceLine);
if ReservationManagement.DeleteItemTrackingConfirm() then
DeleteItemTracking := true;
exit(DeleteItemTracking);
end;
procedure DeleteLine(var ServiceLine: Record "Service Line")
begin
ReservationManagement.SetReservSource(ServiceLine);
if DeleteItemTracking then
ReservationManagement.SetItemTrackingHandling(1); // Allow Deletion
ReservationManagement.DeleteReservEntries(true, 0);
DeleteInvoiceSpecFromLine(ServiceLine);
ServiceLine.CalcFields("Reserved Qty. (Base)");
end;
procedure CallItemTracking(var ServiceLine: Record "Service Line")
var
TrackingSpecification: Record "Tracking Specification";
ItemTrackingLines: Page "Item Tracking Lines";
begin
InitFromServLine(TrackingSpecification, ServiceLine, false);
if ((ServiceLine."Document Type" = ServiceLine."Document Type"::Invoice) and
(ServiceLine."Shipment No." <> ''))
then
ItemTrackingLines.SetRunMode(Enum::"Item Tracking Run Mode"::"Combined Ship/Rcpt");
ItemTrackingLines.SetSourceSpec(TrackingSpecification, ServiceLine."Needed by Date");
ItemTrackingLines.SetInbound(ServiceLine.IsInbound());
OnCallItemTrackingOnBeforeItemTrackingLinesRunModal(ServiceLine, ItemTrackingLines);
ItemTrackingLines.RunModal();
end;
procedure TransServLineToServLine(var OldServiceLine: Record "Service Line"; var NewServiceLine: Record "Service Line"; TransferQty: Decimal)
var
OldReservationEntry: Record "Reservation Entry";
ReservStatus: Enum "Reservation Status";
IsHandled: Boolean;
begin
if not FindReservEntry(OldServiceLine, OldReservationEntry) then
exit;
OldReservationEntry.Lock();
NewServiceLine.TestItemFields(OldServiceLine."No.", OldServiceLine."Variant Code", OldServiceLine."Location Code");
for ReservStatus := ReservStatus::Reservation to ReservStatus::Prospect do begin
if TransferQty = 0 then
exit;
OldReservationEntry.SetRange("Reservation Status", ReservStatus);
if OldReservationEntry.FindSet() then
repeat
OldReservationEntry.TestItemFields(OldServiceLine."No.", OldServiceLine."Variant Code", OldServiceLine."Location Code");
IsHandled := false;
OnTransServLineToServLineOnBeforeCreateReservEntry(OldReservationEntry, OldServiceLine, TransferQty, IsHandled);
if not IsHandled then
TransferQty :=
CreateReservEntry.TransferReservEntry(DATABASE::"Service Line",
NewServiceLine."Document Type".AsInteger(), NewServiceLine."Document No.", '', 0,
NewServiceLine."Line No.", NewServiceLine."Qty. per Unit of Measure", OldReservationEntry, TransferQty);
until (OldReservationEntry.Next() = 0) or (TransferQty = 0);
end;
end;
procedure RetrieveInvoiceSpecification(var ServiceLine: Record "Service Line"; var TempTrackingSpecification: Record "Tracking Specification" temporary; Consume: Boolean) OK: Boolean
var
SourceTrackingSpecification: Record "Tracking Specification";
begin
Clear(TempTrackingSpecification);
if ServiceLine.Type <> ServiceLine.Type::Item then
exit;
if ((ServiceLine."Document Type" = ServiceLine."Document Type"::Invoice) and
(ServiceLine."Shipment No." <> ''))
then
OK := RetrieveInvoiceSpecification2(ServiceLine, TempTrackingSpecification)
else begin
InitFromServLine(SourceTrackingSpecification, ServiceLine, Consume);
OK := ItemTrackingManagement.RetrieveInvoiceSpecWithService(SourceTrackingSpecification, TempTrackingSpecification, Consume);
end;
end;
local procedure RetrieveInvoiceSpecification2(var ServiceLine: Record "Service Line"; var TempInvoicingTrackingSpecification: Record "Tracking Specification" temporary) OK: Boolean
var
TrackingSpecification: Record "Tracking Specification";
ReservationEntry: Record "Reservation Entry";
begin
// Used for combined shipment:
if ServiceLine.Type <> ServiceLine.Type::Item then
exit;
if not FindReservEntry(ServiceLine, 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;
TempInvoicingTrackingSpecification.Insert();
ReservationEntry.Delete();
until ReservationEntry.Next() = 0;
OK := TempInvoicingTrackingSpecification.FindFirst();
end;
procedure DeleteInvoiceSpecFromHeader(ServiceHeader: Record "Service Header")
begin
ItemTrackingManagement.DeleteInvoiceSpecFromHeader(
DATABASE::"Service Line", ServiceHeader."Document Type".AsInteger(), ServiceHeader."No.");
end;
local procedure DeleteInvoiceSpecFromLine(ServiceLine: Record "Service Line")
begin
ItemTrackingManagement.DeleteInvoiceSpecFromLine(
DATABASE::"Service Line", ServiceLine."Document Type".AsInteger(), ServiceLine."Document No.", ServiceLine."Line No.");
end;
procedure TransServLineToItemJnlLine(var ServiceLine: Record "Service Line"; var ItemJournalLine: Record "Item Journal Line"; TransferQty: Decimal; var CheckApplFromItemEntry: Boolean) Result: Decimal
var
OldReservationEntry: Record "Reservation Entry";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeTransServLineToItemJnlLine(ServiceLine, ItemJournalLine, TransferQty, CheckApplFromItemEntry, Result, IsHandled);
if IsHandled then
exit(Result);
if not FindReservEntry(ServiceLine, OldReservationEntry) then
exit(TransferQty);
OldReservationEntry.LockTable();
OldReservationEntry.FindLast();
ItemJournalLine.TestItemFields(ServiceLine."No.", ServiceLine."Variant Code", ServiceLine."Location Code");
if TransferQty = 0 then
exit;
if ItemJournalLine."Invoiced Quantity" <> 0 then
CreateReservEntry.SetUseQtyToInvoice(true);
if ReservationEngineMgt.InitRecordSet(OldReservationEntry) then begin
repeat
OldReservationEntry.TestItemFields(ServiceLine."No.", ServiceLine."Variant Code", ServiceLine."Location Code");
if CheckApplFromItemEntry then begin
OldReservationEntry.TestField("Appl.-from Item Entry");
CreateReservEntry.SetApplyFromEntryNo(OldReservationEntry."Appl.-from Item Entry");
end;
IsHandled := false;
OnTransServLineToItemJnlLineOnBeforeTransferReservationEntry(OldReservationEntry, ServiceLine, ItemJournalLine, IsHandled);
if not IsHandled then
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);
until (ReservationEngineMgt.NEXTRecord(OldReservationEntry) = 0) or (TransferQty = 0);
CheckApplFromItemEntry := false;
end;
exit(TransferQty);
end;
procedure UpdateItemTrackingAfterPosting(ServiceHeader: Record "Service Header")
var
ReservationEntry: Record "Reservation Entry";
begin
// Used for updating Quantity to Handle and Quantity to Invoice after posting
ReservationEntry.SetSourceFilter(DATABASE::"Service Line", ServiceHeader."Document Type".AsInteger(), ServiceHeader."No.", -1, true);
ReservationEntry.SetSourceFilter('', 0);
CreateReservEntry.UpdateItemTrackingAfterPosting(ReservationEntry);
end;
procedure BindToTracking(ServiceLine: Record "Service Line"; TrackingSpecification: Record "Tracking Specification"; Description: Text[100]; ExpectedDate: Date; ReservQty: Decimal; ReservQtyBase: Decimal)
begin
SetBinding("Reservation Binding"::"Order-to-Order");
CreateReservationSetFrom(TrackingSpecification);
CreateBindingReservation(ServiceLine, Description, ExpectedDate, ReservQty, ReservQtyBase);
end;
[EventSubscriber(ObjectType::Page, PAGE::Reservation, 'OnGetQtyPerUOMFromSourceRecRef', '', true, false)]
local procedure OnGetQtyPerUOMFromSourceRecRef(SourceRecRef: RecordRef; var QtyPerUOM: Decimal; var QtyReserved: Decimal; var QtyReservedBase: Decimal; var QtyToReserve: Decimal; var QtyToReserveBase: Decimal)
var
ServiceLine: Record "Service Line";
begin
if MatchThisTable(SourceRecRef.Number) then begin
SourceRecRef.SetTable(ServiceLine);
ServiceLine.Find();
if ServiceLine.UpdatePlanned() then begin
ServiceLine.Modify(true);
Commit();
end;
QtyPerUOM := ServiceLine.GetReservationQty(QtyReserved, QtyReservedBase, QtyToReserve, QtyToReserveBase);
end;
end;
local procedure SetReservSourceFor(SourceRecordRef: RecordRef; var ReservationEntry: record "Reservation Entry"; var CaptionText: Text)
var
ServiceLine: Record "Service Line";
begin
SourceRecordRef.SetTable(ServiceLine);
ServiceLine.TestField(Type, ServiceLine.Type::Item);
ServiceLine.TestField("Needed by Date");
ServiceLine.SetReservationEntry(ReservationEntry);
CaptionText := ServiceLine.GetSourceCaption();
end;
local procedure EntryStartNo(): Integer
begin
exit(Enum::"Reservation Summary Type"::"Service Order".AsInteger() - 1);
end;
local procedure MatchThisEntry(EntryNo: Integer): Boolean
begin
exit(EntryNo = Enum::"Reservation Summary Type"::"Service Order".AsInteger());
end;
local procedure MatchThisTable(TableID: Integer): Boolean
begin
exit(TableID = DATABASE::"Service Line");
end;
[EventSubscriber(ObjectType::Page, Page::Reservation, 'OnSetReservSource', '', true, 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', '', true, false)]
local procedure ReservationOnDrillDownTotalQuantity(SourceRecRef: RecordRef; ReservEntry: Record "Reservation Entry"; EntrySummary: Record "Entry Summary"; Location: Record Location; MaxQtyToReserve: Decimal)
var
AvailableServiceLines: page "Available - Service Lines";
begin
if MatchThisEntry(EntrySummary."Entry No.") then begin
Clear(AvailableServiceLines);
AvailableServiceLines.SetCurrentSubType(EntrySummary."Entry No." - EntryStartNo());
AvailableServiceLines.SetSource(SourceRecRef, ReservEntry, ReservEntry.GetTransferDirection());
AvailableServiceLines.RunModal();
end;
end;
[EventSubscriber(ObjectType::Page, Page::Reservation, 'OnFilterReservEntry', '', true, 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::"Service Line");
FilterReservEntry.SetRange("Source Subtype", ReservEntrySummary."Entry No." - EntryStartNo());
end;
end;
[EventSubscriber(ObjectType::Page, Page::Reservation, 'OnAfterRelatesToSummEntry', '', true, 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::"Service Line") and
(FilterReservEntry."Source Subtype" = FromEntrySummary."Entry No." - EntryStartNo());
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Item Ledger Entry-Reserve", 'OnDrillDownTotalQuantity', '', true, 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")
begin
if MatchThisTable(ReservEntry."Source Type") then begin
sender.DrillDownTotalQuantity(SourceRecRef, EntrySummary, ReservEntry, MaxQtyToReserve);
IsHandled := true;
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnCreateReservation', '', true, false)]
local procedure OnCreateReservation(SourceRecRef: RecordRef; TrackingSpecification: Record "Tracking Specification"; ForReservEntry: Record "Reservation Entry"; Description: Text[100]; ExpectedDate: Date; Quantity: Decimal; QuantityBase: Decimal)
var
ServiceLine: Record "Service Line";
begin
if MatchThisTable(ForReservEntry."Source Type") then begin
CreateReservationSetFrom(TrackingSpecification);
SourceRecRef.SetTable(ServiceLine);
CreateReservation(ServiceLine, Description, ExpectedDate, Quantity, QuantityBase, ForReservEntry);
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnLookupDocument', '', true, false)]
local procedure OnLookupDocument(SourceType: Integer; SourceSubtype: Integer; SourceID: Code[20])
var
ServiceHeader: Record "Service Header";
begin
if MatchThisTable(SourceType) then begin
ServiceHeader.Reset();
ServiceHeader.SetRange("Document Type", SourceSubtype);
ServiceHeader.SetRange("No.", SourceID);
if SourceSubtype = 0 then
PAGE.RunModal(PAGE::"Service Quote", ServiceHeader)
else
PAGE.RunModal(PAGE::"Service Order", ServiceHeader);
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnLookupLine', '', true, false)]
local procedure OnLookupLine(SourceType: Integer; SourceSubtype: Integer; SourceID: Code[20]; SourceRefNo: Integer)
var
ServiceLine: Record "Service Line";
begin
if MatchThisTable(SourceType) then begin
ServiceLine.Reset();
ServiceLine.SetRange("Document Type", SourceSubtype);
ServiceLine.SetRange("Document No.", SourceID);
ServiceLine.SetRange("Line No.", SourceRefNo);
PAGE.Run(0, ServiceLine);
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnFilterReservFor', '', true, false)]
local procedure OnFilterReservFor(SourceRecRef: RecordRef; var ReservEntry: Record "Reservation Entry"; var CaptionText: Text)
var
ServiceLine: Record "Service Line";
begin
if MatchThisTable(SourceRecRef.Number) then begin
SourceRecRef.SetTable(ServiceLine);
ServiceLine.SetReservationFilters(ReservEntry);
CaptionText := ServiceLine.GetSourceCaption();
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnCalculateRemainingQty', '', true, false)]
local procedure OnCalculateRemainingQty(SourceRecRef: RecordRef; var ReservEntry: Record "Reservation Entry"; var RemainingQty: Decimal; var RemainingQtyBase: Decimal)
var
ServiceLine: Record "Service Line";
begin
if MatchThisTable(ReservEntry."Source Type") then begin
SourceRecRef.SetTable(ServiceLine);
ServiceLine.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
ServiceLine: Record "Service Line";
begin
ServiceLine.Get(ReservationEntry."Source Subtype", ReservationEntry."Source ID", ReservationEntry."Source Ref. No.");
SourceRecordRef.GetTable(ServiceLine);
case ReturnOption of
ReturnOption::"Net Qty. (Base)":
exit(ServiceLine."Outstanding Qty. (Base)");
ReturnOption::"Gross Qty. (Base)":
exit(ServiceLine."Quantity (Base)");
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnGetSourceRecordValue', '', true, 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;
local procedure UpdateStatistics(CalcReservationEntry: Record "Reservation Entry"; var TempEntrySummary: Record "Entry Summary" temporary; AvailabilityDate: Date; Positive: Boolean; var TotalQuantity: Decimal)
var
ServiceLine: Record "Service Line";
AvailabilityFilter: Text;
begin
if not ServiceLine.ReadPermission then
exit;
ServiceLine.SetAutoCalcFields("Reserved Qty. (Base)");
AvailabilityFilter := CalcReservationEntry.GetAvailabilityFilter(AvailabilityDate, Positive);
ServiceLine.FindLinesForReservation(CalcReservationEntry, AvailabilityFilter, Positive);
if ServiceLine.FindSet() then
repeat
TempEntrySummary."Total Reserved Quantity" -= ServiceLine."Reserved Qty. (Base)";
TotalQuantity += ServiceLine."Outstanding Qty. (Base)";
until ServiceLine.Next() = 0;
if TotalQuantity = 0 then
exit;
if (TotalQuantity < 0) = Positive then begin
TempEntrySummary."Table ID" := DATABASE::"Service Line";
TempEntrySummary."Summary Type" := CopyStr(StrSubstNo(SummaryTypeTxt, ServiceLine.TableCaption()), 1, MaxStrLen(TempEntrySummary."Summary Type"));
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', '', true, 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." = 110 then
UpdateStatistics(
CalcReservEntry, ReservSummEntry, AvailabilityDate, Positive, TotalQuantity);
end;
[EventSubscriber(ObjectType::Page, Page::"Reservation Entries", 'OnLookupReserved', '', true, 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
ServiceLine: Record "Service Line";
begin
ServiceLine.SetRange("Document Type", ReservationEntry."Source Subtype");
ServiceLine.SetRange("Document No.", ReservationEntry."Source ID");
ServiceLine.SetRange("Line No.", ReservationEntry."Source Ref. No.");
PAGE.RunModal(Page::"Service Line List", ServiceLine);
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnAfterAutoReserveOneLine', '', 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; var sender: Codeunit "Reservation Management")
begin
if MatchThisEntry(ReservSummEntryNo) then
AutoReserveServLine(
CalcReservEntry, sender, ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserveBase,
Description, AvailabilityDate, Search, NextStep, Positive);
end;
local procedure AutoReserveServLine(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";
ServiceLine: Record "Service Line";
QtyThisLine: Decimal;
QtyThisLineBase: Decimal;
ReservQty: Decimal;
IsReserved: Boolean;
begin
IsReserved := false;
OnBeforeAutoReserveServLine(
ReservSummEntryNo, RemainingQtyToReserve, RemainingQtyToReserve, Description, AvailabilityDate, IsReserved, Search, NextStep, CalcReservEntry);
if IsReserved then
exit;
ServiceLine.SetAutoCalcFields("Reserved Qty. (Base)");
ServiceLine.FindLinesForReservation(CalcReservEntry, sender.GetAvailabilityFilter(AvailabilityDate), Positive);
if ServiceLine.Find(Search) then
repeat
QtyThisLine := ServiceLine."Outstanding Quantity";
QtyThisLineBase := ServiceLine."Outstanding Qty. (Base)";
ReservQty := ServiceLine."Reserved Qty. (Base)";
if Positive = (QtyThisLineBase > 0) then begin
QtyThisLine := 0;
QtyThisLineBase := 0;
end;
sender.SetQtyToReserveDownToTrackedQuantity(CalcReservEntry, ServiceLine.RowID1(), QtyThisLine, QtyThisLineBase);
CallTrackingSpecification.InitTrackingSpecification(
Database::"Service Line", ServiceLine."Document Type".AsInteger(), ServiceLine."Document No.", '', 0, ServiceLine."Line No.",
ServiceLine."Variant Code", ServiceLine."Location Code", ServiceLine."Qty. per Unit of Measure");
CallTrackingSpecification.CopyTrackingFromReservEntry(CalcReservEntry);
sender.InsertReservationEntries(
RemainingQtyToReserve, RemainingQtyToReserveBase, ReservQty,
Description, ServiceLine."Needed by Date", QtyThisLine, QtyThisLineBase, CallTrackingSpecification);
until (ServiceLine.Next(NextStep) = 0) or (RemainingQtyToReserveBase = 0);
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnAutoTrackOnCheckSourceType', '', true, false)]
local procedure OnAutoTrackOnCheckSourceType(var ReservationEntry: Record "Reservation Entry"; var ShouldExit: Boolean)
begin
if ReservationEntry."Source Type" = Database::"Service 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', '', true, false)]
local procedure OnTestItemType(SourceRecRef: RecordRef)
var
ServiceLine: Record "Service Line";
begin
if SourceRecRef.Number = Database::"Service Line" then begin
SourceRecRef.SetTable(ServiceLine);
ServiceLine.TestField(Type, ServiceLine.Type::Item);
end;
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeTransServLineToItemJnlLine(var ServLine: Record "Service Line"; var ItemJnlLine: Record "Item Journal Line"; TransferQty: Decimal; var CheckApplFromItemEntry: Boolean; var Result: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransServLineToItemJnlLineOnBeforeTransferReservationEntry(var ReservationEntry: Record "Reservation Entry"; var ServiceLine: Record "Service Line"; var ItemJournalLine: Record "Item Journal Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnVerifyChangeOnBeforeHasError(NewServiceLine: Record "Service Line"; OldServiceLine: Record "Service Line"; var HasError: Boolean; var ShowError: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCallItemTrackingOnBeforeItemTrackingLinesRunModal(var ServiceLine: Record "Service Line"; var ItemTrackingLines: Page "Item Tracking Lines")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeVerifyChange(var NewServiceLine: Record "Service Line"; var OldServiceLine: Record "Service Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterReservQuantity(ServiceLine: Record "Service Line"; var QtyToReserve: Decimal; var QtyToReserveBase: Decimal)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnTransServLineToServLineOnBeforeCreateReservEntry(OldReservationEntry: Record "Reservation Entry"; OldServiceLine: Record "Service Line"; var TransferQty: Decimal; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCreateReservationOnBeforeCreateReservEntry(var ServiceLine: Record "Service Line"; var Quantity: Decimal; var QuantityBase: Decimal; var ForReservEntry: Record "Reservation Entry"; var IsHandled: Boolean; var FromTrackingSpecification: Record "Tracking Specification"; ExpectedReceiptDate: Date; Description: Text[100]; ShipmentDate: Date)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCreateReservation(var ServiceLine: Record "Service Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeAutoReserveServLine(ReservSummEntryNo: Integer; var RemainingQtyToReserve: Decimal; var RemainingQtyToReserveBase: Decimal; Description: Text[100]; AvailabilityDate: Date; var IsReserved: Boolean; Search: Text[1]; NextStep: Integer; CalcReservEntry: Record "Reservation Entry")
begin
end;
#if not CLEAN27
[Obsolete('This event is never raised.', '27.0')]
[IntegrationEvent(false, false)]
local procedure OnSetSourceForReservationOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; ServiceLine: Record "Service Line")
begin
end;
#endif
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnAutoReserveOnBeforeStopReservation', '', true, false)]
local procedure OnAutoReserveOnBeforeStopReservation(var CalcReservEntry: Record "Reservation Entry"; var StopReservation: Boolean);
begin
if MatchThisTable(CalcReservEntry."Source Type") then
StopReservation := not (CalcReservEntry."Source Subtype" = 1); // Only order
end;
// codeunit Reservation Engine Mgt. subscribers
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Engine Mgt.", 'OnRevertDateToSourceDate', '', true, false)]
local procedure OnRevertDateToSourceDate(var ReservEntry: Record "Reservation Entry")
var
ServiceLine: Record "Service Line";
begin
if ReservEntry."Source Type" = Database::"Service Line" then begin
ServiceLine.Get(ReservEntry."Source Subtype", ReservEntry."Source ID", ReservEntry."Source Ref. No.");
ReservEntry."Expected Receipt Date" := 0D;
ReservEntry."Shipment Date" := ServiceLine."Needed by Date";
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Engine Mgt.", 'OnGetActivePointerFieldsOnBeforeAssignArrayValues', '', true, false)]
local procedure OnGetActivePointerFieldsOnBeforeAssignArrayValues(TableID: Integer; var PointerFieldIsActive: array[6] of Boolean; var IsHandled: Boolean)
begin
if TableID = Database::"Service 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', '', true, false)]
local procedure OnAfterCreateText(ReservationEntry: Record "Reservation Entry"; var Description: Text[80])
var
ServiceLine: Record "Service Line";
begin
if ReservationEntry."Source Type" = Database::"Service Line" then
Description := StrSubstNo(SourceDoc2Txt, ServiceLine.TableCaption(), ReservationEntry."Source ID");
end;
procedure InitFromServLine(var TrackingSpecification: Record "Tracking Specification"; var ServiceLine: Record "Service Line"; Consume: Boolean)
begin
TrackingSpecification.Init();
TrackingSpecification.SetItemData(
ServiceLine."No.", ServiceLine.Description, ServiceLine."Location Code", ServiceLine."Variant Code", ServiceLine."Bin Code",
ServiceLine."Qty. per Unit of Measure", ServiceLine."Qty. Rounding Precision (Base)");
TrackingSpecification.SetSource(
Database::"Service Line", ServiceLine."Document Type".AsInteger(), ServiceLine."Document No.", ServiceLine."Line No.", '', 0);
TrackingSpecification."Quantity (Base)" := ServiceLine."Quantity (Base)";
if Consume then begin
TrackingSpecification."Qty. to Invoice (Base)" := ServiceLine."Qty. to Consume (Base)";
TrackingSpecification."Qty. to Invoice" := ServiceLine."Qty. to Consume";
TrackingSpecification."Quantity Invoiced (Base)" := ServiceLine."Qty. Consumed (Base)";
end else begin
TrackingSpecification."Qty. to Invoice (Base)" := ServiceLine."Qty. to Invoice (Base)";
TrackingSpecification."Qty. to Invoice" := ServiceLine."Qty. to Invoice";
TrackingSpecification."Quantity Invoiced (Base)" := ServiceLine."Qty. Invoiced (Base)";
end;
if ServiceLine."Document Type" = ServiceLine."Document Type"::"Credit Memo" then begin
TrackingSpecification."Qty. to Handle" := ServiceLine."Qty. to Invoice";
TrackingSpecification."Qty. to Handle (Base)" := ServiceLine."Qty. to Invoice (Base)";
TrackingSpecification."Quantity Handled (Base)" := ServiceLine."Qty. Invoiced (Base)";
end else begin
TrackingSpecification."Qty. to Handle" := ServiceLine."Qty. to Ship";
TrackingSpecification."Qty. to Handle (Base)" := ServiceLine."Qty. to Ship (Base)";
TrackingSpecification."Quantity Handled (Base)" := ServiceLine."Qty. Shipped (Base)";
end;
OnAfterInitFromServLine(TrackingSpecification, ServiceLine);
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInitFromServLine(var TrackingSpecification: Record "Tracking Specification"; ServiceLine: Record "Service Line")
begin
end;
[EventSubscriber(ObjectType::Table, Database::"Tracking Specification", 'OnBeforeCheckApplyFromItemEntrySourceType', '', true, false)]
local procedure OnBeforeCheckApplyFromItemEntrySourceType(var TrackingSpecification: Record "Tracking Specification"; var IsHandled: Boolean)
begin
if not MatchThisTable(TrackingSpecification."Source Type") then
exit;
if ((TrackingSpecification."Source Subtype" in [3]) and (TrackingSpecification."Quantity (Base)" < 0)) or
((TrackingSpecification."Source Subtype" in [1, 2]) and (TrackingSpecification."Quantity (Base)" > 0))
then
TrackingSpecification.FieldError("Quantity (Base)");
IsHandled := true;
end;
[EventSubscriber(ObjectType::Table, Database::"Reservation Entry", 'OnAfterSummEntryNo', '', true, false)]
local procedure OnBeforeSummEntryNo(ReservationEntry: Record "Reservation Entry"; var ReturnValue: Integer)
begin
if MatchThisTable(ReservationEntry."Source Type") then
ReturnValue := Enum::"Reservation Summary Type"::"Service Order".AsInteger();
end;
[EventSubscriber(ObjectType::Table, Database::"Reservation Entry", 'OnUpdateSourceCost', '', true, false)]
local procedure ReservationEntryOnUpdateSourceCost(ReservationEntry: Record "Reservation Entry"; UnitCost: Decimal)
var
ServiceLine: Record "Service Line";
QtyToReserveNonBase: Decimal;
QtyToReserve: Decimal;
QtyReservedNonBase: Decimal;
QtyReserved: Decimal;
begin
if MatchThisTable(ReservationEntry."Source Type") then begin
ServiceLine.Get(ReservationEntry."Source Subtype", ReservationEntry."Source ID", ReservationEntry."Source Ref. No.");
ServiceLine.GetReservationQty(QtyReservedNonBase, QtyReserved, QtyToReserveNonBase, QtyToReserve);
if ServiceLine."Qty. per Unit of Measure" <> 0 then
ServiceLine."Unit Cost (LCY)" :=
Round(ServiceLine."Unit Cost (LCY)" / ServiceLine."Qty. per Unit of Measure");
if ServiceLine."Quantity (Base)" <> 0 then
ServiceLine."Unit Cost (LCY)" :=
Round(
(ServiceLine."Unit Cost (LCY)" * (ServiceLine."Quantity (Base)" - QtyReserved) + UnitCost * QtyReserved) / ServiceLine."Quantity (Base)", 0.00001);
if ServiceLine."Qty. per Unit of Measure" <> 0 then
ServiceLine."Unit Cost (LCY)" :=
Round(ServiceLine."Unit Cost (LCY)" * ServiceLine."Qty. per Unit of Measure");
ServiceLine.Validate("Unit Cost (LCY)");
ServiceLine.Modify();
end;
end;
[EventSubscriber(ObjectType::Table, Database::"Requisition Line", 'OnReserveBindingOrder', '', true, false)]
local procedure OnReserveBindingOrder(var RequisitionLine: Record "Requisition Line"; TrackingSpecification: Record "Tracking Specification"; SourceDescription: Text[100]; ExpectedDate: Date; ReservQty: Decimal; ReservQtyBase: Decimal; UpdateReserve: Boolean)
begin
if RequisitionLine."Demand Type" = Database::"Service Line" then
ServiceLineBindToTracking(RequisitionLine, TrackingSpecification, SourceDescription, ExpectedDate, ReservQty, ReservQtyBase, UpdateReserve);
end;
local procedure ServiceLineBindToTracking(RequisitionLine: Record "Requisition Line"; TrackingSpecification: Record "Tracking Specification"; Description: Text[100]; ExpectedDate: Date; ReservQty: Decimal; ReservQtyBase: Decimal; UpdateReserve: Boolean)
var
ServiceLine: Record "Service Line";
begin
ServiceLine.Get(RequisitionLine."Demand Subtype", RequisitionLine."Demand Order No.", RequisitionLine."Demand Line No.");
BindToTracking(ServiceLine, TrackingSpecification, Description, ExpectedDate, ReservQty, ReservQtyBase);
if UpdateReserve then
if ServiceLine.Reserve = ServiceLine.Reserve::Never then begin
ServiceLine.Reserve := ServiceLine.Reserve::Optional;
ServiceLine.Modify();
end;
end;
// Codeunit "Req. Wksh.-Make Order"
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Req. Wksh.-Make Order", 'OnReserveBindingOrderToPurch', '', true, false)]
local procedure OnReserveBindingOrderToPurch(var RequisitionLine: Record "Requisition Line"; var PurchaseLine: Record "Purchase Line"; ReservQty: Decimal; ReservQtyBase: Decimal)
var
ServiceLine: Record "Service Line";
TrackingSpecification: Record "Tracking Specification";
ServiceLineReserve: Codeunit "Service Line-Reserve";
begin
case RequisitionLine."Demand Type" of
Database::"Service Line":
begin
ServiceLine.Get(RequisitionLine."Demand Subtype", RequisitionLine."Demand Order No.", RequisitionLine."Demand Line No.");
TrackingSpecification.InitTrackingSpecification(
DATABASE::"Purchase Line",
PurchaseLine."Document Type".AsInteger(), PurchaseLine."Document No.", '', 0, PurchaseLine."Line No.",
PurchaseLine."Variant Code", PurchaseLine."Location Code", PurchaseLine."Qty. per Unit of Measure");
ServiceLineReserve.BindToTracking(
ServiceLine, TrackingSpecification, PurchaseLine.Description, PurchaseLine."Expected Receipt Date", ReservQty, ReservQtyBase);
if ServiceLine.Reserve = ServiceLine.Reserve::Never then begin
ServiceLine.Reserve := ServiceLine.Reserve::Optional;
ServiceLine.Modify();
end;
end;
end;
end;
// Codeunit OrderTrackingManagement
[EventSubscriber(ObjectType::Codeunit, Codeunit::OrderTrackingManagement, 'OnSetSourceRecord', '', true, false)]
local procedure OrderTrackingManagementOnSetSourceRecord(var SourceRecordVar: Variant; var ReservationEntry: Record "Reservation Entry"; var ItemLedgerEntry2: Record "Item Ledger Entry")
var
ServiceLine: Record "Service Line";
SourceRecRef: RecordRef;
begin
SourceRecRef.GetTable(SourceRecordVar);
if MatchThisTable(SourceRecRef.Number) then begin
ServiceLine := SourceRecordVar;
SetServiceLine(ServiceLine, ReservationEntry, ItemLedgerEntry2);
end;
end;
local procedure SetServiceLine(var ServiceLine: Record "Service Line"; var ReservEntry: Record "Reservation Entry"; var ItemLedgerEntry: Record "Item Ledger Entry")
var
ServShptLine: Record Microsoft.Service.History."Service Shipment Line";
begin
ServiceLine.TestField(Type, ServiceLine.Type::Item);
ReservEntry."Source Type" := DATABASE::"Service Line";
ReservEntry.InitSortingAndFilters(false);
ServiceLine.SetReservationFilters(ReservEntry);
if ServiceLine."Qty. Shipped (Base)" <> 0 then begin
ServShptLine.SetCurrentKey("Order No.", "Order Line No.");
ServShptLine.SetRange("Order No.", ServiceLine."Document No.");
ServShptLine.SetRange("Order Line No.", ServiceLine."Line No.");
if ServShptLine.Find('-') then
repeat
if ItemLedgerEntry.Get(ServShptLine."Item Shpt. Entry No.") then
ItemLedgerEntry.Mark(true);
until ServShptLine.Next() = 0;
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::OrderTrackingManagement, 'OnInsertOrderTrackingEntry', '', true, false)]
local procedure OnInsertOrderTrackingEntry(var OrderTrackingEntry: Record "Order Tracking Entry")
var
ServiceLine: Record "Service Line";
begin
if OrderTrackingEntry."For Type" = DATABASE::"Service Line" then
if ServiceLine.Get(OrderTrackingEntry."For Subtype", OrderTrackingEntry."For ID", OrderTrackingEntry."For Ref. No.") then begin
OrderTrackingEntry."Starting Date" := ServiceLine."Needed by Date";
OrderTrackingEntry."Ending Date" := ServiceLine."Needed by Date";
end;
end;
[EventSubscriber(ObjectType::Report, Report::"Carry Out Reservation", 'OnCarryOutReservationOtherDemandType', '', true, false)]
local procedure OnCarryOutReservationOtherDemandType(var ReservationWkshLine: Record "Reservation Wksh. Line"; DemandType: Enum "Reservation Demand Type")
begin
case DemandType of
DemandType::"Service Orders":
ReservationWkshLine.SetRange("Source Type", Database::"Service Line");
end;
end;
procedure ServiceInvLineCheck(ServiceLine: Record "Service Line"; ForceRequest: Boolean)
var
ReservationEntry: Record "Reservation Entry";
ReservationCheckDateConfl: Codeunit "Reservation-Check Date Confl.";
begin
if not FindReservEntry(ServiceLine, ReservationEntry) then
exit;
if ReservationCheckDateConfl.DateConflict(ServiceLine."Needed by Date", ForceRequest, ReservationEntry) then
if ForceRequest then
ReservationCheckDateConfl.IssueError(ServiceLine."Needed by Date");
ReservationCheckDateConfl.UpdateDate(ReservationEntry, ServiceLine."Needed by Date");
ReservationManagement.SetReservSource(ServiceLine);
ReservationManagement.ClearSurplus();
ReservationManagement.AutoTrack(ServiceLine."Outstanding Qty. (Base)");
end;
[EventSubscriber(ObjectType::Table, Database::"Tracking Specification", 'OnGetSourceShipmentDate', '', true, false)]
local procedure OnGetSourceShipmentDate(var TrackingSpecification: Record "Tracking Specification"; var ShipmentDate: Date);
var
ServiceLine: Record "Service Line";
begin
if TrackingSpecification."Source Type" = Database::"Service Line" then begin
ServiceLine.Get(TrackingSpecification."Source Subtype", TrackingSpecification."Source ID", TrackingSpecification."Source Ref. No.");
ShipmentDate := ServiceLine."Needed by Date";
end;
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnAfterSetValueArrayForReservation', '', true, false)]
local procedure OnAfterSetValueArrayForReservation(var ValueArray: array[30] of Integer; var ArrayCounter: Integer)
begin
ArrayCounter += 1;
ValueArray[ArrayCounter] := Enum::"Reservation Summary Type"::"Service Order".AsInteger();
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnAfterSetValueArrayForOrderTracking', '', true, false)]
local procedure OnAfterSetValueArrayForOrderTracking(var ValueArray: array[30] of Integer; var ArrayCounter: Integer)
begin
ArrayCounter += 1;
ValueArray[ArrayCounter] := Enum::"Reservation Summary Type"::"Service Order".AsInteger();
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Reservation Management", 'OnSetSourceForServiceLine', '', true, false)]
local procedure OnSetSourceForServiceLine(SourceRecRef: RecordRef; var CalcReservEntry: Record "Reservation Entry"; var EntryIsPositive: Boolean)
var
ServiceLine: Record "Service Line";
begin
if not MatchThisTable(SourceRecRef.Number) then
exit;
SourceRecRef.SetTable(ServiceLine);
ServiceLine.SetReservationEntry(CalcReservEntry);
OnSetServLineOnBeforeUpdateReservation(CalcReservEntry, ServiceLine);
EntryIsPositive := (CreateReservEntry.SignFactor(CalcReservEntry) * ServiceLine."Outstanding Qty. (Base)") <= 0;
end;
[IntegrationEvent(false, false)]
local procedure OnSetServLineOnBeforeUpdateReservation(var ReservEntry: Record "Reservation Entry"; ServiceLine: Record Microsoft.Service.Document."Service Line")
begin
end;
}