In Dynamics 365 Finance and Operations, finalizing a Purchase Order (PO) is a significant action that prevents further editing and processing of the PO. Reverting the status of finalized POs requires a custom X++ script to update the related tables because there is no out-of-the-box feature to undo the "Finalize" action. However, modifying finalized POs directly through X++ is risky and should be carefully planned, tested, and validated.
Below is a step-by-step guide on how to write the X++ code to revert the "Finalize" action, as well as an overview of the tables and risks to consider.
Understand the Finalize Action:
PurchTable
DocumentStatus
Finalized
PurchLine
Impact of Reverting the Finalize Action:
Testing Environment:
Identify Affected POs:
DocumentStatus = Finalized
Here’s an example X++ script to revert the finalized status on the Purchase Orders:
x++
static void RevertFinalizedPurchaseOrders(Args _args) { PurchTable purchTable; PurchLine purchLine; ttsBegin; // Filter for finalized Purchase Orders while select forUpdate purchTable where purchTable.DocumentStatus == DocumentStatus::Finalized { // Log the PO for auditing (optional) info(strFmt("Reverting status for PO: %1", purchTable.PurchId)); // Revert the status on PurchTable purchTable.DocumentStatus = DocumentStatus::InReview; // Change to desired status purchTable.update(); // Update related PurchLine records while select forUpdate purchLine where purchLine.PurchId == purchTable.PurchId { purchLine.DocumentStatus = DocumentStatus::InReview; // Change to desired status purchLine.update(); } } ttsCommit; info("Finalize action reverted for selected Purchase Orders."); }
Filtering the Purchase Orders:
DocumentStatus::Finalized
Reverting PurchTable.DocumentStatus:
PurchTable.DocumentStatus
InReview
Approved
Reverting PurchLine.DocumentStatus:
PurchLine.DocumentStatus
Transaction Management:
ttsBegin
ttsCommit
Before reverting the status, add validation checks to avoid data integrity issues. For example:
if (purchTable.ReceiptStatus != ReceiptStatus::None || purchTable.InvoiceStatus != InvoiceStatus::None) { warning(strFmt("PO %1 has product receipts or invoices posted. Skipping.", purchTable.PurchId)); continue; }
CreatedDateTime
VendorAccount
To minimize risks:
Audit Trail:
Dependencies:
WorkflowTrackingTable
Production Deployment:
Tables to Update:
Key Fields:
Risks:
Testing:
This approach will safely revert the "Finalize" action while minimizing risks.
Under review
Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.
As AI tools become more common, we’re introducing a Responsible AI Use…
We are honored to recognize Andrés Arias as our Community Spotlight honoree for…
These are the community rock stars!
Stay up to date on forum activity by subscribing.
Sohaib Cheema 789 User Group Leader
André Arnaud de Cal... 607 Super User 2025 Season 2
Martin Dráb 497 Most Valuable Professional