Scenario: Cancel a posted product receipt
Goal. A product receipt was posted in D365 for goods that did not arrive, or arrived for another order. Your warehouse or receiving system cancels the receipt from outside D365, exactly as Cancel in the product receipt journal does: the receipt, its inventory transactions and its ledger postings are reversed, the receipt is kept as a new version with zero quantities, and the order lines are open to receive again.
When to use. Correcting a product receipt before the vendor's invoice is matched to it or posted, for example after Receive and invoice a purchase order step 3 recorded a delivery by mistake. Goods that were received correctly and are going back to the vendor go through Return goods to a vendor. The customer-side twin is Cancel a posted sales packing slip.
Prerequisites
- Security. Canceling a product receipt reverses inventory and ledger postings, so the operation is
high-risk. It needs privilege
MGCLatticeAccountsPayableProductReceiptCancelMaintain("Accounts payable - cancel product receipt (high-risk)"), which is in dutyMGCLatticeIntegrationServiceHighRiskDutyof the integration administrator role only. The operator role andMGCLatticeAccountsPayableServiceMaintain(which posts product receipts) do not grant it. Without it D365 refuses the call with HTTP 403. The read-back entitiesProductReceiptLinesandPurchaseOrderLinesV2are standard entities and need D365's own privileges. See Security model. - A receipt the product receipt journal can cancel. A confirmed purchase order (USMF
00001042for vendorUS-101) with a posted product receipt that is not invoiced, fully or in part, and not matched to a pending vendor invoice. D365 does not offer Cancel for an intercompany direct delivery or a consignment order, and the operation does not cancel a receipt linked to project item requirements; cancel those in the product receipt journal. - Lattice. A valid license (an expired or invalid one refuses the call with
LicenseNotValid). To name the order by your own key, sendPurchaseOrderIdExternalKeywithExternalSystem(Use your own keys).
Steps
The operation is cancelPurchaseProductReceipt on MGCLatticePurchaseOrderPostingService in service group
MGCLatticeAccountsPayableServiceGroup. Send a POST with an OAuth 2.0 bearer token and the request in
_request (see Trial and day-one guide).
-
Know the receipt. It is the
PackingSlipIdyou sent topostPurchasePackingSlip(for exampleGRN-104201), or read the order's receipts:GET https://<your-environment>/data/ProductReceiptLines?cross-company=true&$filter=dataAreaId eq 'USMF' and PurchaseOrderNumber eq '00001042'&$select=ProductReceiptNumber,ReceivedPurchaseQuantity. -
Cancel it.
POST https://<your-environment>/api/services/MGCLatticeAccountsPayableServiceGroup/MGCLatticePurchaseOrderPostingService/cancelPurchaseProductReceipt{"_request": {"RequestId": "a7c3e1f9-2d4b-4b6a-9e08-5f1d3c7a9b26","LegalEntityId": "USMF","UserContext": "Admin","PurchaseOrderId": "00001042","ProductReceiptId": "GRN-104201"}}ProductReceiptIdis optional when the order has only one receipt 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 receipt; to record a different quantity, post a new product receipt afterwards. -
Read the result.
DocumentIdis the purchase order andPostedDocumentIdthe canceled receipt:Product receipt GRN-104201 of purchase order 00001042 was canceled; its quantities are open to receive again.Success is reported only when the receipt reads as canceled and every order line it received is open to receive again by the received quantity; otherwise the cancellation is rolled back and nothing is kept.
The bulk variant cancelPurchaseProductReceiptBatch 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 receipt. - The receipt:
ProductReceiptLinesfor the order andProductReceiptNumbershowsReceivedPurchaseQuantity0. - The order:
PurchaseOrderLinesV2(filter onPurchaseOrderNumber) showsPurchaseOrderLineStatusBackorder(open order) again, andgetPurchaseOrderStatusanswersDocumentStatusBackorder. - In D365: Procurement and sourcing > Purchase orders > All purchase orders, open the order, then on the Receive tab open the Product receipt journal: the receipt shows quantity 0. The line's Inventory > Transactions show the receipt 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 "Product receipt
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; "Purchase order 00001042 has several product receipts that can be canceled: ... Send ProductReceiptId to name the one to cancel."; a receipt number posted on several delivery dates; "Product receipt ... also receives purchase order(s) ... and cannot be canceled for purchase order ... alone." | Name the receipt. A receipt posted for several orders at once, or on several dates, is canceled in the product receipt journal in D365. |
DocumentNotFound (2) | An unknown order; "Product receipt X was not found for purchase order Y." | Check the order and receipt numbers and LegalEntityId. |
InvalidStatus (3) | "Purchase order ... is not confirmed (document state ...)"; "Purchase order ... has no posted product receipt to cancel."; "Product receipt X is already canceled."; "... is invoiced, fully or in part, and cannot be canceled."; "... is matched to a pending vendor invoice; remove it from the invoice or delete the invoice before canceling it."; linked to project item requirements; intercompany direct delivery or consignment order | Nothing to cancel through the service. Remove the receipt from the pending invoice first, or for goods already invoiced, create a purchase 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.
Reference
- API reference: section 2 (Purchase Order Posting Service) and section 19 (Bulk Operations)
- Endpoint payload specification:
MGCLatticePurchaseOrderPostingService - Security model:
MGCLatticeIntegrationServiceHighRiskDuty - Cross-reference keys:
PurchaseOrderIdExternalKey - Receive and invoice a purchase order, Return goods to a vendor, Cancel a posted sales packing slip