#!/usr/bin/env python3 """ Script to fix amount calculation issues in vendor_payment_diff_amount module. This script can be run in Odoo shell to fix payments that have incorrect amounts due to synchronization issues. Usage: 1. Open Odoo shell: python odoo-bin shell -d your_database 2. Run this script: exec(open('customaddons/vendor_payment_diff_amount/fix_amount_issue.py').read()) """ def fix_payment_amounts(): """Fix amount calculation for payments with deductions.""" # Find all payments with deductions that might have incorrect amounts payments = env['account.payment'].search([ ('amount_substract', '>', 0), ('state', '=', 'posted'), ]) print(f"Found {len(payments)} payments with deductions to check...") 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') ) if counterpart_lines: correct_amount = counterpart_lines[0].debit current_amount = payment.amount # Check if amount needs fixing (allow for small rounding differences) if abs(current_amount - correct_amount) > 0.01: 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( "UPDATE account_payment SET amount = %s WHERE id = %s", (correct_amount, payment.id) ) # Invalidate cache and recompute payment.invalidate_recordset(['amount']) payment._compute_final_payment_amount() print(f" āœ“ Fixed! New final amount: {payment.final_payment_amount}") print() fixed_count += 1 else: print(f"Payment {payment.name} is correct (amount: {current_amount})") print(f"Fixed {fixed_count} payments.") # Commit the changes env.cr.commit() print("Changes committed to database.") def check_specific_payment(payment_name_or_id): """Check a specific payment by name or ID.""" if isinstance(payment_name_or_id, str): payment = env['account.payment'].search([('name', '=', payment_name_or_id)], limit=1) else: payment = env['account.payment'].browse(payment_name_or_id) if not payment: print(f"Payment {payment_name_or_id} not found.") return print(f"Payment: {payment.name} (ID: {payment.id})") print(f"State: {payment.state}") print(f"Partner: {payment.partner_id.name}") print(f"Amount: {payment.amount}") print(f"Deductions: {payment.amount_substract}") print(f"Final Payment Amount: {payment.final_payment_amount}") print(f"Expected Final: {payment.amount - payment.amount_substract}") if payment.move_id: print("\nJournal Entry Lines:") for line in payment.move_id.line_ids: print(f" {line.account_id.name}: Debit {line.debit}, Credit {line.credit}") # Check if amounts are correct expected_final = payment.amount - payment.amount_substract if abs(payment.final_payment_amount - expected_final) > 0.01: print(f"\nāŒ ISSUE: Final payment amount is incorrect!") print(f" Expected: {expected_final}") print(f" Actual: {payment.final_payment_amount}") else: print(f"\nāœ… Payment amounts are correct.") # Example usage: if __name__ == "__main__": print("Vendor Payment Diff Amount - Fix Script") print("=" * 50) # Check a specific payment (replace with your payment name) # check_specific_payment("PBCA5858/2025/00061") # Or fix all payments # fix_payment_amounts() print("\nTo use this script:") print("1. check_specific_payment('PBCA5858/2025/00061') # Check specific payment") print("2. fix_payment_amounts() # Fix all payments with issues")