Sales Management
Why this is a runtime problem, not a CRUD problem
Sales execution spans four departments in sequence: the sales rep closes the deal, the warehouse ships, finance collects, and customer service handles returns. Each handoff — quotation accepted, order approved, shipment confirmed, RMA authorized — is a contract that must be permissioned, audited, and survive mid-flight changes such as currency rate shifts, partial shipments, or order amendments.
The CRM use case ends at opportunity.won. The Sales plugin picks up exactly there: the sl:convert_quotation_to_order command on an accepted quotation (sl_sales_quotation) produces a sales order (sl_sales_order) and carries the source-quote reference forward. Everything downstream — shipment, payment collection, RMA, credit memo — is orchestrated through the same command pipeline that enforces five-layer permissions, emits audit events, and remains reachable from automation rules and AI agents.
Data model summary
The Sales plugin ships 17 models. The core ones:
sl_sales_quotation+sl_sales_quotation_line— Formal quote with revision control, validity date, discount, margin; statesdraft → sent → accepted | rejected | expired. Code auto-generated asSQ-{yyyyMMdd}-{seq}.sl_sales_order+sl_sales_order_line— Core sales document with multi-currency totals (transaction + base), ATP date, IPC traceability class; statesdraft → pending → approved → delivering → completed | cancelled. Code:SO-{yyyyMMdd}-{seq}.sl_shipment+sl_shipment_line— Warehouse fulfillment linked to a sales order; statesdraft → confirmed | cancelled. Code:SH-{yyyyMMdd}-{seq}.sl_packing+sl_packing_line— Nested container (carton/pallet) with serial number tracking; linked to a shipment.sl_sales_collection— Payment collection record tracking received amounts and payment method; aggregates payment status back to the order.sl_sales_return+sl_sales_return_line— Return order with fault attribution and inspection workflow.sl_rma— Return Merchandise Authorization with inspection result, disposition decision (repair / replace / refund / scrap), and credit memo linkage; statesauthorized → received → inspected → disposition_decided → closed.sl_credit_memo— Financial credit document generated from RMA; statesdraft → approved → applied | cancelled.sl_order_change— Formal order change request with old-vs-new impact assessment and manager approval.sl_price_list+sl_price_list_item— Effective-dated price list with currency, priority tier, and per-product line items.sl_discount_rule— Configurable discount: percentage, fixed amount, or tiered by quantity.
The plugin declares dependencies on crm (account data), product-catalog (product master), inventory (warehouse stock), and finance (exchange rates). Importing Sales without CRM is rejected at resolution time.
Key commands
The Sales plugin defines 82 commands. Six representative ones:
| Command | Shape | Risk | Idempotent | Why it matters |
|---|---|---|---|---|
sl:convert_quotation_to_order | Action | write | true | One-step accepted-quote → sales order; sets sl_so_source_quote_id |
sales.order.confirm | StateTransition | write | true | draft → pending; gates on required fields before entering approval queue |
sl:approve_sales_order | StateTransition | write | true | pending → approved; handler checks customer credit limit |
sl:confirm_shipment | StateTransition | write | true | Commits shipment; updates order fulfillment progress |
sales.rma.approve | StateTransition | write | true | Authorizes return; triggers goods-receipt workflow |
sl:apply_credit_memo | StateTransition | write | true | approved → applied; offsets against AR; irreversible once applied |
A "Approve" button on the order detail page is wired to sl:approve_sales_order — not to a raw PUT /api/sl_sales_order. The same command is reachable from automation rules ("auto-approve orders under threshold") and from AI agents that carry the agentHint: "Use only after credit-limit check has passed" guard.
Process flow
Quotation Order Fulfillment Post-sale
--------- ----- ----------- ---------
sl_sales_ sl_sales_order sl_shipment sl_rma
quotation (draft) (draft) (authorized)
| | | |
sent pending confirmed received
| | |
accepted approved -----> sl_sales_ inspected
| | collection |
+--convert--> delivering (payment collected) disposition_decided
| |
completed sl_credit_memo
(applied) <--+
Permission example
A realistic Sales configuration across all five layers:
- Layer 1 RBAC: Sales rep holds
sl.sales.manageandsl.sales.read; notsl.financial.credit_memo(Finance team only) orsl.rma.manage(Customer Service). - Layer 2 Org scope: data visibility limited to the rep's own org subtree (
org-and-descendantsonsl_so_assigned_to). A rep in APAC cannot list EMEA orders even by guessed ID — the row filter is appended at the SQL layer. - Layer 3 Org scope — own orders: sales rep sees only orders where
sl_so_assigned_tois in their own org subtree. Cross-region visibility requires an explicit manager grant. - Layer 4 ABAC — RMA approval gated by amount:
sales.rma.approveis available only whensl_rma_authorized_amount ≤ 10_000; above that the platform routes to a manager-approval BPM step before the transition fires. - Layer 5 Field-level masking: the
sl_so_credit_limitand customer credit-score fields are masked from operations staff — invisible on form, omitted from API responses, stripped from CSV export. Finance staff sees them; operations does not.
All five layers are evaluated in order. No custom controller code needed.
Process orchestration
The quote-to-cash flow is a BPM process where each task resolves to a command:
┌──────────────────────┐
│ Quotation sent │ <- sl:send_sales_quotation
└──────────┬───────────┘
|
┌────────────v────────────┐
│ Customer response │
└──┬────────────────────┬─┘
| accepted | rejected/expired
┌─────────v──────────┐ ┌────v──────────────┐
│ Convert to order │ │ Archive quotation │
└─────────┬──────────┘ └───────────────────┘
| <- sl:convert_quotation_to_order
┌─────────v──────────┐
│ Submit + approve │ <- sales.order.confirm, sl:approve_sales_order
└─────────┬──────────┘
|
┌─────────v──────────┐
│ Shipment + packing │ <- sl:create_shipment, sl:confirm_shipment
└─────────┬──────────┘
|
┌─────────v──────────┐
│ Collection │ <- sl:create_sales_collection (auto-aggregates to order)
└─────────┬──────────┘
|
┌─────────v──────────┐
│ RMA loop (if any) │ <- sales.rma.approve, sl:inspect_rma,
│ │ sl:decide_rma_disposition, sl:apply_credit_memo
└────────────────────┘
Order change requests mid-flight go through sl_order_change: impact is calculated, submitted for approval, and applied via sl:apply_order_change — the original order line records carry old-vs-new history.
Agent integration
Three command classes are intentionally exposed to AI agents:
- Read-and-summarize (
sl_sales_order.list_overdue,sales_dashboard.kpi_summary) — read-only, idempotent, low risk. Agents call freely. - Drafting (
sl:create_sales_quotation,sl:add_sq_line) — write, idempotent, reversible. Agent drafts a quotation from an RFQ; the sales rep reviews and sends it. - Operational nudges (
sl:calculate_atp,sl:check_compliance) — write, idempotent. Agent flags an ATP risk on a pending order; cannot itself approve it.
What is not exposed: sl:apply_credit_memo (irreversible financial), sl:cancel_sales_order in approved state (supply-chain commitment), sl:delete_sales_order. These carry agentHint: "Human-only".
How to get it
- Community: build it yourself. The DSL, command pipeline, state-machine engine and five-layer permissions are all open-source; the Sales plugin itself is not bundled.
- Standard: white-label the base platform; build your own sales-shaped plugin on top.
- Professional: get the Sales solution package — 17 models, 82 commands, 33 pages (including Kanban board and real-time dashboard), pre-wired roles and price-list engine.
- Enterprise: same package plus dedicated delivery engineering, multi-currency reconciliation design, ERP/WMS integration, and SLA-backed support.
See Pricing for the full edition comparison.
Enterprise note — Marketplace publication of vertical plugin packs, License/Entitlement enforcement on the Command pipeline, cross-tenant Agent Control Plane for multi-region order orchestration, and Observability Pro per-stage trace spans are commercial-only capabilities. The open-core runtime described above is the same in every edition.
Next steps
- CRM use case — how leads and opportunities flow upstream into sales quotations
- System overview — how plugins, commands, and the runtime fit together
- Command pipeline — the execution contract used by every command above
- Permissions — the five-layer model illustrated by the Sales rep example
- Plugin manifest — how dependency resolution works across Sales, CRM, Inventory and Finance
- Agent readiness — designing agentHint and risk fields for safe execution