From 6f737739e3c61cb96455bac81d6f9f7cbb2df500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joshua=20Mart=C3=ADnez=20Pineda?= Date: Fri, 21 Aug 2026 18:27:44 +0200 Subject: [PATCH 1/2] BaseApp: track receipt on invoice per order line --- .../Tracking/MatchedOrderLineMgmt.Codeunit.al | 190 +++++++++++++----- .../Tracking/POMatchingGroup.Codeunit.al | 4 +- .../Upgrade/UpgradeBaseApp.Codeunit.al | 29 +++ .../Upgrade/UpgradeTagDefinitions.Codeunit.al | 6 + .../Document/PurchaseHeader.Table.al | 8 +- .../Purchases/Document/PurchaseLine.Table.al | 25 ++- .../Document/PurchaseOrderSubform.Page.al | 6 +- .../Vendor/ReceiptOnInvoicePolicy.Enum.al | 13 ++ .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 + .../Purchases/Vendor/VendorCard.Page.al | 5 + .../ERM/ERMMatchedOrderLineTests.Codeunit.al | 128 ++++++++++++ 11 files changed, 356 insertions(+), 63 deletions(-) create mode 100644 src/Layers/W1/BaseApp/Purchases/Vendor/ReceiptOnInvoicePolicy.Enum.al diff --git a/src/Layers/W1/BaseApp/Inventory/Tracking/MatchedOrderLineMgmt.Codeunit.al b/src/Layers/W1/BaseApp/Inventory/Tracking/MatchedOrderLineMgmt.Codeunit.al index 2e4c66ba87d..18162f7c57a 100644 --- a/src/Layers/W1/BaseApp/Inventory/Tracking/MatchedOrderLineMgmt.Codeunit.al +++ b/src/Layers/W1/BaseApp/Inventory/Tracking/MatchedOrderLineMgmt.Codeunit.al @@ -11,6 +11,7 @@ using Microsoft.Inventory.Location; using Microsoft.Purchases.Document; using Microsoft.Purchases.History; using Microsoft.Purchases.Posting; +using Microsoft.Purchases.Vendor; using System.Telemetry; using System.Text; @@ -19,6 +20,64 @@ codeunit 5826 "Matched Order Line Mgmt." Access = Public; Permissions = TableData "Posted Matched Order Line" = RIMD; + internal procedure ApplyVendorsReceiptOnInvoicePolicy(var PurchaseHeader: Record "Purchase Header") + var + Vendor: Record Vendor; + NewReceiptOnInvoice: Boolean; + ResetReceiptOnInvoiceQst: Label 'The vendor''s receipt on invoice policy disables %1, which is currently enabled on this document. Do you want to reset it on the document and its lines?', Comment = '%1 = Receipt on Invoice field caption'; + begin + if not Vendor.Get(PurchaseHeader."Buy-from Vendor No.") then + exit; + case Vendor."Receipt on Invoice Policy" of + Vendor."Receipt on Invoice Policy"::Automatic: + NewReceiptOnInvoice := true; + Vendor."Receipt on Invoice Policy"::Manual: + NewReceiptOnInvoice := false; + else + exit; + end; + if PurchaseHeader."Receipt on Invoice" = NewReceiptOnInvoice then + exit; + if PurchaseHeader."Receipt on Invoice" and not NewReceiptOnInvoice then + if GuiAllowed() then + if not Confirm(ResetReceiptOnInvoiceQst, false, PurchaseHeader.FieldCaption("Receipt on Invoice")) then + exit; + + PurchaseHeader."Receipt on Invoice" := NewReceiptOnInvoice; + ApplyReceiptOnInvoiceToEligibleLines(PurchaseHeader); + end; + + internal procedure ApplyReceiptOnInvoiceToLines(PurchaseHeader: Record "Purchase Header") + var + PurchaseLine: Record "Purchase Line"; + begin + PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type"); + PurchaseLine.SetRange("Document No.", PurchaseHeader."No."); + if PurchaseLine.FindSet() then + repeat + PurchaseLine.Validate("Receipt on Invoice", PurchaseHeader."Receipt on Invoice"); + PurchaseLine.Modify(); + until PurchaseLine.Next() = 0; + end; + + local procedure ApplyReceiptOnInvoiceToEligibleLines(PurchaseHeader: Record "Purchase Header") + var + PurchaseLine: Record "Purchase Line"; + LineReceiptOnInvoice: Boolean; + ErrorMessage: Text; + begin + PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type"); + PurchaseLine.SetRange("Document No.", PurchaseHeader."No."); + if PurchaseLine.FindSet() then + repeat + LineReceiptOnInvoice := PurchaseHeader."Receipt on Invoice"; + if LineReceiptOnInvoice and not IsLineReceiptOnInvoiceAllowed(PurchaseLine, ErrorMessage) then + LineReceiptOnInvoice := false; + PurchaseLine.Validate("Receipt on Invoice", LineReceiptOnInvoice); + PurchaseLine.Modify(); + until PurchaseLine.Next() = 0; + end; + internal procedure ProcessMatchedReceiptOnInvoice(var PurchaseLine: Record "Purchase Line") var MatchedOrderLine: Record "Matched Order Line"; @@ -38,8 +97,9 @@ codeunit 5826 "Matched Order Line Mgmt." repeat PurchaseLineOrder.GetBySystemId(MatchedOrderLine."Matched Order Line SystemId"); + PurchaseLineOrder.TestField("Receipt on Invoice"); + CheckLineReceiptOnInvoiceAllowed(PurchaseLineOrder); PurchaseHeaderOrder.Get(PurchaseLineOrder."Document Type", PurchaseLineOrder."Document No."); - PurchaseHeaderOrder.TestField("Receipt on Invoice"); TempPurchaseHeader := PurchaseHeaderOrder; if TempPurchaseHeader.Insert() then; @@ -97,8 +157,8 @@ codeunit 5826 "Matched Order Line Mgmt." exit; if PurchaseHeader."Document Type" = PurchaseHeader."Document Type"::Order then - if PurchaseHeader."Receipt on Invoice" and IsNullGuid(PurchaseLine."Invoicing From Line SystemId") then - Error(ReceiptOnInvoicePostFromMatchedInvoiceErr, PurchaseHeader.FieldCaption("Receipt on Invoice")); + if PurchaseLine."Receipt on Invoice" and IsNullGuid(PurchaseLine."Invoicing From Line SystemId") then + Error(ReceiptOnInvoicePostFromMatchedInvoiceErr, PurchaseLine.FieldCaption("Receipt on Invoice")); if PurchaseHeader."Document Type" = PurchaseHeader."Document Type"::Invoice then begin if not PurchaseLine.IsMatchedToOrder() then @@ -669,7 +729,7 @@ codeunit 5826 "Matched Order Line Mgmt." if PurchaseHeaderOrder."No." <> PurchaseLineOrder."Document No." then PurchaseHeaderOrder.Get(PurchaseLineOrder."Document Type", PurchaseLineOrder."Document No."); - InsertMatchedOrderLine(PurchaseLineInvoice.SystemId, PurchaseLineOrder.SystemId, NullGuid, PurchaseLineOrder."Qty. Rcd. Not Invoiced", PurchaseLineOrder."Qty. Rcd. Not Invoiced (Base)", PurchaseHeaderOrder."Receipt on Invoice"); + InsertMatchedOrderLine(PurchaseLineInvoice.SystemId, PurchaseLineOrder.SystemId, NullGuid, PurchaseLineOrder."Qty. Rcd. Not Invoiced", PurchaseLineOrder."Qty. Rcd. Not Invoiced (Base)", PurchaseLineOrder."Receipt on Invoice"); PurchRcptLine.SetRange("Order No.", PurchaseLineOrder."Document No."); PurchRcptLine.SetRange("Order Line No.", PurchaseLineOrder."Line No."); @@ -737,7 +797,7 @@ codeunit 5826 "Matched Order Line Mgmt." if IsNullGuid(DetailedMatchedOrderLine."Matched Order Line SystemId") then begin PurchaseLineOrder.Get(PurchaseLineOrder."Document Type"::Order, PurchRcptLine."Order No.", PurchRcptLine."Order Line No."); PurchaseHeaderOrder.Get(PurchaseLineOrder."Document Type", PurchaseLineOrder."Document No."); - InsertMatchedOrderLine(PurchaseLineInvoice.SystemId, PurchaseLineOrder.SystemId, NullGuid, PurchaseLineOrder."Qty. Rcd. Not Invoiced", PurchaseLineOrder."Qty. Rcd. Not Invoiced (Base)", PurchaseHeaderOrder."Receipt on Invoice"); + InsertMatchedOrderLine(PurchaseLineInvoice.SystemId, PurchaseLineOrder.SystemId, NullGuid, PurchaseLineOrder."Qty. Rcd. Not Invoiced", PurchaseLineOrder."Qty. Rcd. Not Invoiced (Base)", PurchaseLineOrder."Receipt on Invoice"); end; ItemTrackingMgt.CopyMatchedItemTrkgToPurchLine( PurchaseLineOrder, @@ -967,7 +1027,7 @@ codeunit 5826 "Matched Order Line Mgmt." QtyBase := PurchaseLineOrder."Outstanding Qty. (Base)"; end; - InsertMatchedOrderLine(PurchaseLineInvoice.SystemId, PurchaseLineOrder.SystemId, NullGuid, Qty, QtyBase, PurchaseHeaderOrder."Receipt on Invoice"); + InsertMatchedOrderLine(PurchaseLineInvoice.SystemId, PurchaseLineOrder.SystemId, NullGuid, Qty, QtyBase, PurchaseLineOrder."Receipt on Invoice"); PurchRcptLine.SetRange("Order No.", PurchaseLineOrder."Document No."); PurchRcptLine.SetRange("Order Line No.", PurchaseLineOrder."Line No."); @@ -999,79 +1059,103 @@ codeunit 5826 "Matched Order Line Mgmt." internal procedure CheckReceiptOnInvoiceAllowed(PurchaseHeader: Record "Purchase Header") var - Item: Record Item; - ItemTrackingCode: record "Item Tracking Code"; - Location: Record Location; PurchaseLine: Record "Purchase Line"; - PurchRcptLine: Record "Purch. Rcpt. Line"; begin PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type"); PurchaseLine.SetRange("Document No.", PurchaseHeader."No."); PurchaseLine.SetLoadFields(Type, "No.", "Location Code"); if PurchaseLine.FindSet() then repeat - if Location.Get(PurchaseLine."Location Code") and Location."Directed Put-away and Pick" then - Error(ReceiptOnInvoiceLocationErr, PurchaseHeader.FieldCaption("Receipt on Invoice"), PurchaseLine."Location Code", PurchaseLine."Line No."); - if PurchaseLine.Type = PurchaseLine.Type::Item then - if Item.Get(PurchaseLine."No.") and (Item."Item Tracking Code" <> '') then - if ItemTrackingCode.Get(Item."Item Tracking Code") and (ItemTrackingCode."SN Specific Tracking" or ItemTrackingCode."Lot Specific Tracking" or ItemTrackingCode."Package Specific Tracking") then - Error(ReceiptOnInvoiceItemTrackingErr, PurchaseHeader.FieldCaption("Receipt on Invoice"), PurchaseLine."No.", PurchaseLine."Line No."); - - PurchRcptLine.SetRange("Order No.", PurchaseLine."Document No."); - PurchRcptLine.SetRange("Order Line No.", PurchaseLine."Line No."); - if not PurchRcptLine.IsEmpty() then - Error(ReceiptOnInvoicePostedReceiptErr, PurchaseHeader.FieldCaption("Receipt on Invoice"), PurchaseLine."Line No."); + CheckLineReceiptOnInvoiceAllowed(PurchaseLine); until PurchaseLine.Next() = 0; end; - internal procedure RefreshMatchedOrderLineReceipt(PurchaseHeader: Record "Purchase Header") + internal procedure CheckLineReceiptOnInvoiceAllowed(PurchaseLine: Record "Purchase Line") var - PurchaseLine: Record "Purchase Line"; - PurchaseLineSystemIDFilter: Text; - FilterValueCount: Integer; + ErrorMessage: Text; begin - PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type"); - PurchaseLine.SetRange("Document No.", PurchaseHeader."No."); - PurchaseLine.SetLoadFields(SystemId); - if PurchaseLine.FindSet() then - repeat - PurchaseLineSystemIDFilter += Format(PurchaseLine.SystemId) + '|'; - FilterValueCount += 1; - if FilterValueCount = MaxFilterValues() then begin - RefreshMatchedOrderLinesBatch(PurchaseLineSystemIDFilter, PurchaseHeader."Receipt on Invoice"); - Clear(PurchaseLineSystemIDFilter); - FilterValueCount := 0; - end; - until PurchaseLine.Next() = 0; - - if PurchaseLineSystemIDFilter <> '' then - RefreshMatchedOrderLinesBatch(PurchaseLineSystemIDFilter, PurchaseHeader."Receipt on Invoice"); + if not IsLineReceiptOnInvoiceAllowed(PurchaseLine, ErrorMessage) then + Error(ErrorMessage); end; - local procedure RefreshMatchedOrderLinesBatch(SystemIDFilter: Text; ReceiptOnInvoice: Boolean) + internal procedure IsLineReceiptOnInvoiceAllowed(PurchaseLine: Record "Purchase Line"; var ErrorMessage: Text): Boolean var - MatchedOrderLine: Record "Matched Order Line"; + Item: Record Item; + PurchRcptLine: Record "Purch. Rcpt. Line"; + ReceiptOnInvoiceCaption: Text; begin - MatchedOrderLine.SetFilter("Matched Order Line SystemId", CopyStr(SystemIDFilter, 1, StrLen(SystemIDFilter) - 1)); - MatchedOrderLine.ModifyAll("Receipt on Invoice", ReceiptOnInvoice); + ReceiptOnInvoiceCaption := PurchaseLine.FieldCaption("Receipt on Invoice"); + if not IsReceiptOnInvoiceAllowedForLocation(PurchaseLine."Location Code") then begin + ErrorMessage := StrSubstNo(ReceiptOnInvoiceLocationErr, ReceiptOnInvoiceCaption, PurchaseLine."Location Code", PurchaseLine."Line No."); + exit(false); + end; + if (PurchaseLine.Type = PurchaseLine.Type::Item) and Item.Get(PurchaseLine."No.") then + if not IsReceiptOnInvoiceAllowedForItem(Item) then begin + ErrorMessage := StrSubstNo(ReceiptOnInvoiceItemTrackingErr, ReceiptOnInvoiceCaption, PurchaseLine."No.", PurchaseLine."Line No."); + exit(false); + end; + PurchRcptLine.SetRange("Order No.", PurchaseLine."Document No."); + PurchRcptLine.SetRange("Order Line No.", PurchaseLine."Line No."); + if not PurchRcptLine.IsEmpty() then begin + ErrorMessage := StrSubstNo(ReceiptOnInvoicePostedReceiptErr, ReceiptOnInvoiceCaption, PurchaseLine."Line No."); + exit(false); + end; + exit(true); end; - internal procedure CheckReceiptOnInvoiceAllowedForItem(Item: Record Item; PurchHeader: Record "Purchase Header") + internal procedure IsReceiptOnInvoiceAllowedForItem(Item: Record Item): Boolean var ItemTrackingCode: Record "Item Tracking Code"; begin - if PurchHeader."Receipt on Invoice" and (Item."Item Tracking Code" <> '') then - if ItemTrackingCode.Get(Item."Item Tracking Code") and (ItemTrackingCode."SN Specific Tracking" or ItemTrackingCode."Lot Specific Tracking" or ItemTrackingCode."Package Specific Tracking") then - Error(ReceiptOnInvoiceItemTrackingLineValidationErr, Item."No.", PurchHeader.FieldCaption("Receipt on Invoice")); + if Item."Item Tracking Code" = '' then + exit(true); + if ItemTrackingCode.Get(Item."Item Tracking Code") then + if ItemTrackingCode."SN Specific Tracking" or ItemTrackingCode."Lot Specific Tracking" or ItemTrackingCode."Package Specific Tracking" then + exit(false); + exit(true); end; - internal procedure CheckReceiptOnInvoiceAllowedForLocation("Location Code": Code[10]; PurchHeader: Record "Purchase Header") + internal procedure IsReceiptOnInvoiceAllowedForLocation(LocationCode: Code[10]): Boolean var Location: Record Location; begin - if PurchHeader."Receipt on Invoice" then - if Location.Get("Location Code") and Location."Directed Put-away and Pick" then - Error(ReceiptOnInvoiceLocationLineValidationErr, "Location Code", PurchHeader.FieldCaption("Receipt on Invoice")); + if Location.Get(LocationCode) then + if Location."Directed Put-away and Pick" then + exit(false); + exit(true); + end; + + internal procedure CheckReceiptOnInvoiceAllowedForItem(Item: Record Item; PurchaseHeader: Record "Purchase Header") + begin + if PurchaseHeader."Receipt on Invoice" and not IsReceiptOnInvoiceAllowedForItem(Item) then + Error(ReceiptOnInvoiceItemTrackingLineValidationErr, Item."No.", PurchaseHeader.FieldCaption("Receipt on Invoice")); + end; + + internal procedure CheckReceiptOnInvoiceAllowedForLocation(LocationCode: Code[10]; PurchaseHeader: Record "Purchase Header") + begin + if PurchaseHeader."Receipt on Invoice" and not IsReceiptOnInvoiceAllowedForLocation(LocationCode) then + Error(ReceiptOnInvoiceLocationLineValidationErr, LocationCode, PurchaseHeader.FieldCaption("Receipt on Invoice")); + end; + + internal procedure ApplyPurchaseLineReceiptSettingToMatches(PurchaseLine: Record "Purchase Line") + var + MatchedOrderLine: Record "Matched Order Line"; + begin + MatchedOrderLine.SetRange("Matched Order Line SystemId", PurchaseLine.SystemId); + MatchedOrderLine.ModifyAll("Receipt on Invoice", PurchaseLine."Receipt on Invoice"); + end; + + internal procedure RefreshMatchedOrderLineReceipt(PurchaseHeader: Record "Purchase Header") + var + PurchaseLine: Record "Purchase Line"; + begin + PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type"); + PurchaseLine.SetRange("Document No.", PurchaseHeader."No."); + PurchaseLine.SetLoadFields("Receipt on Invoice"); + if PurchaseLine.FindSet() then + repeat + ApplyPurchaseLineReceiptSettingToMatches(PurchaseLine); + until PurchaseLine.Next() = 0; end; internal procedure LineCanBeDeleted(var DetailedMatchedOrderLine: Record "Detailed Matched Order Line"; SourceIsOpenDocument: Boolean): Boolean diff --git a/src/Layers/W1/BaseApp/Inventory/Tracking/POMatchingGroup.Codeunit.al b/src/Layers/W1/BaseApp/Inventory/Tracking/POMatchingGroup.Codeunit.al index 49a13e0b2a3..323977f276c 100644 --- a/src/Layers/W1/BaseApp/Inventory/Tracking/POMatchingGroup.Codeunit.al +++ b/src/Layers/W1/BaseApp/Inventory/Tracking/POMatchingGroup.Codeunit.al @@ -386,12 +386,10 @@ codeunit 5829 "PO Matching Group" local procedure ReceiptOnInvoiceForMatch(OrderLineSystemId: Guid): Boolean var - OrderHeader: Record "Purchase Header"; OrderLine: Record "Purchase Line"; begin OrderLine.GetBySystemId(OrderLineSystemId); - OrderHeader.Get(OrderLine."Document Type", OrderLine."Document No."); - exit(OrderHeader."Receipt on Invoice"); + exit(OrderLine."Receipt on Invoice"); end; #endregion diff --git a/src/Layers/W1/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al b/src/Layers/W1/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al index 073e3288b72..bc4f65ec039 100644 --- a/src/Layers/W1/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al +++ b/src/Layers/W1/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al @@ -253,6 +253,7 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeFinancialReportAuditLogAddRetentionPolicy(); UpgradeZeroClosedBankAccountLedgerEntries(); UpgradeDepreciationBooksGLIntegration(); + UpgradePurchaseLineReceiptOnInvoice(); UpgradeWarehouseActivitySourceTypeForJobPlanningLine(); end; @@ -4065,6 +4066,34 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetDepreciationBooksGLIntegrationUpgradeTag()); end; + local procedure UpgradePurchaseLineReceiptOnInvoice() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + UpgradeTag: Codeunit "Upgrade Tag"; + UpgradeTagDefinitions: Codeunit "Upgrade Tag Definitions"; + ReceiptOnInvoiceDataTransfer: DataTransfer; + begin + if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()) then + exit; + + PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order); + PurchaseHeader.SetRange("Receipt on Invoice", true); + PurchaseHeader.SetLoadFields("No."); + if PurchaseHeader.FindSet() then + repeat + Clear(ReceiptOnInvoiceDataTransfer); + ReceiptOnInvoiceDataTransfer.SetTables(Database::"Purchase Line", Database::"Purchase Line"); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document Type"), '=%1', PurchaseLine."Document Type"::Order); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document No."), '=%1', PurchaseHeader."No."); + ReceiptOnInvoiceDataTransfer.AddConstantValue(true, PurchaseLine.FieldNo("Receipt on Invoice")); + ReceiptOnInvoiceDataTransfer.UpdateAuditFields := false; + ReceiptOnInvoiceDataTransfer.CopyFields(); + until PurchaseHeader.Next() = 0; + + UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()); + end; + local procedure UpgradeWarehouseActivitySourceTypeForJobPlanningLine() var WarehouseActivityLine: Record "Warehouse Activity Line"; diff --git a/src/Layers/W1/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al b/src/Layers/W1/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al index 8dc5f6be2d3..88df47b5103 100644 --- a/src/Layers/W1/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al +++ b/src/Layers/W1/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al @@ -180,6 +180,7 @@ codeunit 9998 "Upgrade Tag Definitions" PerCompanyUpgradeTags.Add(GetServiceShptLineFieldsUpgradeTag()); PerCompanyUpgradeTags.Add(GetZeroClosedBankAccountLedgerEntriesUpgradeTag()); PerCompanyUpgradeTags.Add(GetDepreciationBooksGLIntegrationUpgradeTag()); + PerCompanyUpgradeTags.Add(GetPurchLineReceiptOnInvoiceUpgradeTag()); PerCompanyUpgradeTags.Add(GetWarehouseActivitySourceTypeForJobPlanningLineUpgradeTag()); PerCompanyUpgradeTags.Add(GetRemittanceAdviceReportSelectionUpgradeTag()); PerCompanyUpgradeTags.Add(GetProdDefinitionDisplaySetupUpgradeTag()); @@ -1270,6 +1271,11 @@ codeunit 9998 "Upgrade Tag Definitions" exit('MS-626097-DepreciationBooksGLIntegrationUpgradeTag-20260319'); end; + internal procedure GetPurchLineReceiptOnInvoiceUpgradeTag(): Code[250] + begin + exit('MS-625392-PurchLineReceiptOnInvoiceUpgradeTag-20260703'); + end; + internal procedure GetRemittanceAdviceReportSelectionUpgradeTag(): Code[250] begin exit('MS-RemittanceAdviceReportSelection-20260723'); diff --git a/src/Layers/W1/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/W1/BaseApp/Purchases/Document/PurchaseHeader.Table.al index 47c629ab9d0..6c6517749be 100644 --- a/src/Layers/W1/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/W1/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -86,6 +86,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -202,6 +203,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2769,10 +2772,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al index ec5d9ec9925..9b035c31e91 100644 --- a/src/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/W1/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -417,7 +417,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3871,6 +3872,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } field(12100; "No. of Fixed Asset Cards"; Integer) { BlankZero = true; @@ -4496,6 +4515,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4778,7 +4798,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/W1/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al b/src/Layers/W1/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al index 023d36a7e7b..8ab471df0f2 100644 --- a/src/Layers/W1/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al +++ b/src/Layers/W1/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al @@ -232,6 +232,11 @@ page 54 "Purchase Order Subform" Importance = Additional; Visible = false; } + field("Receipt on Invoice"; Rec."Receipt on Invoice") + { + ApplicationArea = All; + Visible = false; + } field("Drop Shipment"; Rec."Drop Shipment") { ApplicationArea = Suite; @@ -2014,4 +2019,3 @@ page 54 "Purchase Order Subform" begin end; } - diff --git a/src/Layers/W1/BaseApp/Purchases/Vendor/ReceiptOnInvoicePolicy.Enum.al b/src/Layers/W1/BaseApp/Purchases/Vendor/ReceiptOnInvoicePolicy.Enum.al new file mode 100644 index 00000000000..e6c5d61f65f --- /dev/null +++ b/src/Layers/W1/BaseApp/Purchases/Vendor/ReceiptOnInvoicePolicy.Enum.al @@ -0,0 +1,13 @@ +// ------------------------------------------------------------------------------------------------ +// 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.Vendor; + +enum 5820 "Receipt on Invoice Policy" +{ + Extensible = true; + + value(0; Manual) { Caption = 'Manual'; } + value(1; Automatic) { Caption = 'Automatic'; } +} diff --git a/src/Layers/W1/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/W1/BaseApp/Purchases/Vendor/Vendor.Table.al index 13f3799d139..177e3932fac 100644 --- a/src/Layers/W1/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/W1/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1685,6 +1685,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } } keys diff --git a/src/Layers/W1/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/W1/BaseApp/Purchases/Vendor/VendorCard.Page.al index 1b9b013c7aa..29da2b965ef 100644 --- a/src/Layers/W1/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/W1/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -534,6 +534,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/W1/Tests/ERM/ERMMatchedOrderLineTests.Codeunit.al b/src/Layers/W1/Tests/ERM/ERMMatchedOrderLineTests.Codeunit.al index ccdd22defce..091827b6ded 100644 --- a/src/Layers/W1/Tests/ERM/ERMMatchedOrderLineTests.Codeunit.al +++ b/src/Layers/W1/Tests/ERM/ERMMatchedOrderLineTests.Codeunit.al @@ -4554,6 +4554,134 @@ codeunit 134468 "ERM Matched Order Line Tests" Assert.RecordIsEmpty(MatchedOrderLine); end; + [Test] + [Scope('OnPrem')] + procedure E2E_ReceiptOnInvoiceLineLevelDrivesAutoReceiveWithoutHeaderFlag() + var + PurchaseHeaderOrder: Record "Purchase Header"; + PurchaseLineOrder: Record "Purchase Line"; + PurchaseHeaderInvoice: Record "Purchase Header"; + PurchaseLineInvoice: Record "Purchase Line"; + PurchRcptLine: Record "Purch. Rcpt. Line"; + MatchedOrderLine: Record "Matched Order Line"; + Item: Record Item; + Vendor: Record Vendor; + Quantity: Decimal; + begin + Initialize(); + Quantity := LibraryRandom.RandIntInRange(10, 100); + LibraryPurchase.CreateVendor(Vendor); + LibraryInventory.CreateItem(Item); + + LibraryPurchase.CreatePurchHeader(PurchaseHeaderOrder, PurchaseHeaderOrder."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLineOrder, PurchaseHeaderOrder, PurchaseLineOrder.Type::Item, Item."No.", Quantity); + PurchaseLineOrder.Validate("Direct Unit Cost", LibraryRandom.RandDecInRange(10, 100, 2)); + PurchaseLineOrder.Validate("Receipt on Invoice", true); + PurchaseLineOrder.Modify(true); + PurchaseHeaderOrder.Get(PurchaseHeaderOrder."Document Type", PurchaseHeaderOrder."No."); + Assert.IsFalse(PurchaseHeaderOrder."Receipt on Invoice", 'Header receipt on invoice should remain disabled'); + + LibraryPurchase.CreatePurchHeader(PurchaseHeaderInvoice, PurchaseHeaderInvoice."Document Type"::Invoice, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLineInvoice, PurchaseHeaderInvoice, PurchaseLineInvoice.Type::Item, Item."No.", Quantity); + PurchaseLineInvoice.Validate("Direct Unit Cost", PurchaseLineOrder."Direct Unit Cost"); + PurchaseLineInvoice.Modify(true); + MatchedOrderLine."Document Line SystemId" := PurchaseLineInvoice.SystemId; + MatchedOrderLine."Matched Order Line SystemId" := PurchaseLineOrder.SystemId; + MatchedOrderLine."Qty. to Invoice" := Quantity; + MatchedOrderLine."Qty. to Invoice (Base)" := Quantity; + MatchedOrderLine."Receipt on Invoice" := true; + MatchedOrderLine.Insert(); + + LibraryPurchase.PostPurchaseDocument(PurchaseHeaderInvoice, false, true); + + PurchaseLineOrder.Get(PurchaseLineOrder."Document Type", PurchaseLineOrder."Document No.", PurchaseLineOrder."Line No."); + Assert.AreEqual(Quantity, PurchaseLineOrder."Quantity Received", 'Order line should be auto-received'); + Assert.AreEqual(Quantity, PurchaseLineOrder."Quantity Invoiced", 'Order line should be fully invoiced'); + PurchRcptLine.SetRange("Order No.", PurchaseLineOrder."Document No."); + PurchRcptLine.SetRange("Order Line No.", PurchaseLineOrder."Line No."); + PurchRcptLine.FindFirst(); + Assert.AreEqual(Quantity, PurchRcptLine.Quantity, 'Auto-posted receipt should cover the full quantity'); + end; + + [Test] + [Scope('OnPrem')] + procedure VendorAutomaticReceiptOnInvoicePolicyInitializesOrderAndLine() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + Item: Record Item; + Vendor: Record Vendor; + begin + Initialize(); + LibraryPurchase.CreateVendor(Vendor); + Vendor.Validate("Receipt on Invoice Policy", Vendor."Receipt on Invoice Policy"::Automatic); + Vendor.Modify(true); + LibraryInventory.CreateItem(Item); + + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item."No.", LibraryRandom.RandInt(10)); + PurchaseHeader.Get(PurchaseHeader."Document Type", PurchaseHeader."No."); + + Assert.IsTrue(PurchaseHeader."Receipt on Invoice", 'Vendor policy should enable receipt on invoice on the order'); + Assert.IsTrue(PurchaseLine."Receipt on Invoice", 'Order line should inherit receipt on invoice from the order'); + end; + + [Test] + [Scope('OnPrem')] + procedure ReceiptOnInvoiceLineRejectsExistingReceipts() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + Item: Record Item; + Vendor: Record Vendor; + begin + Initialize(); + LibraryPurchase.CreateVendor(Vendor); + LibraryInventory.CreateItem(Item); + LibraryPurchase.CreatePurchHeader(PurchaseHeader, PurchaseHeader."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLine, PurchaseHeader, PurchaseLine.Type::Item, Item."No.", LibraryRandom.RandInt(10)); + LibraryPurchase.PostPurchaseDocument(PurchaseHeader, true, false); + PurchaseLine.Get(PurchaseLine."Document Type", PurchaseLine."Document No.", PurchaseLine."Line No."); + + asserterror PurchaseLine.Validate("Receipt on Invoice", true); + end; + + [Test] + [Scope('OnPrem')] + procedure POMatchingGroupUsesOrderLineReceiptOnInvoiceSetting() + var + PurchaseHeaderOrder: Record "Purchase Header"; + PurchaseLineOrder: Record "Purchase Line"; + PurchaseHeaderInvoice: Record "Purchase Header"; + PurchaseLineInvoice: Record "Purchase Line"; + MatchedOrderLine: Record "Matched Order Line"; + Item: Record Item; + Vendor: Record Vendor; + POMatching: Codeunit "PO Matching"; + POMatchingGroup: Codeunit "PO Matching Group"; + Quantity: Decimal; + begin + Initialize(); + Quantity := LibraryRandom.RandInt(10); + LibraryPurchase.CreateVendor(Vendor); + LibraryInventory.CreateItem(Item); + LibraryPurchase.CreatePurchHeader(PurchaseHeaderOrder, PurchaseHeaderOrder."Document Type"::Order, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLineOrder, PurchaseHeaderOrder, PurchaseLineOrder.Type::Item, Item."No.", Quantity); + PurchaseLineOrder.Validate("Receipt on Invoice", true); + PurchaseLineOrder.Modify(true); + LibraryPurchase.CreatePurchHeader(PurchaseHeaderInvoice, PurchaseHeaderInvoice."Document Type"::Invoice, Vendor."No."); + LibraryPurchase.CreatePurchaseLine(PurchaseLineInvoice, PurchaseHeaderInvoice, PurchaseLineInvoice.Type::Item, Item."No.", Quantity); + + POMatchingGroup.AddMatch(POMatching.InvoiceOrderEdge(PurchaseLineInvoice.SystemId, PurchaseLineOrder.SystemId, Quantity, Quantity)); + POMatchingGroup.SaveMatchingGroups(); + + MatchedOrderLine.SetRange("Document Line SystemId", PurchaseLineInvoice.SystemId); + MatchedOrderLine.SetRange("Matched Order Line SystemId", PurchaseLineOrder.SystemId); + MatchedOrderLine.SetRange("Matched Rcpt./Shpt. Line SysId", EmptyGuid); + MatchedOrderLine.FindFirst(); + Assert.IsTrue(MatchedOrderLine."Receipt on Invoice", 'Match should use the order line receipt-on-invoice setting'); + end; + // ============================================================================ // REGION: Local Helper Functions // ============================================================================ From a31a4719cb58009ee371c0dcf2cfb0129a02ab83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joshua=20Mart=C3=ADnez=20Pineda?= Date: Sun, 23 Aug 2026 10:53:12 +0200 Subject: [PATCH 2/2] Propagate receipt-on-invoice line tracking to localizations --- .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../Document/PurchaseOrderSubform.Page.al | 6 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Upgrade/UpgradeBaseApp.Codeunit.al | 29 +++++++++++++++++++ .../Upgrade/UpgradeBaseApp.Codeunit.al | 29 +++++++++++++++++++ .../Upgrade/UpgradeTagDefinitions.Codeunit.al | 6 ++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Upgrade/UpgradeBaseApp.Codeunit.al | 29 +++++++++++++++++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../Document/PurchaseOrderSubform.Page.al | 6 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Document/PurchaseOrderSubform.Page.al | 6 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Upgrade/UpgradeBaseApp.Codeunit.al | 29 +++++++++++++++++++ .../Upgrade/UpgradeTagDefinitions.Codeunit.al | 6 ++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../Document/PurchaseOrderSubform.Page.al | 6 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../Document/PurchaseOrderSubform.Page.al | 5 ++++ .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Upgrade/UpgradeBaseApp.Codeunit.al | 29 +++++++++++++++++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Upgrade/UpgradeBaseApp.Codeunit.al | 29 +++++++++++++++++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Upgrade/UpgradeBaseApp.Codeunit.al | 29 +++++++++++++++++++ .../Upgrade/UpgradeTagDefinitions.Codeunit.al | 6 ++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- .../Document/PurchaseOrderSubform.Page.al | 6 +++- .../BaseApp/Purchases/Vendor/Vendor.Table.al | 5 ++++ .../Purchases/Vendor/VendorCard.Page.al | 5 ++++ .../Document/PurchaseHeader.Table.al | 8 ++--- .../Purchases/Document/PurchaseLine.Table.al | 25 ++++++++++++++-- 69 files changed, 737 insertions(+), 83 deletions(-) diff --git a/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseHeader.Table.al index 58b67acca99..a8e0fdbfa71 100644 --- a/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -88,6 +88,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; SkipCheckVendorRegistered: Boolean; begin @@ -215,6 +216,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2787,10 +2790,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseLine.Table.al index ede423744eb..cd3cf4cf520 100644 --- a/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -425,7 +425,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3897,6 +3898,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } field(12100; "No. of Fixed Asset Cards"; Integer) { BlankZero = true; @@ -4601,6 +4620,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4886,7 +4906,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al b/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al index bbc253ea951..fb35f684099 100644 --- a/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al +++ b/src/Layers/APAC/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al @@ -244,6 +244,11 @@ page 54 "Purchase Order Subform" Importance = Additional; Visible = false; } + field("Receipt on Invoice"; Rec."Receipt on Invoice") + { + ApplicationArea = All; + Visible = false; + } field("Drop Shipment"; Rec."Drop Shipment") { ApplicationArea = Suite; @@ -2027,4 +2032,3 @@ page 54 "Purchase Order Subform" begin end; } - diff --git a/src/Layers/APAC/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/APAC/BaseApp/Purchases/Vendor/Vendor.Table.al index b1248e2ced2..21d85d24d21 100644 --- a/src/Layers/APAC/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/APAC/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1686,6 +1686,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } field(11620; ABN; Text[11]) { Caption = 'ABN'; diff --git a/src/Layers/APAC/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/APAC/BaseApp/Purchases/Vendor/VendorCard.Page.al index 0b168c68974..07e41f74b9b 100644 --- a/src/Layers/APAC/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/APAC/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -617,6 +617,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/AT/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al b/src/Layers/AT/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al index a4656717876..4ea2268e642 100644 --- a/src/Layers/AT/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al +++ b/src/Layers/AT/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al @@ -249,6 +249,7 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeFinancialReportAuditLogAddRetentionPolicy(); UpgradeZeroClosedBankAccountLedgerEntries(); UpgradeDepreciationBooksGLIntegration(); + UpgradePurchaseLineReceiptOnInvoice(); UpgradeWarehouseActivitySourceTypeForJobPlanningLine(); end; @@ -4020,6 +4021,34 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetDepreciationBooksGLIntegrationUpgradeTag()); end; + local procedure UpgradePurchaseLineReceiptOnInvoice() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + UpgradeTag: Codeunit "Upgrade Tag"; + UpgradeTagDefinitions: Codeunit "Upgrade Tag Definitions"; + ReceiptOnInvoiceDataTransfer: DataTransfer; + begin + if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()) then + exit; + + PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order); + PurchaseHeader.SetRange("Receipt on Invoice", true); + PurchaseHeader.SetLoadFields("No."); + if PurchaseHeader.FindSet() then + repeat + Clear(ReceiptOnInvoiceDataTransfer); + ReceiptOnInvoiceDataTransfer.SetTables(Database::"Purchase Line", Database::"Purchase Line"); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document Type"), '=%1', PurchaseLine."Document Type"::Order); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document No."), '=%1', PurchaseHeader."No."); + ReceiptOnInvoiceDataTransfer.AddConstantValue(true, PurchaseLine.FieldNo("Receipt on Invoice")); + ReceiptOnInvoiceDataTransfer.UpdateAuditFields := false; + ReceiptOnInvoiceDataTransfer.CopyFields(); + until PurchaseHeader.Next() = 0; + + UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()); + end; + local procedure UpgradeWarehouseActivitySourceTypeForJobPlanningLine() var WarehouseActivityLine: Record "Warehouse Activity Line"; diff --git a/src/Layers/BE/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al b/src/Layers/BE/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al index 86f62562bdb..330047742ea 100644 --- a/src/Layers/BE/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al +++ b/src/Layers/BE/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al @@ -259,6 +259,7 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeFinancialReportAuditLogAddRetentionPolicy(); UpgradeZeroClosedBankAccountLedgerEntries(); UpgradeDepreciationBooksGLIntegration(); + UpgradePurchaseLineReceiptOnInvoice(); UpgradeWarehouseActivitySourceTypeForJobPlanningLine(); end; @@ -4132,6 +4133,34 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetDepreciationBooksGLIntegrationUpgradeTag()); end; + local procedure UpgradePurchaseLineReceiptOnInvoice() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + UpgradeTag: Codeunit "Upgrade Tag"; + UpgradeTagDefinitions: Codeunit "Upgrade Tag Definitions"; + ReceiptOnInvoiceDataTransfer: DataTransfer; + begin + if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()) then + exit; + + PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order); + PurchaseHeader.SetRange("Receipt on Invoice", true); + PurchaseHeader.SetLoadFields("No."); + if PurchaseHeader.FindSet() then + repeat + Clear(ReceiptOnInvoiceDataTransfer); + ReceiptOnInvoiceDataTransfer.SetTables(Database::"Purchase Line", Database::"Purchase Line"); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document Type"), '=%1', PurchaseLine."Document Type"::Order); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document No."), '=%1', PurchaseHeader."No."); + ReceiptOnInvoiceDataTransfer.AddConstantValue(true, PurchaseLine.FieldNo("Receipt on Invoice")); + ReceiptOnInvoiceDataTransfer.UpdateAuditFields := false; + ReceiptOnInvoiceDataTransfer.CopyFields(); + until PurchaseHeader.Next() = 0; + + UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()); + end; + local procedure UpgradeWarehouseActivitySourceTypeForJobPlanningLine() var WarehouseActivityLine: Record "Warehouse Activity Line"; diff --git a/src/Layers/BE/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al b/src/Layers/BE/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al index 803fbc50da3..f58c4252860 100644 --- a/src/Layers/BE/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al +++ b/src/Layers/BE/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al @@ -198,6 +198,7 @@ codeunit 9998 "Upgrade Tag Definitions" PerCompanyUpgradeTags.Add(GetServiceShptLineFieldsUpgradeTag()); PerCompanyUpgradeTags.Add(GetZeroClosedBankAccountLedgerEntriesUpgradeTag()); PerCompanyUpgradeTags.Add(GetDepreciationBooksGLIntegrationUpgradeTag()); + PerCompanyUpgradeTags.Add(GetPurchLineReceiptOnInvoiceUpgradeTag()); PerCompanyUpgradeTags.Add(GetWarehouseActivitySourceTypeForJobPlanningLineUpgradeTag()); PerCompanyUpgradeTags.Add(GetRemittanceAdviceReportSelectionUpgradeTag()); PerCompanyUpgradeTags.Add(GetProdDefinitionDisplaySetupUpgradeTag()); @@ -1376,6 +1377,11 @@ codeunit 9998 "Upgrade Tag Definitions" exit('MS-626097-DepreciationBooksGLIntegrationUpgradeTag-20260319'); end; + internal procedure GetPurchLineReceiptOnInvoiceUpgradeTag(): Code[250] + begin + exit('MS-625392-PurchLineReceiptOnInvoiceUpgradeTag-20260703'); + end; + internal procedure GetRemittanceAdviceReportSelectionUpgradeTag(): Code[250] begin exit('MS-RemittanceAdviceReportSelection-20260723'); diff --git a/src/Layers/BE/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/BE/BaseApp/Purchases/Document/PurchaseHeader.Table.al index b3e4659b1d1..0e2124b5c0c 100644 --- a/src/Layers/BE/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/BE/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -86,6 +86,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -203,6 +204,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2781,10 +2784,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/BE/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/BE/BaseApp/Purchases/Document/PurchaseLine.Table.al index 4f293536e4a..bc9d0068baa 100644 --- a/src/Layers/BE/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/BE/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -417,7 +417,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3873,6 +3874,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } field(11303; "Suggested Line"; Boolean) { Caption = 'Suggested Line'; @@ -4517,6 +4536,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4800,7 +4820,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/BE/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/BE/BaseApp/Purchases/Vendor/Vendor.Table.al index da5904206f4..e6f5be8c1c6 100644 --- a/src/Layers/BE/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/BE/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1688,6 +1688,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } field(11310; "Enterprise No."; Text[50]) { Caption = 'Enterprise No.'; diff --git a/src/Layers/BE/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/BE/BaseApp/Purchases/Vendor/VendorCard.Page.al index 001f3c8cc26..c04599df422 100644 --- a/src/Layers/BE/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/BE/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -544,6 +544,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/CH/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al b/src/Layers/CH/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al index 1b8b33f59c5..ebf4c3357fd 100644 --- a/src/Layers/CH/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al +++ b/src/Layers/CH/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al @@ -261,6 +261,7 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeFinancialReportAuditLogAddRetentionPolicy(); UpgradeZeroClosedBankAccountLedgerEntries(); UpgradeDepreciationBooksGLIntegration(); + UpgradePurchaseLineReceiptOnInvoice(); UpgradeWarehouseActivitySourceTypeForJobPlanningLine(); end; @@ -4086,6 +4087,34 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetDepreciationBooksGLIntegrationUpgradeTag()); end; + local procedure UpgradePurchaseLineReceiptOnInvoice() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + UpgradeTag: Codeunit "Upgrade Tag"; + UpgradeTagDefinitions: Codeunit "Upgrade Tag Definitions"; + ReceiptOnInvoiceDataTransfer: DataTransfer; + begin + if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()) then + exit; + + PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order); + PurchaseHeader.SetRange("Receipt on Invoice", true); + PurchaseHeader.SetLoadFields("No."); + if PurchaseHeader.FindSet() then + repeat + Clear(ReceiptOnInvoiceDataTransfer); + ReceiptOnInvoiceDataTransfer.SetTables(Database::"Purchase Line", Database::"Purchase Line"); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document Type"), '=%1', PurchaseLine."Document Type"::Order); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document No."), '=%1', PurchaseHeader."No."); + ReceiptOnInvoiceDataTransfer.AddConstantValue(true, PurchaseLine.FieldNo("Receipt on Invoice")); + ReceiptOnInvoiceDataTransfer.UpdateAuditFields := false; + ReceiptOnInvoiceDataTransfer.CopyFields(); + until PurchaseHeader.Next() = 0; + + UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()); + end; + local procedure UpgradeWarehouseActivitySourceTypeForJobPlanningLine() var WarehouseActivityLine: Record "Warehouse Activity Line"; diff --git a/src/Layers/CH/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/CH/BaseApp/Purchases/Document/PurchaseHeader.Table.al index e275a67a24c..fe82556deaf 100644 --- a/src/Layers/CH/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/CH/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -86,6 +86,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -207,6 +208,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2776,10 +2779,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/CH/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/CH/BaseApp/Purchases/Document/PurchaseLine.Table.al index 494fa74b428..772a0907d22 100644 --- a/src/Layers/CH/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/CH/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -417,7 +417,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3875,6 +3876,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } field(12100; "No. of Fixed Asset Cards"; Integer) { BlankZero = true; @@ -4516,6 +4535,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4798,7 +4818,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/CH/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/CH/BaseApp/Purchases/Vendor/Vendor.Table.al index ec08bbe0d52..180c111bc70 100644 --- a/src/Layers/CH/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/CH/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1685,6 +1685,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } #if not CLEANSCHEMA25 field(11000; "Registration No."; Text[20]) { diff --git a/src/Layers/CH/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/CH/BaseApp/Purchases/Vendor/VendorCard.Page.al index ac5f75a58c6..ce418ac6fde 100644 --- a/src/Layers/CH/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/CH/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -533,6 +533,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/DACH/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/DACH/BaseApp/Purchases/Document/PurchaseHeader.Table.al index a33cec735d1..190e5b6409e 100644 --- a/src/Layers/DACH/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/DACH/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -86,6 +86,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -203,6 +204,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2771,10 +2774,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/DACH/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/DACH/BaseApp/Purchases/Document/PurchaseLine.Table.al index 0509f4dd584..6d9e645874a 100644 --- a/src/Layers/DACH/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/DACH/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -417,7 +417,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3871,6 +3872,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } field(12100; "No. of Fixed Asset Cards"; Integer) { BlankZero = true; @@ -4514,6 +4533,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4796,7 +4816,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/DACH/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/DACH/BaseApp/Purchases/Vendor/Vendor.Table.al index 96e740479ee..715ecfc346c 100644 --- a/src/Layers/DACH/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/DACH/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1685,6 +1685,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } #if not CLEANSCHEMA25 field(11000; "Registration No."; Text[20]) { diff --git a/src/Layers/DACH/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/DACH/BaseApp/Purchases/Vendor/VendorCard.Page.al index 180f1cd1ff8..4c423deac01 100644 --- a/src/Layers/DACH/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/DACH/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -533,6 +533,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/ES/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/ES/BaseApp/Purchases/Document/PurchaseHeader.Table.al index a9444e191ea..e89c065b0a4 100644 --- a/src/Layers/ES/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/ES/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -87,6 +87,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -203,6 +204,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2831,10 +2834,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/ES/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/ES/BaseApp/Purchases/Document/PurchaseLine.Table.al index 50f30d77d08..30b1ddab3d1 100644 --- a/src/Layers/ES/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/ES/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -417,7 +417,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3875,6 +3876,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } field(10701; "EC %"; Decimal) { AutoFormatType = 0; @@ -4520,6 +4539,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4802,7 +4822,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/ES/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al b/src/Layers/ES/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al index 3e1354a9a87..9bbdfc2bc6f 100644 --- a/src/Layers/ES/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al +++ b/src/Layers/ES/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al @@ -232,6 +232,11 @@ page 54 "Purchase Order Subform" Importance = Additional; Visible = false; } + field("Receipt on Invoice"; Rec."Receipt on Invoice") + { + ApplicationArea = All; + Visible = false; + } field("Drop Shipment"; Rec."Drop Shipment") { ApplicationArea = Suite; @@ -2019,4 +2024,3 @@ page 54 "Purchase Order Subform" begin end; } - diff --git a/src/Layers/ES/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/ES/BaseApp/Purchases/Vendor/Vendor.Table.al index 4260c11f2ed..fa8b6b8089f 100644 --- a/src/Layers/ES/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/ES/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1688,6 +1688,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } field(10700; "Payment Days Code"; Code[20]) { Caption = 'Payment Days Code'; diff --git a/src/Layers/ES/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/ES/BaseApp/Purchases/Vendor/VendorCard.Page.al index 829f9e0b8ce..c71d75d3c39 100644 --- a/src/Layers/ES/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/ES/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -543,6 +543,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/FI/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/FI/BaseApp/Purchases/Document/PurchaseHeader.Table.al index 6e460c46cef..483bd86b3f8 100644 --- a/src/Layers/FI/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/FI/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -86,6 +86,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -202,6 +203,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2769,10 +2772,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/FI/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/FI/BaseApp/Purchases/Document/PurchaseLine.Table.al index 9c66aee72bf..8cb0607cbbf 100644 --- a/src/Layers/FI/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/FI/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -418,7 +418,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3872,6 +3873,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } #if not CLEANSCHEMA25 field(11200; "Auto. Acc. Group"; Code[10]) { @@ -4507,6 +4526,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4789,7 +4809,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/FI/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/FI/BaseApp/Purchases/Vendor/Vendor.Table.al index a78c48f93b2..d79c1ca750f 100644 --- a/src/Layers/FI/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/FI/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1685,6 +1685,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } field(32000000; "Business Identity Code"; Text[20]) { Caption = 'Business Identity Code'; diff --git a/src/Layers/FI/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/FI/BaseApp/Purchases/Vendor/VendorCard.Page.al index 1a6b2f061d2..6daf036a99c 100644 --- a/src/Layers/FI/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/FI/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -538,6 +538,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/FR/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al b/src/Layers/FR/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al index 77057f5d16d..b2cfb222699 100644 --- a/src/Layers/FR/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al +++ b/src/Layers/FR/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al @@ -232,6 +232,11 @@ page 54 "Purchase Order Subform" Importance = Additional; Visible = false; } + field("Receipt on Invoice"; Rec."Receipt on Invoice") + { + ApplicationArea = All; + Visible = false; + } field("Drop Shipment"; Rec."Drop Shipment") { ApplicationArea = Suite; @@ -2013,4 +2018,3 @@ page 54 "Purchase Order Subform" begin end; } - diff --git a/src/Layers/FR/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/FR/BaseApp/Purchases/Vendor/Vendor.Table.al index 89a519ca714..779e0437413 100644 --- a/src/Layers/FR/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/FR/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1688,6 +1688,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } field(10805; "SIREN No."; Code[9]) { Caption = 'SIREN No.'; diff --git a/src/Layers/FR/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/FR/BaseApp/Purchases/Vendor/VendorCard.Page.al index 5783987251d..988a8117798 100644 --- a/src/Layers/FR/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/FR/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -580,6 +580,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/GB/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/GB/BaseApp/Purchases/Document/PurchaseHeader.Table.al index 9a291ed6063..8cf45005da5 100644 --- a/src/Layers/GB/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/GB/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -86,6 +86,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -202,6 +203,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2769,10 +2772,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/GB/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/GB/BaseApp/Purchases/Document/PurchaseLine.Table.al index d538c2e7f53..63ba2f9f4e8 100644 --- a/src/Layers/GB/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/GB/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -420,7 +420,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3888,6 +3889,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } #if not CLEANSCHEMA30 field(10500; "Reverse Charge Item"; Boolean) { @@ -4539,6 +4558,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4821,7 +4841,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/GB/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/GB/BaseApp/Purchases/Vendor/Vendor.Table.al index 2810448778e..b396b62be16 100644 --- a/src/Layers/GB/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/GB/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1685,6 +1685,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } #if not CLEANSCHEMA26 field(10501; "Exclude from Pmt. Pract. Rep."; Boolean) { diff --git a/src/Layers/GB/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/GB/BaseApp/Purchases/Vendor/VendorCard.Page.al index 8e16d49c746..4356c67042c 100644 --- a/src/Layers/GB/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/GB/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -578,6 +578,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/IS/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/IS/BaseApp/Purchases/Vendor/VendorCard.Page.al index 1e0278615ce..ec0dffcfd84 100644 --- a/src/Layers/IS/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/IS/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -533,6 +533,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/IT/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al b/src/Layers/IT/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al index c70abbfcc28..a2fd280ee1b 100644 --- a/src/Layers/IT/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al +++ b/src/Layers/IT/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al @@ -255,6 +255,7 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeFinancialReportAuditLogAddRetentionPolicy(); UpgradeZeroClosedBankAccountLedgerEntries(); UpgradeDepreciationBooksGLIntegration(); + UpgradePurchaseLineReceiptOnInvoice(); UpgradeWarehouseActivitySourceTypeForJobPlanningLine(); end; @@ -4151,6 +4152,34 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetDepreciationBooksGLIntegrationUpgradeTag()); end; + local procedure UpgradePurchaseLineReceiptOnInvoice() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + UpgradeTag: Codeunit "Upgrade Tag"; + UpgradeTagDefinitions: Codeunit "Upgrade Tag Definitions"; + ReceiptOnInvoiceDataTransfer: DataTransfer; + begin + if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()) then + exit; + + PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order); + PurchaseHeader.SetRange("Receipt on Invoice", true); + PurchaseHeader.SetLoadFields("No."); + if PurchaseHeader.FindSet() then + repeat + Clear(ReceiptOnInvoiceDataTransfer); + ReceiptOnInvoiceDataTransfer.SetTables(Database::"Purchase Line", Database::"Purchase Line"); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document Type"), '=%1', PurchaseLine."Document Type"::Order); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document No."), '=%1', PurchaseHeader."No."); + ReceiptOnInvoiceDataTransfer.AddConstantValue(true, PurchaseLine.FieldNo("Receipt on Invoice")); + ReceiptOnInvoiceDataTransfer.UpdateAuditFields := false; + ReceiptOnInvoiceDataTransfer.CopyFields(); + until PurchaseHeader.Next() = 0; + + UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()); + end; + local procedure UpgradeWarehouseActivitySourceTypeForJobPlanningLine() var WarehouseActivityLine: Record "Warehouse Activity Line"; diff --git a/src/Layers/IT/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al b/src/Layers/IT/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al index 4231ab9e411..923502c50b6 100644 --- a/src/Layers/IT/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al +++ b/src/Layers/IT/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al @@ -181,6 +181,7 @@ codeunit 9998 "Upgrade Tag Definitions" PerCompanyUpgradeTags.Add(GetZeroClosedBankAccountLedgerEntriesUpgradeTag()); PerCompanyUpgradeTags.Add(GetDepreciationBooksGLIntegrationUpgradeTag()); PerCompanyUpgradeTags.Add(GetLegacySubcontractingUpgradeTag()); + PerCompanyUpgradeTags.Add(GetPurchLineReceiptOnInvoiceUpgradeTag()); PerCompanyUpgradeTags.Add(GetWarehouseActivitySourceTypeForJobPlanningLineUpgradeTag()); PerCompanyUpgradeTags.Add(GetRemittanceAdviceReportSelectionUpgradeTag()); PerCompanyUpgradeTags.Add(GetProdDefinitionDisplaySetupUpgradeTag()); @@ -1276,6 +1277,11 @@ codeunit 9998 "Upgrade Tag Definitions" exit('MS-406123-LegacySubcontracting-20260507'); end; + internal procedure GetPurchLineReceiptOnInvoiceUpgradeTag(): Code[250] + begin + exit('MS-625392-PurchLineReceiptOnInvoiceUpgradeTag-20260703'); + end; + internal procedure GetRemittanceAdviceReportSelectionUpgradeTag(): Code[250] begin exit('MS-RemittanceAdviceReportSelection-20260723'); diff --git a/src/Layers/IT/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/IT/BaseApp/Purchases/Document/PurchaseHeader.Table.al index d6814a99d14..34845152759 100644 --- a/src/Layers/IT/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/IT/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -93,6 +93,7 @@ table 38 "Purchase Header" #if not CLEAN28 LegacySubcFeatureHandler: Codeunit "Legacy Subc. Feature Handler"; #endif + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -230,6 +231,8 @@ table 38 "Purchase Header" if xRec."Buy-from Vendor No." = "Buy-from Vendor No." then UpdatePurchLinesByFieldNo(FieldNo("Buy-from Vendor No."), CurrFieldNo <> 0); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2847,10 +2850,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/IT/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/IT/BaseApp/Purchases/Document/PurchaseLine.Table.al index 800a3bb68b8..5dd038af455 100644 --- a/src/Layers/IT/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/IT/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -435,7 +435,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3926,6 +3927,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } field(12100; "No. of Fixed Asset Cards"; Integer) { BlankZero = true; @@ -4766,6 +4785,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -5048,7 +5068,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/IT/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al b/src/Layers/IT/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al index a8976f89ec2..8caab8f1394 100644 --- a/src/Layers/IT/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al +++ b/src/Layers/IT/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al @@ -253,6 +253,11 @@ page 54 "Purchase Order Subform" Importance = Additional; Visible = false; } + field("Receipt on Invoice"; Rec."Receipt on Invoice") + { + ApplicationArea = All; + Visible = false; + } field("Drop Shipment"; Rec."Drop Shipment") { ApplicationArea = Suite; @@ -2035,4 +2040,3 @@ page 54 "Purchase Order Subform" begin end; } - diff --git a/src/Layers/IT/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/IT/BaseApp/Purchases/Vendor/Vendor.Table.al index 5f1e286a15a..df281df668f 100644 --- a/src/Layers/IT/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/IT/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1699,6 +1699,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } field(12100; "Int. on Arrears Code"; Code[10]) { Caption = 'Int. on Arrears Code'; diff --git a/src/Layers/IT/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/IT/BaseApp/Purchases/Vendor/VendorCard.Page.al index a5b3571a731..7d7c8988ac6 100644 --- a/src/Layers/IT/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/IT/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -747,6 +747,11 @@ page 26 "Vendor Card" #pragma warning restore AS0072 } #endif + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/NA/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/NA/BaseApp/Purchases/Document/PurchaseHeader.Table.al index 4e047a11aa5..4e5107c2736 100644 --- a/src/Layers/NA/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/NA/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -86,6 +86,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -203,6 +204,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2825,10 +2828,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/NA/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/NA/BaseApp/Purchases/Document/PurchaseLine.Table.al index 1b98f3df5d4..5b93250f349 100644 --- a/src/Layers/NA/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/NA/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -460,7 +460,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3967,6 +3968,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } field(10001; "Tax To Be Expensed"; Decimal) { AutoFormatType = 0; @@ -4677,6 +4696,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4959,7 +4979,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/NA/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al b/src/Layers/NA/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al index db1a0706f56..2d010b6dcdc 100644 --- a/src/Layers/NA/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al +++ b/src/Layers/NA/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al @@ -237,6 +237,11 @@ page 54 "Purchase Order Subform" Importance = Additional; Visible = false; } + field("Receipt on Invoice"; Rec."Receipt on Invoice") + { + ApplicationArea = All; + Visible = false; + } field("Drop Shipment"; Rec."Drop Shipment") { ApplicationArea = Suite; diff --git a/src/Layers/NA/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/NA/BaseApp/Purchases/Vendor/Vendor.Table.al index 650d2d86fe9..292e5acc8c9 100644 --- a/src/Layers/NA/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/NA/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1685,6 +1685,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } field(10004; "UPS Zone"; Code[2]) { Caption = 'UPS Zone'; diff --git a/src/Layers/NA/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/NA/BaseApp/Purchases/Vendor/VendorCard.Page.al index 8661a6e934c..d149151c5e1 100644 --- a/src/Layers/NA/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/NA/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -580,6 +580,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/NL/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al b/src/Layers/NL/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al index d715b8d17a6..5dd22899861 100644 --- a/src/Layers/NL/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al +++ b/src/Layers/NL/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al @@ -254,6 +254,7 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeFinancialReportAuditLogAddRetentionPolicy(); UpgradeZeroClosedBankAccountLedgerEntries(); UpgradeDepreciationBooksGLIntegration(); + UpgradePurchaseLineReceiptOnInvoice(); UpgradeWarehouseActivitySourceTypeForJobPlanningLine(); end; @@ -4068,6 +4069,34 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetDepreciationBooksGLIntegrationUpgradeTag()); end; + local procedure UpgradePurchaseLineReceiptOnInvoice() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + UpgradeTag: Codeunit "Upgrade Tag"; + UpgradeTagDefinitions: Codeunit "Upgrade Tag Definitions"; + ReceiptOnInvoiceDataTransfer: DataTransfer; + begin + if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()) then + exit; + + PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order); + PurchaseHeader.SetRange("Receipt on Invoice", true); + PurchaseHeader.SetLoadFields("No."); + if PurchaseHeader.FindSet() then + repeat + Clear(ReceiptOnInvoiceDataTransfer); + ReceiptOnInvoiceDataTransfer.SetTables(Database::"Purchase Line", Database::"Purchase Line"); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document Type"), '=%1', PurchaseLine."Document Type"::Order); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document No."), '=%1', PurchaseHeader."No."); + ReceiptOnInvoiceDataTransfer.AddConstantValue(true, PurchaseLine.FieldNo("Receipt on Invoice")); + ReceiptOnInvoiceDataTransfer.UpdateAuditFields := false; + ReceiptOnInvoiceDataTransfer.CopyFields(); + until PurchaseHeader.Next() = 0; + + UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()); + end; + local procedure UpgradeWarehouseActivitySourceTypeForJobPlanningLine() var WarehouseActivityLine: Record "Warehouse Activity Line"; diff --git a/src/Layers/NL/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/NL/BaseApp/Purchases/Document/PurchaseHeader.Table.al index 9c62c1b69a4..28c11e24671 100644 --- a/src/Layers/NL/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/NL/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -86,6 +86,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -202,6 +203,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2773,10 +2776,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/NL/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/NL/BaseApp/Purchases/Document/PurchaseLine.Table.al index 6f6d899c8b5..6b8a11bcc06 100644 --- a/src/Layers/NL/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/NL/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -417,7 +417,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3871,6 +3872,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } field(11303; "Suggested Line"; Boolean) { Caption = 'Suggested Line'; @@ -4501,6 +4520,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4783,7 +4803,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/NL/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/NL/BaseApp/Purchases/Vendor/Vendor.Table.al index eee28d323b9..90259c9a65d 100644 --- a/src/Layers/NL/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/NL/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1725,6 +1725,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } field(11000000; "Transaction Mode Code"; Code[20]) { Caption = 'Transaction Mode Code'; diff --git a/src/Layers/NL/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/NL/BaseApp/Purchases/Vendor/VendorCard.Page.al index f282378b94b..ca06695d444 100644 --- a/src/Layers/NL/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/NL/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -538,6 +538,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/NO/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al b/src/Layers/NO/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al index 25184515070..5d179c1135b 100644 --- a/src/Layers/NO/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al +++ b/src/Layers/NO/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al @@ -251,6 +251,7 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeFinancialReportAuditLogAddRetentionPolicy(); UpgradeZeroClosedBankAccountLedgerEntries(); UpgradeDepreciationBooksGLIntegration(); + UpgradePurchaseLineReceiptOnInvoice(); UpgradeWarehouseActivitySourceTypeForJobPlanningLine(); end; @@ -4021,6 +4022,34 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetDepreciationBooksGLIntegrationUpgradeTag()); end; + local procedure UpgradePurchaseLineReceiptOnInvoice() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + UpgradeTag: Codeunit "Upgrade Tag"; + UpgradeTagDefinitions: Codeunit "Upgrade Tag Definitions"; + ReceiptOnInvoiceDataTransfer: DataTransfer; + begin + if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()) then + exit; + + PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order); + PurchaseHeader.SetRange("Receipt on Invoice", true); + PurchaseHeader.SetLoadFields("No."); + if PurchaseHeader.FindSet() then + repeat + Clear(ReceiptOnInvoiceDataTransfer); + ReceiptOnInvoiceDataTransfer.SetTables(Database::"Purchase Line", Database::"Purchase Line"); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document Type"), '=%1', PurchaseLine."Document Type"::Order); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document No."), '=%1', PurchaseHeader."No."); + ReceiptOnInvoiceDataTransfer.AddConstantValue(true, PurchaseLine.FieldNo("Receipt on Invoice")); + ReceiptOnInvoiceDataTransfer.UpdateAuditFields := false; + ReceiptOnInvoiceDataTransfer.CopyFields(); + until PurchaseHeader.Next() = 0; + + UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()); + end; + local procedure UpgradeWarehouseActivitySourceTypeForJobPlanningLine() var WarehouseActivityLine: Record "Warehouse Activity Line"; diff --git a/src/Layers/NO/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/NO/BaseApp/Purchases/Document/PurchaseHeader.Table.al index 082af6a07e0..47ab118dfd8 100644 --- a/src/Layers/NO/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/NO/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -86,6 +86,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -205,6 +206,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2776,10 +2779,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/NO/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/NO/BaseApp/Purchases/Document/PurchaseLine.Table.al index dd43eeecaa3..709e062d87e 100644 --- a/src/Layers/NO/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/NO/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -418,7 +418,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3875,6 +3876,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } #if not CLEANSCHEMA26 field(10604; "VAT Code"; Code[10]) { @@ -4520,6 +4539,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4802,7 +4822,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo); diff --git a/src/Layers/NO/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/NO/BaseApp/Purchases/Vendor/Vendor.Table.al index 0a5516bf82b..053d4c6b734 100644 --- a/src/Layers/NO/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/NO/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1685,6 +1685,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } field(15000000; Remittance; Boolean) { Caption = 'Remittance'; diff --git a/src/Layers/NO/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/NO/BaseApp/Purchases/Vendor/VendorCard.Page.al index 1f2deaa3fd8..f905a354459 100644 --- a/src/Layers/NO/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/NO/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -548,6 +548,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/RU/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al b/src/Layers/RU/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al index 295e99d7d49..ab0825ea16b 100644 --- a/src/Layers/RU/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al +++ b/src/Layers/RU/BaseApp/OtherCapabilities/Upgrade/UpgradeBaseApp.Codeunit.al @@ -256,6 +256,7 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeFinancialReportAuditLogAddRetentionPolicy(); UpgradeZeroClosedBankAccountLedgerEntries(); UpgradeDepreciationBooksGLIntegration(); + UpgradePurchaseLineReceiptOnInvoice(); UpgradeWarehouseActivitySourceTypeForJobPlanningLine(); end; @@ -4171,6 +4172,34 @@ codeunit 104000 "Upgrade - BaseApp" UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetDepreciationBooksGLIntegrationUpgradeTag()); end; + local procedure UpgradePurchaseLineReceiptOnInvoice() + var + PurchaseHeader: Record "Purchase Header"; + PurchaseLine: Record "Purchase Line"; + UpgradeTag: Codeunit "Upgrade Tag"; + UpgradeTagDefinitions: Codeunit "Upgrade Tag Definitions"; + ReceiptOnInvoiceDataTransfer: DataTransfer; + begin + if UpgradeTag.HasUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()) then + exit; + + PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order); + PurchaseHeader.SetRange("Receipt on Invoice", true); + PurchaseHeader.SetLoadFields("No."); + if PurchaseHeader.FindSet() then + repeat + Clear(ReceiptOnInvoiceDataTransfer); + ReceiptOnInvoiceDataTransfer.SetTables(Database::"Purchase Line", Database::"Purchase Line"); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document Type"), '=%1', PurchaseLine."Document Type"::Order); + ReceiptOnInvoiceDataTransfer.AddSourceFilter(PurchaseLine.FieldNo("Document No."), '=%1', PurchaseHeader."No."); + ReceiptOnInvoiceDataTransfer.AddConstantValue(true, PurchaseLine.FieldNo("Receipt on Invoice")); + ReceiptOnInvoiceDataTransfer.UpdateAuditFields := false; + ReceiptOnInvoiceDataTransfer.CopyFields(); + until PurchaseHeader.Next() = 0; + + UpgradeTag.SetUpgradeTag(UpgradeTagDefinitions.GetPurchLineReceiptOnInvoiceUpgradeTag()); + end; + local procedure UpgradeWarehouseActivitySourceTypeForJobPlanningLine() var WarehouseActivityLine: Record "Warehouse Activity Line"; diff --git a/src/Layers/RU/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al b/src/Layers/RU/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al index 7e1039e8169..71f4d65c30a 100644 --- a/src/Layers/RU/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al +++ b/src/Layers/RU/BaseApp/OtherCapabilities/Upgrade/UpgradeTagDefinitions.Codeunit.al @@ -184,6 +184,7 @@ codeunit 9998 "Upgrade Tag Definitions" PerCompanyUpgradeTags.Add(GetServiceShptLineFieldsUpgradeTag()); PerCompanyUpgradeTags.Add(GetZeroClosedBankAccountLedgerEntriesUpgradeTag()); PerCompanyUpgradeTags.Add(GetDepreciationBooksGLIntegrationUpgradeTag()); + PerCompanyUpgradeTags.Add(GetPurchLineReceiptOnInvoiceUpgradeTag()); PerCompanyUpgradeTags.Add(GetWarehouseActivitySourceTypeForJobPlanningLineUpgradeTag()); PerCompanyUpgradeTags.Add(GetRemittanceAdviceReportSelectionUpgradeTag()); PerCompanyUpgradeTags.Add(GetProdDefinitionDisplaySetupUpgradeTag()); @@ -1296,6 +1297,11 @@ codeunit 9998 "Upgrade Tag Definitions" exit('MS-626097-DepreciationBooksGLIntegrationUpgradeTag-20260319'); end; + internal procedure GetPurchLineReceiptOnInvoiceUpgradeTag(): Code[250] + begin + exit('MS-625392-PurchLineReceiptOnInvoiceUpgradeTag-20260703'); + end; + internal procedure GetRemittanceAdviceReportSelectionUpgradeTag(): Code[250] begin exit('MS-RemittanceAdviceReportSelection-20260723'); diff --git a/src/Layers/RU/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/RU/BaseApp/Purchases/Document/PurchaseHeader.Table.al index 375f3311cc0..c93407b06e4 100644 --- a/src/Layers/RU/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/RU/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -87,6 +87,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -202,6 +203,8 @@ table 38 "Purchase Header" if "Empl. Purchase" then "Vendor Invoice No." := "No."; + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2778,10 +2781,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/RU/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/RU/BaseApp/Purchases/Document/PurchaseLine.Table.al index 58a637754ea..8153143fc98 100644 --- a/src/Layers/RU/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/RU/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -422,7 +422,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3877,6 +3878,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } field(12100; "No. of Fixed Asset Cards"; Integer) { BlankZero = true; @@ -4690,6 +4709,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4976,7 +4996,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; if Item."Gross Weight Mandatory" then Item.TestField("Gross Weight"); diff --git a/src/Layers/RU/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al b/src/Layers/RU/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al index f90d4659b13..1562390c38f 100644 --- a/src/Layers/RU/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al +++ b/src/Layers/RU/BaseApp/Purchases/Document/PurchaseOrderSubform.Page.al @@ -232,6 +232,11 @@ page 54 "Purchase Order Subform" Importance = Additional; Visible = false; } + field("Receipt on Invoice"; Rec."Receipt on Invoice") + { + ApplicationArea = All; + Visible = false; + } field("Drop Shipment"; Rec."Drop Shipment") { ApplicationArea = Suite; @@ -2053,4 +2058,3 @@ page 54 "Purchase Order Subform" begin end; } - diff --git a/src/Layers/RU/BaseApp/Purchases/Vendor/Vendor.Table.al b/src/Layers/RU/BaseApp/Purchases/Vendor/Vendor.Table.al index 0fe30455ad1..ee6e82004d0 100644 --- a/src/Layers/RU/BaseApp/Purchases/Vendor/Vendor.Table.al +++ b/src/Layers/RU/BaseApp/Purchases/Vendor/Vendor.Table.al @@ -1733,6 +1733,11 @@ table 23 Vendor ToolTip = 'Specifies the policy that will be used for the vendor if more items than ordered are received.'; TableRelation = "Over-Receipt Code"; } + field(8551; "Receipt on Invoice Policy"; Enum "Receipt on Invoice Policy") + { + Caption = 'Receipt on Invoice Policy'; + ToolTip = 'Specifies whether receipt on invoice is enabled automatically for new purchase orders from this vendor.'; + } field(12400; "Default Bank Code"; Code[20]) { Caption = 'Default Bank Code'; diff --git a/src/Layers/RU/BaseApp/Purchases/Vendor/VendorCard.Page.al b/src/Layers/RU/BaseApp/Purchases/Vendor/VendorCard.Page.al index 448a94b28ef..f09b76c092c 100644 --- a/src/Layers/RU/BaseApp/Purchases/Vendor/VendorCard.Page.al +++ b/src/Layers/RU/BaseApp/Purchases/Vendor/VendorCard.Page.al @@ -642,6 +642,11 @@ page 26 "Vendor Card" ApplicationArea = All; Visible = OverReceiptAllowed; } + field("Receipt on Invoice Policy"; Rec."Receipt on Invoice Policy") + { + ApplicationArea = All; + Caption = 'Receipt on Invoice'; + } } } area(factboxes) diff --git a/src/Layers/SE/BaseApp/Purchases/Document/PurchaseHeader.Table.al b/src/Layers/SE/BaseApp/Purchases/Document/PurchaseHeader.Table.al index d555836661b..b80940a449f 100644 --- a/src/Layers/SE/BaseApp/Purchases/Document/PurchaseHeader.Table.al +++ b/src/Layers/SE/BaseApp/Purchases/Document/PurchaseHeader.Table.al @@ -86,6 +86,7 @@ table 38 "Purchase Header" trigger OnValidate() var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; IsHandled: Boolean; begin IsHandled := false; @@ -202,6 +203,8 @@ table 38 "Purchase Header" Rec.Validate("Remit-to Code", ''); end else SelectDefaultRemitAddress(Rec); + + MatchedOrderLineMgmt.ApplyVendorsReceiptOnInvoicePolicy(Rec); end; } field(3; "No."; Code[20]) @@ -2769,10 +2772,7 @@ table 38 "Purchase Header" var MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; begin - if "Receipt on Invoice" then - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowed(Rec); - - MatchedOrderLineMgmt.RefreshMatchedOrderLineReceipt(Rec); + MatchedOrderLineMgmt.ApplyReceiptOnInvoiceToLines(Rec); end; } field(7000; "Price Calculation Method"; Enum "Price Calculation Method") diff --git a/src/Layers/SE/BaseApp/Purchases/Document/PurchaseLine.Table.al b/src/Layers/SE/BaseApp/Purchases/Document/PurchaseLine.Table.al index 9c66aee72bf..8cb0607cbbf 100644 --- a/src/Layers/SE/BaseApp/Purchases/Document/PurchaseLine.Table.al +++ b/src/Layers/SE/BaseApp/Purchases/Document/PurchaseLine.Table.al @@ -418,7 +418,8 @@ table 39 "Purchase Line" GetDefaultBin(); CheckWMS(); - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForLocation("Location Code", GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForLocation("Location Code") then + Rec.Validate("Receipt on Invoice", false); if "Document Type" = "Document Type"::"Return Order" then ValidateReturnReasonCode(FieldNo("Location Code")); @@ -3872,6 +3873,24 @@ table 39 "Purchase Line" Editable = false; FieldClass = FlowField; } + field(8513; "Receipt on Invoice"; Boolean) + { + Caption = 'Receipt on Invoice'; + ToolTip = 'Specifies whether the receipt is posted automatically with the invoice.'; + + trigger OnValidate() + var + MatchedOrderLineMgmt: Codeunit "Matched Order Line Mgmt."; + begin + if "Receipt on Invoice" then + MatchedOrderLineMgmt.CheckLineReceiptOnInvoiceAllowed(Rec); + + if "Document Type" = "Document Type"::Order then + InitQtyToReceive(); + + MatchedOrderLineMgmt.ApplyPurchaseLineReceiptSettingToMatches(Rec); + end; + } #if not CLEANSCHEMA25 field(11200; "Auto. Acc. Group"; Code[10]) { @@ -4507,6 +4526,7 @@ table 39 "Purchase Line" "Promised Receipt Date" := PurchHeader."Promised Receipt Date"; "Inbound Whse. Handling Time" := PurchHeader."Inbound Whse. Handling Time"; "Order Date" := PurchHeader."Order Date"; + Rec."Receipt on Invoice" := PurchHeader."Receipt on Invoice"; OnAfterInitHeaderDefaults(Rec, PurchHeader, TempPurchLine); end; @@ -4789,7 +4809,8 @@ table 39 "Purchase Line" Item.TestField("Inventory Posting Group"); "Posting Group" := Item."Inventory Posting Group"; end; - MatchedOrderLineMgmt.CheckReceiptOnInvoiceAllowedForItem(Item, GetPurchHeader()); + if Rec."Receipt on Invoice" and not MatchedOrderLineMgmt.IsReceiptOnInvoiceAllowedForItem(Item) then + Rec.Validate("Receipt on Invoice", false); end; OnCopyFromItemOnAfterCheck(Rec, Item, CurrFieldNo);