237 lines
6.9 KiB
Markdown
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
|
|
```
|