fix error sync when account types Advance and Expense is used
This commit is contained in:
parent
82d45bf902
commit
69f874b38c
0
.gitignore
vendored
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
0
AMOUNT_FIX_GUIDE.md
Normal file → Executable file
0
AMOUNT_FIX_GUIDE.md
Normal file → Executable file
0
CHANGELOG.md
Normal file → Executable file
0
CHANGELOG.md
Normal file → Executable file
0
__init__.py
Normal file → Executable file
0
__init__.py
Normal file → Executable file
0
__manifest__.py
Normal file → Executable file
0
__manifest__.py
Normal file → Executable file
0
__pycache__/__init__.cpython-310.pyc
Normal file → Executable file
0
__pycache__/__init__.cpython-310.pyc
Normal file → Executable file
20
fix_amount_issue.py
Normal file → Executable file
20
fix_amount_issue.py
Normal file → Executable file
@ -24,23 +24,25 @@ def fix_payment_amounts():
|
||||
fixed_count = 0
|
||||
for payment in payments:
|
||||
if payment.move_id:
|
||||
# Find the counterpart line (payable/expense line with debit)
|
||||
counterpart_lines = payment.move_id.line_ids.filtered(
|
||||
lambda l: l.debit > 0 and l.account_id.account_type in ('liability_payable', 'expense')
|
||||
)
|
||||
# Robust logic to find gross amount from moves
|
||||
liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines()
|
||||
non_liquidity_lines = counterpart_lines + writeoff_lines
|
||||
|
||||
if counterpart_lines:
|
||||
correct_amount = counterpart_lines[0].debit
|
||||
if payment.payment_type == 'outbound':
|
||||
gross_lines = non_liquidity_lines.filtered(lambda l: l.debit > 0)
|
||||
else:
|
||||
gross_lines = non_liquidity_lines.filtered(lambda l: l.credit > 0)
|
||||
|
||||
if gross_lines:
|
||||
correct_amount = sum(abs(l.amount_currency) for l in gross_lines)
|
||||
current_amount = payment.amount
|
||||
|
||||
# Check if amount needs fixing (allow for small rounding differences)
|
||||
if abs(current_amount - correct_amount) > 0.01:
|
||||
if abs(current_amount - correct_amount) > 0.001:
|
||||
print(f"Payment {payment.name} (ID: {payment.id}):")
|
||||
print(f" Current amount: {current_amount}")
|
||||
print(f" Correct amount: {correct_amount}")
|
||||
print(f" Deductions: {payment.amount_substract}")
|
||||
print(f" Current final: {payment.final_payment_amount}")
|
||||
print(f" Expected final: {correct_amount - payment.amount_substract}")
|
||||
|
||||
# Fix the amount using SQL to avoid triggering computed fields
|
||||
env.cr.execute(
|
||||
|
||||
0
models/__init__.py
Normal file → Executable file
0
models/__init__.py
Normal file → Executable file
0
models/__pycache__/__init__.cpython-310.pyc
Normal file → Executable file
0
models/__pycache__/__init__.cpython-310.pyc
Normal file → Executable file
0
models/__pycache__/account_batch_payment.cpython-310.pyc
Normal file → Executable file
0
models/__pycache__/account_batch_payment.cpython-310.pyc
Normal file → Executable file
0
models/__pycache__/account_payment.cpython-310.pyc
Normal file → Executable file
0
models/__pycache__/account_payment.cpython-310.pyc
Normal file → Executable file
0
models/account_batch_payment.py
Normal file → Executable file
0
models/account_batch_payment.py
Normal file → Executable file
77
models/account_payment.py
Normal file → Executable file
77
models/account_payment.py
Normal file → Executable file
@ -100,13 +100,18 @@ class AccountPayment(models.Model):
|
||||
if payment.amount_substract and payment.amount_substract > 0:
|
||||
# Get the correct amount from the journal entry
|
||||
if payment.move_id:
|
||||
# Find the counterpart line (payable/expense line)
|
||||
counterpart_lines = payment.move_id.line_ids.filtered(
|
||||
lambda l: l.account_id.account_type in ('liability_payable', 'expense') and l.debit > 0
|
||||
)
|
||||
if counterpart_lines:
|
||||
correct_amount = counterpart_lines[0].debit
|
||||
if abs(payment.amount - correct_amount) > 0.01: # Allow for rounding differences
|
||||
liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines()
|
||||
non_liquidity_lines = counterpart_lines + writeoff_lines
|
||||
|
||||
# Find gross amount lines (Debits for outbound, Credits for inbound)
|
||||
if payment.payment_type == 'outbound':
|
||||
gross_lines = non_liquidity_lines.filtered(lambda l: l.debit > 0)
|
||||
else:
|
||||
gross_lines = non_liquidity_lines.filtered(lambda l: l.credit > 0)
|
||||
|
||||
if gross_lines:
|
||||
correct_amount = sum(abs(l.amount_currency) for l in gross_lines)
|
||||
if abs(payment.amount - correct_amount) > 0.001:
|
||||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
_logger.info(f"Fixing amount for payment {payment.id}: {payment.amount} -> {correct_amount}")
|
||||
@ -133,14 +138,19 @@ class AccountPayment(models.Model):
|
||||
fixed_count = 0
|
||||
for payment in payments:
|
||||
if payment.move_id:
|
||||
# Find the counterpart line (payable/expense line with debit)
|
||||
counterpart_lines = payment.move_id.line_ids.filtered(
|
||||
lambda l: l.debit > 0 and l.account_id.account_type in ('liability_payable', 'expense')
|
||||
)
|
||||
# Robust logic to find gross amount from moves
|
||||
liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines()
|
||||
non_liquidity_lines = counterpart_lines + writeoff_lines
|
||||
|
||||
if counterpart_lines:
|
||||
correct_amount = counterpart_lines[0].debit
|
||||
if abs(payment.amount - correct_amount) > 0.01:
|
||||
# Find gross amount lines (Debits for outbound, Credits for inbound)
|
||||
if payment.payment_type == 'outbound':
|
||||
gross_lines = non_liquidity_lines.filtered(lambda l: l.debit > 0)
|
||||
else:
|
||||
gross_lines = non_liquidity_lines.filtered(lambda l: l.credit > 0)
|
||||
|
||||
if gross_lines:
|
||||
correct_amount = sum(abs(l.amount_currency) for l in gross_lines)
|
||||
if abs(payment.amount - correct_amount) > 0.001:
|
||||
# Fix using SQL to avoid sync issues
|
||||
payment.env.cr.execute(
|
||||
"UPDATE account_payment SET amount = %s WHERE id = %s",
|
||||
@ -165,36 +175,49 @@ class AccountPayment(models.Model):
|
||||
Override to handle synchronization when we have deductions.
|
||||
|
||||
When we have a substract amount, the bank credit line is reduced to final_payment_amount,
|
||||
but we want to keep the payment amount at the original value (not sync it down).
|
||||
but we want to keep the payment amount at the original gross value.
|
||||
"""
|
||||
# For payments with deductions, we need to handle synchronization carefully
|
||||
for payment in self:
|
||||
if payment.amount_substract and payment.amount_substract > 0:
|
||||
# Store the original amount before any synchronization
|
||||
# Store potential original values
|
||||
original_amount = payment.amount
|
||||
original_substract = payment.amount_substract
|
||||
|
||||
# Try to call parent sync but handle any errors
|
||||
# Call parent sync
|
||||
try:
|
||||
super(AccountPayment, payment)._synchronize_from_moves(changed_fields)
|
||||
except Exception as e:
|
||||
# If there's an error (like missing payable account when using expense_account_id),
|
||||
# that's expected, so we just continue
|
||||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
_logger.info(f"Sync error for payment {payment.id} (expected with deductions): {e}")
|
||||
_logger.debug(f"Sync info for payment {payment.id} (handling deductions): {e}")
|
||||
|
||||
# After sync, ensure the amount is still correct
|
||||
# The sync might have changed it based on journal entry lines
|
||||
if payment.amount != original_amount:
|
||||
# Restore gross amount from the move's counterpart lines
|
||||
if payment.move_id:
|
||||
liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines()
|
||||
|
||||
# The gross amount is the sum of counterpart/writeoff lines that balance the liquidity line
|
||||
# For outbound (Send Money): Gross = Sum of Debits (excluding liquidity)
|
||||
# For inbound (Receive Money): Gross = Sum of Credits (excluding liquidity)
|
||||
|
||||
non_liquidity_lines = counterpart_lines + writeoff_lines
|
||||
if payment.payment_type == 'outbound':
|
||||
gross_lines = non_liquidity_lines.filtered(lambda l: l.debit > 0)
|
||||
else:
|
||||
gross_lines = non_liquidity_lines.filtered(lambda l: l.credit > 0)
|
||||
|
||||
if gross_lines:
|
||||
# Use amount_currency because it represents the amount in payment currency
|
||||
correct_gross_amount = sum(abs(l.amount_currency) for l in gross_lines)
|
||||
|
||||
if abs(payment.amount - correct_gross_amount) > 0.001:
|
||||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
_logger.info(f"Restoring amount for payment {payment.id}: {payment.amount} -> {original_amount}")
|
||||
_logger.info(f"Restoring gross amount for payment {payment.id}: {payment.amount} -> {correct_gross_amount}")
|
||||
|
||||
# Use SQL to restore the original amount without triggering more syncs
|
||||
# Use SQL to restore to avoid triggering more syncs
|
||||
payment.env.cr.execute(
|
||||
"UPDATE account_payment SET amount = %s WHERE id = %s",
|
||||
(original_amount, payment.id)
|
||||
(correct_gross_amount, payment.id)
|
||||
)
|
||||
payment.invalidate_recordset(['amount'])
|
||||
|
||||
|
||||
0
models/payment_deduction_line.py
Normal file → Executable file
0
models/payment_deduction_line.py
Normal file → Executable file
0
security/ir.model.access.csv
Normal file → Executable file
0
security/ir.model.access.csv
Normal file → Executable file
0
tests/__init__.py
Normal file → Executable file
0
tests/__init__.py
Normal file → Executable file
0
tests/__pycache__/__init__.cpython-310.pyc
Normal file → Executable file
0
tests/__pycache__/__init__.cpython-310.pyc
Normal file → Executable file
0
tests/__pycache__/test_account_payment.cpython-310.pyc
Normal file → Executable file
0
tests/__pycache__/test_account_payment.cpython-310.pyc
Normal file → Executable file
0
tests/__pycache__/test_batch_payment_integration.cpython-310.pyc
Normal file → Executable file
0
tests/__pycache__/test_batch_payment_integration.cpython-310.pyc
Normal file → Executable file
0
tests/test_account_payment.py
Normal file → Executable file
0
tests/test_account_payment.py
Normal file → Executable file
0
tests/test_batch_payment_integration.py
Normal file → Executable file
0
tests/test_batch_payment_integration.py
Normal file → Executable file
0
views/account_batch_payment_views.xml
Normal file → Executable file
0
views/account_batch_payment_views.xml
Normal file → Executable file
0
views/account_payment_views.xml
Normal file → Executable file
0
views/account_payment_views.xml
Normal file → Executable file
0
wizard/__init__.py
Normal file → Executable file
0
wizard/__init__.py
Normal file → Executable file
0
wizard/payment_amount_fix_wizard.py
Normal file → Executable file
0
wizard/payment_amount_fix_wizard.py
Normal file → Executable file
0
wizard/payment_amount_fix_wizard_views.xml
Normal file → Executable file
0
wizard/payment_amount_fix_wizard_views.xml
Normal file → Executable file
Loading…
Reference in New Issue
Block a user