Zenithonsoft

Odoo Commissions Deep Dive: OCA vs. Enterprise (v15, v19, v20) & The Migration Traps

If you are planning an upgrade from an older Odoo version (v14, v15, or v16) to Odoo 19 or Odoo 20, you might have noticed an exciting addition in the Enterprise release notes: a native sale_commission module.

For companies running wholesale distribution, manufacturing, or multi-channel sales that have long relied on the open-source Odoo Community Association (OCA) commission suite, the initial reaction is usually relief: “Did Odoo finally adopt the OCA commission module into core Enterprise?”

We conducted an exhaustive source code audit across OCA v19, Odoo 19 Enterprise, Odoo 20 Enterprise, and real-world v15 production codebases.

Here is the straightforward answer:

No, Odoo did not adopt or convert the OCA commission module. Odoo S.A. built an entirely separate, proprietary module from scratch under the exact same technical name (sale_commission) in Odoo 19 Enterprise (licensed under OEEL-1). Because Odoo claimed that namespace, the OCA had to rename their entire suite to _oca.

They share zero schema, zero models, and zero business logic.

If your business relies on gross margin calculations, external independent sales reps, line-level commission splits, or automated vendor bill payouts, switching blindly to Odoo Enterprise’s module will break your compensation workflows.

Here is an architectural breakdown of how both engines work, what changed in Odoo 20, and how to avoid costly migration traps.


1. High-Level Comparison: OCA vs. Enterprise sale_commission

The two systems were designed to solve fundamentally different business problems:

Dimension OCA Suite (commission_oca / sale_commission_oca) Odoo Enterprise (sale_commission)
Primary Paradigm Remuneration & Settlement: Line-level commission tracking, agent billing, and Accounts Payable vendor bill generation. Incentive Compensation Management (ICM): Sales quotas, On-Target Commission (OTC), achievement tiers, and team performance tracking.
Recipient Entity Any res.partner flagged as agent=True (external brokers, independent reps, 1099 contractors, or employees). Strictly internal res.users (domain="[('share', '=', False)]") or crm.team. External partners cannot be assigned.
Granularity Order Line Level (sale.order.line.agent, account.invoice.line.agent). Multiple agents can split commissions on a single item. Document / Header Level aggregated via SQL views. Attribution belongs strictly to order.user_id or invoice.invoice_user_id.
Calculation Basis - Gross invoiced amount
- Net Margin / Profit (Amount - Cost)
- Tiered brackets per amount interval
- Linear % or Tiered quota attainment %
- v19: Amount Invoiced, Amount Sold, Qty Invoiced, Qty Sold
- v20: Added Amount Paid
- NO Margin / Gross Profit support.
Settlement & Payout Settlement wizard generates real Vendor Bills (in_invoice) to pay agents through standard Accounts Payable (AP). Dynamic SQL reporting views (sale.commission.report). Does not generate accounting entries or vendor bills; payouts must be pushed to Payroll or journal entries manually.
Cash-Basis / Paid Date Settle based on invoice validation or cash receipt; supports automatic reversals on unreconciliation or credit notes. v19 is accrual-only (invoice/order date). v20 introduces cash basis via a calculated paid_ratio.

2. A Breakdown of the Four Codebases

A. The Real-World Legacy Model (v15 OCA / Custom)

In wholesale and distribution environments, commissions rarely follow simple top-line sales percentages. Production implementations typically require:

  • Authoritative Customer Ownership: The commission belongs to the territory manager or account executive assigned to the customer (partner_id.sales_person_ids), not the customer service rep (sale.order.user_id) who typed the order into Odoo.
  • Gross Profit Commissions: Calculating commissions strictly on margin (Sale Price - Cost of Goods Sold) to discourage discounting.
  • Commission Aging & Cash Basis: Commission is realized only when the customer pays their invoice (in_payment / paid). If the customer pays 60 days late past the due date, commission aging rules apply deductions.
  • Weekly Draws & Reversals: Handling weekly minimum draw advances against future commissions, with automated debit adjustments if a customer bounces a payment or receives a credit memo.

B. The Modern v19 OCA Suite (commission_oca)

To avoid collisions with Odoo Enterprise’s new namespace, the OCA cleanly refactored the suite in v19 into standalone modular apps:

  1. commission_oca: Base framework, agent definitions on res.partner, settlement calculations, and lines.
  2. sale_commission_oca: Injects sale.order.line.agent and auto-populates designated agents on quotation lines.
  3. account_commission_oca: Injects account.invoice.line.agent and provides the settlement wizard that creates vendor bills for agent payouts.

In the v19 OCA migration, partner fields were explicitly renamed (such as agent_ids → commission_agent_ids) to ensure total isolation from core fields.

C. Odoo 19 Enterprise (sale_commission)

Introduced in v19 under OEEL-1, Enterprise approaches commissions as Incentive Compensation Management (ICM):

  • Centered on sale.commission.plan: Admins configure target quotas and On-Target Commission (OTC) benchmarks (e.g., 50% quota = 0% payout, 100% quota = 100% OTC, 120% quota = 150% OTC).
  • Only tracks four operational metrics: amount_invoiced, amount_sold, qty_invoiced, and qty_sold.
  • Accrual only: Achievements are calculated based on invoice or order confirmation dates, regardless of whether the customer has paid.
  • Reporting-only: Payouts are computed via dynamic SQL database views (sale.commission.report and sale.commission.achievement.report).

D. What Odoo 20 Enterprise Changed

A detailed comparison of odoo19/enterprise/sale_commission against odoo20/enterprise/sale_commission reveals several major additions:

  1. Cash Basis Support (amount_paid): Odoo 20 adds amount_paid (“Amount Paid in Full”) to commission achievements. The underlying SQL query introduces a paid_ratio = (amount_total - amount_residual) / amount_total.
  2. Terminology Shift: The plan type selection shifted from ('target', 'Targets') / ('achieve', 'Achievements') to ('achieve', 'Linear') / ('target', 'Tiered').
  3. Dynamic / Cascading Quotas: Sales managers can now have dynamic quotas that automatically aggregate the quotas of their subordinate team members (dynamic_plan_ids).
  4. Team Rollups: Added a user_ids Many2many (“Sum of achievements”) to sale.commission.plan.user. Deals closed by team reps can roll up into the team leader’s commission achievement.
  5. Adjustments & Payroll Locks: Manual adjustments (sale.commission.achievement) can link directly to a specific order_id or move_id, and achievements can be marked readonly (“Locked”) once payroll has run.
  6. Conflict Detection: Added a wizard to flag overlapping commission plans assigned to the same user during the same date range.

3. The 5 Breaking Migration Traps

If you attempt to migrate an existing v14/v15/v16 database with OCA commissions to Odoo 19 or 20 Enterprise, be prepared for these critical pitfalls:

Trap 1: Technical Database Collision

If your database has a module named sales_commission or sale_commission from older OCA releases, attempting to install Enterprise sale_commission will trigger database integrity crashes during the migration script. The Enterprise module expects tables like sale_commission_plan and sale_commission_achievement, which do not exist in the legacy schema.

Trap 2: Complete Loss of Gross Margin / Profit Commissions

Wholesale and distribution companies rarely pay commissions on top-line revenue because reps would discount prices to close volume, eroding profits. Neither Odoo 19 Enterprise nor Odoo 20 Enterprise supports product cost or gross profit in their commission queries. If your reps are paid on margin ($Price - Cost$), Enterprise cannot do this out of the box.

Trap 3: Independent Contractors and 1099 Brokers Are Locked Out

In OCA, commissions can be assigned to any res.partner (external agencies, independent brokers, manufacturer reps). In Enterprise, commission plans strictly require an internal res.users account (share=False). If you have 30 independent external agents, you cannot configure them in Enterprise without buying 30 Odoo Enterprise user licenses and setting them up as internal users.

Trap 4: Loss of Multi-Agent Line Splitting

In OCA, Line 1 of an order can pay 5% to Agent A and 2% to Agent B, while Line 2 pays 3% to Agent C. In Enterprise, the entire sale belongs strictly to the single salesperson (order.user_id) or sales team on the order header.

Trap 5: The “Order Creator” Attribution Error

In most distribution and trade businesses, outside sales reps spend their days in the field, while customer service reps (CSRs) enter quotes and orders into Odoo. Enterprise attributes the achievement to the user who creates or owns the document in Odoo. Unless customized, your CSRs will receive the commission instead of the outside account rep who owns the client relationship (partner_id.sales_person_ids).

Trap 6: Missing Accounting Settlement (No Vendor Bills)

OCA provides an end-to-end accounting workflow: Calculate Settlements → Generate Vendor Bills → Approve & Pay via Accounts Payable. Enterprise stops at the dashboard report. If you pay non-employee agents, you will have to manually copy figures from Odoo reports and create vendor bills by hand.


4. The Decision Matrix: Which One Should You Use?

                                  Your Compensation Model
                                             │
             ┌───────────────────────────────┴───────────────────────────────┐
             ▼                                                               ▼
   Wholesale / Distribution / B2B                               SaaS / Internal Direct Sales
   ──────────────────────────────                               ────────────────────────────
   • Paid on Gross Margin (Profit)                               • Paid on Invoiced Revenue or Units
   • External Brokers & 1099 Reps                                • Internal W-2 Employees only
   • Line-level multi-agent splits                               • Single rep per deal
   • Payout via Accounts Payable Vendor Bills                    • Monthly / Quarterly Quotas & OTC
   • Cash-basis aging deductions                                 • Payout rolled into Monthly Payroll
             │                                                               │
             ▼                                                               ▼
   USE OCA SUITE (v19/v20)                                      USE ODOO ENTERPRISE
   `commission_oca` + `sale_commission_oca`                     `sale_commission`
  1. Choose the OCA Suite (commission_oca) if:

    • You work in distribution, trading, contracting, or wholesale.
    • You pay independent agents, brokers, or external partners.
    • You calculate commissions on gross profit / net margin.
    • You need automated Vendor Bills generated in Accounts Payable.
  2. Choose Odoo Enterprise (sale_commission) if:

    • You have an internal sales team on structured On-Target Commission (OTC) plans.
    • Quota attainment tiers (e.g., accelerators at 110% of target) drive your incentives.
    • Sales reps are internal employees and commissions are paid out through HR payroll.
    • You are on Odoo 20 and want native cash-basis tracking (amount_paid) across linear or tiered plans.

Where Zenithonsoft Fits

Migrating complex business logic between Odoo versions is where most ERP upgrades hit unexpected delays and budget overruns.

At Zenithonsoft, we specialize in pragmatic Odoo engineering and technical assessments:

  • Custom-to-OCA Migration: Safely refactoring legacy v14/v15 custom commission modules into the modern commission_oca v19/v20 schema without data loss.
  • Enterprise Margin Extensions: If your team wants Enterprise quota dashboards but needs gross margin calculation and customer account attribution, we build targeted, upgrade-safe extensions to Enterprise sale_commission.
  • Pre-Upgrade Code Review: Before you commit to an upgrade cutover date, request an Independent Code Review — we inspect your custom addons, identify breaking namespace collisions, and provide a clear, fixed-price migration roadmap.

Have questions about your commission structure or planning an Odoo 19/20 upgrade? Book a 30-minute discovery call with our team.