vendor_payment_diff_amount/SCENARIOS.md
2025-12-06 10:24:16 +07:00

237 lines
6.9 KiB
Markdown

# 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
```python
# 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
```python
# 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
```