10 KiB
Accounting & Journal Entries - How It Works
Executive Summary
There is NO duplicate journal entry creation. The system is working correctly.
When you create and post invoices/bills, commission and expenses are added as invoice lines, not as separate journal entries. When the invoice is posted, Odoo automatically creates ONE journal entry that includes all the invoice lines (products, commission, expenses, shipping, etc.).
How Commission and Expense Accounting Works
Modern Workflow (Current Implementation) ✅
1. Creating Customer Invoices
When you create a customer invoice using the "Create Invoice" wizard (wizard/create_invoice_wizard.py):
- Product lines are added from Master Order lines
- Commission line is added based on commission rate (e.g., 10% of product sales)
- Expense lines are added for expenses that should be invoiced to the customer
- Shipping charge line is added if applicable
All of these are added as invoice lines, not as separate journal entries.
2. Posting the Invoice
When you post the invoice using action_post():
- Odoo automatically creates ONE journal entry with multiple lines:
- Debit: Customer Receivable Account (total amount owed by customer)
- Credit: Income accounts for each line:
- Product income account (for products sold)
- Commission income account (for commission)
- Expense income account (for reinvoiced expenses)
- Shipping income account (for shipping charges)
Result: ONE balanced journal entry that includes everything.
3. Example
If you create an invoice with:
- Products: $1,000
- Commission (10%): $100
- Shipping: $50
- Total: $1,150
The posted journal entry will be:
Date Account Debit Credit
---------------------------------------------------------
2024-01-14 Customer Receivable $1,150
2024-01-14 Product Income $1,000
2024-01-14 Commission Income $100
2024-01-14 Shipping Income $50
---------------------------------------------------------
TOTAL $1,150 $1,150 ✅ BALANCED
This is ONE journal entry, not multiple separate entries.
Legacy Methods (DO NOT USE) ❌
The following methods exist in the code but are NEVER called:
_create_commission_journal_entry()inmodels/master_order.py_create_expense_customer_journal_entry()inmodels/master_order.py_create_expenses_journal_entry()inmodels/master_order.py
These were part of an old workflow where commission and expenses were recorded as separate journal entries apart from the invoice. This approach was:
- More complex to manage
- Required manual reconciliation
- Created confusion about whether items were "double-counted"
The old workflow has been completely replaced. These methods are kept only for backward compatibility and are clearly marked as "LEGACY - DO NOT USE".
Why You Might Think There Are "Duplicate" Entries
You may see what looks like duplicate entries in Odoo, but they're actually the same data viewed from different perspectives:
1. Journal Items vs. Invoices
- Accounting > Journal Items: Shows the raw journal entry with all debit/credit lines
- Invoicing > Customer Invoices: Shows the invoice document with line items
These are two views of the SAME data, not duplicates.
2. Analytic Entries
If you have analytic accounting enabled:
- Each invoice line creates an analytic entry on the analytic account
- This is for cost/revenue tracking by project or department
- These are not journal entries, they're analytic distribution records
3. Partner Ledger
When you view the partner ledger for a customer:
- You see the invoice amount as a single line
- If you drill down, you see the invoice line details
- Again, this is the SAME data viewed at different levels of detail
Vendor Bills
The same logic applies to vendor bills:
Creating a Vendor Bill
- Products, shipping costs, and other expenses are added as bill lines
- When posted, Odoo creates ONE journal entry:
- Debit: Expense accounts (for each bill line)
- Credit: Vendor Payable Account (total amount owed to vendor)
Example
If you create a vendor bill for:
- Product purchase: $800
- Shipping cost: $50
- Total: $850
The posted journal entry will be:
Date Account Debit Credit
---------------------------------------------------------
2024-01-14 Product Expense $800
2024-01-14 Shipping Expense $50
2024-01-14 Vendor Payable $850
---------------------------------------------------------
TOTAL $850 $850 ✅ BALANCED
What To Do If You See Unexpected Journal Entries
If you're seeing journal entries that you think are duplicates:
Step 1: Check the Journal Entry Source
- Go to Accounting > Accounting > Journal Items
- Find the journal entry you think is a duplicate
- Check the Reference field - it will show you where it came from:
INV/2024/00001= Customer InvoiceBILL/2024/00001= Vendor BillMISC/2024/00001= Manual Journal EntryPAYMENT/2024/00001= Payment
Step 2: Verify It's Not the Same Entry
- Check the Date and Amount
- Check the Partner (customer/vendor)
- Check the Journal (Sales, Purchase, Miscellaneous, etc.)
If they match, they're likely the same entry viewed in different places.
Step 3: Check for Manual Entries
If you find entries with the reference pattern MISC/* or similar:
- These might be manual journal entries created by mistake
- Check if they reference the Master Order
- These can be deleted if they're truly duplicates
Best Practices
✅ DO:
- Create invoices/bills using the wizards - they automatically include commission, expenses, and shipping as invoice lines
- Let Odoo create journal entries automatically when you post invoices/bills
- Use the "Journal Items" report to see the full accounting details
- Review the balance - every journal entry should be balanced (Debit = Credit)
❌ DON'T:
- Don't manually create journal entries for commission or expenses - they're already included in the invoice
- Don't use the legacy methods (
_create_commission_journal_entry, etc.) - they're deprecated - Don't panic if you see "multiple" entries - check if they're the same entry in different views
- Don't delete journal entries without understanding their source - they might be legitimate
Technical Details
Code References
Invoice Creation with Commission and Expenses
File: wizard/create_invoice_wizard.py
Method: action_create_invoice()
Lines: 222-255
This is where commission and expense lines are added to the invoice:
# Add commission line (lines 222-239)
if has_commission and total_products > 0:
commission_amount = (total_products * self.commission_rate) / 100.0
if commission_amount > 0:
commission_product = self._get_or_create_commission_product(master)
invoice_vals['invoice_line_ids'].append((0, 0, {
'product_id': commission_product.id,
'name': f'Commission ({self.commission_rate}%)',
'quantity': 1.0,
'price_unit': commission_amount,
# ... (account_id set from product's income account)
}))
# Add expense lines (lines 241-255)
if has_expenses:
for expense in self.expense_ids:
expense_product = self._get_or_create_expense_product(expense, master)
invoice_vals['invoice_line_ids'].append((0, 0, {
'product_id': expense_product.id,
'name': f'{expense.expense_type}: {expense.description}',
'quantity': 1.0,
'price_unit': expense.amount,
# ... (account_id set from product's income account)
}))
Invoice Posting (No Additional Journal Entries Created)
File: models/account_move.py
Method: action_post()
Lines: 947-978
The override only validates balance and syncs bill lines to Master Order. No additional journal entries are created.
def action_post(self):
"""Override to validate invoice balance and sync vendor bill lines to Master Order.
NOTE: Commission and expenses are added as invoice lines (not separate journal entries).
When the invoice is posted, they become part of the invoice's journal entry automatically.
"""
# Validate balance before posting
if self.move_type in ['out_invoice', 'out_refund', 'in_invoice', 'in_refund']:
total_debit = sum(self.line_ids.mapped('debit'))
total_credit = sum(self.line_ids.mapped('credit'))
if abs(total_debit - total_credit) > 0.01:
raise ValidationError(_('The entry is not balanced...'))
res = super().action_post() # Standard Odoo posting - creates the journal entry
# Sync vendor bill lines to MO when bill is posted
if self.move_type == 'in_invoice' and self.master_order_id:
for line in self.invoice_line_ids.filtered(...):
line._sync_to_master_order()
# Create supplier debt record for tracking
if self.move_type == 'in_invoice' and self.master_order_customer_id:
self._create_supplier_debt_record() # This creates a vera.client.supplier record, NOT a journal entry
return res
Summary
The system is working correctly. Commission and expenses are included as invoice lines, and when the invoice is posted, Odoo creates ONE balanced journal entry that includes everything.
If you're seeing what looks like "duplicate" journal entries, they're likely:
- The same entry viewed from different perspectives (Journal Items vs. Invoices)
- Analytic entries (for project/department tracking)
- Different entries for different transactions
If you have specific journal entries you think are duplicates, please provide:
- Journal Entry Reference numbers (e.g.,
MISC/2024/00001) - Dates and amounts
- Partner names
This will help identify if there's an actual issue or just confusion about how the accounting views work.
Last Updated: 2026-01-14 Module: at_master_order Version: 18.0