Scenario: Cancel a posted sales packing slip
Goal. A shipment was posted in D365 that did not leave the warehouse, or was posted for the wrong quantity. Your warehouse or order management system cancels the packing slip from outside D365, exactly as Cancel in the packing slip journal does: the delivery, its inventory transactions and its ledger postings are reversed, the packing slip is kept as a new version with zero quantities, and the order lines are open to deliver again.
When to use. Correcting a packing slip before it is invoiced, for example after Sales order to invoice step 4 posted a shipment that was then stopped. Once the packing slip is invoiced it cannot be canceled: goods that come back after the invoice go through Sales return to credit note. The vendor-side twin is Cancel a posted product receipt.
Prerequisites
- Security. Canceling a packing slip reverses inventory and ledger postings, so the operation is
high-risk. It needs privilege
MGCLatticeAccountsReceivablePackingSlipCancelMaintain("Accounts receivable - cancel sales packing slip (high-risk)"), which is in dutyMGCLatticeIntegrationServiceHighRiskDutyof the integration administrator role only. The operator role andMGCLatticeAccountsReceivableServiceMaintain(which posts packing slips) do not grant it. Without it D365 refuses the call with HTTP 403. Reading the result back throughLatticeCustomerPackingSlipJournalLinescomes with the Lattice roles; the standardSalesOrderLinesentity needs D365's own privileges. See Security model. - A packing slip the packing slip journal can cancel. A sales order (USMF
001367for customerUS-001) with a posted packing slip that is not invoiced, fully or in part. D365 does not offer Cancel for a drop shipment, a packing slip with open warehouse work, a line with a project item requirement, or an order type that cannot be corrected; the operation refuses those too. - Lattice. A valid license (an expired or invalid one refuses the call with
LicenseNotValid). To name the order by your own key, sendSalesOrderIdExternalKeywithExternalSystem(Use your own keys).
Steps
The operation is cancelSalesPackingSlip on MGCLatticeSalesOrderPostingService in service group
MGCLatticeAccountsReceivableServiceGroup. Send a POST with an OAuth 2.0 bearer token and the request in
_request (see Trial and day-one guide).
-
Know the packing slip. It is the
PostedDocumentIdthatpostSalesPackingSlipanswered (for exampleSPK-00002040), or read the order's packing slips:GET https://<your-environment>/data/LatticeCustomerPackingSlipJournalLines?cross-company=true&$filter=dataAreaId eq 'USMF' and SalesOrderNumber eq '001367'&$select=PackingSlipId,Quantity. -
Cancel it.
POST https://<your-environment>/api/services/MGCLatticeAccountsReceivableServiceGroup/MGCLatticeSalesOrderPostingService/cancelSalesPackingSlip{"_request": {"RequestId": "4e2a9c71-0b3d-4f58-8a16-7d5c3e9b2f40","LegalEntityId": "USMF","UserContext": "Admin","SalesOrderId": "001367","PackingSlipId": "SPK-00002040"}}PackingSlipIdis optional when the order has only one packing slip that can be canceled: without it, that one is canceled. When the order has several, name the one you mean. The operation cancels the whole packing slip; to deliver a different quantity, post a new packing slip afterwards. -
Read the result.
DocumentIdis the sales order andPostedDocumentIdthe canceled packing slip:Packing slip SPK-00002040 of sales order 001367 was canceled; its quantities are open to deliver again.Success is reported only when the packing slip reads as canceled and every order line it delivered is open to deliver again by the delivered quantity; otherwise the cancellation is rolled back and nothing is kept.
The bulk variant cancelSalesPackingSlipBatch takes { "_requests": [ ... ] }, each item a full request with
its own RequestId, and answers one result per item (see Batch and async operations).
The operation is synchronous only and has no preview.
How to verify
- The response:
Successtrue,Status3,DocumentIdthe order,PostedDocumentIdthe packing slip. - The packing slip:
LatticeCustomerPackingSlipJournalLinesfor the order and packing slip showsQuantity0. - The order:
SalesOrderLines(filter onSalesOrderNumber) showsSalesOrderLineStatusBackorder(open order) again, andgetSalesOrderStatusanswersDocumentStatusBackorder. - In D365: Sales and marketing > Sales orders > All sales orders, open the order, then on the Pick and pack tab open the Packing slip journal: the packing slip shows quantity 0, and its version history shows the cancellation. The line's Inventory > Transactions show the delivery reversed.
- The call: System administration > Inquiries > Lattice > Services > Service call log, or
LatticeServiceCallLogsfiltered on yourRequestId.
When it goes wrong
A failed call answers Success false, Status 4, an ErrorCode and the message "Packing slip cancellation
failed due to validation or business rule constraints."; the reasons are in Errors. Nothing is canceled.
| ErrorCode | Typical cause (text in Errors) | What to do |
|---|---|---|
ValidationFailed (1) | No RequestId, LegalEntityId or order; "Sales order 001367 has several packing slips that can be canceled: ... Send PackingSlipId to name the one to cancel."; a packing slip number posted on several delivery dates; "Packing slip ... also delivers sales order(s) ... and cannot be canceled for sales order ... alone." | Name the packing slip. A packing slip posted for several orders at once, or on several dates, is canceled in the packing slip journal in D365. |
DocumentNotFound (2) | An unknown order; "Packing slip X was not found for sales order Y." | Check the order and packing slip numbers and LegalEntityId. |
InvalidStatus (3) | "Sales order 001367 has no posted packing slip to cancel."; "Packing slip X is already canceled."; "Packing slip X is invoiced, fully or in part, and cannot be canceled."; "Packing slip X cannot be canceled: the packing slip journal's Cancel is not available for it (...)" | Nothing to cancel. For goods already invoiced, create a sales return. |
BusinessRule (4) | D365 refused the cancellation (its messages in Errors), or the cancellation completed without opening the order lines again and was rolled back | Fix the cause named in Errors, then resend. |
PreviewUnsupported (10) | PreviewMode true | Send without PreviewMode. Nothing was run. |
TransientRuntime (6) | A runtime fault; IsRetryable true | Resend with the same RequestId. |
DuplicateRequest (7) | The RequestId was first used for another operation | Send a new RequestId. |
LicenseNotValid (12) | The Lattice license is expired or invalid | Renew the license, then resend. |
Retries are safe. Resending a successful request with the same RequestId cancels nothing again: the answer
repeats the original result with the message Duplicate request detected. Original request processed at ....
A failed request releases its RequestId, so you can resend it after fixing the cause. Failed calls show on the
Failed service calls (24 h) tile of the Integration operations workspace
(Integration operations).
Reference
- API reference: section 1 (Sales Order Posting Service) and section 19 (Bulk Operations)
- Endpoint payload specification:
MGCLatticeSalesOrderPostingService - Security model:
MGCLatticeIntegrationServiceHighRiskDuty - Cross-reference keys:
SalesOrderIdExternalKey - Data entity reference:
LatticeCustomerPackingSlipJournalLines - Sales order to invoice, Sales return to credit note, Cancel a posted product receipt