Skip to content

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 asset
  • sale.order - Canonical representation of a commercial contract over time
  • stock.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.line entries
  • Binding is per line, per serial
  • ABS ServicePlan objects 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.line has 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

  1. Binding is created in Odoo
  2. Odoo emits a ServicePlan creation signal to ABS
  3. ABS enforces during validity
  4. Any change (replacement, termination, reassignment):
  5. Happens first in Odoo
  6. Is propagated to ABS
  7. 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.line may 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