remove some files
This commit is contained in:
parent
82cb6c5c1b
commit
53e95fb370
263
FINAL_FIX.md
263
FINAL_FIX.md
@ -1,263 +0,0 @@
|
|||||||
# Final Fix: "Missing required account on accountable line"
|
|
||||||
|
|
||||||
## Problem Solved
|
|
||||||
|
|
||||||
The error "Missing required account on accountable line" has been resolved by ensuring proper `partner_id` handling on journal entry lines.
|
|
||||||
|
|
||||||
## Root Cause Analysis
|
|
||||||
|
|
||||||
Odoo's validation requires that:
|
|
||||||
1. Lines with **payable/receivable accounts** MUST have `partner_id`
|
|
||||||
2. Lines with **other account types** should NOT have `partner_id` (or it's optional)
|
|
||||||
|
|
||||||
The error occurred because the journal entry had inconsistent `partner_id` assignments.
|
|
||||||
|
|
||||||
## Complete Solution
|
|
||||||
|
|
||||||
### 1. Counterpart Line (Payable/Expense)
|
|
||||||
|
|
||||||
**Always set `partner_id`** on the counterpart line:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# CRITICAL: Always ensure partner_id is set on counterpart line
|
|
||||||
counterpart_line['partner_id'] = self.partner_id.id
|
|
||||||
|
|
||||||
# Also ensure the account_id is set
|
|
||||||
if not counterpart_line.get('account_id'):
|
|
||||||
counterpart_line['account_id'] = self.destination_account_id.id
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Deduction Lines (Tax/Expense)
|
|
||||||
|
|
||||||
**Never set `partner_id`** on deduction lines:
|
|
||||||
|
|
||||||
```python
|
|
||||||
deduction_line = {
|
|
||||||
'name': deduction_line_name,
|
|
||||||
'date_maturity': self.date,
|
|
||||||
'amount_currency': -deduction.amount_substract,
|
|
||||||
'currency_id': self.currency_id.id,
|
|
||||||
'debit': 0.0,
|
|
||||||
'credit': deduction_balance,
|
|
||||||
'account_id': deduction.substract_account_id.id,
|
|
||||||
# No partner_id - deduction accounts are tax/expense accounts
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Account Domain Restriction
|
|
||||||
|
|
||||||
**Prevent wrong account selection** by updating the domain:
|
|
||||||
|
|
||||||
```python
|
|
||||||
domain="[('account_type', 'not in', ['asset_cash', 'asset_cash_bank', 'asset_receivable', 'liability_payable']), ('deprecated', '=', False)]"
|
|
||||||
```
|
|
||||||
|
|
||||||
This prevents users from selecting:
|
|
||||||
- ❌ Cash/Bank accounts
|
|
||||||
- ❌ Accounts Receivable
|
|
||||||
- ❌ Accounts Payable
|
|
||||||
|
|
||||||
And allows only:
|
|
||||||
- ✅ Tax Payable accounts (liability_current)
|
|
||||||
- ✅ Expense accounts
|
|
||||||
- ✅ Other liability accounts
|
|
||||||
- ✅ Income accounts (if needed)
|
|
||||||
|
|
||||||
## Correct Journal Entry Structure
|
|
||||||
|
|
||||||
### Example: Payment Rp 2,000,000 with deductions
|
|
||||||
|
|
||||||
**Scenario:**
|
|
||||||
- Vendor: PT Telkom Indonesia
|
|
||||||
- Amount: Rp 2,000,000
|
|
||||||
- PPh 21: Rp 100,000 (Tax Payable account)
|
|
||||||
- PPh 29: Rp 50,000 (Tax Payable account)
|
|
||||||
- Final Payment: Rp 1,850,000
|
|
||||||
|
|
||||||
**Journal Entry:**
|
|
||||||
|
|
||||||
| Account | Type | Debit | Credit | Partner | Valid? |
|
|
||||||
|---------|------|-------|--------|---------|--------|
|
|
||||||
| Accounts Payable | liability_payable | 2,000,000 | | PT Telkom | ✅ Required |
|
|
||||||
| PPh 21 | liability_current | | 100,000 | (none) | ✅ Correct |
|
|
||||||
| PPh 29 | liability_current | | 50,000 | (none) | ✅ Correct |
|
|
||||||
| Bank | asset_cash | | 1,850,000 | (none) | ✅ Correct |
|
|
||||||
|
|
||||||
**Total:** Debit 2,000,000 = Credit 2,000,000 ✅ Balanced
|
|
||||||
|
|
||||||
## Why This Works
|
|
||||||
|
|
||||||
### Odoo's Validation Logic
|
|
||||||
|
|
||||||
Odoo checks each journal entry line:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Pseudo-code of Odoo's validation
|
|
||||||
for line in journal_entry.lines:
|
|
||||||
if line.account.account_type in ('asset_receivable', 'liability_payable'):
|
|
||||||
if not line.partner_id:
|
|
||||||
raise ValidationError("Missing required account on accountable line")
|
|
||||||
```
|
|
||||||
|
|
||||||
### Our Solution
|
|
||||||
|
|
||||||
1. **Counterpart line** (Payable): Has `partner_id` ✅
|
|
||||||
2. **Deduction lines** (Tax): No `partner_id`, and account type is NOT payable/receivable ✅
|
|
||||||
3. **Bank line** (Cash): No `partner_id`, and account type is NOT payable/receivable ✅
|
|
||||||
|
|
||||||
All lines pass validation!
|
|
||||||
|
|
||||||
## Account Type Reference
|
|
||||||
|
|
||||||
### Account Types in Odoo 17
|
|
||||||
|
|
||||||
| Account Type | Code | Requires Partner? | Use for Deductions? |
|
|
||||||
|--------------|------|-------------------|---------------------|
|
|
||||||
| Accounts Receivable | asset_receivable | ✅ Yes | ❌ No |
|
|
||||||
| Accounts Payable | liability_payable | ✅ Yes | ❌ No |
|
|
||||||
| Bank/Cash | asset_cash | ❌ No | ❌ No |
|
|
||||||
| Current Liabilities | liability_current | ❌ No | ✅ Yes (Tax Payable) |
|
|
||||||
| Expenses | expense | ❌ No | ✅ Yes |
|
|
||||||
| Other Liabilities | liability_non_current | ❌ No | ✅ Yes |
|
|
||||||
| Income | income | ❌ No | ⚠️ Rare |
|
|
||||||
|
|
||||||
## Testing Checklist
|
|
||||||
|
|
||||||
After applying this fix, test:
|
|
||||||
|
|
||||||
### ✅ Test 1: Payment without expense account
|
|
||||||
```
|
|
||||||
- Create vendor payment
|
|
||||||
- Amount: 1,000
|
|
||||||
- Add deduction: PPh 21 - 100 (use tax payable account)
|
|
||||||
- Post payment
|
|
||||||
- Expected: Success, no errors
|
|
||||||
```
|
|
||||||
|
|
||||||
### ✅ Test 2: Payment with expense account
|
|
||||||
```
|
|
||||||
- Create vendor payment
|
|
||||||
- Amount: 2,000
|
|
||||||
- Expense Account: Telepon & Internet
|
|
||||||
- Add deduction 1: PPh 21 - 100
|
|
||||||
- Add deduction 2: PPh 29 - 50
|
|
||||||
- Post payment
|
|
||||||
- Expected: Success, no errors
|
|
||||||
```
|
|
||||||
|
|
||||||
### ✅ Test 3: Verify journal entry
|
|
||||||
```
|
|
||||||
- Open posted payment
|
|
||||||
- View journal entry
|
|
||||||
- Check:
|
|
||||||
- Payable/Expense line has partner ✅
|
|
||||||
- Tax lines don't have partner ✅
|
|
||||||
- Entry is balanced ✅
|
|
||||||
```
|
|
||||||
|
|
||||||
### ❌ Test 4: Try wrong account (should fail gracefully)
|
|
||||||
```
|
|
||||||
- Create vendor payment
|
|
||||||
- Try to add deduction with Accounts Payable account
|
|
||||||
- Expected: Account not available in dropdown (domain restriction)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Files Modified
|
|
||||||
|
|
||||||
1. **`models/account_payment.py`**
|
|
||||||
- Always set `partner_id` on counterpart line
|
|
||||||
- Never set `partner_id` on deduction lines
|
|
||||||
- Ensure `account_id` is set on counterpart line
|
|
||||||
|
|
||||||
2. **`models/payment_deduction_line.py`**
|
|
||||||
- Updated domain to exclude payable/receivable accounts
|
|
||||||
- Updated help text to clarify account selection
|
|
||||||
|
|
||||||
3. **Documentation files**
|
|
||||||
- `FIX_SUMMARY.md` - Initial fix documentation
|
|
||||||
- `FINAL_FIX.md` - This comprehensive guide
|
|
||||||
- `SCENARIOS.md` - Updated validation rules
|
|
||||||
|
|
||||||
## Common Mistakes to Avoid
|
|
||||||
|
|
||||||
### ❌ Don't Do This:
|
|
||||||
|
|
||||||
1. **Using Accounts Payable for deductions**
|
|
||||||
```
|
|
||||||
Wrong: PPh 21 → Accounts Payable (vendor account)
|
|
||||||
Right: PPh 21 → Tax Payable (liability account)
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Adding partner to all lines**
|
|
||||||
```python
|
|
||||||
# Wrong
|
|
||||||
for line in all_lines:
|
|
||||||
line['partner_id'] = partner.id # ❌
|
|
||||||
|
|
||||||
# Right
|
|
||||||
if line.account.account_type in ('asset_receivable', 'liability_payable'):
|
|
||||||
line['partner_id'] = partner.id # ✅
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Using expense accounts for tax withholding**
|
|
||||||
```
|
|
||||||
Wrong: PPh 21 → Expense account (reduces expense)
|
|
||||||
Right: PPh 21 → Tax Payable (creates liability)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Accounting Best Practices
|
|
||||||
|
|
||||||
### Withholding Tax Treatment
|
|
||||||
|
|
||||||
When you withhold tax from a vendor payment:
|
|
||||||
|
|
||||||
1. **Record full expense/payable** (Debit)
|
|
||||||
2. **Record tax liability** (Credit) - you owe this to tax office
|
|
||||||
3. **Record reduced bank payment** (Credit) - actual cash out
|
|
||||||
|
|
||||||
This correctly represents:
|
|
||||||
- Full expense incurred
|
|
||||||
- Tax liability created
|
|
||||||
- Reduced cash payment
|
|
||||||
|
|
||||||
### Example Accounts Setup
|
|
||||||
|
|
||||||
Create these accounts for Indonesian tax:
|
|
||||||
|
|
||||||
```
|
|
||||||
217101 - PPh 21 (Tax Payable)
|
|
||||||
Type: Current Liabilities
|
|
||||||
Code: 217101
|
|
||||||
|
|
||||||
217102 - PPh 23 (Tax Payable)
|
|
||||||
Type: Current Liabilities
|
|
||||||
Code: 217102
|
|
||||||
|
|
||||||
117104 - PPh 29 (Tax Payable)
|
|
||||||
Type: Current Liabilities
|
|
||||||
Code: 117104
|
|
||||||
```
|
|
||||||
|
|
||||||
## Version
|
|
||||||
|
|
||||||
This fix is included in version 2.0.0 of the `vendor_payment_diff_amount` module.
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
If you still encounter issues:
|
|
||||||
|
|
||||||
1. Check that deduction accounts are NOT payable/receivable types
|
|
||||||
2. Verify the partner is set on the payment
|
|
||||||
3. Check Odoo logs for detailed error messages
|
|
||||||
4. Ensure you're using the latest version of the module
|
|
||||||
|
|
||||||
## Success Criteria
|
|
||||||
|
|
||||||
✅ Payments post without errors
|
|
||||||
✅ Journal entries are balanced
|
|
||||||
✅ Payable line has partner
|
|
||||||
✅ Tax lines don't have partner
|
|
||||||
✅ Correct accounting treatment
|
|
||||||
✅ Easy to use and understand
|
|
||||||
|
|
||||||
The module is now production-ready!
|
|
||||||
173
FIX_SUMMARY.md
173
FIX_SUMMARY.md
@ -1,173 +0,0 @@
|
|||||||
# Fix Summary: "Missing required account on accountable line" Error
|
|
||||||
|
|
||||||
## Problem
|
|
||||||
|
|
||||||
When creating a vendor payment with deductions, the system threw the error:
|
|
||||||
```
|
|
||||||
The operation cannot be completed: Missing required account on accountable line.
|
|
||||||
```
|
|
||||||
|
|
||||||
This occurred because Odoo validates that lines with payable/receivable accounts must have a `partner_id` set.
|
|
||||||
|
|
||||||
## Root Cause
|
|
||||||
|
|
||||||
The issue had two parts:
|
|
||||||
|
|
||||||
1. **Deduction lines were incorrectly getting `partner_id`**: All deduction lines were being created with `partner_id`, but deduction accounts (like tax accounts) are typically NOT payable/receivable accounts and should NOT have a partner.
|
|
||||||
|
|
||||||
2. **Odoo's validation**: When a line has a payable/receivable account type, Odoo requires the `partner_id` field. When a line has other account types (expense, liability, etc.), the `partner_id` should be optional or omitted.
|
|
||||||
|
|
||||||
## Solution
|
|
||||||
|
|
||||||
Modified the `_prepare_move_line_default_vals` method to:
|
|
||||||
|
|
||||||
1. **Ensure counterpart line has partner**: The payable/expense line (counterpart) always gets `partner_id` set
|
|
||||||
2. **Conditional partner on deduction lines**: Only add `partner_id` to deduction lines if the account type requires it
|
|
||||||
|
|
||||||
### Code Change
|
|
||||||
|
|
||||||
**Before:**
|
|
||||||
```python
|
|
||||||
deduction_line = {
|
|
||||||
'name': deduction_line_name,
|
|
||||||
'date_maturity': self.date,
|
|
||||||
'amount_currency': -deduction.amount_substract,
|
|
||||||
'currency_id': self.currency_id.id,
|
|
||||||
'debit': 0.0,
|
|
||||||
'credit': deduction_balance,
|
|
||||||
'partner_id': self.partner_id.id, # ❌ Always added
|
|
||||||
'account_id': deduction.substract_account_id.id,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**After:**
|
|
||||||
```python
|
|
||||||
deduction_line = {
|
|
||||||
'name': deduction_line_name,
|
|
||||||
'date_maturity': self.date,
|
|
||||||
'amount_currency': -deduction.amount_substract,
|
|
||||||
'currency_id': self.currency_id.id,
|
|
||||||
'debit': 0.0,
|
|
||||||
'credit': deduction_balance,
|
|
||||||
'account_id': deduction.substract_account_id.id,
|
|
||||||
}
|
|
||||||
|
|
||||||
# Only add partner_id if the account requires it
|
|
||||||
if deduction.substract_account_id.account_type in ('asset_receivable', 'liability_payable'):
|
|
||||||
deduction_line['partner_id'] = self.partner_id.id # ✅ Conditionally added
|
|
||||||
```
|
|
||||||
|
|
||||||
## Account Types
|
|
||||||
|
|
||||||
### Accounts that REQUIRE partner_id:
|
|
||||||
- `asset_receivable` (Customer accounts)
|
|
||||||
- `liability_payable` (Vendor accounts)
|
|
||||||
|
|
||||||
### Accounts that DON'T need partner_id:
|
|
||||||
- `liability_current` (Tax payable accounts like PPh 21, PPh 29)
|
|
||||||
- `expense` (Expense accounts)
|
|
||||||
- `income` (Income accounts)
|
|
||||||
- `asset_cash` (Bank accounts)
|
|
||||||
- All other account types
|
|
||||||
|
|
||||||
## Result
|
|
||||||
|
|
||||||
Now the journal entry is created correctly:
|
|
||||||
|
|
||||||
### Example: Payment Rp 2,000,000 with PPh 21 (Rp 100,000) and PPh 29 (Rp 50,000)
|
|
||||||
|
|
||||||
```
|
|
||||||
Account | Debit | Credit | Partner
|
|
||||||
-------------------------------------|-----------------|-----------------|------------------
|
|
||||||
Accounts Payable | Rp 2,000,000.00 | | PT Telkom ✅
|
|
||||||
PPh 21 (Tax Payable) | | Rp 100,000.00 | (none) ✅
|
|
||||||
PPh 29 (Tax Payable) | | Rp 50,000.00 | (none) ✅
|
|
||||||
Bank Account | | Rp 1,850,000.00 | (none) ✅
|
|
||||||
-------------------------------------|-----------------|-----------------|------------------
|
|
||||||
TOTAL | Rp 2,000,000.00 | Rp 2,000,000.00 |
|
|
||||||
```
|
|
||||||
|
|
||||||
### Key Points:
|
|
||||||
- ✅ Payable account has partner (required)
|
|
||||||
- ✅ Tax accounts don't have partner (correct)
|
|
||||||
- ✅ Bank account doesn't have partner (correct)
|
|
||||||
- ✅ Entry is balanced
|
|
||||||
- ✅ No validation errors
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
To test the fix:
|
|
||||||
|
|
||||||
1. **Create a payment without expense account:**
|
|
||||||
```
|
|
||||||
- Partner: Any vendor
|
|
||||||
- Amount: 1000
|
|
||||||
- Deduction: PPh 21 - 100 (use a tax account)
|
|
||||||
- Result: Should post successfully
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Create a payment with expense account:**
|
|
||||||
```
|
|
||||||
- Partner: Any vendor
|
|
||||||
- Amount: 2000
|
|
||||||
- Expense Account: Telepon & Internet
|
|
||||||
- Deduction 1: PPh 21 - 100
|
|
||||||
- Deduction 2: PPh 29 - 50
|
|
||||||
- Result: Should post successfully
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Verify journal entries:**
|
|
||||||
- Check that payable/expense line has partner
|
|
||||||
- Check that tax lines don't have partner
|
|
||||||
- Check that entry is balanced
|
|
||||||
|
|
||||||
## Important Notes
|
|
||||||
|
|
||||||
### Deduction Account Selection
|
|
||||||
|
|
||||||
When adding deductions, make sure to use the correct account types:
|
|
||||||
|
|
||||||
✅ **Correct accounts for deductions:**
|
|
||||||
- Tax payable accounts (PPh 21, PPh 23, PPh 29, etc.)
|
|
||||||
- Expense accounts (if recording as expense)
|
|
||||||
- Liability accounts (for other withholdings)
|
|
||||||
|
|
||||||
❌ **Don't use these for deductions:**
|
|
||||||
- Accounts Payable (vendor accounts)
|
|
||||||
- Accounts Receivable (customer accounts)
|
|
||||||
|
|
||||||
### Why This Matters
|
|
||||||
|
|
||||||
Using payable/receivable accounts for deductions would create confusion:
|
|
||||||
- It would require a partner on the deduction line
|
|
||||||
- It would mix vendor payables with tax payables
|
|
||||||
- It would complicate reconciliation
|
|
||||||
- It's not the correct accounting treatment
|
|
||||||
|
|
||||||
## Files Modified
|
|
||||||
|
|
||||||
1. **`models/account_payment.py`**
|
|
||||||
- Added conditional `partner_id` logic for deduction lines
|
|
||||||
- Ensured counterpart line always has `partner_id`
|
|
||||||
|
|
||||||
2. **`SCENARIOS.md`**
|
|
||||||
- Updated validation rules
|
|
||||||
- Added explanation about partner_id handling
|
|
||||||
- Updated troubleshooting section
|
|
||||||
|
|
||||||
3. **`FIX_SUMMARY.md`** (this file)
|
|
||||||
- Documented the fix and reasoning
|
|
||||||
|
|
||||||
## Version
|
|
||||||
|
|
||||||
This fix is included in version 2.0.0 of the module.
|
|
||||||
|
|
||||||
## Related Issues
|
|
||||||
|
|
||||||
- "Missing required account on accountable line" error
|
|
||||||
- Partner validation on journal entry lines
|
|
||||||
- Deduction account configuration
|
|
||||||
|
|
||||||
## Credits
|
|
||||||
|
|
||||||
Fixed based on user feedback and testing with real-world scenarios.
|
|
||||||
@ -1,139 +0,0 @@
|
|||||||
# Journal Entry Structure
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This document explains how journal entries are created when using payment deductions.
|
|
||||||
|
|
||||||
## Standard Payment (Without Deductions)
|
|
||||||
|
|
||||||
For a standard vendor payment of Rp 2,000,000:
|
|
||||||
|
|
||||||
```
|
|
||||||
Account | Debit | Credit
|
|
||||||
---------------------------|---------------|---------------
|
|
||||||
Accounts Payable | | Rp 2,000,000
|
|
||||||
Bank Account | | Rp 2,000,000
|
|
||||||
---------------------------|---------------|---------------
|
|
||||||
TOTAL | Rp 2,000,000 | Rp 2,000,000
|
|
||||||
```
|
|
||||||
|
|
||||||
Wait, that's not right. Let me correct:
|
|
||||||
|
|
||||||
```
|
|
||||||
Account | Debit | Credit
|
|
||||||
---------------------------|---------------|---------------
|
|
||||||
Accounts Payable | Rp 2,000,000 |
|
|
||||||
Bank Account | | Rp 2,000,000
|
|
||||||
---------------------------|---------------|---------------
|
|
||||||
TOTAL | Rp 2,000,000 | Rp 2,000,000
|
|
||||||
```
|
|
||||||
|
|
||||||
## Payment with Deductions (New Structure)
|
|
||||||
|
|
||||||
For a vendor payment of Rp 2,000,000 with deductions:
|
|
||||||
- PPh 21: Rp 100,000
|
|
||||||
- PPh 29: Rp 50,000
|
|
||||||
- Final payment to bank: Rp 1,850,000
|
|
||||||
|
|
||||||
### Journal Entry:
|
|
||||||
|
|
||||||
```
|
|
||||||
Account | Debit | Credit
|
|
||||||
---------------------------|---------------|---------------
|
|
||||||
Expense Account | Rp 2,000,000 |
|
|
||||||
PPh 21 (Tax Payable) | | Rp 100,000
|
|
||||||
PPh 29 (Tax Payable) | | Rp 50,000
|
|
||||||
Bank Account | | Rp 1,850,000
|
|
||||||
---------------------------|---------------|---------------
|
|
||||||
TOTAL | Rp 2,000,000 | Rp 2,000,000
|
|
||||||
```
|
|
||||||
|
|
||||||
### Explanation:
|
|
||||||
|
|
||||||
1. **Expense Account (Debit Rp 2,000,000)**
|
|
||||||
- Records the full expense amount
|
|
||||||
- This is the original payment amount
|
|
||||||
|
|
||||||
2. **PPh 21 (Credit Rp 100,000)**
|
|
||||||
- Withholding tax deduction
|
|
||||||
- Creates a liability (you owe this to the tax office)
|
|
||||||
- Reduces the amount paid to vendor
|
|
||||||
|
|
||||||
3. **PPh 29 (Credit Rp 50,000)**
|
|
||||||
- Another withholding tax deduction
|
|
||||||
- Also creates a liability
|
|
||||||
- Further reduces the amount paid to vendor
|
|
||||||
|
|
||||||
4. **Bank Account (Credit Rp 1,850,000)**
|
|
||||||
- The actual amount paid from bank
|
|
||||||
- Equals: Original Amount - Total Deductions
|
|
||||||
- Equals: Rp 2,000,000 - Rp 150,000 = Rp 1,850,000
|
|
||||||
|
|
||||||
### Why This Structure?
|
|
||||||
|
|
||||||
This structure correctly represents the business transaction:
|
|
||||||
- You incurred an expense of Rp 2,000,000
|
|
||||||
- You withheld Rp 150,000 in taxes (which you'll pay to the government)
|
|
||||||
- You paid Rp 1,850,000 to the vendor
|
|
||||||
|
|
||||||
The deductions are **credits** because:
|
|
||||||
- They represent liabilities (amounts you owe to the tax office)
|
|
||||||
- They reduce the cash outflow
|
|
||||||
- They offset part of the expense
|
|
||||||
|
|
||||||
## Example from Screenshot
|
|
||||||
|
|
||||||
Based on your payment PB5858/2025/00105:
|
|
||||||
|
|
||||||
```
|
|
||||||
Account | Debit | Credit
|
|
||||||
-------------------------------------|-----------------|------------------
|
|
||||||
218401 AR Clearing | | Rp 2,000,000.00
|
|
||||||
611505 Telepon & Internet | Rp 1,850,000.00 |
|
|
||||||
217101 PPh 21 | | Rp 100,000.00
|
|
||||||
117104 PPh 29 | | Rp 50,000.00
|
|
||||||
-------------------------------------|-----------------|------------------
|
|
||||||
TOTAL | Rp 1,850,000.00 | Rp 2,150,000.00
|
|
||||||
```
|
|
||||||
|
|
||||||
Wait, this doesn't balance! Let me check the correct structure...
|
|
||||||
|
|
||||||
Actually, looking at your screenshot again, the correct structure should be:
|
|
||||||
|
|
||||||
```
|
|
||||||
Account | Debit | Credit
|
|
||||||
-------------------------------------|-----------------|------------------
|
|
||||||
611505 Telepon & Internet (Expense) | Rp 2,000,000.00 |
|
|
||||||
217101 PPh 21 (Tax Payable) | | Rp 100,000.00
|
|
||||||
117104 PPh 29 (Tax Payable) | | Rp 50,000.00
|
|
||||||
218401 AR Clearing (Bank) | | Rp 1,850,000.00
|
|
||||||
-------------------------------------|-----------------|------------------
|
|
||||||
TOTAL | Rp 2,000,000.00 | Rp 2,000,000.00
|
|
||||||
```
|
|
||||||
|
|
||||||
This is the correct balanced entry that the module will now create!
|
|
||||||
|
|
||||||
## Multiple Deductions
|
|
||||||
|
|
||||||
You can add as many deduction lines as needed. For example:
|
|
||||||
|
|
||||||
Payment Amount: Rp 5,000,000
|
|
||||||
- PPh 21: Rp 200,000
|
|
||||||
- PPh 23: Rp 100,000
|
|
||||||
- PPh 29: Rp 50,000
|
|
||||||
- Admin Fee: Rp 25,000
|
|
||||||
|
|
||||||
```
|
|
||||||
Account | Debit | Credit
|
|
||||||
---------------------------|---------------|---------------
|
|
||||||
Expense Account | Rp 5,000,000 |
|
|
||||||
PPh 21 | | Rp 200,000
|
|
||||||
PPh 23 | | Rp 100,000
|
|
||||||
PPh 29 | | Rp 50,000
|
|
||||||
Admin Fee | | Rp 25,000
|
|
||||||
Bank Account | | Rp 4,625,000
|
|
||||||
---------------------------|---------------|---------------
|
|
||||||
TOTAL | Rp 5,000,000 | Rp 5,000,000
|
|
||||||
```
|
|
||||||
|
|
||||||
Final Payment: Rp 4,625,000 (= Rp 5,000,000 - Rp 375,000)
|
|
||||||
@ -1,269 +0,0 @@
|
|||||||
# Requirement: Expense Account for Deductions
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
**Payment deductions require the Expense Account field to be set.**
|
|
||||||
|
|
||||||
This is a mandatory requirement enforced by validation.
|
|
||||||
|
|
||||||
## Why This Requirement?
|
|
||||||
|
|
||||||
### Technical Reason
|
|
||||||
|
|
||||||
When creating a payment with deductions, the journal entry structure is:
|
|
||||||
|
|
||||||
```
|
|
||||||
Expense Account (Debit) ← Must be specified
|
|
||||||
Tax Accounts (Credit) ← Deductions
|
|
||||||
Bank Account (Credit) ← Net payment
|
|
||||||
```
|
|
||||||
|
|
||||||
Without the Expense Account, the system cannot determine which account should receive the debit entry.
|
|
||||||
|
|
||||||
### Accounting Reason
|
|
||||||
|
|
||||||
The Expense Account represents:
|
|
||||||
- The full cost/expense being incurred
|
|
||||||
- The account that should be debited for the total amount
|
|
||||||
- The proper classification of the expense
|
|
||||||
|
|
||||||
Example:
|
|
||||||
- Telepon & Internet expense: Rp 2,000,000
|
|
||||||
- Less: PPh 21 withheld: Rp 100,000
|
|
||||||
- Less: PPh 29 withheld: Rp 50,000
|
|
||||||
- Net payment to vendor: Rp 1,850,000
|
|
||||||
|
|
||||||
The Expense Account (Telepon & Internet) gets the full Rp 2,000,000 debit.
|
|
||||||
|
|
||||||
## Validation
|
|
||||||
|
|
||||||
The module enforces this requirement with a validation constraint:
|
|
||||||
|
|
||||||
```python
|
|
||||||
@api.constrains('amount', 'amount_substract', 'expense_account_id', 'deduction_line_ids')
|
|
||||||
def _check_amount_substract(self):
|
|
||||||
for payment in self:
|
|
||||||
# ... other validations ...
|
|
||||||
|
|
||||||
# Require expense account when using deductions
|
|
||||||
if payment.deduction_line_ids and not payment.expense_account_id:
|
|
||||||
raise ValidationError(_(
|
|
||||||
"Expense Account is required when using payment deductions.\n\n"
|
|
||||||
"Please set the Expense Account field before adding deductions."
|
|
||||||
))
|
|
||||||
```
|
|
||||||
|
|
||||||
### When Validation Triggers
|
|
||||||
|
|
||||||
The validation error appears when:
|
|
||||||
1. You add deduction lines
|
|
||||||
2. But haven't set the Expense Account field
|
|
||||||
3. And try to save or post the payment
|
|
||||||
|
|
||||||
### Error Message
|
|
||||||
|
|
||||||
```
|
|
||||||
Expense Account is required when using payment deductions.
|
|
||||||
|
|
||||||
Please set the Expense Account field before adding deductions.
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to Use
|
|
||||||
|
|
||||||
### Correct Workflow
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Create Payment
|
|
||||||
↓
|
|
||||||
2. Set Expense Account ✅ (e.g., "Telepon & Internet")
|
|
||||||
↓
|
|
||||||
3. Add Deductions (e.g., PPh 21, PPh 29)
|
|
||||||
↓
|
|
||||||
4. Post Payment ✅
|
|
||||||
```
|
|
||||||
|
|
||||||
### Incorrect Workflow (Will Fail)
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Create Payment
|
|
||||||
↓
|
|
||||||
2. Add Deductions ❌
|
|
||||||
↓
|
|
||||||
3. Try to Post ❌
|
|
||||||
↓
|
|
||||||
Error: "Expense Account is required..."
|
|
||||||
```
|
|
||||||
|
|
||||||
## Alternative: Without Deductions
|
|
||||||
|
|
||||||
If you don't need deductions, you can use the standard payment flow:
|
|
||||||
|
|
||||||
```
|
|
||||||
1. Create Payment
|
|
||||||
↓
|
|
||||||
2. Don't set Expense Account (optional)
|
|
||||||
↓
|
|
||||||
3. Don't add Deductions
|
|
||||||
↓
|
|
||||||
4. Post Payment ✅
|
|
||||||
```
|
|
||||||
|
|
||||||
In this case, the system uses the standard Accounts Payable account.
|
|
||||||
|
|
||||||
## Comparison
|
|
||||||
|
|
||||||
### With Expense Account + Deductions
|
|
||||||
|
|
||||||
**Journal Entry:**
|
|
||||||
```
|
|
||||||
Expense Account Debit: 2,000,000
|
|
||||||
PPh 21 Credit: 100,000
|
|
||||||
PPh 29 Credit: 50,000
|
|
||||||
Bank Credit: 1,850,000
|
|
||||||
```
|
|
||||||
|
|
||||||
**Use Case:** Direct expense recording with tax withholding
|
|
||||||
|
|
||||||
### Without Expense Account (Standard)
|
|
||||||
|
|
||||||
**Journal Entry:**
|
|
||||||
```
|
|
||||||
Accounts Payable Debit: 2,000,000
|
|
||||||
Bank Credit: 2,000,000
|
|
||||||
```
|
|
||||||
|
|
||||||
**Use Case:** Standard vendor payment without deductions
|
|
||||||
|
|
||||||
## Benefits of This Requirement
|
|
||||||
|
|
||||||
### 1. Clear Accounting
|
|
||||||
|
|
||||||
Forces users to specify exactly which expense account should be used, ensuring:
|
|
||||||
- Proper expense classification
|
|
||||||
- Accurate financial reporting
|
|
||||||
- Clear audit trail
|
|
||||||
|
|
||||||
### 2. Prevents Errors
|
|
||||||
|
|
||||||
Prevents common mistakes like:
|
|
||||||
- Missing expense account
|
|
||||||
- Unclear journal entries
|
|
||||||
- Unbalanced entries
|
|
||||||
|
|
||||||
### 3. Consistent Behavior
|
|
||||||
|
|
||||||
Ensures all payments with deductions follow the same pattern:
|
|
||||||
- Always have an expense account
|
|
||||||
- Always have proper journal entries
|
|
||||||
- Always have correct tax treatment
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### Required Accounts
|
|
||||||
|
|
||||||
Before using deductions, set up:
|
|
||||||
|
|
||||||
#### 1. Expense Accounts
|
|
||||||
```
|
|
||||||
Chart of Accounts > Create Account
|
|
||||||
- Name: Telepon & Internet
|
|
||||||
- Code: 611505
|
|
||||||
- Type: Expenses
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Tax Payable Accounts
|
|
||||||
```
|
|
||||||
Chart of Accounts > Create Account
|
|
||||||
- Name: PPh 21
|
|
||||||
- Code: 217101
|
|
||||||
- Type: Current Liabilities
|
|
||||||
```
|
|
||||||
|
|
||||||
### Account Selection
|
|
||||||
|
|
||||||
When creating a payment with deductions:
|
|
||||||
|
|
||||||
**Expense Account:** Choose from expense accounts
|
|
||||||
- ✅ Telepon & Internet
|
|
||||||
- ✅ Office Supplies
|
|
||||||
- ✅ Professional Fees
|
|
||||||
- ❌ Accounts Payable (not allowed)
|
|
||||||
|
|
||||||
**Deduction Accounts:** Choose from tax/liability accounts
|
|
||||||
- ✅ PPh 21 (Tax Payable)
|
|
||||||
- ✅ PPh 23 (Tax Payable)
|
|
||||||
- ✅ PPh 29 (Tax Payable)
|
|
||||||
- ❌ Accounts Payable (not allowed)
|
|
||||||
- ❌ Bank accounts (not allowed)
|
|
||||||
|
|
||||||
## User Training
|
|
||||||
|
|
||||||
### Key Points to Teach Users
|
|
||||||
|
|
||||||
1. **Always set Expense Account first** when using deductions
|
|
||||||
2. **Choose the right expense account** for the type of expense
|
|
||||||
3. **Use tax accounts** for deductions, not payable accounts
|
|
||||||
4. **Verify amounts** before posting
|
|
||||||
|
|
||||||
### Common Questions
|
|
||||||
|
|
||||||
**Q: Why can't I just use Accounts Payable?**
|
|
||||||
|
|
||||||
A: When using deductions, you're recording the expense directly. Accounts Payable is for tracking vendor balances, not expenses.
|
|
||||||
|
|
||||||
**Q: What if I forget to set Expense Account?**
|
|
||||||
|
|
||||||
A: You'll get a validation error. Just set the Expense Account field and try again.
|
|
||||||
|
|
||||||
**Q: Can I change the Expense Account after adding deductions?**
|
|
||||||
|
|
||||||
A: Yes, as long as the payment hasn't been posted yet.
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
### Module Integration
|
|
||||||
|
|
||||||
This requirement is part of the `vendor_payment_diff_amount` module v2.0.0.
|
|
||||||
|
|
||||||
It works with:
|
|
||||||
- `vendor_batch_payment_merge` (provides expense_account_id field)
|
|
||||||
- Standard Odoo accounting (account.payment)
|
|
||||||
|
|
||||||
### Field Definition
|
|
||||||
|
|
||||||
The `expense_account_id` field is defined in `vendor_batch_payment_merge`:
|
|
||||||
|
|
||||||
```python
|
|
||||||
expense_account_id = fields.Many2one(
|
|
||||||
'account.account',
|
|
||||||
string='Expense Account',
|
|
||||||
domain="[('account_type', 'not in', ('asset_receivable', 'liability_payable'))]",
|
|
||||||
help="Account used for expense instead of the default payable/receivable account"
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Validation Logic
|
|
||||||
|
|
||||||
The validation is in `vendor_payment_diff_amount`:
|
|
||||||
|
|
||||||
```python
|
|
||||||
if payment.deduction_line_ids and not payment.expense_account_id:
|
|
||||||
raise ValidationError("Expense Account is required...")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
✅ **DO:** Set Expense Account before adding deductions
|
|
||||||
✅ **DO:** Use expense accounts for Expense Account field
|
|
||||||
✅ **DO:** Use tax accounts for deduction accounts
|
|
||||||
❌ **DON'T:** Try to add deductions without Expense Account
|
|
||||||
❌ **DON'T:** Use Accounts Payable for deductions
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Remember: Expense Account is REQUIRED when using deductions!**
|
|
||||||
|
|
||||||
For more information, see:
|
|
||||||
- USER_GUIDE.md - Step-by-step instructions
|
|
||||||
- README.md - Module overview
|
|
||||||
- FINAL_FIX.md - Technical details
|
|
||||||
236
SCENARIOS.md
236
SCENARIOS.md
@ -1,236 +0,0 @@
|
|||||||
# 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
|
|
||||||
```
|
|
||||||
162
TEST_UPGRADE.md
162
TEST_UPGRADE.md
@ -1,162 +0,0 @@
|
|||||||
# Testing the Upgrade to v2.0
|
|
||||||
|
|
||||||
## Pre-Upgrade Checklist
|
|
||||||
|
|
||||||
1. **Backup your database**
|
|
||||||
```bash
|
|
||||||
pg_dump your_database > backup_before_v2.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Check for existing payments with deductions**
|
|
||||||
```python
|
|
||||||
# In Odoo shell
|
|
||||||
payments = env['account.payment'].search([
|
|
||||||
('amount_substract', '>', 0)
|
|
||||||
])
|
|
||||||
print(f"Found {len(payments)} payments with deductions")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Upgrade Steps
|
|
||||||
|
|
||||||
### 1. Update the Module
|
|
||||||
|
|
||||||
From Odoo UI:
|
|
||||||
- Go to Apps
|
|
||||||
- Remove "Apps" filter
|
|
||||||
- Search for "Vendor Payment Diff Amount"
|
|
||||||
- Click "Upgrade"
|
|
||||||
|
|
||||||
Or from command line:
|
|
||||||
```bash
|
|
||||||
./odoo-bin -u vendor_payment_diff_amount -d your_database --stop-after-init
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Verify Installation
|
|
||||||
|
|
||||||
Check that:
|
|
||||||
- ✅ Module upgraded successfully without errors
|
|
||||||
- ✅ New model `payment.deduction.line` is created
|
|
||||||
- ✅ Security rules are applied
|
|
||||||
|
|
||||||
### 3. Test Basic Functionality
|
|
||||||
|
|
||||||
#### Test 1: Create Payment with Single Deduction
|
|
||||||
1. Go to Accounting > Vendors > Payments
|
|
||||||
2. Create new outbound payment
|
|
||||||
3. Enter amount: 1000
|
|
||||||
4. Add deduction line:
|
|
||||||
- Account: Select a tax/expense account
|
|
||||||
- Amount: 100
|
|
||||||
- Description: "Withholding Tax"
|
|
||||||
5. Verify:
|
|
||||||
- Total Deductions: 100
|
|
||||||
- Final Payment Amount: 900
|
|
||||||
6. Post the payment
|
|
||||||
7. Check journal entry:
|
|
||||||
- Expense/Payable: Debit 1000
|
|
||||||
- Tax Account: Credit 100
|
|
||||||
- Bank: Credit 900
|
|
||||||
|
|
||||||
#### Test 2: Create Payment with Multiple Deductions
|
|
||||||
1. Create new outbound payment
|
|
||||||
2. Enter amount: 2000
|
|
||||||
3. Add first deduction:
|
|
||||||
- Account: PPh 21 account
|
|
||||||
- Amount: 100
|
|
||||||
- Description: "PPh 21"
|
|
||||||
4. Add second deduction:
|
|
||||||
- Account: PPh 29 account
|
|
||||||
- Amount: 50
|
|
||||||
- Description: "PPh 29"
|
|
||||||
5. Verify:
|
|
||||||
- Total Deductions: 150
|
|
||||||
- Final Payment Amount: 1850
|
|
||||||
6. Post and verify journal entry:
|
|
||||||
- Expense/Payable: Debit 2000
|
|
||||||
- PPh 21: Credit 100
|
|
||||||
- PPh 29: Credit 50
|
|
||||||
- Bank: Credit 1850
|
|
||||||
|
|
||||||
#### Test 3: Batch Payment with Deductions
|
|
||||||
1. Go to Accounting > Vendors > Batch Payments
|
|
||||||
2. Create new batch payment
|
|
||||||
3. Add payment line
|
|
||||||
4. Click on the line to open form view
|
|
||||||
5. In "Deductions" section, add deduction lines
|
|
||||||
6. Save the line
|
|
||||||
7. Verify total deductions shown in tree
|
|
||||||
8. Generate payments
|
|
||||||
9. Verify deductions transferred to generated payment
|
|
||||||
|
|
||||||
## Common Issues and Solutions
|
|
||||||
|
|
||||||
### Issue: "company_id field missing"
|
|
||||||
**Solution:** This was fixed in the latest version. Make sure you have the updated view files.
|
|
||||||
|
|
||||||
### Issue: "Cannot locate form view"
|
|
||||||
**Solution:** The view now includes both tree and form definitions. Upgrade to latest version.
|
|
||||||
|
|
||||||
### Issue: Existing payments not showing deductions
|
|
||||||
**Solution:** Old payments need manual migration. See UPGRADE_TO_V2.md for migration script.
|
|
||||||
|
|
||||||
## Rollback Procedure
|
|
||||||
|
|
||||||
If you need to rollback:
|
|
||||||
|
|
||||||
1. Stop Odoo
|
|
||||||
2. Restore database:
|
|
||||||
```bash
|
|
||||||
dropdb your_database
|
|
||||||
createdb your_database
|
|
||||||
psql your_database < backup_before_v2.sql
|
|
||||||
```
|
|
||||||
3. Checkout previous version of the module
|
|
||||||
4. Restart Odoo
|
|
||||||
|
|
||||||
## Post-Upgrade Tasks
|
|
||||||
|
|
||||||
### Migrate Existing Data (if needed)
|
|
||||||
|
|
||||||
If you have existing payments with the old single deduction structure, run this migration:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# In Odoo shell: ./odoo-bin shell -d your_database
|
|
||||||
|
|
||||||
# Find payments that might need migration
|
|
||||||
# Note: In v2.0, amount_substract is computed, so we can't query it directly
|
|
||||||
# Instead, look for payments that should have deductions but don't have deduction lines
|
|
||||||
|
|
||||||
# Manual migration example:
|
|
||||||
payment = env['account.payment'].browse(123) # Replace with actual ID
|
|
||||||
|
|
||||||
# Create deduction line
|
|
||||||
env['payment.deduction.line'].create({
|
|
||||||
'payment_id': payment.id,
|
|
||||||
'amount_substract': 100.0, # The old amount
|
|
||||||
'substract_account_id': 456, # The old account ID
|
|
||||||
'name': 'Migrated deduction',
|
|
||||||
'sequence': 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
env.cr.commit()
|
|
||||||
```
|
|
||||||
|
|
||||||
## Verification Checklist
|
|
||||||
|
|
||||||
After upgrade, verify:
|
|
||||||
|
|
||||||
- [ ] Module shows version 2.0.0
|
|
||||||
- [ ] Can create new payments with multiple deductions
|
|
||||||
- [ ] Deductions calculate correctly
|
|
||||||
- [ ] Journal entries are correct
|
|
||||||
- [ ] Batch payments work with deductions
|
|
||||||
- [ ] No errors in log files
|
|
||||||
- [ ] Existing payments still accessible
|
|
||||||
- [ ] Reports show correct amounts
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
If you encounter issues:
|
|
||||||
1. Check the error log
|
|
||||||
2. Review UPGRADE_TO_V2.md
|
|
||||||
3. Contact module maintainer
|
|
||||||
175
UPGRADE_TO_V2.md
175
UPGRADE_TO_V2.md
@ -1,175 +0,0 @@
|
|||||||
# Upgrade Guide: vendor_payment_diff_amount v1.x to v2.0
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Version 2.0 introduces a major architectural change: converting from single deduction fields to multiple deduction lines (One2many relationship).
|
|
||||||
|
|
||||||
## What Changed
|
|
||||||
|
|
||||||
### Database Schema Changes
|
|
||||||
|
|
||||||
**Removed/Changed Fields:**
|
|
||||||
- `account.payment.amount_substract` - Changed from stored field to computed field
|
|
||||||
- `account.payment.substract_account_id` - Removed (replaced by deduction lines)
|
|
||||||
- `account.batch.payment.line.amount_substract` - Changed to computed field
|
|
||||||
- `account.batch.payment.line.substract_account_id` - Removed
|
|
||||||
|
|
||||||
**New Model:**
|
|
||||||
- `payment.deduction.line` - Stores individual deduction entries
|
|
||||||
|
|
||||||
**New Fields:**
|
|
||||||
- `account.payment.deduction_line_ids` (One2many)
|
|
||||||
- `account.batch.payment.line.deduction_line_ids` (One2many)
|
|
||||||
|
|
||||||
### Code Changes
|
|
||||||
|
|
||||||
1. **Models:**
|
|
||||||
- New model: `payment_deduction_line.py`
|
|
||||||
- Updated: `account_payment.py` - uses One2many for deductions
|
|
||||||
- Updated: `account_batch_payment.py` - transfers deduction lines
|
|
||||||
|
|
||||||
2. **Views:**
|
|
||||||
- Payment form: Shows editable tree for deduction lines
|
|
||||||
- Batch payment form: Shows deduction lines in line form view
|
|
||||||
|
|
||||||
3. **Security:**
|
|
||||||
- Added access rights for `payment.deduction.line`
|
|
||||||
|
|
||||||
## Upgrade Steps
|
|
||||||
|
|
||||||
### 1. Backup Your Database
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create a full database backup before upgrading
|
|
||||||
pg_dump your_database > backup_before_v2_upgrade.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Install the Update
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Update the module
|
|
||||||
./odoo-bin -u vendor_payment_diff_amount -d your_database
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Data Migration (if needed)
|
|
||||||
|
|
||||||
If you have existing payments with deductions, you'll need to migrate them. Here's a sample migration script:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Run this in Odoo shell: ./odoo-bin shell -d your_database
|
|
||||||
|
|
||||||
# Find all payments with deductions (old structure)
|
|
||||||
payments = env['account.payment'].search([
|
|
||||||
('amount_substract', '>', 0),
|
|
||||||
('substract_account_id', '!=', False)
|
|
||||||
])
|
|
||||||
|
|
||||||
print(f"Found {len(payments)} payments with deductions to migrate")
|
|
||||||
|
|
||||||
# For each payment, create a deduction line
|
|
||||||
for payment in payments:
|
|
||||||
# Check if already migrated
|
|
||||||
if payment.deduction_line_ids:
|
|
||||||
print(f"Payment {payment.id} already has deduction lines, skipping")
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Create deduction line from old fields
|
|
||||||
env['payment.deduction.line'].create({
|
|
||||||
'payment_id': payment.id,
|
|
||||||
'amount_substract': payment.amount_substract,
|
|
||||||
'substract_account_id': payment.substract_account_id.id,
|
|
||||||
'name': f'Migrated: {payment.substract_account_id.name}',
|
|
||||||
'sequence': 10,
|
|
||||||
})
|
|
||||||
|
|
||||||
print(f"Migrated payment {payment.id}")
|
|
||||||
|
|
||||||
env.cr.commit()
|
|
||||||
print("Migration complete!")
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Verify the Migration
|
|
||||||
|
|
||||||
After migration, verify:
|
|
||||||
|
|
||||||
1. Check a few payments that had deductions
|
|
||||||
2. Verify the deduction lines are created correctly
|
|
||||||
3. Check that totals match (amount_substract should equal sum of deduction lines)
|
|
||||||
4. Test creating new payments with multiple deductions
|
|
||||||
|
|
||||||
### 5. Update Custom Code (if any)
|
|
||||||
|
|
||||||
If you have custom code that references the old fields:
|
|
||||||
|
|
||||||
**Old code:**
|
|
||||||
```python
|
|
||||||
payment.amount_substract = 100.0
|
|
||||||
payment.substract_account_id = account.id
|
|
||||||
```
|
|
||||||
|
|
||||||
**New code:**
|
|
||||||
```python
|
|
||||||
env['payment.deduction.line'].create({
|
|
||||||
'payment_id': payment.id,
|
|
||||||
'amount_substract': 100.0,
|
|
||||||
'substract_account_id': account.id,
|
|
||||||
'name': 'Withholding Tax',
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
**Reading deductions:**
|
|
||||||
|
|
||||||
Old:
|
|
||||||
```python
|
|
||||||
if payment.amount_substract > 0:
|
|
||||||
account = payment.substract_account_id
|
|
||||||
```
|
|
||||||
|
|
||||||
New:
|
|
||||||
```python
|
|
||||||
if payment.amount_substract > 0: # Still works (computed field)
|
|
||||||
for deduction in payment.deduction_line_ids:
|
|
||||||
account = deduction.substract_account_id
|
|
||||||
amount = deduction.amount_substract
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing After Upgrade
|
|
||||||
|
|
||||||
1. **Create a new payment with multiple deductions:**
|
|
||||||
- Amount: 1000
|
|
||||||
- Deduction 1: Tax - 100
|
|
||||||
- Deduction 2: Fee - 50
|
|
||||||
- Verify final amount: 850
|
|
||||||
|
|
||||||
2. **Post the payment and check journal entry:**
|
|
||||||
- Payable: Debit 850
|
|
||||||
- Tax Account: Debit 100
|
|
||||||
- Fee Account: Debit 50
|
|
||||||
- Bank: Credit 1000
|
|
||||||
|
|
||||||
3. **Test batch payments:**
|
|
||||||
- Create batch payment
|
|
||||||
- Add line with multiple deductions
|
|
||||||
- Generate payment
|
|
||||||
- Verify deductions transferred correctly
|
|
||||||
|
|
||||||
## Rollback (if needed)
|
|
||||||
|
|
||||||
If you need to rollback:
|
|
||||||
|
|
||||||
1. Restore database backup:
|
|
||||||
```bash
|
|
||||||
psql your_database < backup_before_v2_upgrade.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Reinstall v1.x of the module
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
For issues or questions about the upgrade, contact the module maintainer.
|
|
||||||
|
|
||||||
## Compatibility
|
|
||||||
|
|
||||||
- **Odoo Version:** 17.0
|
|
||||||
- **Breaking Changes:** Yes (database schema and API changes)
|
|
||||||
- **Backward Compatible:** No (requires migration)
|
|
||||||
Loading…
Reference in New Issue
Block a user