Odoo Customization Best Practices: The 5S Framework for Developers

5S Framework is a technical documentation standard used for Odoo Architects and Developers to bridge the gap between functional requirements and high-quality code. This framework ensures that every customization is documented with precision, covering the UI, logic, automation, database structure, and data retrieval.

Each layer answers one core question:

Layer Answers Output
Screen What does the user see? XML views, fields, layouts
Pseudo Code What does the system think? Logic in plain English before Python
Script What runs automatically? Automations, cron jobs, workflows
Schema How is data stored? Python models, field types, relations
SQL How is data retrieved? Raw queries, reports, dashboards

5S Framework for Odoo

Here’s a clean visual overview of the 5S Framework, followed by a breakdown of each layer.

The golden rule of 5S is that you work top-to-bottom, never jumping ahead. You don’t write Python until the Screen is documented. You don’t write SQL until the Schema is defined. This prevents the most common Odoo mistake — developers writing code before they’ve agreed on what the field is called or where it lives.

Here’s how each layer maps to actual files inside your custom Odoo module:

Layer Name Focus Output Odoo Artifact
S1 Screen UI/UX XML views ir.ui.view
S2 Pseudo Code Logic Python code models.Model
S3 Script Automation Cron / triggers ir.cron / ir.actions
S4 Schema Database Model definition models.Model (_name)
S5 SQL Reporting PostgreSQL view SQL + read-only model

1️⃣

Screen — UI & Field Mapping

XML views · form · tree · kanban · xpath inheritance

What is Screen?

The Screen phase defines how the user interacts with the system. In Odoo, this translates directly to XML view definitions. Before writing a single line of Python, the developer documents which fields exist, where they appear in the UI, and who can see or edit them.

Key decisions in Screen

Decision What to document
View type Form (edit one record), Tree/List (browse many), Kanban (card layout), Pivot (reports)
Field type Char, Float, Many2one, Selection, Boolean, Monetary, Html, Date
Inheritance Which existing Odoo view ID is being inherited (use xpath expressions)
Visibility attrs=invisible / readonly per user group or field value
Permissions Which groups (Sales Manager, Inventory User) see or edit the field

Example — adding commission fields to sale.order form

Scenario: Add a Commission Rate and Commission Total field to the Sales Order form view.

Technical name Label
x_comm_rate Commission %
x_comm_total Total Commission

2️⃣

Pseudo Code — Business Logic

Python · @api.depends · @api.constrains · UserError

What is Pseudo Code?

Before writing actual Python, every developer must document the logic in plain, structured English. This ensures that business rules are agreed upon before implementation begins — preventing costly rewrites when requirements are misunderstood.

Logic types

Type When to use
Computed field (@api.depends) Auto-recalculates a field value when a source field changes. Use store=True to save to DB.
Constraint (@api.constrains) Raises a ValidationError to block saving invalid data (e.g. credit limit exceeded).
Onchange (@api.onchange) Updates the UI instantly before saving (useful for live feedback to the user).
Override (super()) Extend Odoo built-in methods like action_confirm or write to inject custom logic.
UserError Raise a user-facing error message to halt an operation with a clear explanation.

Example — commission total computed field

Pseudo logic: If the order is in state ‘sale’ or ‘done’, calculate commission as untaxed amount × rate. If no rate is set, default to 10%. Otherwise set commission to zero.

3️⃣

Script — Automation & Scheduled Actions

Cron jobs · automated actions · server actions · API sync

What is Script?

Script refers to automated actions and background processes that keep the ERP running without manual intervention. The focus is: who does what, in what order. This covers scheduled jobs, event-based triggers (on create / on update / on delete), server actions tied to buttons, and external API integrations.

Script types

Type Description
Automated Action Triggers on record creation, update, or deletion. Configured in Settings → Technical → Automation.
Scheduled Action (Cron) Runs at a fixed interval (hourly, daily, monthly). Ideal for reports, syncs, and digest emails.
Server Action Multi-step process triggered by a button click (e.g. Batch Validate, Send Reminders).
External API Script Maps the data flow for third-party integrations (Shopify, WooCommerce, payment gateways).

Workflow example — sales order lifecycle

Step Actor & Action
1 Sales Executive creates quotation
2 Customer confirms quotation (portal or email)
3 Sales Executive converts to Sales Order
4 System automatically checks stock availability
5a (stock available) System creates Delivery Order → Warehouse validates
5b (stock unavailable) System creates backorder, notifies warehouse
6 Invoice generated after delivery confirmation
7 Accounts records payment → order marked as paid
Exception If payment overdue → block new orders for that customer

4️⃣

Schema — Database & Model Structure

models.Model · Many2one · One2many · ondelete strategy

What is Schema?

Schema is the blueprint of the data layer. In Odoo, this means Python model class definitions — which become real PostgreSQL tables via the ORM. Field types, relationships between models, and deletion rules all need to be thought through before writing code.

_inherit vs _name — the most important distinction

Keyword Behaviour
_inherit = ‘sale.order’ Adds fields/methods to an existing model and its table. No new table is created.
_name = ‘commission.history’ Creates a brand new model with its own PostgreSQL table.
Both together Copies the existing model into a new one (prototype inheritance — rarely used).

Relation types

Type Meaning & Example
Many2one Many records link to one parent. e.g. sale.order → res.partner (customer).
One2many One parent has many children. e.g. sale.order → sale.order.line (order lines).
Many2many Cross-links between two models. e.g. product.template ↔ product.tag.

5️⃣

SQL — Reporting & Data Queries

PostgreSQL views · JOIN · GROUP BY · read-only Odoo model

What is SQL?

While Odoo uses an ORM (Object-Relational Mapper) for most operations, complex reporting often requires raw SQL for performance. The SQL layer is used to build management dashboards by creating PostgreSQL VIEWs and exposing them as read-only Odoo models accessible via pivot and graph views.

When to use raw SQL

Scenario Reason
Cross-module reports Join Sales + Accounting + Inventory in a single query — ORM can’t do this cleanly.
Aggregation at scale SUM, COUNT, AVG across thousands of records is far faster in native SQL.
Management dashboards Read-only model backed by a PostgreSQL VIEW for pivot/graph views.
Performance tuning Bypass ORM overhead for high-volume analytics queries.

Example

Let’s look at how all 5 layers connect in a real Odoo customization project — the complete flow from requirement to deployed feature

Putting It All Together — Module Structure

File / Folder 5S Layer & Purpose
__manifest__.py Module metadata — name, version, depends, data file list
models/sale_order.py S2 Pseudo Code + S4 Schema — extends sale.order with commission fields and computed logic
models/commission_history.py S4 Schema — new commission.history model with its own table
views/sale_commission_views.xml S1 Screen — XML view inheriting sale.order form, adding commission fields
views/commission_report_views.xml S5 SQL — pivot and graph views for the commission analysis report
data/cron_commission.xml S3 Script — scheduled action for monthly commission digest email
data/automated_action.xml S3 Script — event-based trigger (e.g. on order confirmation)
report/commission_analysis.py S5 SQL — read-only Odoo model backed by PostgreSQL view
report/commission_analysis.sql S5 SQL — raw SQL for the PostgreSQL VIEW (optional separate file)
security/ir.model.access.csv Access rights — which user groups can read/write each model

 

Leave a Reply

Your email address will not be published. Required fields are marked *

odoo_casestudy