Files
odoo-addons/addons/at_master_order/INVOICE_EXPENSE_DESIGN.md

51 KiB
Raw Blame History

Invoice Expense Tracking - Design Document

Overview

Track expenses paid on behalf of customers directly on invoices, with automatic accounting settlement.

Key Concept: "Customer Fund" is conceptual - it means "expenses we'll charge to the customer". It's a monitoring/tracking mechanism, NOT a deposit account. Customer deposits are handled by a separate module.


Design Decisions

Decision Choice Rationale
Invoice Line Account Uses same Asset account (Customer Expenses Receivable) Directly credits/settles the asset
Tax Treatment No tax on expenses Pass-through charges, not revenue
Currency Single currency only Simplified implementation
Partial Addition Not allowed One expense = One invoice line
Expense Splitting Not allowed Create multiple expenses instead
Payment Source Always Bank No need to track source (customer deposits handled separately)
Invoice-MO Link Required Invoice must be linked to Master Order
Settlement Automatic when added to invoice Asset account credited
Collection Standard AR process Sales team follows up with customer
Default Expense Type Customer Expense invoice_to_customer = True by default

Business Flow

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           EXPENSE TRACKING FLOW                                  │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                  │
│  1. PAY EXPENSE                    2. TRACK ON INVOICE                           │
│  ───────────────                   ────────────────────                          │
│                                                                                  │
│  Company pays on behalf            Record expense on                             │
│  of customer:                      customer invoice:                             │
│                                                                                  │
│  • Certificate Fee: $100           Invoice #INV/2026/001                         │
│  • Customs: $200                   ├── Products: $5,000                          │
│  • Documentation: $50              ├── Certificate Fee: $100                     │
│                                    ├── Customs: $200                             │
│  Paid from:                        └── Documentation: $50                        │
│  Bank / Customer Expenses Fund                                                   │
│                                    TOTAL: $5,350                                 │
│                                                                                  │
│                                                                                  │
│  3. CUSTOMER PAYS                  4. SETTLEMENT                                 │
│  ────────────────                  ───────────────                               │
│                                                                                  │
│  Customer pays invoice             Expense account is                            │
│  total: $5,350                     automatically settled                         │
│                                                                                  │
│  ✅ Products paid                  ✅ No manual reconciliation                   │
│  ✅ Expenses reimbursed            ✅ Clean accounting                           │
│                                                                                  │
└─────────────────────────────────────────────────────────────────────────────────┘

Accounting Entries

Step 1: Pay Expense (Manual or Bank Transaction)

When company pays expense on behalf of customer:

Account Debit Credit
Customer Expenses Receivable (Asset) $100
Bank Account $100

Step 2: Create Invoice with Expense

When expense is added to customer invoice:

Account Debit Credit
Accounts Receivable (Customer) $5,100
Sales Revenue $5,000
Customer Expenses Receivable (Asset) $100

Result: Expense receivable is credited (settled)


Expense Types - Customer vs Company

Two Types of Expenses

Type invoice_to_customer Account Used Can Add to Invoice?
Customer Expense (Default) True Customer Expenses Receivable (Asset) Yes
Company Expense ☐ False Company Expense Account (P&L) No

Default Behavior

┌─────────────────────────────────────────────────────────────────┐
│  CREATE EXPENSE                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Expense Type:        [Shipping ▼]                              │
│  Description:         [Certificate Fee             ]            │
│  Amount:              [$100                        ]            │
│  Date:                [2026-01-10                  ]            │
│                                                                 │
│  ☑️ Invoice to Customer   ← DEFAULT IS CHECKED                  │
│     └─ Checked: Customer pays (Asset account)                   │
│     └─ Unchecked: Company absorbs (P&L account)                 │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Customer Expense Flow (Default)

Payment:  Debit: Customer Expenses Receivable (Asset)
          Credit: Bank

Settlement: Add to customer invoice
            → Asset credited (zeroed)
            → Customer owes via AR

Company Expense Flow (Unchecked)

Payment:  Debit: Company Expense Account (P&L)
          Credit: Bank

No settlement needed - direct expense recognition
Cannot be added to customer invoice

Reclassification: Customer → Company (Company Absorbs)

If expense was created as customer expense but company decides to absorb:

Expense Status Action Accounting
Not on invoice Click [Company Absorbs] Debit P&L, Credit Asset
On draft invoice Remove from invoice first, then reclassify Remove line + Debit P&L, Credit Asset
On posted invoice Create Credit Note + Reclassify Reverse AR + Move to P&L

Step 3: Customer Pays Invoice

When customer pays the full invoice:

Account Debit Credit
Bank Account $5,100
Accounts Receivable (Customer) $5,100

Result: Full settlement complete


Workflows for Adding Expenses to Invoice

Workflow A: Select Existing Pending Expenses

User creates invoice FIRST, then adds expenses that were already paid earlier.

┌─────────────────────────────────────────────────────────────────┐
│  ADD EXISTING EXPENSE TO INVOICE                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  User is on DRAFT Invoice Form                                  │
│                                                                 │
│  1. Clicks [+ Add Existing Expense] button                      │
│                                                                 │
│  2. System shows selection wizard:                              │
│     ┌─────────────────────────────────────────────────────────┐ │
│     │  SELECT PENDING EXPENSES                                │ │
│     │  Customer: ABC Trading Co.                              │ │
│     │                                                         │ │
│     │  ☐ Certificate Fee      $100    Paid: Jan 05            │ │
│     │  ☐ Customs Clearance    $200    Paid: Jan 07            │ │
│     │  ☐ Documentation        $50     Paid: Jan 08            │ │
│     │                                                         │ │
│     │  Filter: Same customer + Status=Pending                 │ │
│     │                                                         │ │
│     │  [Cancel]                    [Add Selected to Invoice]  │ │
│     └─────────────────────────────────────────────────────────┘ │
│                                                                 │
│  3. User selects expenses → System adds invoice lines           │
│                                                                 │
│  4. Expenses marked as "Added to Invoice"                       │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Workflow B: Create New Expense Directly on Invoice (Simplified)

User wants to record an expense and add to invoice. Payment entry is handled separately (manual or already exists).

┌─────────────────────────────────────────────────────────────────┐
│  CREATE & ADD NEW EXPENSE (Simplified)                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  User is on DRAFT Invoice Form                                  │
│                                                                 │
│  1. Clicks [+ Create New Expense] button                        │
│                                                                 │
│  2. System shows creation wizard:                               │
│     ┌─────────────────────────────────────────────────────────┐ │
│     │  CREATE NEW EXPENSE                                     │ │
│     │                                                         │ │
│     │  Expense Account:  [Customer Expenses Receivable ▼]     │ │
│     │                    (pre-filled from configuration)      │ │
│     │  Expense Type:     [Shipping / Customs / Other ▼]       │ │
│     │  Description:      [Certificate Fee            ]        │ │
│     │  Amount:           [$100                       ]        │ │
│     │  Date:             [2026-01-10                 ]        │ │
│     │                                                         │ │
│     │   Payment entry should be created separately          │ │
│     │                                                         │ │
│     │  [Cancel]                      [Create & Add to Invoice]│ │
│     └─────────────────────────────────────────────────────────┘ │
│                                                                 │
│  3. System creates:                                             │
│     a) Expense record (linked to Master Order from invoice)     │
│     b) Invoice line (using Asset account = settlement)          │
│                                                                 │
│  Note: Payment journal entry is NOT auto-created.               │
│        User creates payment entry manually/separately.          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Note: In this simplified workflow, the expense is created and immediately added to invoice. The payment entry (Debit Asset, Credit Bank) must be handled separately by the user. This keeps the system simple and flexible.


Edge Cases & Business Rules

State-Based Rules

Invoice State Add Existing Expense Create New Expense Remove Expense
DRAFT Allowed Allowed Allowed
POSTED Blocked Blocked Blocked
CANCELLED Blocked Blocked N/A

Edge Case Solutions

Edge Case Decision Solution
Partial expense addition Not allowed Create multiple expenses at start
Remove from DRAFT invoice Allowed Reset expense status to "Pending"
Remove from POSTED invoice Not allowed Must use Credit Note workflow
Split expense across invoices Not allowed Create multiple expense records
Add to POSTED invoice Not allowed Create new supplementary invoice
Edit amount (not invoiced) Allowed Direct edit on expense
Edit amount (on draft invoice) Requires steps Remove → Edit → Re-add
Edit amount (on posted invoice) Not allowed Credit Note required
Invoice cancelled Auto-reset All expenses return to "Pending"
Customer mismatch Blocked Validation error prevents action

Remove Expense from Draft Invoice

┌─────────────────────────────────────────────────────────────────┐
│  REMOVE EXPENSE FROM DRAFT INVOICE                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. User clicks [Remove] on expense line                        │
│                                                                 │
│  2. System actions:                                             │
│     • Delete the corresponding invoice line                     │
│     • Reset expense: added_to_invoice = False                   │
│     • Clear links: invoice_id = False, invoice_line_id = False  │
│                                                                 │
│  3. Result:                                                     │
│     • Expense returns to "Pending" status                       │
│     • Can be added to different invoice                         │
│     • Invoice total recalculates automatically                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Correct Expense on Posted Invoice (Credit Note Flow)

┌─────────────────────────────────────────────────────────────────┐
│  CORRECT EXPENSE ON POSTED INVOICE                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Cannot directly modify posted invoice. Steps:                  │
│                                                                 │
│  1. Create Credit Note for the expense amount only              │
│     • Debits: Customer Expenses Receivable (reverses credit)    │
│     • Credits: Accounts Receivable (reduces customer balance)   │
│                                                                 │
│  2. Post the Credit Note                                        │
│                                                                 │
│  3. Create new invoice with expense on correct customer         │
│     (if needed)                                                 │
│                                                                 │
│  Result: Original expense receivable is restored, can be        │
│          properly re-invoiced                                   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Invoice Cancellation - Expense Handling

┌─────────────────────────────────────────────────────────────────┐
│  INVOICE CANCELLATION                                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  When invoice is cancelled, system automatically:               │
│                                                                 │
│  1. Resets ALL linked expenses:                                 │
│     • added_to_invoice = False                                  │
│     • invoice_id = False                                        │
│     • invoice_line_id = False                                   │
│                                                                 │
│  2. Expenses return to "Pending" status                         │
│                                                                 │
│  3. Expenses can be added to new invoice later                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Customer Validation Rule

Validation: Expense.master_order_id.partner_id == Invoice.partner_id

If mismatch → Block with error:
"Expense belongs to [Customer A] but invoice is for [Customer B]"

Company Absorbs Cost (Reclassification)

When expense should NOT be charged to customer:

Original Entry:
  Debit: Customer Expenses Receivable    $100
  Credit: Bank                           $100

Reclassification Entry:
  Debit: Company Expense Account         $100
  Credit: Customer Expenses Receivable   $100

Result: Cost moved from asset to company expense

Data Model

Expense Model (Simplified)

class MasterOrderExpense(models.Model):
    _name = 'at.master.order.expense'
    
    # Links
    master_order_id = fields.Many2one('at.master.order')
    invoice_id = fields.Many2one('account.move')  # NEW - link to invoice
    
    # Expense Details
    expense_account_id = fields.Many2one('account.account')  # PRIMARY - select from COA
    description = fields.Char('Description')
    amount = fields.Float('Amount')
    date = fields.Date('Date')
    
    # Status
    added_to_invoice = fields.Boolean('Added to Invoice')  # Track if converted to invoice line
    invoice_line_id = fields.Many2one('account.move.line')  # Link to created invoice line

Invoice Model (Extended)

class AccountMove(models.Model):
    _inherit = 'account.move'
    
    # Expense tracking
    expense_ids = fields.One2many('at.master.order.expense', 'invoice_id')
    
    # Computed totals
    invoice_total_expenses = fields.Float(compute='_compute_expense_totals')

UI Design

1. Invoice Form - Expenses Tab (DRAFT)

┌───────────────────────────────────────────────────────────────────────────────────┐
│  📋 CUSTOMER INVOICE (DRAFT)                                    INV/2026/00123    │
├───────────────────────────────────────────────────────────────────────────────────┤
│  Customer: ABC Trading Co.          │  Invoice Date: 2026-01-10                   │
│  Master Order: MO/2026/00045        │  Due Date: 2026-02-10                       │
├───────────────────────────────────────────────────────────────────────────────────┤
│                                                                                    │
│  [Invoice Lines]  [Expenses]  [Other Info]                                        │
│  ════════════════════════════════════════════════════════════════════════════════ │
│                                                                                    │
│  EXPENSES ON THIS INVOICE                                                          │
│  ┌────────────────────────┬─────────────────┬──────────┬──────────┬─────────────┐ │
│  │  Type                  │  Description    │  Amount  │  Date    │  Action     │ │
│  ├────────────────────────┼─────────────────┼──────────┼──────────┼─────────────┤ │
│  │  Customs               │ Import Duty     │  $200    │ Jan 05   │  [Remove]   │ │
│  │  Documentation         │ Certificate Fee │  $100    │ Jan 07   │  [Remove]   │ │
│  │  Shipping              │ Air Freight     │  $350    │ Jan 08   │  [Remove]   │ │
│  └────────────────────────┴─────────────────┴──────────┴──────────┴─────────────┘ │
│                                                         Expenses Total:  $650     │
│                                                                                    │
│  [+ Add Existing Expense]     [+ Create New Expense]                              │
│                                                                                    │
│  ════════════════════════════════════════════════════════════════════════════════ │
│                                                                                    │
│  PENDING EXPENSES (Not Yet Added)                                                  │
│  ┌────────────────────────┬─────────────────┬──────────┬──────────┬─────────────┐ │
│  │  Type                  │  Description    │  Amount  │  Date    │  Action     │ │
│  ├────────────────────────┼─────────────────┼──────────┼──────────┼─────────────┤ │
│  │  Handling              │ Warehouse Fee   │  $75     │ Jan 09   │  [+ Add]    │ │
│  │  Other                 │ Inspection      │  $50     │ Jan 10   │  [+ Add]    │ │
│  └────────────────────────┴─────────────────┴──────────┴──────────┴─────────────┘ │
│                                                          Pending Total:  $125     │
│                                                                                    │
│  ════════════════════════════════════════════════════════════════════════════════ │
│                                                                                    │
│  SUMMARY                                                                           │
│  ┌─────────────────────────────────────────────────────────────────────────────┐  │
│  │  Product Lines:              $5,000                                         │  │
│  │  Expenses on Invoice:        $650                                           │  │
│  │  ─────────────────────────────────                                          │  │
│  │  INVOICE TOTAL:              $5,650                                         │  │
│  └─────────────────────────────────────────────────────────────────────────────┘  │
│                                                                                    │
└───────────────────────────────────────────────────────────────────────────────────┘

2. Invoice Form - Expenses Tab (POSTED - Read Only)

┌───────────────────────────────────────────────────────────────────────────────────┐
│  📋 CUSTOMER INVOICE (POSTED)                                   INV/2026/00123    │
├───────────────────────────────────────────────────────────────────────────────────┤
│  Customer: ABC Trading Co.          │  Invoice Date: 2026-01-10                   │
│  Master Order: MO/2026/00045        │  Status: Posted ✓                           │
├───────────────────────────────────────────────────────────────────────────────────┤
│                                                                                    │
│  [Invoice Lines]  [Expenses]  [Other Info]                                        │
│  ════════════════════════════════════════════════════════════════════════════════ │
│                                                                                    │
│  EXPENSES ON THIS INVOICE                           (Read-only - Invoice Posted)  │
│  ┌────────────────────────┬─────────────────┬──────────┬──────────┬─────────────┐ │
│  │  Type                  │  Description    │  Amount  │  Date    │  Status     │ │
│  ├────────────────────────┼─────────────────┼──────────┼──────────┼─────────────┤ │
│  │  Customs               │ Import Duty     │  $200    │ Jan 05   │  ✓ Settled  │ │
│  │  Documentation         │ Certificate Fee │  $100    │ Jan 07   │  ✓ Settled  │ │
│  │  Shipping              │ Air Freight     │  $350    │ Jan 08   │  ✓ Settled  │ │
│  └────────────────────────┴─────────────────┴──────────┴──────────┴─────────────┘ │
│                                                         Expenses Total:  $650     │
│                                                                                    │
│  ⚠️ Invoice is posted. To modify expenses, create a Credit Note.                  │
│                                                                                    │
└───────────────────────────────────────────────────────────────────────────────────┘

3. Master Order - Expenses Section

┌───────────────────────────────────────────────────────────────────────────────────┐
│  📦 MASTER ORDER                                                MO/2026/00045     │
├───────────────────────────────────────────────────────────────────────────────────┤
│                                                                                    │
│  [Order Info]  [Lines]  [Expenses]  [Invoices]  [Shipments]                       │
│  ════════════════════════════════════════════════════════════════════════════════ │
│                                                                                    │
│  EXPENSES                                                         [+ Add Expense] │
│  ┌────────────┬─────────────────┬──────────┬──────────┬───────────┬─────────────┐ │
│  │  Type      │  Description    │  Amount  │  Date    │  Invoice  │  Status     │ │
│  ├────────────┼─────────────────┼──────────┼──────────┼───────────┼─────────────┤ │
│  │  Customs   │ Import Duty     │  $200    │ Jan 05   │ INV/00123 │ ✓ Invoiced  │ │
│  │  Docs      │ Certificate Fee │  $100    │ Jan 07   │ INV/00123 │ ✓ Invoiced  │ │
│  │  Shipping  │ Air Freight     │  $350    │ Jan 08   │ INV/00123 │ ✓ Invoiced  │ │
│  │  Handling  │ Warehouse Fee   │  $75     │ Jan 09   │    -      │ ⏳ Pending  │ │
│  │  Other     │ Samples         │  $50     │ Jan 10   │    -      │ 🏢 Company  │ │
│  └────────────┴─────────────────┴──────────┴──────────┴───────────┴─────────────┘ │
│                                                                                    │
│  ════════════════════════════════════════════════════════════════════════════════ │
│                                                                                    │
│  EXPENSE SUMMARY                                                                   │
│  ┌─────────────────────────────────────────────────────────────────────────────┐  │
│  │  Total Customer Expenses:     $725    (charged to customer)                 │  │
│  │    - Invoiced:                $650    ✓                                     │  │
│  │    - Pending:                 $75     ⏳                                    │  │
│  │                                                                             │  │
│  │  Total Company Expenses:      $50     (company absorbed)                    │  │
│  └─────────────────────────────────────────────────────────────────────────────┘  │
│                                                                                    │
└───────────────────────────────────────────────────────────────────────────────────┘

4. Create Expense Form (Popup/Wizard)

┌─────────────────────────────────────────────────────────────────┐
│  CREATE NEW EXPENSE                                       [X]   │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Expense Type:        [Customs                         ▼]       │
│                                                                 │
│  Description:         [Import duty for shipment        ]        │
│                                                                 │
│  Amount:              [$200.00                         ]        │
│                                                                 │
│  Date:                [2026-01-10                      ]        │
│                                                                 │
│  Expense Account:     [1300 - Customer Exp. Receivable ▼]       │
│                       (pre-filled from settings)                │
│                                                                 │
│  ─────────────────────────────────────────────────────────────  │
│                                                                 │
│  ☑️ Invoice to Customer                                         │
│     ├─ ✓ Checked: Customer will be charged (default)            │
│     └─ ☐ Unchecked: Company absorbs cost                        │
│                                                                 │
│  ─────────────────────────────────────────────────────────────  │
│                                                                 │
│           [Cancel]                    [Create Expense]          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

5. Select Existing Expenses Wizard

┌─────────────────────────────────────────────────────────────────┐
│  SELECT EXPENSES TO ADD                                   [X]   │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Invoice: INV/2026/00123                                        │
│  Customer: ABC Trading Co.                                      │
│                                                                 │
│  ─────────────────────────────────────────────────────────────  │
│                                                                 │
│  AVAILABLE PENDING EXPENSES                                     │
│  ┌────┬────────────┬─────────────────┬──────────┬────────────┐  │
│  │ ☐  │  Type      │  Description    │  Amount  │  Date      │  │
│  ├────┼────────────┼─────────────────┼──────────┼────────────┤  │
│  │ ☑️ │  Handling  │ Warehouse Fee   │  $75     │ Jan 09     │  │
│  │ ☑️ │  Other     │ Inspection      │  $50     │ Jan 10     │  │
│  │ ☐  │  Shipping  │ Local Delivery  │  $30     │ Jan 11     │  │
│  └────┴────────────┴─────────────────┴──────────┴────────────┘  │
│                                                                 │
│                                        Selected Total: $125     │
│                                                                 │
│  ─────────────────────────────────────────────────────────────  │
│                                                                 │
│           [Cancel]              [Add Selected to Invoice]       │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

6. Company Absorbs Action (Reclassification)

┌─────────────────────────────────────────────────────────────────┐
│  COMPANY ABSORBS EXPENSE                                  [X]   │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Expense: Samples for client                                    │
│  Amount: $50                                                    │
│                                                                 │
│  ─────────────────────────────────────────────────────────────  │
│                                                                 │
│  ⚠️ This will:                                                  │
│     • Move expense from Customer to Company                     │
│     • Create reclassification journal entry                     │
│     • Expense will NOT be charged to customer                   │
│                                                                 │
│  Reclassification Entry:                                        │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │  Debit:  Company Expense (P&L)              $50         │    │
│  │  Credit: Customer Expenses Receivable       $50         │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                 │
│  ─────────────────────────────────────────────────────────────  │
│                                                                 │
│           [Cancel]                    [Confirm - Company Pays]  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Configuration

Default Customer Expense Account Setting

Use existing settings pattern in models/settings.py:

Parameter: at_master_order.customer_expense_account_id

┌─────────────────────────────────────────────────────────────────┐
│  MASTER ORDER SETTINGS → Account Configuration                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Commission Income Account:     [4100 - Commission Income ▼]    │
│  Shipping Revenue Account:      [4200 - Shipping Revenue ▼]     │
│  Shipping Expense Account:      [5100 - Shipping Expense ▼]     │
│  Other Expense Account:         [5200 - Other Expenses ▼]       │
│                                                                 │
│  ─── NEW ───                                                     │
│  Customer Expense Account:      [1300 - Cust. Exp. Receivable ▼]│
│                                                                 │
│   Used for expenses paid on behalf of customers.              │
│     Debited when expense is paid, credited when added to        │
│     customer invoice for settlement.                            │
│                                                                 │
│  Account Filter: Asset accounts only                            │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Implementation (Existing Pattern)

File: models/settings.py

Section Add
Field definition (line ~35) customer_expense_account_id = fields.Many2one('account.account', ...)
get_values() (line ~145) Read from at_master_order.customer_expense_account_id
set_values() (line ~190) Write to at_master_order.customer_expense_account_id

File: models/expense_box.py

Section Add
get_expense_account() Add fallback to at_master_order.customer_expense_account_id
Setting Behavior Description
Pre-fills expense account When creating expense, this account is selected by default
User can override Default is convenience, not mandatory
Follows existing pattern Same as other account configurations

Chart of Accounts

Account Code Account Name Type Purpose
1300 Customer Expenses Receivable Asset (Receivable) Track expenses paid on behalf of customers

Alternative names:

  • Customer Advances
  • Customer Expense Fund
  • Prepaid Customer Expenses

Implementation Tasks

Phase 0: Configuration

# Task File Status
0 Add customer_expense_account_id field to settings models/settings.py
0b Add to get_values() method models/settings.py
0c Add to set_values() method models/settings.py
0d Add field to settings view (if exists) views/master_order_config_views.xml

Phase 1: Model Changes

# Task File Status
1 Add invoice_id field to expense model models/expense_box.py
2 Add added_to_invoice, invoice_line_id fields models/expense_box.py
3 Add expense_id field to invoice line (reverse link) models/account_move.py
4 Add expense_ids One2many to account.move models/account_move.py
5 Add computed expense totals models/account_move.py
6 Add action_add_to_invoice() method models/expense_box.py
7 Add action_remove_from_invoice() method models/expense_box.py
8 Override invoice cancel to reset expenses models/account_move.py
9 Add customer validation on expense add models/expense_box.py
10 Use default account in expense creation models/expense_box.py

Phase 2: Wizard Development

# Task File Status
10 Create "Select Existing Expense" wizard wizard/add_expense_to_invoice_wizard.py
11 Create "Create New Expense" wizard wizard/create_expense_wizard.py
12 Wizard views wizard/expense_wizard_views.xml

Phase 3: View Changes

# Task File Status
13 Add Expenses section to invoice form views/invoice_expense_views.xml
14 Add wizard buttons (draft state only) views/invoice_expense_views.xml
15 Add pending expenses quick list views/invoice_expense_views.xml
16 State-based visibility (draft vs posted) views/invoice_expense_views.xml

Phase 4: Testing & Deployment

# Task Status
17 Test Workflow A: Select existing expense
18 Test Workflow B: Create new expense on invoice
19 Test remove expense from draft invoice
20 Test invoice cancellation resets expenses
21 Test customer validation
22 Test accounting entries (settlement)
23 Deploy to aspir database

Key Features

Feature Description
Expense Account Selection Choose any account from COA
Track on Invoice Link expenses to specific customer invoice
Add to Invoice Line Convert expense to invoice line for billing
Auto Settlement Expense account settles when customer pays
Aggregate to MO Expenses also visible at Master Order level

Notes

  1. No Vendor Bills - This is for expenses paid directly, not through vendor bills
  2. Simple Tracking - Just account + description + amount
  3. Flexible Accounts - Use any expense/asset account from COA
  4. Automatic Settlement - Adding to invoice creates the settlement entry

Approval

  • Design approved by user
  • Option A: Invoice line uses Asset account (settlement)
  • No tax treatment
  • Single currency only
  • Workflow A + B confirmed
  • Edge cases reviewed and approved
  • Ready for implementation
  • Implementation Complete (2026-01-10)