Acumatica · Customization

Acumatica Purchase Order Screen — A Deep Dive

Acumatica Purchase Order Screen — A Deep Dive is the screen the user actually lives in. Every other piece of Acumatica — the workflows, the reports, the integrations — exists to.

John Kihiu12 min read

Purchase Orders (PO301000) is the SO301000 of the buy side — same header/detail shape, same reliance on a "type" field to change behavior, and the same graph-extension-first customization pattern. The graph is POOrderEntry, the header is POOrder, and lines are POLine. What makes this screen distinct is how much of its behavior is controlled by POOrderType rather than the screen itself.

Order type drives everything

Normal, Drop-Ship, Blanket, and Standard order types aren't just labels — they change which fields are visible, whether the order expects a receipt at all (Drop-Ship orders typically skip a physical receipt and go straight to bill, since the vendor ships direct to the customer), and how quantities on a Blanket order get released against child orders over time. A customization that adds a required field to POLine needs to consider whether it makes sense across every order type, or scope the requirement to the types where it applies.

Key tabs

Extending POOrderEntry

A frequent request is enforcing budget or commitment checks beyond what the Projects module provides out of the box — for example, blocking a PO line against a cost code that's already over its allocated amount for a non-project purchase. That's a validation on POLine during persist, checking against a custom budget DAC rather than the standard commitment tracking.

C# · GRAPH EXTENSION
public class POOrderEntry_Extension : PXGraphExtension<POOrderEntry>
{
    protected virtual void POLine_RowPersisting(PXCache cache, PXRowPersistingEventArgs e)
    {
        var line = (POLine)e.Row;
        if (line?.LineAmt == null) return;

        decimal remaining = GetRemainingBudget(line.SubItemID, line.InventoryID);
        if (line.LineAmt > remaining)
            throw new PXSetPropertyException($"This line exceeds the remaining budget of {remaining:C}.");
    }
}

Custom fields and tabs via the Customization Project Editor

Adding a field to the Details tab is routine. Adding one that's visible on the printed PO document sent to the vendor requires the same second step as invoices — a corresponding change in the Report Designer template, not just the screen. Teams that customize the screen and forget the report end up with a field that's tracked internally but invisible to the vendor receiving the PO.

Common validation and event-handler use cases

Beyond budget checks: defaulting vendor-specific lead time onto POLine to feed a custom expediting report, restricting which warehouses a given vendor's items can be received into, and syncing PO status changes back to a linked Sales Order for Drop-Ship orders so sales reps see purchasing progress without leaving the SO screen. All are graph-extension event handlers rather than base-table changes.

Gotchas

A Blanket PO's "released" quantity and its child orders' consumed quantity are tracked separately — a customization that sums POLine quantities directly without accounting for blanket-order linkage will double-count or under-count depending on which side it reads. Drop-Ship orders create a dependency on the originating Sales Order that isn't always obvious from the PO screen alone — cancelling a Drop-Ship PO line without checking the linked SO line leaves the sales order in an inconsistent state. And vendor price/lead-time defaults only populate at line-add time; changing a Vendor Price/Catalog record afterward does not retroactively update existing PO lines.

Blanket orders aren't just "big" normal orders

The release-and-consume mechanics between a Blanket PO and its child orders are a distinct data model, not a variant of a normal PO's line quantities. Any reporting or validation logic built against POLine directly needs to explicitly handle blanket linkage or it will misreport blanket-order fulfillment.

Wrapping up

The Purchase Order screen's complexity lives almost entirely in POOrderType behavior, not in the screen's layout. Build customizations against the specific type they're meant for, keep the printed document in sync with any new screen fields, and treat Blanket and Drop-Ship as genuinely different data flows rather than edge cases of a Normal order.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.