From 7dff0858bc453835264636df4ce5b927c5866f70 Mon Sep 17 00:00:00 2001 From: Jeffrey Bulanadi Date: Tue, 21 Apr 2026 16:42:36 +0800 Subject: [PATCH 1/2] Fix: Restore Completely Shipped after RedistributeInvoiceDiscounts in Sales Order API pages RedistributeInvoiceDiscounts called in OnAfterGetRecord triggers an OnAfterModifySalesLine event handler (UpdateCompletelyShipped) that copies spurious filters from the SalesLine record and incorrectly evaluates IsEmpty() as true, causing Completely Shipped to be set to true regardless of actual shipment status. Save and restore Rec.'Completely Shipped' around the call in both APIV1 - Sales Orders and APIV2 - Sales Orders pages so that the value returned by the API reflects the actual state of sales lines. Fixes #29071 --- Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al | 7 ++++++- Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al b/Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al index 254a581d1c..530017b224 100644 --- a/Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al +++ b/Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al @@ -451,10 +451,15 @@ page 20028 "APIV1 - Sales Orders" } trigger OnAfterGetRecord() + var + IsCompletelyShipped: Boolean; begin SetCalculatedFields(); - if HasWritePermission then + if HasWritePermission then begin + IsCompletelyShipped := Rec."Completely Shipped"; GraphMgtSalesOrderBuffer.RedistributeInvoiceDiscounts(Rec); + Rec."Completely Shipped" := IsCompletelyShipped; + end; end; trigger OnDeleteRecord(): Boolean diff --git a/Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al index acf7eff5df..90ccdfe0e6 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al @@ -613,10 +613,15 @@ page 30028 "APIV2 - Sales Orders" } trigger OnAfterGetRecord() + var + IsCompletelyShipped: Boolean; begin SetCalculatedFields(); - if HasWritePermission then + if HasWritePermission then begin + IsCompletelyShipped := Rec."Completely Shipped"; GraphMgtSalesOrderBuffer.RedistributeInvoiceDiscounts(Rec); + Rec."Completely Shipped" := IsCompletelyShipped; + end; end; trigger OnDeleteRecord(): Boolean From 572c71e18c19b958b5d9ecba2e705ca4436df1a5 Mon Sep 17 00:00:00 2001 From: Jeffrey Bulanadi Date: Thu, 30 Apr 2026 01:14:25 +0800 Subject: [PATCH 2/2] Fix: re-read Sales Header from DB after RedistributeInvoiceDiscounts Replace the IsCompletelyShipped save/restore pattern with Rec.Find() after RedistributeInvoiceDiscounts. This re-reads the entire Sales Header record from the database, ensuring all fields including Completely Shipped reflect the true persisted state regardless of any in-memory side effects from the invoice discount redistribution call chain. --- Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al | 5 +---- Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al b/Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al index 530017b224..09b16c5b3e 100644 --- a/Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al +++ b/Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al @@ -451,14 +451,11 @@ page 20028 "APIV1 - Sales Orders" } trigger OnAfterGetRecord() - var - IsCompletelyShipped: Boolean; begin SetCalculatedFields(); if HasWritePermission then begin - IsCompletelyShipped := Rec."Completely Shipped"; GraphMgtSalesOrderBuffer.RedistributeInvoiceDiscounts(Rec); - Rec."Completely Shipped" := IsCompletelyShipped; + Rec.Find(); end; end; diff --git a/Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al b/Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al index 90ccdfe0e6..9a82565e94 100644 --- a/Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al +++ b/Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al @@ -613,14 +613,11 @@ page 30028 "APIV2 - Sales Orders" } trigger OnAfterGetRecord() - var - IsCompletelyShipped: Boolean; begin SetCalculatedFields(); if HasWritePermission then begin - IsCompletelyShipped := Rec."Completely Shipped"; GraphMgtSalesOrderBuffer.RedistributeInvoiceDiscounts(Rec); - Rec."Completely Shipped" := IsCompletelyShipped; + Rec.Find(); end; end;