Reference for the orders and order_lines sub-modules of sales_orders, with fields, PO check, PO revisions, milestones, statuses, actions, routes, and roll-up.
This page describes the orders and order_lines sub-modules of src/cluster_erp/modules/sales_orders/ and the header roll-up in rollup.py. A sales order (SalesOrder) is created from a customer purchase order that references a quote. The order holds the PO check attempts, the frozen PO revisions, and the milestones; its lines hold the products and prices copied from the quote.
Defined in: orders/models.py, orders/services.py (SalesOrderService), orders/routes.py, orders/metadata.py, the same files of order_lines, and rollup.py.
Count: 6 tables (5 in orders, 1 in order_lines); 17 order routes and 7 line routes (@router. decorators); 11 ActionMeta entries on orders and 2 on lines.
In prose: the PO check sets matched or mismatch; a mismatch leads to a revision request and a revised PO, which returns the order to po_received. accept opens a matched order. The order then moves through production and shipping to closed. on_hold is reachable from opened, in_production, partially_shipped, and ready_to_ship; cancelled from opened, in_production, and ready_to_ship. closed and cancelled are terminal (src/cluster_erp/modules/sales_orders/orders/services.py:46-57).
The order references a quote that is sent or already won; the RFQ and the customer are read through the EventBus (src/cluster_erp/modules/sales_orders/orders/services.py:189-215).
The quote's open lines are copied into order lines, in full or per selected line, and the drawdown is recorded on the quote with ReferenceQuoteLines (src/cluster_erp/modules/sales_orders/orders/services.py:253-330).
Version 1 of the customer PO is frozen as a PoRevision snapshot at creation; a revised PO adds the next version (src/cluster_erp/modules/sales_orders/orders/services.py:312, src/cluster_erp/modules/sales_orders/orders/services.py:498-587, src/cluster_erp/modules/sales_orders/orders/services.py:871-939).
The PO check compares qty, unit_price, currency, incoterm, delivery_date, and payment_terms with the quote (src/cluster_erp/modules/sales_orders/orders/services.py:59, src/cluster_erp/modules/sales_orders/orders/services.py:342-463).
accept needs a passed PO check, mints the internal order number unless the tenant setting switches it off, and creates the default milestones kickoff, material_ready, production_start, qc_done, shipped, and delivered (src/cluster_erp/modules/sales_orders/orders/services.py:61-68, src/cluster_erp/modules/sales_orders/orders/services.py:588-648).
A delivery date on a non-working day of the customer party's calendar is refused through GetOwnerWorkingDays (src/cluster_erp/modules/sales_orders/orders/services.py:78-115).
Cancelling releases the order's quote line references with ReleaseQuoteLineReferences (src/cluster_erp/modules/sales_orders/orders/services.py:697-750).
A terminal order cannot be updated; an address change freezes the address text and marks generated documents stale (src/cluster_erp/modules/sales_orders/orders/services.py:786-827, src/cluster_erp/modules/sales_orders/orders/services.py:965-980).
Line breakdowns are checked with ensure_product_breakdown; every line change recomputes the line and rolls the header up (src/cluster_erp/modules/sales_orders/order_lines/services.py:54-130).
The roll-up sets the header total to the sum of line totals with ROUND_HALF_EVEN at the currency's decimal places (src/cluster_erp/modules/sales_orders/rollup.py:1-79).
create-bom needs a catalogue line with model and version, reuses a linked BOM, and otherwise asks CreateBomForProduct (src/cluster_erp/modules/sales_orders/order_lines/routes.py:132-177).