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