Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Business modules

Reference

Sales orders and order lines

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.

Scope and source

  • 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.

Order fields

Group Fields Source
Identity order_no, quote_id, customer_id, project_id, status (default po_received) src/cluster_erp/modules/sales_orders/orders/models.py:30-77
Customer PO customer_po_no, customer_po_version, customer_po_date, received_email_id src/cluster_erp/modules/sales_orders/orders/models.py:49-64
Commercial total_price (Numeric(19, 4)), currency, incoterm, payment_terms, delivery_date, qty src/cluster_erp/modules/sales_orders/orders/models.py:81-92
Addresses ship_to_party_id, ship_to_address_id, ship_to_address, bill_to_party_id, bill_to_address_id, bill_to_address src/cluster_erp/modules/sales_orders/orders/models.py:97-106
Lifecycle record opened_at, opened_by, cancelled_at, cancelled_by, cancel_reason, on_hold_reason, shipped_at, delivered_at, closed_at, notes src/cluster_erp/modules/sales_orders/orders/models.py:109-139

Child records

Entity Table Key fields Source
PoCheck so_po_checks sales_order_id, quote_id, attempt_no, mismatch_fields, has_mismatch, overall_result, decision, revision_requested_at src/cluster_erp/modules/sales_orders/orders/models.py:142-185
PoCheckLine so_po_check_lines po_check_id, quote_line_item_id, field_name, quote_value, po_value, is_match src/cluster_erp/modules/sales_orders/orders/models.py:187-209
SalesOrderMilestone so_milestones sales_order_id, milestone_type, planned_at, actual_at, status, notes src/cluster_erp/modules/sales_orders/orders/models.py:211-236
PoRevision so_po_revisions sales_order_id, version_no, customer_po_no, customer_po_date, reason, snapshot, received_at, received_by src/cluster_erp/modules/sales_orders/orders/models.py:238-264
SalesOrderLine so_sales_order_lines line_no, customer_line_no, project_id, part_id, part_model_id, part_version_id, customer_part_id, description, qty, uom, unit_price, currency, line_total, delivery_date, quote_line_item_id, bom_id, status (default open) src/cluster_erp/modules/sales_orders/order_lines/models.py:22-102

Order statuses and actions

The service allows these transitions (src/cluster_erp/modules/sales_orders/orders/services.py:41-55).

stateDiagram-v2
 [*] --> po_received
 po_received --> matched: run_po_check
 po_received --> mismatch: run_po_check
 mismatch --> revision_requested: request_revision
 revision_requested --> po_received: receive_revised_po
 matched --> opened: accept
 opened --> in_production
 opened --> on_hold
 in_production --> ready_to_ship
 in_production --> partially_shipped
 partially_shipped --> ready_to_ship
 ready_to_ship --> shipped
 shipped --> delivered
 delivered --> closed
 on_hold --> opened
 opened --> cancelled

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).

Action Label Condition Endpoint Permission Source
run_po_check Run PO Check status is po_received POST /sales-orders/{id}/run-po-check sales_order.create src/cluster_erp/modules/sales_orders/orders/metadata.py:120-130, src/cluster_erp/modules/sales_orders/orders/routes.py:115
request_revision Request Revision status is mismatch POST /sales-orders/{id}/request-revision sales_order.create src/cluster_erp/modules/sales_orders/orders/metadata.py:131-141, src/cluster_erp/modules/sales_orders/orders/routes.py:148
receive_revised_po Receive Revised PO status is revision_requested POST /sales-orders/{id}/receive-revised-po sales_order.create src/cluster_erp/modules/sales_orders/orders/metadata.py:142-155, src/cluster_erp/modules/sales_orders/orders/routes.py:164
accept Accept Order status is matched POST /sales-orders/{id}/accept sales_order.accept src/cluster_erp/modules/sales_orders/orders/metadata.py:156-166, src/cluster_erp/modules/sales_orders/orders/routes.py:183
advance_in_production, advance_ready_to_ship, advance_shipped, advance_delivered, advance_closed Start Production, Ready to Ship, Mark Shipped, Mark Delivered, Close Order status is opened, in_production, ready_to_ship, shipped, delivered POST /sales-orders/{id}/advance/{target_status} sales_order.create src/cluster_erp/modules/sales_orders/orders/metadata.py:167-221, src/cluster_erp/modules/sales_orders/orders/routes.py:201
cancel Cancel Order allowed by the service table POST /sales-orders/{id}/cancel sales_order.cancel src/cluster_erp/modules/sales_orders/orders/metadata.py:222-231, src/cluster_erp/modules/sales_orders/orders/routes.py:220
run_po_check (on the PO check list) Run PO Check parent order POST /sales-orders/{parent_id}/run-po-check sales_order.create src/cluster_erp/modules/sales_orders/orders/metadata.py:670-679
create_bom (line) Create Bill of Materials none POST /sales-orders/lines/{id}/create-bom CreateBomForProduct.REQUIRED_PERMISSION src/cluster_erp/modules/sales_orders/order_lines/metadata.py:73-85, src/cluster_erp/modules/sales_orders/order_lines/routes.py:104-114
generate_units (line) Generate Units none POST /sales-orders/lines/{id}/generate-units sales_order_unit.create src/cluster_erp/modules/sales_orders/order_lines/metadata.py:88-114, src/cluster_erp/modules/sales_orders/units/routes.py:70

Order and line routes

Method and path Permission Source
GET /sales-orders/, GET /sales-orders/{order_id} sales_order.read src/cluster_erp/modules/sales_orders/orders/routes.py:52, src/cluster_erp/modules/sales_orders/orders/routes.py:98
POST /sales-orders/from-po sales_order.create src/cluster_erp/modules/sales_orders/orders/routes.py:86
GET /sales-orders/{order_id}/po-checks sales_order.read src/cluster_erp/modules/sales_orders/orders/routes.py:130
POST /sales-orders/{order_id}/hold, /resume; PATCH /sales-orders/{order_id} sales_order.create src/cluster_erp/modules/sales_orders/orders/routes.py:239-273
GET /sales-orders/{order_id}/milestones; PATCH /sales-orders/{order_id}/milestones/{milestone_type} sales_order.read, sales_order.create src/cluster_erp/modules/sales_orders/orders/routes.py:292-307
GET /sales-orders/{order_id}/po-revisions, GET /sales-orders/po-revisions/{revision_id} po_revision.read src/cluster_erp/modules/sales_orders/orders/routes.py:327-338
GET, POST /sales-orders/{order_id}/lines; GET, PUT, DELETE /sales-orders/lines/{line_id}; POST /sales-orders/lines/bulk-delete sales_order.read, .create, .delete, .bulk_delete src/cluster_erp/modules/sales_orders/order_lines/routes.py:27-165

Constraints and validation

  • 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).

Discrepancies

Terms introduced

Term Code identifier Definition Turkish term Source
PO check PoCheck One comparison of the customer PO with the quote, with its result. PO kontrolü src/cluster_erp/modules/sales_orders/orders/models.py:142
PO revision PoRevision A frozen snapshot of one version of the customer PO. PO revizyonu src/cluster_erp/modules/sales_orders/orders/models.py:238
milestone SalesOrderMilestone A planned and actual date for one step of an order. Kilometre taşı src/cluster_erp/modules/sales_orders/orders/models.py:211

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13