Skip to Content
Odoo Menu
  • Sign in
  • Try it free
  • Apps
    Finance
    • Accounting
    • Invoicing
    • Expenses
    • Spreadsheet (BI)
    • Documents
    • Sign
    Sales
    • CRM
    • Sales
    • POS Shop
    • POS Restaurant
    • Subscriptions
    • Rental
    Websites
    • Website Builder
    • eCommerce
    • Blog
    • Forum
    • Live Chat
    • eLearning
    Supply Chain
    • Inventory
    • Manufacturing
    • PLM
    • Purchase
    • Maintenance
    • Quality
    Human Resources
    • Employees
    • Recruitment
    • Time Off
    • Appraisals
    • Referrals
    • Fleet
    Marketing
    • Social Marketing
    • Email Marketing
    • SMS Marketing
    • Events
    • Marketing Automation
    • Surveys
    Services
    • Project
    • Timesheets
    • Field Service
    • Helpdesk
    • Planning
    • Appointments
    Productivity
    • Discuss
    • Approvals
    • IoT
    • VoIP
    • Knowledge
    • WhatsApp
    Third party apps Odoo Studio Odoo Cloud Platform
  • Industries
    Retail
    • Book Store
    • Clothing Store
    • Furniture Store
    • Grocery Store
    • Hardware Store
    • Toy Store
    Food & Hospitality
    • Bar and Pub
    • Restaurant
    • Fast Food
    • Guest House
    • Beverage Distributor
    • Hotel
    Real Estate
    • Real Estate Agency
    • Architecture Firm
    • Construction
    • Property Management
    • Gardening
    • Property Owner Association
    Consulting
    • Accounting Firm
    • Odoo Partner
    • Marketing Agency
    • Law firm
    • Talent Acquisition
    • Audit & Certification
    Manufacturing
    • Textile
    • Metal
    • Furnitures
    • Food
    • Brewery
    • Corporate Gifts
    Health & Fitness
    • Sports Club
    • Eyewear Store
    • Fitness Center
    • Wellness Practitioners
    • Pharmacy
    • Hair Salon
    Trades
    • Handyman
    • IT Hardware & Support
    • Solar Energy Systems
    • Shoe Maker
    • Cleaning Services
    • HVAC Services
    Others
    • Nonprofit Organization
    • Environmental Agency
    • Billboard Rental
    • Photography
    • Bike Leasing
    • Software Reseller
    Browse all Industries
  • Community
    Learn
    • Tutorials
    • Documentation
    • Certifications
    • Training
    • Blog
    • Podcast
    Empower Education
    • Education Program
    • Scale Up! Business Game
    • Visit Odoo
    Get the Software
    • Download
    • Compare Editions
    • Releases
    Collaborate
    • Github
    • Forum
    • Events
    • Translations
    • Become a Partner
    • Services for Partners
    • Register your Accounting Firm
    Get Services
    • Find a Partner
    • Find an Accountant
      • Get a Tailored Demo
    • Implementation Services
    • Customer References
    • Support
    • Upgrades
    Github Youtube Twitter Linkedin Instagram Facebook Spotify
    +32 2 290 34 90
    • Get a Tailored Demo
  • Pricing
  • Help
  1. APPS
  2. Productivity
  3. Approval Workflow Engine v 19.0
  4. Sales Conditions FAQ

Approval Workflow Engine

by Abd Elhamed Saad https://www.linkedin.com/in/abd-el-hamed-saad/
Odoo

$ 129.36

In-App Purchases
v 19.0 Third Party
Apps purchases are linked to your Odoo account, please sign in or sign up first.
Availability
Odoo Online
Odoo.sh
On Premise
Odoo Apps Dependencies Discuss (mail)
Lines of code 5104
Technical Name dynamic_state_approval
LicenseLGPL-3
Websitehttps://www.linkedin.com/in/abd-el-hamed-saad/
Versions 18.0 19.0
You bought this module and need support? Click here!
Availability
Odoo Online
Odoo.sh
On Premise
Odoo Apps Dependencies Discuss (mail)
Lines of code 5104
Technical Name dynamic_state_approval
LicenseLGPL-3
Websitehttps://www.linkedin.com/in/abd-el-hamed-saad/
Versions 18.0 19.0
Community
Enterprise
Odoo.sh

TEMPLATE-DRIVEN APPROVAL WORKFLOWS FOR ANY ODOO MODEL

Approval Workflow Engine

Build custom approval workflows from reusable templates — define states, transitions, gate rules, and access controls entirely from the UI. No code changes required.

Connect on LinkedIn Email Us

Key Highlights

Template Library

Ready-to-use approval templates for Journal Entries, Transfers, Sales, Purchase Orders, and generic multi-step approvals

Custom State Machine

Define states with color coding, sequences, and links to standard Odoo states. Add transition buttons with labels, types, and ordering

Gate Rules

Block or hide native Odoo buttons (Post, Validate, Confirm) until the required custom state is reached — no code changes needed

Access Control

Restrict each transition to specific users or groups. Domain-based visibility rules for conditional button display

Live Dashboard

Real-time counters for every custom state across all active workflows. Drill down directly to filtered record lists

Multi-Company & Domain

Isolate workflows per company. Apply domain filters to restrict a workflow to specific record types (e.g. Customer Invoices only)

Approval Flows for Any Odoo Model

From Journal Entry approvals to Stock Transfer validations — configure multi-step approval workflows
directly from the UI using pre-built templates or build your own from scratch.

Connect on LinkedIn Get in Touch
  • Screenshots
  • Features
  • Releases
🗂️ Templates Library

Ready-to-Use Workflow Templates

Browse the built-in template library — pre-configured approval flows for Journal Entries, Stock Transfers, Sales Orders, Purchase Orders, and generic 2- or 3-step approvals.
Click Apply to create a live workflow in seconds.

Workflow Templates Library
  1. Journal Entry C — Accounting / Journal Entry (3-step: Draft → Approve C → Manger C → Posted)
  2. Journal Entry Bill — Accounting / Journal Entry (2-step: Draft → Approve B → Manger B → Posted)
  3. Transfer D — Inventory / Transfer — Delivery Orders only (domain filtered)
  4. Transfer R — Inventory / Transfer — Receipts only (domain filtered)
  5. Sales Order — Sales / Sales Order (2-step approval before confirmation)
  6. Purchase Order — Purchasing / Purchase Order (2-step approval before confirmation)
  7. 2 Approve — General / any model (generic 2-step: Draft → Approve → Done)
  8. 3 Approve — General / any model (generic 3-step: Draft → Approve → Manager → Done)
🔍 Model: workflow.template — Kanban / List / Form views
💡 Example: Click Apply on "Transfer D" → dialog opens → type field name → click Create Workflow → 7 states + 2 transitions + 1 gate rule created instantly
🚀 One-Click Apply

Apply Template in One Step

The Apply wizard pre-fills the model, field name, and states from the template JSON.
Confirm the workflow name and click Create Workflow — states, transitions, and gate rules are all created automatically.

Apply Template Wizard
  1. Info notice — "Button users and groups are not copied from templates. Set button access manually after the workflow is created."
  2. Workflow Name — pre-filled from template name (e.g., "Transfer D"), editable before creation
  3. State Name — technical field name for the custom state field (e.g., Delivery_state → creates x_delivery_state)
  4. Create Workflow — one click creates the full workflow: states, transitions, gate rules, and injects the field into the model
🔍 Model: workflow.template.apply.wizard — TransientModel dialog
💡 Example: Template "Transfer D" applied with State Name Delivery_state → creates field x_delivery_state on stock.picking with 7 states and 2 transition buttons
🔵 States Tab

Custom States with Color Coding

Define any number of custom states with technical names, display labels, color styles, and sequences.
Map each custom state to a standard Odoo state for seamless two-way synchronization. Drag & drop rows to reorder states in the status bar.

States Configuration
  1. State Name — display label shown in the status bar and chatter (e.g., Draft, Waiting, Ready, Approve D, Manger D, Done, Cancelled)
  2. Technical Name — unique internal identifier stored in the database (e.g., draft, confirmed, assigned, approve_d, manger_d)
  3. Linked Standard State — maps the custom state to a native Odoo state for compatibility (e.g., Waiting → confirmed, Done → done, Cancelled → cancel)
  4. State Style — color-coded pill in the status bar (Gray, Blue, Orange, Dark Blue, Green, Red) — chatter on the right logs every state added
🔍 Model: workflow.state — inline editable list in workflow.config form
💡 Example: State "Waiting" → technical: confirmed → linked standard: confirmed → style: Blue | State "Manger D" → technical: manger_d → no link → style: Green
🔘 Transition Buttons

Dynamic Action Buttons

Each transition becomes a clickable button injected into the form header.
Configure button label, type (Primary / Success / Danger / Warning), sequence, confirmation message, icon, and the from/to states it connects. Technical name is auto-generated from states.

Transition Button Configuration
  1. Button Label — text displayed on the form header button (e.g., "Approve D")
  2. Workflow — parent workflow this transition belongs to (e.g., "Transfer D (Transfer)")
  3. Technical Name — auto-generated Python method name from states (e.g., action_draft_waiting_confirmed_to_done)
  4. From States — button appears only when record is in one of these states (multi-select: Draft, Waiting)
  5. To State — the state the record moves to when the button is clicked (e.g., Approve D)
  6. Button Type — visual style of the button (Primary / Success / Danger / Warning / Link)
  7. Confirmation Message — optional popup shown before executing the transition (e.g., "Are you sure you want to proceed?")
🔍 Model: workflow.transition — form dialog from Transitions tab
💡 Example: "Approve D": From [Draft, Waiting] → To Approve D, type Primary, icon fa-check, sequence 10 → button injected into Transfer form header automatically
🔐 Access Control

User & Group Restrictions

Restrict each transition button to specific users or security groups.
Unauthorized users who attempt the action receive a clear error listing who is allowed — enforced server-side for full security.

User Access Control
  1. Specific Users — button is restricted to an explicit list of named users; others get an error message when clicking
  2. User Group — restricts the button to an entire security group (e.g., Purchase Manager, Inventory / Administrator)
  3. Allowed Users — the actual users assigned (e.g., Administrator, test) — enforced server-side on every click
🔍 Fields: visibility_type, allowed_user_ids, group_ids on workflow.transition
💡 Example: visibility_type = 'user', allowed: [Administrator, test] → unauthorized user clicks "Approve D" → error: "You are not authorized to perform this action. Allowed: Administrator, test"
🛡️ Gate Rules

Block Native Odoo Buttons

Gate rules intercept standard Odoo buttons (Post, Validate, Confirm, etc.) and block or hide them until a required custom approval state is reached.
Choose from Block Only, Hide Always, or Hide Until State visibility modes. Set a custom error message for a professional user experience.

Gate Rules Configuration
  1. Button — the native Odoo button being gated (e.g., "Validate (button_validate) ×2" means it appears twice in the view)
  2. Gate Name — friendly label for this rule (e.g., "Validate") — used in error messages
  3. Visibility — enforcement mode: Block Only (visible but blocked), Hide Always (always hidden), Hide Until State (hidden until required state is reached)
  4. Occurrence — which instance to gate when the same button appears multiple times (Auto / [1] / [2])
  5. Required Custom State — the workflow state that must be reached before the button works (e.g., "Manger D")
  6. Error Message — shown to the user when blocked (e.g., "Manger D approval is required before validation.")
🔍 Model: workflow.state.gate — Gates tab in workflow.config
💡 Example: Gate "Validate" → blocks button_validate → required state: Manger D → visibility: Block Only → error: "Manger D approval is required before validation."
🔍 Auto-Discovery

Auto-Discover Form Buttons

Click Discover Buttons to automatically scan the model's primary form view and extract all native action buttons.
Handles duplicate button occurrences with [1] / [2] occurrence selectors.

Discovered Buttons
  1. Discover Buttons — scans the model's primary form view XML and extracts all native <button> elements automatically
  2. Label — the button's display text as shown in the form (e.g., Cancel, Check Availability, Mark as Todo, Validate, Print)
  3. Method — the Python method name on the model called when clicked (e.g., action_cancel, action_assign, button_validate)
  4. Notification — "20 button(s) found for Transfer" — success message shown after scan; Validate appears with count ×2 (appears twice in view)
🔍 Model: workflow.view.button — action action_discover_buttons()
💡 Example: Transfer model → 20 buttons discovered including Validate (button_validate ×2), Cancel (action_cancel), Check Availability (action_assign), Packages, Put in Pack, Scraps
🎯 Domain Filtering

Apply to Specific Record Types

Use the built-in domain builder to restrict a workflow to a subset of records.
Example: apply only to Customer Invoices or Outgoing Transfers. A live counter shows how many records match the current domain.

Domain Builder
  1. Field selector — pick any field on the model (e.g., "Type" = move_type on Journal Entry)
  2. Operator — condition type: is / is not / is in / is not in / contains / > / < / etc.
  3. Values — multi-select from available options (e.g., Journal Entry, Customer Invoice, Vendor Bill, Customer Credit Note...)
  4. Code editor — raw domain preview: [("move_type", "in", ["entry"])] — editable directly for advanced use
  5. New Rule — add additional AND/OR conditions to build complex multi-field filters
🔍 Field: apply_domain on workflow.config — widget: domain
💡 Example: Journal Entry workflow → domain [("move_type","in",["in_invoice","in_refund"])] → applies only to Vendor Bills and Vendor Credit Notes, ignoring all other journal entries
🚫 Runtime Enforcement

Gate Blocks at Runtime

When a user tries to click a gated button before reaching the required state, a descriptive error is raised showing exactly which state must be reached first.
Enforcement is server-side — no client-side bypass is possible.

Runtime Gate Error
  1. Approve D button — workflow transition button injected into the Transfer form header by the engine
  2. Custom state bar — Draft → Waiting → Ready → Approve D → Manger D → Done → Cancelled (all custom states displayed natively)
  3. Validate button clicked — user attempts to validate while record is in "Approve D" state (not yet in "Manger D")
  4. Validation Error dialog — "Cannot proceed: the record must reach the 'Manger D' state first. Manger D approval is required before validation." — enforced server-side, no bypass possible
🔍 Method: _get_error_message() on workflow.state.gate
💡 Example: WH/OUT/00013 in state "Waiting" → user clicks Validate → gate checks current state vs required "Manger D" → raises: "Cannot proceed: the record must reach the 'Manger D' state first."
📊 Live Dashboard

State Counters & Drilldown

The dedicated dashboard aggregates record counts per custom state across every active workflow.
Click any counter to open a filtered list of matching records for immediate action. Managers get a birds-eye view of all pending approvals across the organization.

Dashboard State Drilldown
  1. Journal Entry card — groups all active workflows on Journal Entry (Journal Entry C) with per-state counters: Draft / Approve C / Manger C / Posted / Cancelled
  2. Transfer card — shows Transfer D and Transfer R side by side with their own state counters per workflow
  3. Ready: 2 — clicking any counter opens a filtered list of records in that exact state (e.g., transfers in "Ready" state = 2 records)
  4. Drilldown list view — records from multiple workflows shown together with workflow state columns (Transfer D, Transfer R, Status) — each row is a live record ready for action
🔍 Component: OWL dashboard widget — WfDashboard
💡 Example: "Ready: 2" clicked → list filtered to x_delivery_state = assigned → shows WH/IN/00007 and WH/IN/00005 ready for the next approval step
⚠️ Validation

Duplicate Domain Protection

The engine prevents two active workflows from targeting the same model and domain combination.
A clear validation error is shown before saving, protecting data integrity and preventing conflicting approval flows.

Duplicate Domain Error
  1. "Oh snap!" title — error dialog triggered on save when a duplicate model+domain combination is detected
  2. Error message — "A workflow configuration for model 'Journal Entry' with the same domain already exists (Journal Entry Bill). Each model+domain combination must be unique per company."
  3. Stay here — keeps the form open so the user can correct the domain or rename the workflow
  4. Discard changes — abandons the conflicting configuration without saving
🔍 Constraint: _check_duplicate_domain() on workflow.config
💡 Example: Two workflows on account.move both with domain [("move_type","in",["in_invoice","in_refund"])] → save blocked: "Journal Entry Bill already owns this domain for My Company"

Template library with 8 built-in approval patterns for common Odoo models

Custom states with color coding, sequences, and standard state mapping

Transition buttons auto-injected into form headers — no view customization needed

Per-transition access control by specific users or security groups (server-side enforced)

Gate rules: block / hide standard Odoo buttons until required approval state is reached

Auto button discovery: scans model form views and detects all native action buttons

Domain-based filtering: apply workflow to a subset of records (e.g. Customer Invoices only)

Live dashboard with state counters and one-click drilldown to filtered record lists

Full chatter tracking: state changes, field edits, and line additions/removals logged automatically

Multi-company support: isolate workflows per company with no cross-company conflicts

Duplicate domain protection: prevents conflicting approval flows on the same record type

Clean uninstall: removes all generated fields, views, and automation rules automatically

Release 18.0.2.0.0

April 2026
Improve
  • Template library with 8 ready-to-use approval patterns
  • Auto-save before adding states or transitions (JS widget)
  • Full chatter tracking for form fields and One2many lines
  • Smart needs_update detection — fires only on view-relevant changes
  • Cache invalidation on access-control field changes
  • Notification Manager integration for transition events
  • Button registry sync for external notification modules

Release 18.0.1.0.0

December 2025
Initial Release
  • Core workflow engine: states, transitions, and gate rules
  • Dynamic field generation via Odoo Studio API
  • Auto-detection of native form view buttons
  • Domain-based filtering per workflow
  • Multi-company isolation
  • OWL dashboard with state counters and drilldown
  • Duplicate domain validation
  • Clean uninstall hook
  • Translations: Arabic (ar_001), French (fr), Spanish (es_AR), Turkish (tr)

Developer

Abd Elhamed Saad

Odoo Developer & Consultant

Connect on LinkedIn

For support, customization requests, or feature enhancements

License: LGPL-3  |  Category: Productivity  |  Version: 18.0.2.0.0

Please log in to comment on this module

  • The author can leave a single reply to each comment.
  • This section is meant to ask simple questions or leave a rating. Every report of a problem experienced while using the module should be addressed to the author directly (refer to the following point).
  • If you want to start a discussion with the author or have a question related to your purchase, please use the support page.
Community
  • Tutorials
  • Documentation
  • Forum
Open Source
  • Download
  • Github
  • Runbot
  • Translations
Services
  • Odoo.sh Hosting
  • Support
  • Upgrade
  • Custom Developments
  • Education
  • Find an Accountant
  • Find a Partner
  • Become a Partner
About us
  • Our company
  • Brand Assets
  • Contact us
  • Jobs
  • Events
  • Podcast
  • Blog
  • Customers
  • Legal • Privacy
  • Security

Odoo is a suite of open source business apps that cover all your company needs: CRM, eCommerce, accounting, inventory, point of sale, project management, etc.

Odoo's unique value proposition is to be at the same time very easy to use and fully integrated.

Website made with