Odoo Sales Order as Contract¶
Purpose: Define the Sales Order as a contract envelope with line-level semantics for asset-service binding.
Audience: Developers, operations teams, ABS integration engineers.
A. Foundational Principle¶
Odoo as SPOT for Physical Assets and Contractual Bindings¶
Odoo serves as the Single Point of Truth (SPOT) for:
- Physical asset identity
- Physical movement history
- Serial-number lifecycle
- Commercial contracts and amendments
Core Odoo Models¶
stock.lot(serial number) - Canonical representation of a specific, non-fungible assetsale.order- Canonical representation of a commercial contract over timestock.move.line- Record of which serial fulfilled which contractual obligation
ABS consumes bindings authored and persisted in Odoo; it never infers bindings independently.
B. "Swap Privilege" as Composite Commercial Right¶
"Swap privilege" is not a simple service—it decomposes into three implied bindings:
B1. Asset-Class Compatibility¶
The motorbike model implies: * Battery form factor * Electrical interface * Safety envelope
This is product-model logic, not runtime logic, and belongs in: * Product definition / category rules * Service terms metadata
B2. Serial-Scoped Entitlement¶
A specific motorbike serial number entitles: * The holder * During a defined period * To access a defined battery circulation pool * And a defined swap station network
This service–serial binding must be: * Explicit * Queryable * Time-bounded
B3. Ownership vs Access (Rental Case)¶
In rental scenarios: * No sale occurs * Asset remains on company balance sheet * Physical issuance occurs via contract
In Odoo terms:
* Serial exists independently of sale
* sale.order expresses right of use, not transfer of ownership
* Physical movement may occur without revenue recognition
Principle: Serial numbers are asset identities, not sale artifacts.
C. Multi-Service Binding to One Serial¶
One serial → many services is the norm, not an edge case.
Examples bound to the same serial: * Warranty * Anti-theft / tracking * Swap privilege * Extended maintenance * Insurance-like coverage
Odoo Implementation¶
- Services are
sale.order.lineentries - Binding is per line, per serial
- ABS
ServicePlanobjects are one per (service × serial), not one per order
This clarifies downstream enforcement and lifecycle management.
D. Sales Order as Time-Persistent Contract¶
D1. Sales Order = Contract Envelope¶
sale.order persists and anchors:
* Commercial intent
* Amendments
* References
It does not natively enforce time or recurrence.
D2. Contract Semantics Are Line-Level¶
Each sale.order.line has its own:
* Effective date
* Duration
* Termination logic
Warranty, subscription, rental, and privilege cannot be safely modeled as order-level attributes.
D3. Selective Use of Contract/Subscription Constructs¶
Use Odoo's contract/subscription constructs only where temporal behavior (recurrence, renewal, suspension) exists.
Do not force all service bindings into the subscription model.
E. Multiple Physical Picks with Different Semantics¶
One Sales Order may involve multiple physical pickings with different meanings:
- Motorbike sold → ownership transfer
- Battery issued → rental / circulation asset
- Access privilege → no physical movement
Resolution¶
- Each
sale.order.linehas its own fulfillment semantics - Each serial is bound to a specific line, not to the order
F. Line-Item ↔ Serial Is 1-to-1¶
There is no such thing as "the serial number of a Sales Order."
Serial numbers bind to sale.order.line entries, one-to-one.
Consequences¶
A single Sales Order may involve: * Many serials * Each with different commercial meaning
Binding logic operates at:
* (sale.order.line_id, serial_id)
This resolves: * Multi-serial ambiguity * Multi-service ambiguity * Rental vs sale confusion
G. Odoo-First Binding, ABS as Execution Mirror¶
Binding Lifecycle¶
- Binding is created in Odoo
- Odoo emits a ServicePlan creation signal to ABS
- ABS enforces during validity
- Any change (replacement, termination, reassignment):
- Happens first in Odoo
- Is propagated to ABS
- ABS never originates commercial truth
Example: Faulty Asset Replacement¶
- Replacement is a commercial transaction
- New serial is issued
- Old binding is closed
- New binding is created
- ABS receives:
- Termination of old ServicePlan
- Activation of new ServicePlan
This keeps accounting, audit, and enforcement in perfect alignment.
H. Consolidated Specification¶
- Odoo is the SPOT for asset identity, physical movement, and service–serial binding
- Serial numbers represent tracked assets, independent of sale mechanics
- A Sales Order is a contract envelope containing multiple line-level obligations
- Each
sale.order.linemay bind to exactly one serial number, with its own semantics - A serial number may have multiple services bound to it concurrently
- Swap privilege is a composite right combining asset compatibility, serial-scoped entitlement, and network access
- ABS consumes bindings from Odoo to instantiate and enforce ServicePlans
- Any change in binding originates in Odoo and is propagated to ABS
Related Documentation¶
- Service Bundles Intent - Bundle architecture overview
- Odoo Lot/Serial Numbers - Physical asset identity
- ABS ServicePlan Integration - Odoo-ABS contract
- Non-Fungibility Concepts - Serial as non-fungible anchor