Skip to content

Real-World Business Examples

Learning Through Examples

This section provides comprehensive real-world scenarios showing how Odoo's data model concepts apply to actual business cases. Study these to understand how to analyze and design solutions for client requirements.

Example 1: Hospital Patient Management

Business Requirement

A hospital needs to track patients, their doctors, appointments, and medical records. Each patient is assigned a primary doctor, can have multiple appointments, and needs a complete medical history.

Data Model

mermaid
graph LR
    P["Patient
    hospital.patient"] -->|Many2one| D["Doctor
    hospital.doctor"]
    P -->|One2many| A["Appointments
    hospital.appointment"]
    P -->|One2many| MR["Medical Records
    hospital.record"]
    A -->|Many2one| D
    D -->|Many2many| S["Specializations
    hospital.specialization"]

Model Definitions

ModelKey FieldsField TypeNotes
hospital.patientnameChar (required)Patient full name
date_of_birthDateFor age calculation
genderSelection [male, female, other]Medical requirement
blood_typeSelection [A+, A-, B+, B-, AB+, AB-, O+, O-]Emergency info
doctor_idMany2one → hospital.doctorPrimary physician
appointment_idsOne2many → hospital.appointmentAll appointments
ageInteger (computed, not stored)Calculated from DOB
hospital.doctornameCharDoctor's name
license_numberCharMedical license
specialization_idsMany2many → hospital.specializationCan have multiple
patient_idsOne2many → hospital.patientPrimary patients
appointment_idsOne2many → hospital.appointmentAll appointments
hospital.appointmentpatient_idMany2one → hospital.patientWhich patient
doctor_idMany2one → hospital.doctorWhich doctor
appointment_dateDatetimeWhen
stateSelection [draft, confirmed, in_progress, done, cancelled]Workflow
diagnosisTextAfter consultation
prescription_idsOne2many → hospital.prescriptionMedications

Key Design Decisions

RequirementSolutionWhy
Patient can have multiple appointmentsOne2many on patientNatural parent-child
Doctor has multiple specializationsMany2manyNo extra data needed
Track appointment workflowSelection state fieldFixed states, code controls
Calculate patient ageComputed field, NOT storedChanges daily
Show doctor's name on appointment listRelated field, storedPerformance in list view

Workflow

mermaid
graph LR
    D[Draft] --> C[Confirmed]
    C --> IP[In Progress]
    IP --> DO[Done]
    D --> CA[Cancelled]
    C --> CA

Example 2: E-Commerce Order Flow

Business Requirement

Track the complete order lifecycle from quotation through delivery and payment, including inventory management and invoicing.

Data Flow

mermaid
graph LR
    C["Customer
    res.partner"] --> SO["Sale Order
    sale.order"]
    SO --> L["Order Lines
    sale.order.line"]
    L --> P["Product
    product.product"]
    SO -->|Confirm| D["Delivery
    stock.picking"]
    SO -->|Invoice| I["Invoice
    account.move"]
    D --> SM["Stock Move
    stock.move"]
    I --> IL["Invoice Lines
    account.move.line"]

Key Relationships

FromToRelationshipPurpose
Sale OrderCustomerMany2oneWho is buying
Sale OrderOrder LinesOne2manyWhat they're buying
Order LineProductMany2oneWhich product
Sale OrderDeliveryOne2manyShipments created
Sale OrderInvoiceMany2manyCan have multiple invoices
ProductCategoryMany2oneFor reporting
ProductTagsMany2manyFor filtering

State Transitions

DocumentStatesKey Actions
Sale OrderDraft → Sent → Sale → DoneConfirm creates delivery
DeliveryDraft → Waiting → Ready → DoneValidate updates stock
InvoiceDraft → Posted → PaidPost creates accounting entries

Common Computed Fields

FieldOn ModelFormulaStored?
amount_untaxedsale.orderSum of line subtotals✅ Yes
amount_taxsale.orderSum of line taxes✅ Yes
amount_totalsale.orderUntaxed + tax✅ Yes
price_subtotalsale.order.lineqty × unit_price✅ Yes
qty_deliveredsale.order.lineFrom stock moves✅ Yes
qty_to_deliversale.order.lineqty - delivered❌ No (changes)

Example 3: Manufacturing Scenario

Key Manufacturing Relationships

Understanding the manufacturing data model helps when clients need production tracking or MRP implementations.

Core Manufacturing Objects

mermaid
graph TD
    PT["Product Template
    product.template"] --> PP["Product Variant
    product.product"]
    PP --> BOM["Bill of Materials
    mrp.bom"]
    BOM --> BOML["BOM Lines
    mrp.bom.line"]
    BOML --> COMP["Component Products
    product.product"]
    BOM --> MO["Manufacturing Order
    mrp.production"]
    MO --> WO["Work Orders
    mrp.workorder"]
    WO --> WC["Work Center
    mrp.workcenter"]

Model Relationships

ModelPurposeKey Fields
mrp.bomBill of Materialsproduct_id (what to make), bom_line_ids (components)
mrp.bom.lineBOM Componentproduct_id, product_qty, bom_id
mrp.productionManufacturing Orderproduct_id, bom_id, product_qty, state
mrp.workorderWork Order Stepproduction_id, workcenter_id, state, duration
mrp.workcenterWork Centername, capacity, costs_hour

Relationship Chain

Work Order → Manufacturing Order → Bill of Materials → Product

Work Center (where work happens)

Manufacturing Workflow

mermaid
graph LR
    D[Draft] --> C[Confirmed]
    C --> P[In Progress]
    P --> DO[Done]
    C --> CA[Cancelled]
StateWhat Happens
DraftMO created, not yet confirmed
ConfirmedComponents reserved, work orders created
In ProgressProduction started, consuming materials
DoneFinished product produced, stock updated

Example 4: B2B Order Exchange (EDI)

EDI Order Flow Between Companies

mermaid
graph LR
    BSO["Buyer's Sale Order
    sale.order"] -->|Export| XML["XML File
    Peppol BIS 3"]
    XML -->|Import| SPO["Supplier's Purchase Order
    purchase.order"]
    SPO -->|Confirm| SPK["Supplier's Delivery
    stock.picking"]
    SPK -->|Ship| BPK["Buyer's Receipt
    stock.picking"]

Document Mapping

Buyer's DocumentEDI MessageSupplier's Document
Sale Order (to supplier)OrderPurchase Order
-Order ResponseSale Order Confirmation
Purchase ReceiptDespatch AdviceSale Delivery
Purchase InvoiceInvoiceSale Invoice

When to Use EDI

  • Regular orders between same trading partners
  • High-volume B2B transactions
  • Compliance with Peppol network requirements
  • Reducing manual data entry errors
  • Legal requirements (e-invoicing mandates)

Example 5: HR Leave Management

Leave Request Flow

mermaid
graph LR
    E["Employee
    hr.employee"] --> LR["Leave Request
    hr.leave"]
    LR --> LT["Leave Type
    hr.leave.type"]
    LR --> A["Approver
    res.users"]
    E --> D["Department
    hr.department"]
    D --> M["Manager
    hr.employee"]

Model Structure

ModelKey FieldsPurpose
hr.leaveemployee_id, holiday_status_id, date_from, date_to, stateThe leave request
hr.leave.typename, allocation_type, max_daysTypes like "Sick", "Vacation"
hr.leave.allocationemployee_id, holiday_status_id, number_of_daysLeave balance

Approval Workflow

mermaid
graph LR
    D[Draft] --> C[Confirm]
    C --> A1[First Approval]
    A1 --> A2[Second Approval]
    A2 --> V[Validated]
    C --> R[Refused]
    A1 --> R

Key Computed Fields

FieldComputationStored?
number_of_daysBusiness days between dates✅ Yes
remaining_leavesAllocation - used❌ No (dynamic)
can_approveUser has approval rights❌ No (context)

Example 6: Project & Task Management

Project Structure

mermaid
graph TD
    P["Project
    project.project"] --> T["Tasks
    project.task"]
    T --> ST["Subtasks
    project.task"]
    T --> S["Stage
    project.task.type"]
    T --> U["Assignees
    res.users"]
    T --> TS["Timesheets
    account.analytic.line"]

Key Features

FeatureImplementationNotes
Kanban stagesMany2one to project.task.typePer-project stages
Task hierarchyparent_id Many2one to selfSubtasks
Multiple assigneesMany2many to res.usersTeam assignment
Time trackingOne2many to analytic.lineTimesheet entries
PropertiesProperties fieldCustom fields per project

Stage (Not State) Pattern

Projects use Stages (Many2one) instead of States (Selection):

AspectProject Stages
Customizable✅ Each project has different stages
Kanban view✅ Drag-and-drop between columns
Order✅ Sequence field for ordering
Fold in kanban✅ Collapse completed stages

Example 7: CRM Pipeline

Lead to Customer Flow

mermaid
graph LR
    L["Lead
    crm.lead"] -->|Convert| O["Opportunity
    crm.lead"]
    O -->|Won| SO["Sale Order
    sale.order"]
    O -->|Won| P["Partner
    res.partner"]

CRM Stages

StageProbabilityActions
New10%Initial contact
Qualified30%Need confirmed
Proposition50%Quote sent
Negotiation70%Discussing terms
Won100%Creates customer, order
Lost0%Marked with reason

Key Fields

FieldTypePurpose
expected_revenueMonetaryDeal value
probabilityFloatWin likelihood (PLS)
stage_idMany2onePipeline position
user_idMany2oneSalesperson
team_idMany2oneSales team
partner_idMany2oneCustomer (if known)

Knowledge Check

Q1: Hospital: Why is patient age NOT stored?

Answer: It changes every day

Storing age would require daily recalculation for all patients. Computing on-demand is more efficient since age only needs to be shown, not searched or grouped.

Q2: E-commerce: Why does Sale Order have One2many to deliveries but Many2many to invoices?

Answer: Multiple invoices can cover multiple orders

Deliveries are created per-order (one delivery serves one order). But invoices can consolidate multiple orders (one invoice for multiple orders), requiring Many2many.

Q3: Manufacturing: What's the relationship between BOM and Manufacturing Order?

Answer: BOM is the recipe, MO is the actual production

Bill of Materials defines HOW to make a product (components, steps). Manufacturing Order is a specific request to make X units using that recipe.

Q4: Project: Why do projects use Stages instead of States?

Answer: Each project can have different workflow stages

States are fixed in code. Stages (Many2one records) let each project define its own workflow (e.g., "Design → Review → Done" vs "Backlog → Sprint → Done").

Q5: CRM: How does probability relate to stages?

Answer: Each stage has a default probability, PLS refines it

Stages define baseline probability (New=10%, Won=100%). Predictive Lead Scoring (PLS) adjusts based on historical data and lead characteristics.