Skip to content

Fix: Restore Completely Shipped after RedistributeInvoiceDiscounts in Sales Order API pages#29954

Open
jeffreybulanadi wants to merge 1 commit intomicrosoft:mainfrom
jeffreybulanadi:fix/29071-sales-order-completely-shipped
Open

Fix: Restore Completely Shipped after RedistributeInvoiceDiscounts in Sales Order API pages#29954
jeffreybulanadi wants to merge 1 commit intomicrosoft:mainfrom
jeffreybulanadi:fix/29071-sales-order-completely-shipped

Conversation

@jeffreybulanadi
Copy link
Copy Markdown

@jeffreybulanadi jeffreybulanadi commented Apr 21, 2026

Summary

Fixes #29071

Root Cause

In OnAfterGetRecord of both APIV1 - Sales Orders (page 20000) and APIV2 - Sales Orders (page 30028), calling GraphMgtSalesOrderBuffer.RedistributeInvoiceDiscounts(Rec) has an unintended side effect on Rec.\Completely Shipped\`.

The call chain is:

  1. RedistributeInvoiceDiscounts calls SalesCalcDiscountByType.ResetRecalculateInvoiceDisc(SalesHeader)
  2. Which calls SalesLine.ModifyAll(\Recalculate Invoice Disc.\, false) with a filter on Recalculate Invoice Disc. = Yes
  3. This fires OnAfterModifySalesLine on codeunit 5496, which calls UpdateCompletelyShipped(Rec) where Rec still carries the Recalculate Invoice Disc. = Yes filter
  4. UpdateCompletelyShipped calls SearchSalesLine.CopyFilters(SalesLine), inheriting the spurious filter
  5. SearchSalesLine.IsEmpty() returns rue because no lines have Recalculate Invoice Disc. = Yes after the ModifyAll
  6. Rec.\Completely Shipped\ := SearchSalesLine.IsEmpty() is set to rue incorrectly

Fix

Save the value of Rec.\Completely Shipped\` from the database before invoking RedistributeInvoiceDiscounts and restore it afterward. The invoice discount redistribution function has no business modifying shipping status; this ensures the API returns the actual shipment state of the sales lines.

Files Changed

  • Apps/W1/APIV2/app/src/pages/APIV2SalesOrders.Page.al
  • Apps/W1/APIV1/app/src/pages/APIV1SalesOrders.Page.al

How to Test

  1. Create a Sales Order with one or more sales lines (do not ship any lines).
  2. Call GET /api/v2.0/companies({id})/salesOrders({id}).
  3. Verify ullyShipped is alse.
  4. Before this fix, ullyShipped would incorrectly return rue.

… 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 microsoft#29071
@jeffreybulanadi jeffreybulanadi requested a review from a team as a code owner April 21, 2026 08:43
@JesperSchulz JesperSchulz added the Integration GitHub request for Integration area label Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Integration GitHub request for Integration area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: SalesOrder "Completely Shipped" is always true in "Sales Order Entity Buffer"

2 participants