vendor_payment_diff_amount/SCENARIOS.md

6.9 KiB

Payment Scenarios with Deductions

This document explains how the module handles different payment scenarios.

Scenario 1: Payment WITHOUT Expense Account

When you create a vendor payment without setting an expense account, the system uses the standard vendor payable account.

Example:

  • Vendor: PT Telkom Indonesia
  • Amount: Rp 2,000,000
  • Deductions:
    • PPh 21: Rp 100,000
    • PPh 29: Rp 50,000
  • Final Payment: Rp 1,850,000

Journal Entry:

Account                              | Debit           | Credit
-------------------------------------|-----------------|------------------
Accounts Payable - PT Telkom         | Rp 2,000,000.00 |
PPh 21 (Tax Payable)                 |                 | Rp 100,000.00
PPh 29 (Tax Payable)                 |                 | Rp 50,000.00
Bank Account                         |                 | Rp 1,850,000.00
-------------------------------------|-----------------|------------------
TOTAL                                | Rp 2,000,000.00 | Rp 2,000,000.00

Explanation:

  • The Accounts Payable line uses the vendor's payable account (from partner configuration)
  • The payable account has the partner_id set (PT Telkom Indonesia)
  • This is the standard Odoo behavior, just with deductions added

Scenario 2: Payment WITH Expense Account

When you create a vendor payment with an expense account set, the system uses that expense account instead of the payable account.

Example:

  • Vendor: PT Telkom Indonesia
  • Amount: Rp 2,000,000
  • Expense Account: 611505 Telepon & Internet
  • Deductions:
    • PPh 21: Rp 100,000
    • PPh 29: Rp 50,000
  • Final Payment: Rp 1,850,000

Journal Entry:

Account                              | Debit           | Credit
-------------------------------------|-----------------|------------------
611505 Telepon & Internet (Expense)  | Rp 2,000,000.00 |
PPh 21 (Tax Payable)                 |                 | Rp 100,000.00
PPh 29 (Tax Payable)                 |                 | Rp 50,000.00
Bank Account                         |                 | Rp 1,850,000.00
-------------------------------------|-----------------|------------------
TOTAL                                | Rp 2,000,000.00 | Rp 2,000,000.00

Explanation:

  • The Expense Account replaces the payable account
  • This allows direct expense recording without going through payables
  • The expense account still has the partner_id set for tracking
  • This is useful for immediate expense recognition

Key Differences

Aspect Without Expense Account With Expense Account
Counterpart Account Accounts Payable Expense Account
Account Type liability_payable expense
Partner Required Yes Yes
Use Case Standard vendor payment Direct expense recording
Payable Created Yes No

When to Use Each Scenario

Use WITHOUT Expense Account when:

  • You want to track vendor payables
  • You need to reconcile with vendor bills
  • You're following standard AP workflow
  • You need aging reports for vendors

Use WITH Expense Account when:

  • You want immediate expense recognition
  • You don't need to track payables
  • You're making direct payments (no bill)
  • You want simplified accounting

Technical Notes

Module Integration

This module (vendor_payment_diff_amount) works seamlessly with vendor_batch_payment_merge:

  1. vendor_batch_payment_merge provides the expense_account_id field
  2. vendor_payment_diff_amount adds deduction functionality
  3. Both modules modify _prepare_move_line_default_vals() method
  4. The methods are called in sequence (inheritance chain)

Method Call Order

1. Standard Odoo: Creates basic 2-line entry (bank + payable)
2. vendor_batch_payment_merge: Replaces payable with expense (if set)
3. vendor_payment_diff_amount: Adds deduction lines and adjusts bank

Result

Final journal entry has:

  • 1 debit line (payable or expense at original amount)
  • N credit lines (one per deduction)
  • 1 credit line (bank at final_payment_amount)

Total: 2 + N lines (where N = number of deductions)


Validation Rules

The module ensures:

  1. Counterpart line always has partner_id set
  2. Counterpart line stays at original amount
  3. Bank line reduced to final_payment_amount
  4. Deduction lines are credits
  5. Deduction lines only have partner_id if account type requires it (payable/receivable)
  6. Entry is balanced (total debit = total credit)
  7. All required fields are present

Troubleshooting

Error: "Missing required account on accountable line"

Cause: An accountable line (payable/receivable account) is missing the required partner_id field.

Solution: The module now automatically handles this:

  • Counterpart line (payable/expense) always has partner_id set
  • Deduction lines only have partner_id if the account type requires it
  • Tax accounts (liability/expense) don't need partner_id

If you still see this error:

  1. Check that the partner has a payable account configured
  2. Check that the expense account (if used) is valid
  3. Verify the payment has a partner selected
  4. Ensure deduction accounts are NOT payable/receivable accounts (use tax/expense accounts instead)

Error: "Entry is not balanced"

Cause: The debit and credit totals don't match.

Solution: This should not happen with the current implementation. If it does:

  1. Check that all deduction amounts are positive
  2. Verify currency conversion is working
  3. Check for rounding issues

Examples

Example 1: Simple Payment with One Deduction

# Create payment
payment = env['account.payment'].create({
    'payment_type': 'outbound',
    'partner_type': 'supplier',
    'partner_id': partner.id,
    'amount': 1000.0,
    'journal_id': bank_journal.id,
})

# Add deduction
env['payment.deduction.line'].create({
    'payment_id': payment.id,
    'amount_substract': 100.0,
    'substract_account_id': tax_account.id,
    'name': 'Withholding Tax',
})

# Post payment
payment.action_post()

# Result:
# - Payable: Debit 1000
# - Tax: Credit 100
# - Bank: Credit 900

Example 2: Payment with Expense Account and Multiple Deductions

# Create payment with expense account
payment = env['account.payment'].create({
    'payment_type': 'outbound',
    'partner_type': 'supplier',
    'partner_id': partner.id,
    'amount': 2000.0,
    'expense_account_id': expense_account.id,
    'journal_id': bank_journal.id,
})

# Add multiple deductions
env['payment.deduction.line'].create({
    'payment_id': payment.id,
    'amount_substract': 100.0,
    'substract_account_id': pph21_account.id,
    'name': 'PPh 21',
})

env['payment.deduction.line'].create({
    'payment_id': payment.id,
    'amount_substract': 50.0,
    'substract_account_id': pph29_account.id,
    'name': 'PPh 29',
})

# Post payment
payment.action_post()

# Result:
# - Expense: Debit 2000
# - PPh 21: Credit 100
# - PPh 29: Credit 50
# - Bank: Credit 1850