- A property manager orders twelve identical smoke detectors.
- Five are for one building, four for another and three for a third.
- A normal ecommerce cart sees twelve units.
- That was the client problem we solved on a procurement platform built with Medusa.
The client problem
A property manager orders twelve identical smoke detectors.
Five are for one building, four for another and three for a third. The purchase is one product line from one supplier, but finance cannot charge the whole amount to an arbitrary account or property. Each portion belongs to the place that will use it and to the general-ledger account that explains the expense.
A normal ecommerce cart sees twelve units. Property accounting sees three responsibilities.
That was the client problem we solved on a procurement platform built with Medusa. We added line-item allocations that let a buyer split purchased quantity across GL accounts and property units, validate the split before the transaction advances and preserve the allocation from cart to quote, order and accounting export.
The important decision was to allocate quantity first. Money is derived later from the commercial line, with deterministic handling of rounding and discounts.
Checkout totals are not enough for property finance
An ecommerce order already knows product, quantity, unit price, tax, shipping and total. That is enough to charge a card and fulfil a parcel.
A property organisation needs more context.
Finance must know which building or unit consumed the goods and which GL account should receive the expense. A single order line may support several maintenance jobs. The buyer may know that allocation at purchase time, while the accounting team should not have to reconstruct it weeks later from emails.
Without an allocation model, teams usually choose one of three poor options:
- duplicate the same product into several cart lines;
- put the split in free-form notes;
- place the order first and recreate the allocation in the accounting system.
Duplicated lines distort the buying experience. Notes cannot be validated. Re-keying introduces delay and disagreement between commerce and accounting.
We wanted the purchase itself to carry the business explanation.
Model portions of quantity, not arbitrary percentages
The allocation primitive is deliberately concrete.
Each portion contains a positive integer quantity and may reference a GL account, a property unit or both. One line item can have many portions. The sum of their quantities must equal the line quantity exactly.
For twelve smoke detectors, a valid split might be:
- five units to GL Repairs and Unit Group A;
- four units to GL Safety Equipment and Unit Group B;
- three units to GL Repairs and Unit Group C.
The model does not ask the buyer to invent monetary percentages while prices, discounts or tax may still change. It records the operational truth the buyer knows: where the physical units belong.
That choice also makes validation understandable. Twelve purchased units must produce twelve allocated units. Eleven is incomplete. Thirteen allocates something that was never bought.
Accounting values can then be derived from the final commercial line rather than entered twice.
Make incomplete allocation impossible to overlook
An allocation interface is useful only if the platform knows when the work is finished.
The workflow rejects empty portions, zero or fractional quantities and any split whose sum differs from the line quantity. Every portion must reference at least a GL account or a unit. Later business gates can require a GL account on every portion before a quote converts or an accounting action proceeds.
This creates two layers of validation.
The first protects the structural allocation: every purchased unit is represented and every portion means something. The second protects the destination process: if finance requires a GL code, no unit-only portion can quietly pass as complete.
The error identifies the affected product line instead of returning a generic “invalid order.” That gives the buyer a bounded correction: open this item and finish its allocation.
Completeness becomes a product rule, not a checklist somebody remembers outside Medusa.
Prevent cross-organisation accounting mistakes
A valid identifier is not necessarily an authorised identifier.
The platform may contain GL accounts for several buying organisations and units for many properties. Accepting any existing ID from the browser would allow a line to be charged to the wrong company or building.
Before writing a cart allocation, the workflow resolves the cart, line item, requested accounts and units. It checks that:
- the signed-in customer owns the cart;
- the line belongs to that cart;
- the cart property matches the current property context;
- every GL account belongs to the buyer organisation;
- every unit belongs to the cart property.
Those checks happen on the server. The dropdown can improve usability by showing only relevant options, but it is not the security boundary.
For the business, this means accounting context cannot be widened by changing a request payload. For the architecture, it means tenant and property scope travel with the allocation decision.
Preserve the split as the purchase evolves
A cart is not always the final commercial object.
The buyer may request a quote. A seller may negotiate price. The accepted quote may become an order. The buyer or an authorised operator may later review allocations on the placed order.
If allocation exists only in a cart component's local state, it disappears during those transitions.
The platform stores cart-side portions with the line context, copies them into quote and draft-order flows and materialises order-side allocation records when the purchase becomes durable. Order records use their own linked allocation rows rather than depending forever on the original cart.
Copying rather than reusing the same row is important. The cart describes buying intent. The order is the historical transaction. Each needs a coherent snapshot for its lifecycle.
Tests cover the quote wiring and order materialisation paths so a new commercial transition cannot silently drop the finance context.
Allow correction without erasing the history model
Placed orders sometimes need allocation correction.
A buyer may have selected the wrong GL account or a finance operator may learn that the goods served a different unit. The order interface exposes the current portions and, when authorised, supports an explicit edit-and-save flow.
Edits are staged locally until the user commits them. The server then revalidates quantity and ownership before rematerialising the order-side allocations.
This is better than making every select change immediately mutate accounting data. The operator can inspect the full split, adjust several portions and save one coherent allocation decision.
It also keeps the same rules across cart and order. Editing later does not become an administrative bypass around organisation, property or completeness checks.
The allocation is flexible where the business needs correction and strict where accounting needs consistency.
Derive money from quantity portions
Finance ultimately needs amounts, not only quantities.
Suppose a line costs $10 for three units and two units belong to one GL account while one belongs to another. A proportional split produces values that may not divide perfectly once prices, discounts and currency precision are considered.
The accounting transformation uses quantity as the weight. It allocates the final merchandise amount across portions and distributes rounding remainders deterministically so the allocated rows reconcile with the source line.
The same principle applies when discounts affect the commercial amount. The allocation does not recalculate the order independently. It starts from the amount Medusa owns and explains how that amount is distributed.
This prevents two accounting failures:
- portions whose amounts add up to less or more than the order line;
- repeated exports that move a rounding cent between accounts unpredictably.
Quantity is the operational input. Money is a deterministic projection of the final transaction.
Keep merchandise allocation separate from tax and shipping
A line-item allocation should not silently decide how every order-level charge is booked.
Merchandise, shipping, tax and discounts have different accounting meanings. The broader export capability separates those components and reconciles the produced rows with the order total.
This article's allocation model answers who consumed the purchased goods and which account represents them. A dedicated accounting transformation decides how shipping and tax become export rows according to the organisation's rules.
That separation avoids hiding policy inside a cart widget. The buyer allocates what they understand. Finance controls how the full transaction maps to the target accounting format.
It also makes future changes safer. A new tax or shipping policy does not require rewriting the historical quantity portions attached to every order line.
Why Medusa was the right foundation
Medusa already owns carts, line items, quotes, draft orders and final orders. We added the property and accounting dimensions the client's procurement journey required.
The allocation module is linked to those commerce objects rather than maintained in a separate finance application. Workflows validate and carry the data through the same transitions that change the purchase.
That is the architectural advantage of an extensible commerce engine.
We did not rebuild cart or order management merely because standard ecommerce does not understand property units and GL codes. We kept Medusa's commerce lifecycle and added a precise business capability on top.
The result serves both sides. Buyers allocate products in the context where they understand the need. Finance receives structured dimensions connected to the transaction it must account for.
What this changed for the client
The procurement platform could capture accounting intent before it became detective work.
A buyer could split one supplier line across the properties, units and GL accounts that actually consumed it. The system could prove that every purchased unit was covered. It could reject foreign organisation accounts and unrelated property units. Quotes and orders could retain the decision. Accounting exports could derive balanced amounts from the final commerce values.
The visible feature is a split editor. The valuable capability is continuity.
Product choice, property responsibility and accounting destination remain connected from the cart to the financial hand-off.
A practical allocation checklist
Before adding GL allocation to a commerce platform, define:
- Is the buyer allocating quantity, money or a clearly governed combination?
- Must portion quantities equal the purchased line quantity exactly?
- Can a portion reference a GL account, a unit or both?
- Which process gates require a GL account on every portion?
- How does the server prove the GL account belongs to the buyer organisation?
- How does it prove the unit belongs to the active property?
- What data moves from cart to quote, draft order and final order?
- Can authorised corrections be made without bypassing the same invariants?
- How are final amounts and rounding remainders derived deterministically?
- Which rules belong to merchandise allocation and which belong to tax or shipping export policy?
These answers turn an accounting field into a dependable commerce capability.
The broader lesson
The client did not need another free-text box labelled “GL code.”
They needed one purchase line to express how real properties consumed the goods, without losing quantity, crossing organisational boundaries or asking finance to rebuild the split after checkout.
We modelled quantity portions, validated their ownership and completeness, carried them through Medusa's commerce lifecycle and derived accounting amounts from final transaction values.
That is how a twelve-unit ecommerce line becomes three explainable property expenses—and still reconciles to the order.
