From 498100a5ac69a761e34bc963370511838731cf45 Mon Sep 17 00:00:00 2001 From: Dusan Jakovljevic Date: Wed, 9 Sep 2026 11:03:28 +0200 Subject: [PATCH 1/4] Add configuration for updating order quantities on credit memo/return postings --- .../Sales/Document/SalesHeader.Table.al | 5 ++++ .../CancelPstdSalesInvYesNo.Codeunit.al | 13 +++++++-- .../CorrectPostedSalesInvoice.Codeunit.al | 28 +++++++++++++------ .../Sales/Posting/SalesPost.Codeunit.al | 4 +++ .../Setup/SalesReceivablesSetup.Table.al | 8 ++++++ 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al b/src/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al index a3416266fcd..62281f6a808 100644 --- a/src/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al +++ b/src/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al @@ -9670,9 +9670,14 @@ table 36 "Sales Header" procedure UpdateSalesOrderLineIfExist() var SalesCreditMemoHeader: Record "Sales Cr.Memo Header"; + SalesReceivablesSetup: Record "Sales & Receivables Setup"; CorrectPostedSalesInvoice: Codeunit "Correct Posted Sales Invoice"; IsHandled: Boolean; begin + SalesReceivablesSetup.GetRecordOnce(); + if not SalesReceivablesSetup."Update Order Qty. on CM/Return" then + exit; + SalesCreditMemoHeader.SetLoadFields("Pre-Assigned No.", "Cust. Ledger Entry No."); SalesCreditMemoHeader.SetRange("Pre-Assigned No.", Rec."No."); if not SalesCreditMemoHeader.FindFirst() then diff --git a/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al b/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al index 39dbd724621..e23dac4dc61 100644 --- a/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al +++ b/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al @@ -4,6 +4,7 @@ // ------------------------------------------------------------------------------------------------ namespace Microsoft.Sales.History; +using Microsoft.Sales.Setup; using Microsoft.Utilities; /// @@ -21,7 +22,7 @@ codeunit 1323 "Cancel PstdSalesInv (Yes/No)" end; var - CancelPostedInvoiceFromOrderQst: Label 'This invoice was posted from a sales order. To cancel it, a sales credit memo will be created and posted. The quantities from the original sales order will be restored, provided the sales order still exists.\ \Do you want to continue?'; + CancelPostedInvoiceFromOrderQst: Label 'This invoice was posted from a sales order. To cancel it, a sales credit memo will be created and posted. The quantities from the will be restored, provided the sales order still exists.\ \Do you want to continue?'; CancelPostedInvoiceQst: Label 'The posted sales invoice will be canceled, and a sales credit memo will be created and posted.\ \Do you want to continue?'; OpenPostedCreditMemoQst: Label 'A credit memo was successfully created. Do you want to open the posted credit memo?'; @@ -61,9 +62,15 @@ codeunit 1323 "Cancel PstdSalesInv (Yes/No)" end; local procedure GetCancelPostedInvoiceQst(SalesInvoiceHeader: Record "Sales Invoice Header"): Text + var + SalesReceivablesSetup: Record "Sales & Receivables Setup"; begin - if SalesInvoiceHeader."Order No." <> '' then - exit(CancelPostedInvoiceFromOrderQst); + if SalesInvoiceHeader."Order No." <> '' then begin + SalesReceivablesSetup.GetRecordOnce(); + if SalesReceivablesSetup."Update Order Qty. on CM/Return" then + exit(CancelPostedInvoiceFromOrderQst); + end; + exit(CancelPostedInvoiceQst); end; diff --git a/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al b/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al index 8c2454d5312..b2bd8fe596e 100644 --- a/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al +++ b/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al @@ -208,7 +208,7 @@ codeunit 1303 "Correct Posted Sales Invoice" /// True if the credit memo was successfully created, otherwise false. procedure CreateCreditMemoCopyDocument(var SalesInvoiceHeader: Record "Sales Invoice Header"; var SalesHeader: Record "Sales Header"): Boolean var - SalesHdr: Record "Sales Header"; + SalesHeaderOrder: Record "Sales Header"; ConfirmQuestion: Text; begin OnBeforeCreateCreditMemoCopyDocument(SalesInvoiceHeader); @@ -219,13 +219,17 @@ codeunit 1303 "Correct Posted Sales Invoice" ShowInvoiceAppliedNotification(SalesInvoiceHeader); exit(false); end; - SalesHdr.SetRange("Document Type", SalesHdr."Document Type"::Order); - SalesHdr.SetRange("No.", SalesInvoiceHeader."Order No."); - if not SalesHdr.IsEmpty then begin - ConfirmQuestion := CreateCreditMemoQst; - OnCreateCreditMemoCopyDocumentOnBeforeConfirm(SalesInvoiceHeader, SalesHdr, ConfirmQuestion); - if not Confirm(ConfirmQuestion) then - exit(false); + + SalesReceivablesSetup.GetRecordOnce(); + if SalesReceivablesSetup."Update Order Qty. on CM/Return" then begin + SalesHeaderOrder.SetRange("Document Type", SalesHeaderOrder."Document Type"::Order); + SalesHeaderOrder.SetRange("No.", SalesInvoiceHeader."Order No."); + if not SalesHeaderOrder.IsEmpty() then begin + ConfirmQuestion := CreateCreditMemoQst; + OnCreateCreditMemoCopyDocumentOnBeforeConfirm(SalesInvoiceHeader, SalesHeaderOrder, ConfirmQuestion); + if not Confirm(ConfirmQuestion) then + exit(false); + end; end; CreateCopyDocument(SalesInvoiceHeader, SalesHeader, SalesHeader."Document Type"::"Credit Memo", false); @@ -1029,6 +1033,10 @@ codeunit 1303 "Correct Posted Sales Invoice" SalesInvoiceLine: Record "Sales Invoice Line"; TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; begin + SalesReceivablesSetup.GetRecordOnce(); + if not SalesReceivablesSetup."Update Order Qty. on CM/Return" then + exit; + SalesCrMemoLine.SetLoadFields("Document No.", "No.", "Appl.-from Item Entry", Quantity, "Variant Code"); SalesCrMemoLine.SetRange("Document No.", SalesCreditMemoNo); SalesCrMemoLine.SetFilter("No.", '<>%1', ''); @@ -1124,6 +1132,10 @@ codeunit 1303 "Correct Posted Sales Invoice" UndoPostingManagement: Codeunit "Undo Posting Management"; IsHandled: Boolean; begin + SalesReceivablesSetup.GetRecordOnce(); + if not SalesReceivablesSetup."Update Order Qty. on CM/Return" then + exit; + IsHandled := false; OnBeforeUpdateSalesOrderLinesFromCancelledInvoice(SalesInvoiceHeaderNo, IsHandled); if IsHandled then diff --git a/src/Layers/W1/BaseApp/Sales/Posting/SalesPost.Codeunit.al b/src/Layers/W1/BaseApp/Sales/Posting/SalesPost.Codeunit.al index 782be6a2192..f8885a64d69 100644 --- a/src/Layers/W1/BaseApp/Sales/Posting/SalesPost.Codeunit.al +++ b/src/Layers/W1/BaseApp/Sales/Posting/SalesPost.Codeunit.al @@ -8951,6 +8951,10 @@ codeunit 80 "Sales-Post" CorrectPostedSalesInvoice: Codeunit "Correct Posted Sales Invoice"; IsHandled: Boolean; begin + SalesSetup.GetRecordOnce(); + if not SalesSetup."Update Order Qty. on CM/Return" then + exit; + IsHandled := false; OnBeforeUpdateSalesOrderLineIfExist(DocumentNo, IsHandled); if IsHandled then diff --git a/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Table.al b/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Table.al index 96520d7410f..44129639026 100644 --- a/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Table.al +++ b/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Table.al @@ -616,6 +616,14 @@ table 311 "Sales & Receivables Setup" ToolTip = 'Specifies that the reservation confirmation message is not shown on sales lines. This is useful to avoid noise when you are processing many lines.'; } /// + /// Indicates whether posting a sales credit memo or return order restores the reversed quantities on the related sales order. + /// + field(70; "Update Order Qty. on CM/Return"; Boolean) + { + Caption = 'Update Order Quantity on Credit Memo/Return Posting'; + ToolTip = 'Specifies whether posting a sales credit memo or sales return order restores quantities on the related sales order. When enabled, Qty. to Ship, Qty. to Invoice, and the shipped and invoiced quantities on the original sales order are updated based on the reversed quantity.'; + } + /// /// Indicates whether customer name changes on open sales documents apply only to the document without searching for matching customers. /// field(160; "Disable Search by Name"; Boolean) From 470e6412a33caf8ad2423ebd9175459cead09294 Mon Sep 17 00:00:00 2001 From: Dusan Jakovljevic Date: Thu, 10 Sep 2026 16:42:24 +0200 Subject: [PATCH 2/4] Rename "Update Order Qty. on CM/Return" to "Restore Order qty. on return" for clarity in sales posting logic --- src/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al | 2 +- .../Sales/History/CancelPstdSalesInvYesNo.Codeunit.al | 2 +- .../Sales/History/CorrectPostedSalesInvoice.Codeunit.al | 6 +++--- src/Layers/W1/BaseApp/Sales/Posting/SalesPost.Codeunit.al | 2 +- .../W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Table.al | 5 +++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al b/src/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al index 62281f6a808..0ffbc1dfaa2 100644 --- a/src/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al +++ b/src/Layers/W1/BaseApp/Sales/Document/SalesHeader.Table.al @@ -9675,7 +9675,7 @@ table 36 "Sales Header" IsHandled: Boolean; begin SalesReceivablesSetup.GetRecordOnce(); - if not SalesReceivablesSetup."Update Order Qty. on CM/Return" then + if not SalesReceivablesSetup."Restore Order qty. on return" then exit; SalesCreditMemoHeader.SetLoadFields("Pre-Assigned No.", "Cust. Ledger Entry No."); diff --git a/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al b/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al index e23dac4dc61..c17903aae80 100644 --- a/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al +++ b/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al @@ -67,7 +67,7 @@ codeunit 1323 "Cancel PstdSalesInv (Yes/No)" begin if SalesInvoiceHeader."Order No." <> '' then begin SalesReceivablesSetup.GetRecordOnce(); - if SalesReceivablesSetup."Update Order Qty. on CM/Return" then + if SalesReceivablesSetup."Restore Order qty. on return" then exit(CancelPostedInvoiceFromOrderQst); end; diff --git a/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al b/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al index b2bd8fe596e..1b2b14152b9 100644 --- a/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al +++ b/src/Layers/W1/BaseApp/Sales/History/CorrectPostedSalesInvoice.Codeunit.al @@ -221,7 +221,7 @@ codeunit 1303 "Correct Posted Sales Invoice" end; SalesReceivablesSetup.GetRecordOnce(); - if SalesReceivablesSetup."Update Order Qty. on CM/Return" then begin + if SalesReceivablesSetup."Restore Order qty. on return" then begin SalesHeaderOrder.SetRange("Document Type", SalesHeaderOrder."Document Type"::Order); SalesHeaderOrder.SetRange("No.", SalesInvoiceHeader."Order No."); if not SalesHeaderOrder.IsEmpty() then begin @@ -1034,7 +1034,7 @@ codeunit 1303 "Correct Posted Sales Invoice" TempUsedSalesInvoiceLine: Record "Sales Invoice Line" temporary; begin SalesReceivablesSetup.GetRecordOnce(); - if not SalesReceivablesSetup."Update Order Qty. on CM/Return" then + if not SalesReceivablesSetup."Restore Order qty. on return" then exit; SalesCrMemoLine.SetLoadFields("Document No.", "No.", "Appl.-from Item Entry", Quantity, "Variant Code"); @@ -1133,7 +1133,7 @@ codeunit 1303 "Correct Posted Sales Invoice" IsHandled: Boolean; begin SalesReceivablesSetup.GetRecordOnce(); - if not SalesReceivablesSetup."Update Order Qty. on CM/Return" then + if not SalesReceivablesSetup."Restore Order qty. on return" then exit; IsHandled := false; diff --git a/src/Layers/W1/BaseApp/Sales/Posting/SalesPost.Codeunit.al b/src/Layers/W1/BaseApp/Sales/Posting/SalesPost.Codeunit.al index f8885a64d69..8b0b4a16e4f 100644 --- a/src/Layers/W1/BaseApp/Sales/Posting/SalesPost.Codeunit.al +++ b/src/Layers/W1/BaseApp/Sales/Posting/SalesPost.Codeunit.al @@ -8952,7 +8952,7 @@ codeunit 80 "Sales-Post" IsHandled: Boolean; begin SalesSetup.GetRecordOnce(); - if not SalesSetup."Update Order Qty. on CM/Return" then + if not SalesSetup."Restore Order qty. on return" then exit; IsHandled := false; diff --git a/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Table.al b/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Table.al index 44129639026..b3c340cdf42 100644 --- a/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Table.al +++ b/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Table.al @@ -618,10 +618,11 @@ table 311 "Sales & Receivables Setup" /// /// Indicates whether posting a sales credit memo or return order restores the reversed quantities on the related sales order. /// - field(70; "Update Order Qty. on CM/Return"; Boolean) + field(70; "Restore Order qty. on return"; Boolean) { - Caption = 'Update Order Quantity on Credit Memo/Return Posting'; + Caption = 'Restore Order quantities on Credit Memo or Return Order posting'; ToolTip = 'Specifies whether posting a sales credit memo or sales return order restores quantities on the related sales order. When enabled, Qty. to Ship, Qty. to Invoice, and the shipped and invoiced quantities on the original sales order are updated based on the reversed quantity.'; + InitValue = true; } /// /// Indicates whether customer name changes on open sales documents apply only to the document without searching for matching customers. From a4438260b6182c980c27282a0c344f9458684dd8 Mon Sep 17 00:00:00 2001 From: Dusan Jakovljevic Date: Thu, 10 Sep 2026 16:47:27 +0200 Subject: [PATCH 3/4] Add field for restoring order quantity on return in Sales & Receivables Setup --- .../W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Page.al | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Page.al b/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Page.al index 5e9c53e5449..b390d4e3850 100644 --- a/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Page.al +++ b/src/Layers/W1/BaseApp/Sales/Setup/SalesReceivablesSetup.Page.al @@ -58,6 +58,11 @@ page 459 "Sales & Receivables Setup" ApplicationArea = Basic, Suite; Importance = Additional; } + field("Restore Order qty. on return"; Rec."Restore Order qty. on return") + { + ApplicationArea = Basic, Suite; + Importance = Additional; + } field("Invoice Rounding"; Rec."Invoice Rounding") { ApplicationArea = Basic, Suite; From 4b06320bf6e2777c3d203ad265cb2474748bf648 Mon Sep 17 00:00:00 2001 From: Dusan Jakovljevic Date: Thu, 10 Sep 2026 16:49:47 +0200 Subject: [PATCH 4/4] Reverse wrong change --- .../BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al b/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al index c17903aae80..f060d5e3b66 100644 --- a/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al +++ b/src/Layers/W1/BaseApp/Sales/History/CancelPstdSalesInvYesNo.Codeunit.al @@ -22,7 +22,7 @@ codeunit 1323 "Cancel PstdSalesInv (Yes/No)" end; var - CancelPostedInvoiceFromOrderQst: Label 'This invoice was posted from a sales order. To cancel it, a sales credit memo will be created and posted. The quantities from the will be restored, provided the sales order still exists.\ \Do you want to continue?'; + CancelPostedInvoiceFromOrderQst: Label 'This invoice was posted from a sales order. To cancel it, a sales credit memo will be created and posted. The quantities from the original sales order will be restored, provided the sales order still exists.\ \Do you want to continue?'; CancelPostedInvoiceQst: Label 'The posted sales invoice will be canceled, and a sales credit memo will be created and posted.\ \Do you want to continue?'; OpenPostedCreditMemoQst: Label 'A credit memo was successfully created. Do you want to open the posted credit memo?';