Acumatica · Customization

Acumatica MRP — Planned Orders Explained

How Acumatica MRP works — demand and supply, planned order generation, firming the plan, and the configuration that turns MRP from a black box into a planning tool.

John Kihiu12 min read

The first time a client asked me why MRP was telling them to buy 4,000 units of a part they already had on the shelf, I learned more about Acumatica's planning engine in a week than the documentation had taught me in a year. Planned orders are the output of MRP, but understanding why a specific planned order exists means understanding the inputs the regeneration run consumed — and most "MRP is wrong" tickets turn out to be "the inputs were wrong."

This post walks through how the MRP regeneration in the Acumatica Manufacturing Edition builds planned orders, where the data lives, and the diagnostic path I follow when the output looks insane.

What a planned order actually is

MRP in Acumatica is a full regeneration, not a net-change engine. When you run Regenerate MRP (AM505000), the engine wipes the previous plan and rebuilds it from scratch: it nets gross requirements (sales orders, production demand from higher-level orders, forecasts) against supply (on-hand quantity, open purchase orders, open production orders), explodes BOMs level by level, offsets by lead time, and writes the shortfall as planned orders into the AMRPPlan and related tables.

A planned order is a suggestion, nothing more. It has no document number in PO or Production terms, it reserves nothing, and it disappears on the next regeneration if the conditions that created it change. It only becomes real when someone fires it from MRP Display (AM400000) — at which point Acumatica creates an actual purchase order line or production order, and the next MRP run sees that as supply instead of re-suggesting it.

The inputs that actually drive the numbers

When a planned order quantity or date looks wrong, the cause is almost always one of these, roughly in order of how often I've seen it:

Check the exceptions screen first

Before staring at planned orders, open MRP Exceptions. Move-in, move-out, expedite and cancel recommendations against existing supply are usually more actionable than the raw plan, and they tell you what MRP thinks about the orders you already have.

Tracing a single planned order

MRP Display gives you pegging: select a planned order and drill into the requirements that generated it. I still sometimes go to the database when the pegging looks off, because seeing the raw plan rows makes the netting logic obvious:

SQL
SELECT InventoryID, SiteID, PlanDate, ActionDate,
       BaseQty, Type, RefNoteID
FROM AMRPPlan
WHERE CompanyID = 2
  AND InventoryID = (SELECT InventoryID FROM InventoryItem
                     WHERE InventoryCD LIKE 'BRKT-100%')
ORDER BY PlanDate;

Reading supply and demand rows in date order for one item is the fastest way I know to answer "why did it suggest this quantity on this date." You can see the running balance dip below safety stock and the planned order appear exactly where the engine decided it had to.

Firing planned orders programmatically

On one project the planners wanted approved planned orders converted automatically overnight rather than clicked through MRP Display. The supported way is the same as any mass action: instantiate the graph, set the filter, mark rows selected, and invoke the action. Roughly:

C#
var graph = PXGraph.CreateInstance<MRPEngine>(); // MRP display graph
foreach (AMRPDetail row in graph.Detailrecs.Select())
{
    if (row.Type != MRPPlanningType.PlannedOrder) continue;
    if (ShouldFire(row))                    // your approval rule
    {
        row.Selected = true;
        graph.Detailrecs.Update(row);
    }
}
graph.Actions["CreateOrders"].Press();      // fires selected rows

Two gotchas from doing this in production. First, run it on a processing schedule after the nightly MRP regeneration completes, never overlapping — firing against a half-built plan creates duplicates. Second, log every fired order with its pegged demand; when a planner asks "why did the system buy this," you want an answer that doesn't involve reconstructing last Tuesday's plan.

Performance and scheduling the run

Regeneration is heavy — it locks planning tables and chews CPU roughly in proportion to BOM depth times active items times open orders. Practical rules I follow: run it once nightly via an automation schedule during the quietest window; keep BOMs shallow where the engineering allows it (phantoms are cheaper than real subassembly levels); and archive or close stale sales orders and production orders, because MRP dutifully plans for demand from 2023 if you leave it open.

If the run takes more than an hour on a mid-size dataset, look at SQL before looking at Acumatica settings — missing index maintenance on the MRP tables shows up here first.

Wrapping up

Planned orders are deterministic: same inputs, same plan. Every "MRP is broken" investigation I've done ended in a data problem — a lot size, a lead time, a warehouse flag, an open order someone forgot to close. Learn to read the plan rows for a single item in date order, fix the input, regenerate, and the suggestion fixes itself. Treat the planned order as the messenger, not the problem.

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.