- APPS
- OmniApproval™: One platform. Every approval. 17.0
One approval engine for every document in your Odoo
Define who approves what, in which order, for any model - a payment, a contract, a vehicle booking, a journal entry - and get a record of exactly what was approved.
OmniApproval™: One platform. Every approval. (technical name viin_approval) is an Odoo 17.0 app for Odoo Community and Odoo Enterprise and Viindoo Cloud, built for requester, approver, process owner, auditor.
At a Glance
The facts of OmniApproval™: One platform. Every approval., version 0.2.4, in one place. Published by Viindoo.
Key Features
Most approval apps bolt a two-step check onto one document: a purchase order, or a leave request. This one is the other way round: you declare an approval type, point it at any model in the database, and describe the approvers - a named user, the requester's manager, a group, a rule written in Python, or several of them in sequence. From then on the request carries its own approval trail, and a snapshot of the record as it stood when each approver said yes, so an audit can see what was actually approved rather than what the record looks like today.
Waiting on me
An approver's own list, filtered to what is actually theirs - not the whole queue with a search they have to remember.
Approve a batch as lines
Select the source records - payments, invoices - and raise one request whose lines mirror them, instead of one request per document.
Approval analysis
Volume, status and duration by type and period, on the requests themselves.
Types as a catalogue
Every approval process in the company on one screen, with what it applies to and how long it may take.
How It Works
Three steps to put a document under approval, and one to read the result.
Declare the approval type
Name the type, choose the model it approves, set how many days it may take, and decide whether the requester's own manager is always required. This is configuration - no development, and no new module per document type.
Describe who approves, in what order
Each step picks its approver: a named user, the manager of the requester, a group, or a Python expression for the cases a dropdown cannot express - approve above an amount, approve for this department. Steps run in sequence, so a second approver only sees the request once the first has signed.
Raise the request
A request is raised from the overview or from the document itself. It carries the amount, the dates, the department and the lines, and it shows the approvers still to come. Refusing asks for a reason, which stays on the record.
Read the workload, not the inbox
Three reports come with it: requests by type and status, approvals over time, and the workload per approver. That last one is the answer to the question every process owner eventually asks - who is the bottleneck this month.
What You Get
Approval types for any model - the shipped ones already cover payments, customer invoices, contacts, employee contracts and fleet bookings
Approver steps in sequence: a specific user, the requester's manager, everyone in a group, or a Python rule - with the option to require all of them or any one
Snapshots: what the record looked like at the moment of approval, kept beside the request
Requests with lines, so a batch of payments can be approved as one request instead of twenty
A deadline per type in days, with the requests that are late visible as their own list
Reports on requests, on approvals and on the workload each approver is carrying
More Screens
Everything below was taken on a database seeded with real business data, on this series - not a mock-up and not a screenshot from an older version.
Every request, with type, requester, amount and status
A request waiting on its next approver
An approval type opened from the overview
What This App Does Not Do
Read this before you buy. Everything below is something the app deliberately leaves to another app or to you.
Approvers run in sequence with conditions; branching diagrams, parallel gateways and loops are not modelled. If you need BPMN, this is not it.
Types that point at a payment or an invoice map the source record's fields onto the request. Creating one by hand and typing lines is not the intended path, and the app should refuse it more clearly than it currently does.
Approval decides whether something proceeds; it does not decide who may read or write the record. Access rights stay where they are.
A three-day approval window counts three calendar days.
Works Well With
Apps from the same stack, built to fit this one:
Approval for Accounting
Payments, customer invoices and journal entries under approval, with the document as the source.
viin_approval_accountEmployee Advance
Cash advances raised, approved and settled on the same engine.
to_hr_employee_advanceOvertime approval
Overtime requests routed through the same approver steps as everything else.
viin_hr_overtime_approvalWorkflow Automation
When the decision is not a person but a rule that has to fire on a schedule.
viin_workflow_automationWho Should Use OmniApproval™: One platform. Every approval.?
Requester
Raises a request from the overview or straight from the document, and follows it.
Approver
Sees only what is waiting on them, approves or refuses with a reason, and never has to open the underlying document to know what changed.
Process owner
Declares the type, the model it applies to and the sequence of approvers, without writing a module.
Auditor
Reads the trail: who approved, when, and what the record looked like at that moment.
Frequently Asked Questions
What does OmniApproval™: One platform. Every approval. do?
Define who approves what, in which order, for any model - a payment, a contract, a vehicle booking, a journal entry - and get a record of exactly what was approved.
What does OmniApproval™: One platform. Every approval. not do?
It is not a graphical workflow designer. Approvers run in sequence with conditions; branching diagrams, parallel gateways and loops are not modelled. If you need BPMN, this is not it. A document-backed type must be raised from its document. Types that point at a payment or an invoice map the source record's fields onto the request. Creating one by hand and typing lines is not the intended path, and the app should refuse it more clearly than it currently does. It does not replace record rules. Approval decides whether something proceeds; it does not decide who may read or write the record. Access rights stay where they are. Deadlines are in days, not working days. A three-day approval window counts three calendar days.
Who is OmniApproval™: One platform. Every approval. for?
Requester: Raises a request from the overview or straight from the document, and follows it. Approver: Sees only what is waiting on them, approves or refuses with a reason, and never has to open the underlying document to know what changed. Process owner: Declares the type, the model it applies to and the sequence of approvers, without writing a module. Auditor: Reads the trail: who approved, when, and what the record looked like at that moment.
Which Odoo version and editions does it support?
Odoo 17.0 - Odoo Community, Odoo Enterprise, Viindoo Cloud. Upgrades to a newer Odoo series are a separate purchase for that series.
What does it depend on?
It installs on top of: base_setup, to_approvals, viin_safe_field_model_selector, product. Odoo installs them with it.
How do I set it up?
Three steps to put a document under approval, and one to read the result.
What works well with it?
Approval for Accounting (viin_approval_account): Payments, customer invoices and journal entries under approval, with the document as the source. Employee Advance (to_hr_employee_advance): Cash advances raised, approved and settled on the same engine. Overtime approval (viin_hr_overtime_approval): Overtime requests routed through the same approver steps as everything else. Fleet Booking (viin_fleet_booking): Vehicle requests approved before a dispatcher sees them. Workflow Automation (viin_workflow_automation): When the decision is not a person but a rule that has to fire on a schedule.
Can I try it before buying?
Yes - the Live Preview button at the top of this page opens the module's own screen on a working database.
How do I get support?
Write to apps.support@viindoo.com with your Odoo version and the technical name viin_approval; pre-sales questions go to sales@viindoo.com.
See OmniApproval™: One platform. Every approval. in Action
Live demo: v17demo-int.viindoo.com/web#action=to_approvals.approval_request_action
Need help with OmniApproval™: One platform. Every approval.?
For questions, implementation support or a custom feature, contact Viindoo.
Pre-Sales & Partnership
sales@viindoo.comUpgrades to a newer Odoo series are a separate purchase for that series.
Approval documentation: viindoo.com/documentation/17.0/applications/productivity/approvals.html
All Viindoo apps: apps.odoo.com/apps/modules/browse?author=Viindoo
Technical Requirement
Changes log
0.2.4 - Latest on the 17.0 line
- Snapshots of the approved record are stored per approval step, so an audit sees the version that was signed.
- Approver steps accept a Python selector for the rules a dropdown cannot express.
- The waiting list is filtered to the approver's own pending steps rather than the whole queue.
- Approval types that map a source document refuse a request whose required lines are missing, naming the type.
OmniApproval™ (viin_approval)
Installation
- Go to Apps.
- Search for viin_approval.
- Click Activate.
Note
viin_approval is the core engine of OmniApproval™ and must be installed before any vertical approval modules.
Configuration
Approval Types
- Navigate to OmniApproval™ - Configuration - Approval Types.
- Create or open an approval type.
- Set the following fields:
- Source Model
- Source Button Label
- Applicable Records Domain (optional)
- Before-Approval Required Domain (optional)
- Field Mapping Strategy: single or multi
- Has Lines / Lines Required (if line-level approval is needed)
Approvers
- Open the Approvers tab.
- Configure:
- Required approvers
- Sequence
- Minimum approvals
Field Enablement (Head)
- For each toggle field, choose one of:
- none: hidden
- optional: shown, optional
- required: shown, mandatory
Common head toggles include:
- has_document
- has_reference
- has_date
- has_period
- has_amount / has_amount2 / has_amount_currency
- has_quantity / has_quantity_integer
- has_partner / has_partner_ids
- has_user_id / has_user_ids
- has_employee_id / has_employee_ids
- has_department_id / has_job_id
- has_product_id / has_product_tmpl_id
- has_country_id / has_country_state_id
- has_address_id
- has_location
- has_resource_calendar_id
- has_description / has_description_html
- has_res_ref
- has_time_period
- etc
Field Enablement (Lines)
Line toggle fields follow the same structure, using line_has_... prefixes.
Custom Labels
- In the Labels section, set custom labels for enabled fields. These labels override defaults in both the request form and the wizard.
Field Mapping
- Open the Field Mappings tab.
- Add mapping lines specifying:
- Source Model
- Source Field
- Destination Model (Request or Request Line)
- Destination Field
- Optional Child Mappings for nested structures
Mapping Strategy Behavior
Single Strategy
- One approval request per source record.
- If line mappings exist, source lines map to request lines.
Multi Strategy
- One approval request for multiple source records.
- Each source record becomes one request line.
Allowed mapping field types:
- Basic stored fields
- many2one
- many2many
- one2many (converted into lines)
Snapshots and Diff
- When a request is confirmed, a snapshot is stored:
- One snapshot for the request head
- One snapshot per request line
- Later changes to the source record are detected and displayed as diffs.
Using OmniApproval™
Creating a Request
- Open any supported source record.
- Click Get Approved.
- The wizard loads mapped values.
- Select an approval type.
- Confirm to create the request.
Attaching to an Existing Request
(Available only when the approval type uses multi strategy.)
- Select multiple source records.
- Choose Attach to existing request.
- Select the target request.
- Confirm.
Inline Python Hooks (Admin Only)
These hooks allow system admins to add controlled automation.
Action Hooks
Executed before or after actions:
- Confirm -> code_confirm_pre / code_confirm_post
- Validate -> code_validate_pre / code_validate_post
- Refuse -> code_refuse_pre / code_refuse_post
- Cancel -> code_cancel_pre / code_cancel_post
- Draft -> code_draft_pre / code_draft_post
Available variables:
- env
- records (batched approval requests)
- log (logging helper)
Example:
# Confirm related transfers when approval is validated
pickings = records._get_res_ref_records_map().get('stock.picking')
if pickings:
pickings.action_confirm()
Inline Onchange Hooks (UI Only)
These run only in web client onchange events, never on backend create/write:
- code_onchange_request
- code_onchange_request_line
Example:
# Autofill quantity when product changes
for r in records:
if r.product_id and not r.quantity:
r.quantity = 1
Default Code Snippets
Each hook field includes example code which demonstrates:
- Allowed global variables
- Safe operation patterns
- Batch processing via records
Admins should begin with these examples.
Best Practices
- Keep mapping rules simple and focused.
- Do not map compute-only or non-stored fields.
- Use snapshot/diff to track post-approval changes.
- Use inline hooks for lightweight automation only.
- For complex logic, create a dedicated module.
Summary
viin_approval provides:
- Configurable approval request structures
- Head/line field toggles
- Customizable labels
- Flexible field mapping
- Snapshot and diff audit trails
- Safe inline Python automation
It is the foundation of the OmniApproval™ ecosystem.
This software and associated files (the "Software") may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file).
You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one).
It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software.
The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.