Codeunit 5813 Undo Purchase Receipt Line, source in 29
Source29
src/Layers/W1/BaseApp/Purchases/History/UndoPurchaseReceiptLine.Codeunit.al829 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.History;
using Microsoft.Foundation.AuditCodes;
using Microsoft.Foundation.UOM;
using Microsoft.Inventory;
using Microsoft.Inventory.Costing;
using Microsoft.Inventory.Item;
using Microsoft.Inventory.Journal;
using Microsoft.Inventory.Ledger;
using Microsoft.Inventory.Posting;
using Microsoft.Inventory.Setup;
using Microsoft.Purchases.Document;
using Microsoft.Sales.History;
using Microsoft.Utilities;
using Microsoft.Warehouse.History;
using Microsoft.Warehouse.Journal;
using Microsoft.Warehouse.Ledger;
codeunit 5813 "Undo Purchase Receipt Line"
{
Permissions = TableData "Purchase Line" = rimd,
TableData "Purch. Rcpt. Line" = rimd,
TableData "Item Entry Relation" = ri,
TableData "Whse. Item Entry Relation" = rimd;
TableNo = "Purch. Rcpt. Line";
EventSubscriberInstance = Manual;
trigger OnRun()
var
SkipTypeCheck: Boolean;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeOnRun(Rec, IsHandled, SkipTypeCheck, HideDialog);
if IsHandled then
exit;
if not HideDialog then
if not Confirm(Text000) then
exit;
PurchRcptLine.Copy(Rec);
Code();
Rec := PurchRcptLine;
end;
var
PurchRcptLine: Record "Purch. Rcpt. Line";
TempWhseJnlLine: Record "Warehouse Journal Line" temporary;
TempGlobalItemLedgEntry: Record "Item Ledger Entry" temporary;
TempGlobalItemEntryRelation: Record "Item Entry Relation" temporary;
UndoPostingMgt: Codeunit "Undo Posting Management";
WhseUndoQty: Codeunit "Whse. Undo Quantity";
UOMMgt: Codeunit "Unit of Measure Management";
ItemsToAdjust: List of [Code[20]];
HideDialog: Boolean;
JobItem: Boolean;
UndoSalesShptLineExists: Boolean;
NextLineNo: Integer;
#pragma warning disable AA0074
Text000: Label 'Do you really want to undo the selected Receipt lines?';
Text001: Label 'Undo quantity posting...';
Text002: Label 'There is not enough space to insert correction lines.';
Text003: Label 'Checking lines...';
Text004: Label 'This receipt has already been invoiced. Undo Receipt can be applied only to posted, but not invoiced receipts.';
#pragma warning restore AA0074
NoLinesToReverseErr: Label 'No lines with a quantity available for reversal were found among the selected lines. Select a line with a quantity that has not already been reversed, and try again.';
AlreadyReversedErr: Label 'This receipt has already been reversed.';
AmbiguousDropShipmentLinkErr: Label 'The posted sales shipment line for drop shipment line %1 in posted purchase receipt %2 cannot be identified, because sales order %3 has more than one matching posted shipment line. Undo the shipment from the posted sales shipment instead.', Comment = '%1 - Purch. Rcpt. Line No., %2 - Purch. Rcpt. Header No., %3 - Sales Order No.';
procedure SetHideDialog(NewHideDialog: Boolean)
begin
HideDialog := NewHideDialog;
end;
local procedure "Code"()
var
PostedWhseRcptLine: Record "Posted Whse. Receipt Line";
PurchLine: Record "Purchase Line";
Window: Dialog;
ItemRcptEntryNo: Integer;
DocLineNo: Integer;
PostedWhseRcptLineFound: Boolean;
ShouldFindPostedWhseRcptLine: Boolean;
begin
OnBeforeCode(PurchRcptLine, UndoPostingMgt);
CheckPurchRcptLines(PurchRcptLine, Window);
BindSubscription(this);
PurchRcptLine.Find('-');
OnCodeOnBeforeLoopPurchRcptLine(PurchRcptLine);
repeat
TempGlobalItemLedgEntry.Reset();
if not TempGlobalItemLedgEntry.IsEmpty() then
TempGlobalItemLedgEntry.DeleteAll();
TempGlobalItemEntryRelation.Reset();
if not TempGlobalItemEntryRelation.IsEmpty() then
TempGlobalItemEntryRelation.DeleteAll();
if not HideDialog then
Window.Open(Text001);
UndoDropShipmentPurchRcptLine(PurchRcptLine);
ShouldFindPostedWhseRcptLine := PurchRcptLine.Type = PurchRcptLine.Type::Item;
OnCodeOnBeforeFindPostedWhseRcptLine(PurchRcptLine, ShouldFindPostedWhseRcptLine);
if ShouldFindPostedWhseRcptLine then begin
PostedWhseRcptLineFound :=
WhseUndoQty.FindPostedWhseRcptLine(
PostedWhseRcptLine,
DATABASE::"Purch. Rcpt. Line",
PurchRcptLine."Document No.",
DATABASE::"Purchase Line",
PurchLine."Document Type"::Order.AsInteger(),
PurchRcptLine."Order No.",
PurchRcptLine."Order Line No.");
ItemRcptEntryNo := PostItemJnlLine(PurchRcptLine, DocLineNo);
end else
DocLineNo := GetCorrectionLineNo(PurchRcptLine);
InsertNewReceiptLine(PurchRcptLine, ItemRcptEntryNo, DocLineNo);
OnAfterInsertNewReceiptLine(PurchRcptLine, PostedWhseRcptLine, PostedWhseRcptLineFound, DocLineNo, PostedWhseRcptLine);
if PostedWhseRcptLineFound then
WhseUndoQty.UndoPostedWhseRcptLine(PostedWhseRcptLine);
UpdateOrderLine(PurchRcptLine);
if PostedWhseRcptLineFound then
WhseUndoQty.UpdateRcptSourceDocLines(PostedWhseRcptLine);
if (PurchRcptLine."Blanket Order No." <> '') and (PurchRcptLine."Blanket Order Line No." <> 0) then
UpdateBlanketOrder(PurchRcptLine);
PurchRcptLine."Quantity Invoiced" := PurchRcptLine.Quantity;
PurchRcptLine."Qty. Invoiced (Base)" := PurchRcptLine."Quantity (Base)";
PurchRcptLine."Qty. Rcd. Not Invoiced" := 0;
PurchRcptLine.Correction := true;
OnBeforePurchRcptLineModify(PurchRcptLine, TempWhseJnlLine);
PurchRcptLine.Modify();
OnAfterPurchRcptLineModify(PurchRcptLine, TempWhseJnlLine, DocLineNo, UndoPostingMgt);
if not JobItem then
JobItem := (PurchRcptLine.Type = PurchRcptLine.Type::Item) and (PurchRcptLine."Job No." <> '');
until PurchRcptLine.Next() = 0;
UnbindSubscription(this);
OnCodeOnBeforeMakeInventoryAdjustment(PurchLine, PurchRcptLine);
MakeInventoryAdjustment();
WhseUndoQty.PostTempWhseJnlLine(TempWhseJnlLine);
OnAfterCode(PurchRcptLine, UndoPostingMgt);
end;
local procedure CheckPurchRcptLines(var PurchRcptLine: Record "Purch. Rcpt. Line"; var Window: Dialog)
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCheckPurchRcptLines(PurchRcptLine, Window, IsHandled);
if IsHandled then
exit;
PurchRcptLine.SetFilter(Quantity, '<>0');
PurchRcptLine.SetRange(Correction, false);
OnCheckPurchRcptLinesAfterPurchRcptLineSetFilters(PurchRcptLine);
if PurchRcptLine.IsEmpty() then
Error(NoLinesToReverseErr);
PurchRcptLine.FindFirst();
repeat
if not HideDialog then
Window.Open(Text003);
CheckPurchRcptLine(PurchRcptLine);
until PurchRcptLine.Next() = 0;
end;
local procedure CheckPurchRcptLine(PurchRcptLine: Record "Purch. Rcpt. Line")
var
TempItemLedgEntry: Record "Item Ledger Entry" temporary;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCheckPurchRcptLine(PurchRcptLine, IsHandled, TempItemLedgEntry);
if IsHandled then
exit;
if PurchRcptLine.Correction then
Error(AlreadyReversedErr);
if PurchRcptLine."Qty. Rcd. Not Invoiced" <> PurchRcptLine.Quantity then begin
if PurchRcptLine.IsProdOrder() then
Error(Text004);
if HasInvoicedNotReturnedQuantity(PurchRcptLine) then
Error(Text004);
end;
if PurchRcptLine.Type = PurchRcptLine.Type::Item then begin
UndoPostingMgt.TestPurchRcptLine(PurchRcptLine);
IsHandled := false;
OnCheckPurchRcptLineOnBeforeCollectItemLedgEntries(PurchRcptLine, TempItemLedgEntry, IsHandled);
if not IsHandled then
if PurchRcptLine.IsProdOrder() then begin
if UndoPostingMgt.CollectOutputItemLedgEntriesForSubcontructingPurcReceiptLine(TempItemLedgEntry, PurchRcptLine) then
UndoPostingMgt.CheckItemLedgEntries(TempItemLedgEntry, PurchRcptLine."Line No.", PurchRcptLine."Qty. Rcd. Not Invoiced" <> PurchRcptLine.Quantity);
end else begin
if (PurchRcptLine."Sales Order No." <> '') and (PurchRcptLine."Sales Order Line No." <> 0) then
exit;
UndoPostingMgt.CollectItemLedgEntries(TempItemLedgEntry, DATABASE::"Purch. Rcpt. Line",
PurchRcptLine."Document No.", PurchRcptLine."Line No.", PurchRcptLine."Quantity (Base)", PurchRcptLine."Item Rcpt. Entry No.");
UndoPostingMgt.CheckItemLedgEntries(TempItemLedgEntry, PurchRcptLine."Line No.", PurchRcptLine."Qty. Rcd. Not Invoiced" <> PurchRcptLine.Quantity);
end;
end;
end;
local procedure GetCorrectionLineNo(PurchRcptLine: Record "Purch. Rcpt. Line") Result: Integer
var
PurchRcptLine2: Record "Purch. Rcpt. Line";
LineSpacing: Integer;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetCorrectionLineNo(PurchRcptLine, Result, IsHandled);
if IsHandled then
exit(Result);
PurchRcptLine2.SetRange("Document No.", PurchRcptLine."Document No.");
PurchRcptLine2."Document No." := PurchRcptLine."Document No.";
PurchRcptLine2."Line No." := PurchRcptLine."Line No.";
PurchRcptLine2.Find('=');
if PurchRcptLine2.Find('>') then begin
LineSpacing := (PurchRcptLine2."Line No." - PurchRcptLine."Line No.") div 2;
if LineSpacing = 0 then
Error(Text002);
end else
LineSpacing := 10000;
exit(PurchRcptLine."Line No." + LineSpacing);
end;
local procedure PostItemJnlLine(PurchRcptLine: Record "Purch. Rcpt. Line"; var DocLineNo: Integer): Integer
var
ItemJnlLine: Record "Item Journal Line";
PurchLine: Record "Purchase Line";
PurchRcptHeader: Record "Purch. Rcpt. Header";
SourceCodeSetup: Record "Source Code Setup";
TempApplyToEntryList: Record "Item Ledger Entry" temporary;
ItemApplicationEntry: Record "Item Application Entry";
ItemLedgerEntry: Record "Item Ledger Entry";
Item: Record Item;
ItemJnlPostLine: Codeunit "Item Jnl.-Post Line";
ItemLedgEntryNo: Integer;
ItemRcptEntryNo: Integer;
ItemShptEntryNo: Integer;
IsHandled: Boolean;
NewDocLineNo: Integer;
ItemRcptEntryNoFilled: Boolean;
begin
IsHandled := false;
OnBeforePostItemJnlLine(PurchRcptLine, DocLineNo, ItemLedgEntryNo, IsHandled, NewDocLineNo, TempWhseJnlLine);
if NewDocLineNo > DocLineNo then
DocLineNo := NewDocLineNo;
if IsHandled then
exit(ItemLedgEntryNo);
if NewDocLineNo = 0 then
DocLineNo := GetCorrectionLineNo(PurchRcptLine);
SourceCodeSetup.Get();
PurchRcptHeader.Get(PurchRcptLine."Document No.");
ItemJnlLine.Init();
ItemJnlLine."Entry Type" := ItemJnlLine."Entry Type"::Purchase;
ItemJnlLine."Item No." := PurchRcptLine."No.";
ItemJnlLine."Posting Date" := PurchRcptHeader."Posting Date";
ItemJnlLine."Document No." := PurchRcptLine."Document No.";
ItemJnlLine."Document Line No." := DocLineNo;
ItemJnlLine."Document Type" := ItemJnlLine."Document Type"::"Purchase Receipt";
ItemJnlLine."Gen. Bus. Posting Group" := PurchRcptLine."Gen. Bus. Posting Group";
ItemJnlLine."Gen. Prod. Posting Group" := PurchRcptLine."Gen. Prod. Posting Group";
ItemJnlLine."Location Code" := PurchRcptLine."Location Code";
ItemJnlLine."Source Code" := SourceCodeSetup.Purchases;
ItemJnlLine."Variant Code" := PurchRcptLine."Variant Code";
ItemJnlLine."Bin Code" := PurchRcptLine."Bin Code";
ItemJnlLine."Unit of Measure Code" := PurchRcptLine."Unit of Measure Code";
ItemJnlLine."Qty. per Unit of Measure" := PurchRcptLine."Qty. per Unit of Measure";
ItemJnlLine."Document Date" := PurchRcptHeader."Document Date";
ItemJnlLine."Shortcut Dimension 1 Code" := PurchRcptLine."Shortcut Dimension 1 Code";
ItemJnlLine."Shortcut Dimension 2 Code" := PurchRcptLine."Shortcut Dimension 2 Code";
ItemJnlLine."Dimension Set ID" := PurchRcptLine."Dimension Set ID";
ItemJnlLine.Description := PurchRcptLine.Description;
ItemJnlLine."Drop Shipment" := (PurchRcptLine."Sales Order No." <> '') and (PurchRcptLine."Sales Order Line No." <> 0);
if PurchRcptLine."Job No." = '' then begin
ItemJnlLine.Correction := true;
ItemJnlLine."Applies-to Entry" := PurchRcptLine."Item Rcpt. Entry No.";
end else begin
ItemJnlLine."Job No." := PurchRcptLine."Job No.";
ItemJnlLine."Job Task No." := PurchRcptLine."Job Task No.";
ItemJnlLine."Job Purchase" := true;
ItemJnlLine."Unit Cost" := PurchRcptLine."Unit Cost (LCY)";
end;
ItemJnlLine.Quantity := -(PurchRcptLine.Quantity - PurchRcptLine."Quantity Invoiced");
ItemJnlLine."Quantity (Base)" := -(PurchRcptLine."Quantity (Base)" - PurchRcptLine."Qty. Invoiced (Base)");
ItemRcptEntryNoFilled := PurchRcptLine."Item Rcpt. Entry No." <> 0;
if PurchRcptLine.IsProdOrder() then
OnUpdateItemJnlLineProdOrderSubcontracting(ItemJnlLine, PurchRcptLine, TempApplyToEntryList, ItemRcptEntryNoFilled);
IsHandled := false;
OnAfterCopyItemJnlLineFromPurchRcpt(ItemJnlLine, PurchRcptHeader, PurchRcptLine, WhseUndoQty, ItemLedgEntryNo, NextLineNo, TempWhseJnlLine, TempGlobalItemLedgEntry, TempGlobalItemEntryRelation, IsHandled);
if IsHandled then
exit(ItemLedgEntryNo);
WhseUndoQty.InsertTempWhseJnlLine(ItemJnlLine,
DATABASE::"Purchase Line", PurchLine."Document Type"::Order.AsInteger(), PurchRcptLine."Order No.", PurchRcptLine."Order Line No.",
TempWhseJnlLine."Reference Document"::"Posted Rcpt.".AsInteger(), TempWhseJnlLine, NextLineNo);
OnPostItemJnlLineOnAfterInsertTempWhseJnlLine(PurchRcptLine, ItemJnlLine, TempWhseJnlLine, NextLineNo);
if ItemRcptEntryNoFilled then begin
if PurchRcptLine."Job No." <> '' then
UndoPostingMgt.TransferSourceValues(ItemJnlLine, PurchRcptLine."Item Rcpt. Entry No.");
IsHandled := false;
OnPostItemJnlLineOnBeforeUndoPosting(ItemJnlLine, PurchRcptHeader, PurchRcptLine, SourceCodeSetup, IsHandled);
if IsHandled then
exit(ItemJnlLine."Item Shpt. Entry No.");
UndoPostingMgt.PostItemJnlLine(ItemJnlLine);
IsHandled := false;
OnPostItemJnlLineOnBeforeUndoValuePostingWithJob(PurchRcptHeader, PurchRcptLine, ItemJnlLine, IsHandled);
if not IsHandled then
if PurchRcptLine."Job No." <> '' then begin
Item.Get(PurchRcptLine."No.");
if Item.Type = Item.Type::Inventory then begin
ItemLedgerEntry.Get(PurchRcptLine."Item Rcpt. Entry No.");
if ItemLedgerEntry.Positive then begin
ItemRcptEntryNo := PurchRcptLine."Item Rcpt. Entry No.";
ItemShptEntryNo := ItemJnlLine."Item Shpt. Entry No.";
end else begin
ItemApplicationEntry.GetInboundEntriesTheOutbndEntryAppliedTo(PurchRcptLine."Item Rcpt. Entry No.");
ItemRcptEntryNo := ItemApplicationEntry."Inbound Item Entry No.";
ItemApplicationEntry.GetOutboundEntriesAppliedToTheInboundEntry(ItemJnlLine."Item Shpt. Entry No.");
ItemShptEntryNo := ItemApplicationEntry."Outbound Item Entry No.";
end;
UndoPostingMgt.FindItemReceiptApplication(ItemApplicationEntry, ItemRcptEntryNo);
ItemJnlPostLine.UndoValuePostingWithJob(
ItemRcptEntryNo, ItemApplicationEntry."Outbound Item Entry No.");
IsHandled := false;
OnPostItemJournalInboundItemEntryPostingWithJob(ItemJnlLine, ItemApplicationEntry, IsHandled);
if not IsHandled then begin
UndoPostingMgt.FindItemShipmentApplication(ItemApplicationEntry, ItemShptEntryNo);
ItemJnlPostLine.UndoValuePostingWithJob(
ItemApplicationEntry."Inbound Item Entry No.", ItemShptEntryNo);
end;
Clear(UndoPostingMgt);
UndoPostingMgt.ReapplyJobConsumption(ItemRcptEntryNo);
end;
end;
exit(ItemShptEntryNo);
end;
if not PurchRcptLine.IsProdOrder() then
UndoPostingMgt.CollectItemLedgEntries(
TempApplyToEntryList, DATABASE::"Purch. Rcpt. Line", PurchRcptLine."Document No.", PurchRcptLine."Line No.", PurchRcptLine."Quantity (Base)", PurchRcptLine."Item Rcpt. Entry No.");
if PurchRcptLine.IsProdOrder() then //When subcontracting base value is 0, value required for UndoPostingMgt.PostItemJnlLineAppliedToList call
PurchRcptLine."Quantity (Base)" := UOMMgt.CalcBaseQty(PurchRcptLine."No.", '', PurchRcptLine."Unit of Measure Code", PurchRcptLine.Quantity, PurchRcptLine."Qty. per Unit of Measure", 0);
IsHandled := false;
OnPostItemJnlLineOnAfterCollectItemLedgEntries(PurchRcptHeader, PurchRcptLine, SourceCodeSetup, IsHandled);
if IsHandled then
exit(0);
// "Item Shpt. Entry No."
if PurchRcptLine."Job No." <> '' then
ReapplyJobConsumptionFromApplyToEntryList(PurchRcptHeader, PurchRcptLine, ItemJnlLine, TempApplyToEntryList);
if ItemJnlLine.Subcontracting and (TempApplyToEntryList.Count() = 0) then //if no output posted
UndoPostingMgt.PostItemJnlLine(ItemJnlLine)
else
UndoPostingMgt.PostItemJnlLineAppliedToList(ItemJnlLine, TempApplyToEntryList,
PurchRcptLine.Quantity - PurchRcptLine."Quantity Invoiced", PurchRcptLine."Quantity (Base)" - PurchRcptLine."Qty. Invoiced (Base)", TempGlobalItemLedgEntry, TempGlobalItemEntryRelation, PurchRcptLine."Qty. Rcd. Not Invoiced" <> PurchRcptLine.Quantity);
exit(0); // "Item Shpt. Entry No."
end;
local procedure ReapplyJobConsumptionFromApplyToEntryList(PurchRcptHeader: Record "Purch. Rcpt. Header"; PurchRcptLine: Record "Purch. Rcpt. Line"; ItemJnlLine: Record "Item Journal Line"; var TempApplyToEntryList: Record "Item Ledger Entry" temporary)
var
TempItemLedgerEntry: Record "Item Ledger Entry" temporary;
ShowAppliedEntries: Codeunit "Show Applied Entries";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeReapplyJobConsumptionFromApplyToEntryList(PurchRcptHeader, PurchRcptLine, ItemJnlLine, TempApplyToEntryList, IsHandled);
if IsHandled then
exit;
if TempApplyToEntryList.FindSet() then
repeat
//negative purchase receipt linked with job
if (TempApplyToEntryList."Entry Type" = TempApplyToEntryList."Entry Type"::Purchase) and (TempApplyToEntryList."Document Type" = TempApplyToEntryList."Document Type"::"Purchase Receipt") and (TempApplyToEntryList.Quantity < 0) and (TempApplyToEntryList."Job No." <> '') then begin
ShowAppliedEntries.FindAppliedEntries(TempApplyToEntryList, TempItemLedgerEntry);
TempItemLedgerEntry.FindSet();
repeat
UndoPostingMgt.ReapplyJobConsumption(TempItemLedgerEntry."Entry No.");
until TempItemLedgerEntry.Next() = 0;
end else
UndoPostingMgt.ReapplyJobConsumption(TempApplyToEntryList."Entry No.");
until TempApplyToEntryList.Next() = 0;
end;
local procedure InsertNewReceiptLine(OldPurchRcptLine: Record "Purch. Rcpt. Line"; ItemRcptEntryNo: Integer; DocLineNo: Integer)
var
NewPurchRcptLine: Record "Purch. Rcpt. Line";
SkipInsertItemEntryRelation: Boolean;
begin
NewPurchRcptLine.Init();
NewPurchRcptLine.Copy(OldPurchRcptLine);
NewPurchRcptLine."Line No." := DocLineNo;
NewPurchRcptLine."Appl.-to Item Entry" := OldPurchRcptLine."Item Rcpt. Entry No.";
NewPurchRcptLine."Item Rcpt. Entry No." := ItemRcptEntryNo;
NewPurchRcptLine.Quantity := -OldPurchRcptLine.Quantity;
NewPurchRcptLine."Quantity (Base)" := -OldPurchRcptLine."Quantity (Base)";
NewPurchRcptLine."Quantity Invoiced" := NewPurchRcptLine.Quantity;
NewPurchRcptLine."Qty. Invoiced (Base)" := NewPurchRcptLine."Quantity (Base)";
NewPurchRcptLine."Qty. Rcd. Not Invoiced" := 0;
NewPurchRcptLine.Correction := true;
NewPurchRcptLine."Dimension Set ID" := OldPurchRcptLine."Dimension Set ID";
OnBeforeNewPurchRcptLineInsert(NewPurchRcptLine, OldPurchRcptLine);
NewPurchRcptLine.Insert();
SkipInsertItemEntryRelation := false;
OnAfterNewPurchRcptLineInsert(NewPurchRcptLine, OldPurchRcptLine, TempGlobalItemEntryRelation, SkipInsertItemEntryRelation);
if not SkipInsertItemEntryRelation then
InsertItemEntryRelation(TempGlobalItemEntryRelation, NewPurchRcptLine);
end;
procedure UpdateOrderLine(PurchRcptLine: Record "Purch. Rcpt. Line")
var
PurchLine: Record "Purchase Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeUpdateOrderLine(PurchRcptLine, IsHandled);
if IsHandled then
exit;
PurchLine.Get(PurchLine."Document Type"::Order, PurchRcptLine."Order No.", PurchRcptLine."Order Line No.");
OnUpdateOrderLineOnBeforeUpdatePurchLine(PurchRcptLine, PurchLine);
UndoPostingMgt.UpdatePurchLine(PurchLine, PurchRcptLine.Quantity - PurchRcptLine."Quantity Invoiced", PurchRcptLine."Quantity (Base)" - PurchRcptLine."Qty. Invoiced (Base)", TempGlobalItemLedgEntry);
UndoPostingMgt.UpdatePurchaseLineOverRcptQty(PurchLine, PurchRcptLine."Over-Receipt Quantity");
OnAfterUpdateOrderLine(PurchRcptLine, PurchLine);
end;
procedure UpdateBlanketOrder(PurchRcptLine: Record "Purch. Rcpt. Line")
var
BlanketOrderPurchaseLine: Record "Purchase Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeUpdateBlanketOrder(PurchRcptLine, IsHandled);
if IsHandled then
exit;
if BlanketOrderPurchaseLine.Get(
BlanketOrderPurchaseLine."Document Type"::"Blanket Order", PurchRcptLine."Blanket Order No.", PurchRcptLine."Blanket Order Line No.")
then begin
BlanketOrderPurchaseLine.TestField(Type, PurchRcptLine.Type);
BlanketOrderPurchaseLine.TestField("No.", PurchRcptLine."No.");
BlanketOrderPurchaseLine.TestField("Buy-from Vendor No.", PurchRcptLine."Buy-from Vendor No.");
if BlanketOrderPurchaseLine."Qty. per Unit of Measure" = PurchRcptLine."Qty. per Unit of Measure" then
BlanketOrderPurchaseLine."Quantity Received" := BlanketOrderPurchaseLine."Quantity Received" - PurchRcptLine.Quantity
else
BlanketOrderPurchaseLine."Quantity Received" :=
BlanketOrderPurchaseLine."Quantity Received" -
Round(
PurchRcptLine."Qty. per Unit of Measure" / BlanketOrderPurchaseLine."Qty. per Unit of Measure" * PurchRcptLine.Quantity, UOMMgt.QtyRndPrecision());
BlanketOrderPurchaseLine."Qty. Received (Base)" := BlanketOrderPurchaseLine."Qty. Received (Base)" - PurchRcptLine."Quantity (Base)";
OnBeforeBlanketOrderInitOutstanding(BlanketOrderPurchaseLine, PurchRcptLine);
BlanketOrderPurchaseLine.InitOutstanding();
BlanketOrderPurchaseLine.Modify();
end;
end;
local procedure InsertItemEntryRelation(var TempItemEntryRelation: Record "Item Entry Relation" temporary; NewPurchRcptLine: Record "Purch. Rcpt. Line")
var
ItemEntryRelation: Record "Item Entry Relation";
begin
if TempItemEntryRelation.Find('-') then
repeat
ItemEntryRelation := TempItemEntryRelation;
ItemEntryRelation.TransferFieldsPurchRcptLine(NewPurchRcptLine);
ItemEntryRelation.Insert();
until TempItemEntryRelation.Next() = 0;
end;
procedure HasInvoicedNotReturnedQuantity(PurchRcptLine: Record "Purch. Rcpt. Line"): Boolean
var
ItemLedgerEntry: Record "Item Ledger Entry";
ReturnedInvoicedItemLedgerEntry: Record "Item Ledger Entry";
ItemApplicationEntry: Record "Item Application Entry";
PurchInvHeader: Record "Purch. Inv. Header";
PurchInvLine: Record "Purch. Inv. Line";
InvoicedQuantity: Decimal;
ReturnedInvoicedQuantity: Decimal;
begin
if PurchRcptLine.Type = PurchRcptLine.Type::Item then begin
ItemLedgerEntry.SetRange("Document Type", ItemLedgerEntry."Document Type"::"Purchase Receipt");
ItemLedgerEntry.SetRange("Entry Type", ItemLedgerEntry."Entry Type"::"Purchase");
ItemLedgerEntry.SetRange("Document No.", PurchRcptLine."Document No.");
ItemLedgerEntry.SetRange("Document Line No.", PurchRcptLine."Line No.");
ItemLedgerEntry.SetLoadFields("Invoiced Quantity", "Entry No.");
ItemLedgerEntry.FindSet();
repeat
InvoicedQuantity += ItemLedgerEntry."Invoiced Quantity";
if ItemApplicationEntry.AppliedOutbndEntryExists(ItemLedgerEntry."Entry No.", false, false) then
repeat
if ItemApplicationEntry."Item Ledger Entry No." = ItemApplicationEntry."Outbound Item Entry No." then begin
ReturnedInvoicedItemLedgerEntry.Get(ItemApplicationEntry."Item Ledger Entry No.");
if IsCancelled(ReturnedInvoicedItemLedgerEntry) then
ReturnedInvoicedQuantity += ReturnedInvoicedItemLedgerEntry."Invoiced Quantity";
end;
until ItemApplicationEntry.Next() = 0;
until ItemLedgerEntry.Next() = 0;
exit(InvoicedQuantity + ReturnedInvoicedQuantity <> 0);
end else begin
PurchInvLine.SetRange("Order No.", PurchRcptLine."Order No.");
PurchInvLine.SetRange("Order Line No.", PurchRcptLine."Order Line No.");
if PurchInvLine.FindSet() then
repeat
PurchInvHeader.Get(PurchInvLine."Document No.");
PurchInvHeader.CalcFields(Cancelled);
if not PurchInvHeader.Cancelled then
exit(true);
until PurchInvLine.Next() = 0;
exit(false);
end;
end;
local procedure IsCancelled(ItemLedgerEntry: Record "Item Ledger Entry"): Boolean
var
CancelledDocument: Record "Cancelled Document";
ReturnShipmentHeader: Record "Return Shipment Header";
PurchCrMemoHdr: Record "Purch. Cr. Memo Hdr.";
begin
case ItemLedgerEntry."Document Type" of
ItemLedgerEntry."Document Type"::"Purchase Return Shipment":
begin
ReturnShipmentHeader.Get(ItemLedgerEntry."Document No.");
if ReturnShipmentHeader."Applies-to Doc. Type" = ReturnShipmentHeader."Applies-to Doc. Type"::Invoice then
exit(CancelledDocument.Get(Database::"Purch. Inv. Header", ReturnShipmentHeader."Applies-to Doc. No."));
end;
ItemLedgerEntry."Document Type"::"Purchase Credit Memo":
begin
PurchCrMemoHdr.Get(ItemLedgerEntry."Document No.");
if PurchCrMemoHdr."Applies-to Doc. Type" = PurchCrMemoHdr."Applies-to Doc. Type"::Invoice then
exit(CancelledDocument.Get(Database::"Purch. Inv. Header", PurchCrMemoHdr."Applies-to Doc. No."));
end;
end;
exit(false);
end;
local procedure MakeInventoryAdjustment()
var
InvtAdjmtHandler: Codeunit "Inventory Adjustment Handler";
begin
InvtAdjmtHandler.SetJobUpdateProperties(not JobItem);
InvtAdjmtHandler.MakeAutomaticInventoryAdjustment(ItemsToAdjust);
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Item Jnl.-Post Line", 'OnSetItemAdjmtPropertiesOnBeforeCheckModifyItem', '', false, false)]
local procedure OnSetItemAdjmtPropertiesOnBeforeCheckModifyItem(var Item2: Record Item)
var
InventorySetup: Record "Inventory Setup";
begin
if InventorySetup.UseLegacyPosting() then
exit;
if not ItemsToAdjust.Contains(Item2."No.") then
ItemsToAdjust.Add(Item2."No.");
end;
local procedure UndoDropShipmentPurchRcptLine(var PurchRcptLine: Record "Purch. Rcpt. Line")
var
SalesShipmentLine: Record "Sales Shipment Line";
UndoSalesShipmentLine: Codeunit "Undo Sales Shipment Line";
begin
if (PurchRcptLine."Sales Order No." = '') and (PurchRcptLine."Sales Order Line No." = 0) then
exit;
if UndoSalesShptLineExists then
exit;
FindSalesShipmentLine(SalesShipmentLine, PurchRcptLine);
UndoSalesShipmentLine.SetHideDialog(true);
UndoSalesShipmentLine.SetCalledFromUndoPurchaseReceiptLine(true);
UndoSalesShipmentLine.Run(SalesShipmentLine);
end;
local procedure FindSalesShipmentLine(var SalesShipmentLine: Record "Sales Shipment Line"; PurchRcptLine: Record "Purch. Rcpt. Line")
var
InboundItemLedgerEntry, OutboundItemLedgerEntry : Record "Item Ledger Entry";
ItemApplicationEntry: Record "Item Application Entry";
begin
InboundItemLedgerEntry.SetLoadFields("Document No.", "Document Line No.", "Entry No.");
InboundItemLedgerEntry.SetRange("Document No.", PurchRcptLine."Document No.");
InboundItemLedgerEntry.SetRange("Document Line No.", PurchRcptLine."Line No.");
if InboundItemLedgerEntry.FindFirst() then begin
ItemApplicationEntry.SetLoadFields("Inbound Item Entry No.", "Outbound Item Entry No.");
ItemApplicationEntry.SetRange("Inbound Item Entry No.", InboundItemLedgerEntry."Entry No.");
ItemApplicationEntry.SetFilter("Outbound Item Entry No.", '<>%1', 0);
if ItemApplicationEntry.FindFirst() then begin
OutboundItemLedgerEntry.Get(ItemApplicationEntry."Outbound Item Entry No.");
SalesShipmentLine.SetRange("Document No.", OutboundItemLedgerEntry."Document No.");
SalesShipmentLine.SetRange("Line No.", OutboundItemLedgerEntry."Document Line No.");
if (OutboundItemLedgerEntry."Lot No." = '') and (OutboundItemLedgerEntry."Serial No." = '') then begin
SalesShipmentLine.SetRange("Item Shpt. Entry No.", OutboundItemLedgerEntry."Entry No.");
if SalesShipmentLine.FindFirst() then
exit;
SalesShipmentLine.SetRange("Item Shpt. Entry No.");
end;
if SalesShipmentLine.FindFirst() then
exit;
end;
end;
FindSalesShipmentLineByDropShipmentLink(SalesShipmentLine, PurchRcptLine);
end;
local procedure FindSalesShipmentLineByDropShipmentLink(var SalesShipLine: Record "Sales Shipment Line"; PurchReceiptLine: Record "Purch. Rcpt. Line")
begin
SalesShipLine.Reset();
SalesShipLine.SetRange("Order No.", PurchReceiptLine."Sales Order No.");
SalesShipLine.SetRange("Order Line No.", PurchReceiptLine."Sales Order Line No.");
SalesShipLine.SetRange("Purchase Order No.", PurchReceiptLine."Order No.");
SalesShipLine.SetRange("Purch. Order Line No.", PurchReceiptLine."Order Line No.");
SalesShipLine.SetRange("Drop Shipment", true);
SalesShipLine.SetRange(Correction, false);
SalesShipLine.SetRange(Quantity, PurchReceiptLine.Quantity);
if SalesShipLine.Count() > 1 then
Error(AmbiguousDropShipmentLinkErr, PurchReceiptLine."Line No.", PurchReceiptLine."Document No.", PurchReceiptLine."Sales Order No.");
SalesShipLine.FindFirst();
end;
procedure IsUndoSalesShipmentLineForDropShipment(NewUndoSalesShptLineExists: Boolean)
begin
UndoSalesShptLineExists := NewUndoSalesShptLineExists;
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCode(var PurchRcptLine: Record "Purch. Rcpt. Line"; var UndoPostingManagement: Codeunit "Undo Posting Management")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterCopyItemJnlLineFromPurchRcpt(var ItemJournalLine: Record "Item Journal Line"; PurchRcptHeader: Record "Purch. Rcpt. Header"; var PurchRcptLine: Record "Purch. Rcpt. Line"; var WhseUndoQty: Codeunit "Whse. Undo Quantity"; var ItemLedgEntryNo: Integer; var NextLineNo: Integer; var TempWhseJnlLine: Record "Warehouse Journal Line" temporary; var TempGlobalItemLedgerEntry: Record "Item Ledger Entry" temporary; var TempGlobalItemEntryRelation: Record "Item Entry Relation" temporary; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterInsertNewReceiptLine(var PurchRcptLine: Record "Purch. Rcpt. Line"; PostedWhseReceiptLine: Record "Posted Whse. Receipt Line"; var PostedWhseRcptLineFound: Boolean; DocLineNo: Integer; var PostedWhseRcptLine: Record "Posted Whse. Receipt Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCodeOnBeforeFindPostedWhseRcptLine(var PurchRcptLine: Record "Purch. Rcpt. Line"; var ShouldFindPostedWhseRcptLine: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterNewPurchRcptLineInsert(var NewPurchRcptLine: Record "Purch. Rcpt. Line"; OldPurchRcptLine: Record "Purch. Rcpt. Line"; var TempGlobalItemEntryRelation: Record "Item Entry Relation" temporary; var SkipInsertItemEntryRelation: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterPurchRcptLineModify(var PurchRcptLine: Record "Purch. Rcpt. Line"; var TempWhseJnlLine: Record "Warehouse Journal Line" temporary; DocLineNo: Integer; var UndoPostingManagement: Codeunit "Undo Posting Management")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnAfterUpdateOrderLine(var PurchRcptLine: Record "Purch. Rcpt. Line"; var PurchLine: Record "Purchase Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeBlanketOrderInitOutstanding(var BlanketOrderPurchaseLine: Record "Purchase Line"; PurchRcptLine: Record "Purch. Rcpt. Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCheckPurchRcptLine(var PurchRcptLine: Record "Purch. Rcpt. Line"; var IsHandled: Boolean; var TempItemLedgerEntry: Record "Item Ledger Entry" temporary)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCode(var PurchRcptLine: Record "Purch. Rcpt. Line"; var UndoPostingManagement: Codeunit "Undo Posting Management")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCheckPurchRcptLines(var PurchRcptLine: Record "Purch. Rcpt. Line"; var Window: Dialog; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeGetCorrectionLineNo(PurchRcptLine: Record "Purch. Rcpt. Line"; var Result: Integer; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeNewPurchRcptLineInsert(var NewPurchRcptLine: Record "Purch. Rcpt. Line"; OldPurchRcptLine: Record "Purch. Rcpt. Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeOnRun(var PurchRcptLine: Record "Purch. Rcpt. Line"; var IsHandled: Boolean; var SkipTypeCheck: Boolean; var HideDialog: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforePostItemJnlLine(var PurchRcptLine: Record "Purch. Rcpt. Line"; DocLineNo: Integer; var ItemLedgEntryNo: Integer; var IsHandled: Boolean; var NewDocLineNo: Integer; var TempWarehouseJournalLine: Record "Warehouse Journal Line" temporary)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforePurchRcptLineModify(var PurchRcptLine: Record "Purch. Rcpt. Line"; var TempWarehouseJournalLine: Record "Warehouse Journal Line" temporary)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeReapplyJobConsumptionFromApplyToEntryList(PurchRcptHeader: Record "Purch. Rcpt. Header"; PurchRcptLine: Record "Purch. Rcpt. Line"; ItemJnlLine: Record "Item Journal Line"; var TempApplyToEntryList: Record "Item Ledger Entry" temporary; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateBlanketOrder(var PurchRcptLine: Record "Purch. Rcpt. Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateOrderLine(var PurchRcptLine: Record "Purch. Rcpt. Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostItemJournalInboundItemEntryPostingWithJob(var ItemJournalLine: Record "Item Journal Line"; ItemApplicationEntry: Record "Item Application Entry"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostItemJnlLineOnAfterCollectItemLedgEntries(var PurchRcptHeader: Record "Purch. Rcpt. Header"; var PurchRcptLine: Record "Purch. Rcpt. Line"; SourceCodeSetup: Record "Source Code Setup"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostItemJnlLineOnAfterInsertTempWhseJnlLine(PurchRcptLine: Record "Purch. Rcpt. Line"; var ItemJnlLine: Record "Item Journal Line"; var TempWhseJnlLine: Record "Warehouse Journal Line" temporary; var NextLineNo: Integer)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostItemJnlLineOnBeforeUndoPosting(var ItemJournalLine: Record "Item Journal Line"; var PurchRcptHeader: Record "Purch. Rcpt. Header"; var PurchRcptLine: Record "Purch. Rcpt. Line"; SourceCodeSetup: Record "Source Code Setup"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnPostItemJnlLineOnBeforeUndoValuePostingWithJob(PurchRcptHeader: Record "Purch. Rcpt. Header"; PurchRcptLine: Record "Purch. Rcpt. Line"; var ItemJnlLine: Record "Item Journal Line"; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateOrderLineOnBeforeUpdatePurchLine(var PurchRcptLine: Record "Purch. Rcpt. Line"; var PurchaseLine: Record "Purchase Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCheckPurchRcptLinesAfterPurchRcptLineSetFilters(var PurchRcptLine: Record "Purch. Rcpt. Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCheckPurchRcptLineOnBeforeCollectItemLedgEntries(var PurchRcptLine: Record "Purch. Rcpt. Line"; var TempItemLedgEntry: Record "Item Ledger Entry" temporary; var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnCodeOnBeforeLoopPurchRcptLine(var PurchRcptLine: Record "Purch. Rcpt. Line")
begin
end;
#if not CLEAN28
[Obsolete('This event is no longer used.', '28.0')]
[IntegrationEvent(false, false)]
local procedure OnBeforeCheckPurchRcptLineFields(var PurchRcptLine: Record "Purch. Rcpt. Line"; var IsHandled: Boolean)
begin
end;
#endif
[IntegrationEvent(false, false)]
local procedure OnCodeOnBeforeMakeInventoryAdjustment(var PurchaseLine: Record "Purchase Line"; var PurchaseReceiptLine: Record "Purch. Rcpt. Line")
begin
end;
[IntegrationEvent(false, false)]
local procedure OnUpdateItemJnlLineProdOrderSubcontracting(var ItemJnlLine: Record "Item Journal Line"; var PurchRcptLine: Record "Purch. Rcpt. Line"; var TempOutputItemLedgerEntry: Record "Item Ledger Entry" temporary; var OneLinePostingUndo: Boolean)
begin
end;
}