Tower: upload at_master_order 18.0.10.0 (via marketplace)
This commit is contained in:
285
addons/at_master_order/ACCOUNTING_JOURNAL_ENTRIES_EXPLAINED.md
Normal file
285
addons/at_master_order/ACCOUNTING_JOURNAL_ENTRIES_EXPLAINED.md
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
# 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`):
|
||||||
|
|
||||||
|
1. **Product lines** are added from Master Order lines
|
||||||
|
2. **Commission line** is added based on commission rate (e.g., 10% of product sales)
|
||||||
|
3. **Expense lines** are added for expenses that should be invoiced to the customer
|
||||||
|
4. **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**:
|
||||||
|
|
||||||
|
1. `_create_commission_journal_entry()` in `models/master_order.py`
|
||||||
|
2. `_create_expense_customer_journal_entry()` in `models/master_order.py`
|
||||||
|
3. `_create_expenses_journal_entry()` in `models/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
|
||||||
|
|
||||||
|
1. Products, shipping costs, and other expenses are added as **bill lines**
|
||||||
|
2. 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
|
||||||
|
|
||||||
|
1. Go to **Accounting > Accounting > Journal Items**
|
||||||
|
2. Find the journal entry you think is a duplicate
|
||||||
|
3. Check the **Reference** field - it will show you where it came from:
|
||||||
|
- `INV/2024/00001` = Customer Invoice
|
||||||
|
- `BILL/2024/00001` = Vendor Bill
|
||||||
|
- `MISC/2024/00001` = Manual Journal Entry
|
||||||
|
- `PAYMENT/2024/00001` = Payment
|
||||||
|
|
||||||
|
### Step 2: Verify It's Not the Same Entry
|
||||||
|
|
||||||
|
1. Check the **Date** and **Amount**
|
||||||
|
2. Check the **Partner** (customer/vendor)
|
||||||
|
3. 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:
|
||||||
|
|
||||||
|
1. **Create invoices/bills using the wizards** - they automatically include commission, expenses, and shipping as invoice lines
|
||||||
|
2. **Let Odoo create journal entries automatically** when you post invoices/bills
|
||||||
|
3. **Use the "Journal Items" report** to see the full accounting details
|
||||||
|
4. **Review the balance** - every journal entry should be balanced (Debit = Credit)
|
||||||
|
|
||||||
|
### ❌ DON'T:
|
||||||
|
|
||||||
|
1. **Don't manually create journal entries** for commission or expenses - they're already included in the invoice
|
||||||
|
2. **Don't use the legacy methods** (`_create_commission_journal_entry`, etc.) - they're deprecated
|
||||||
|
3. **Don't panic if you see "multiple" entries** - check if they're the same entry in different views
|
||||||
|
4. **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:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 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**.
|
||||||
|
|
||||||
|
```python
|
||||||
|
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:
|
||||||
|
1. The same entry viewed from different perspectives (Journal Items vs. Invoices)
|
||||||
|
2. Analytic entries (for project/department tracking)
|
||||||
|
3. 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
|
||||||
Reference in New Issue
Block a user