From f2d8f2c7e336e06a4036a86a0ae0d4c258d55a0f Mon Sep 17 00:00:00 2001 From: "admin.suherdy" Date: Mon, 24 Nov 2025 15:48:49 +0700 Subject: [PATCH] fix bug --- models/account_payment.py | 72 ++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/models/account_payment.py b/models/account_payment.py index 155d5e7..07a95bb 100644 --- a/models/account_payment.py +++ b/models/account_payment.py @@ -1,6 +1,8 @@ from odoo import api, fields, models, _ + + class AccountPayment(models.Model): _inherit = 'account.payment' @@ -23,48 +25,48 @@ class AccountPayment(models.Model): @api.depends('move_id.line_ids.amount_residual', 'move_id.line_ids.amount_residual_currency', - 'move_id.line_ids.reconciled', + 'move_id.line_ids.account_id', + 'move_id.line_ids.account_id.account_type', 'is_matched') def _compute_payment_residual(self): - """Compute the residual amount from payment journal items - - Shows 0 residual when payment is matched with bank statement. - Otherwise shows the residual from all reconcilable lines except liquidity accounts. + """Compute the residual amount for payments. + + Matched payments always display zero residual. + For unmatched payments, we first look at residuals on reconcilable counterpart + lines (receivable/payable/write-off). If those are fully cleared, we fall back + to the liquidity lines to surface outstanding balances waiting for bank + statement matching. """ for pay in self: - # If payment is matched with bank statement, no residual to show - if pay.is_matched: + if pay.is_matched or not pay.move_id: pay.payment_residual = 0.0 pay.payment_residual_currency = 0.0 continue - - if not pay.move_id: - pay.payment_residual = 0.0 - pay.payment_residual_currency = 0.0 - continue - - # Get all reconcilable lines except liquidity accounts - # This includes receivable, payable, and other reconcilable accounts - # but excludes bank/cash accounts that get matched with statements - reconcilable_lines = pay.move_id.line_ids.filtered( - lambda line: line.account_id.reconcile and - line.account_id.account_type not in ('asset_cash', 'liability_credit_card') + + company_currency = pay.company_id.currency_id + payment_currency = pay.currency_id or company_currency + + liquidity_lines, counterpart_lines, writeoff_lines = pay._seek_for_lines() + reconcilable_lines = (counterpart_lines + writeoff_lines).filtered(lambda l: l.account_id.reconcile) + + residual = sum(reconcilable_lines.mapped('amount_residual')) + residual_currency = sum( + reconcilable_lines.mapped( + 'amount_residual_currency' if payment_currency != company_currency else 'amount_residual' + ) ) - - # Calculate residual based on currency - residual = 0.0 - residual_currency = 0.0 - - for line in reconcilable_lines: - # Always add to company currency residual - residual += line.amount_residual - - # For foreign currency, use amount_residual_currency - if line.currency_id and line.currency_id != pay.company_id.currency_id: - residual_currency += line.amount_residual_currency - else: - residual_currency += line.amount_residual - - # Store absolute values + + liquidity_residual = sum(liquidity_lines.mapped('amount_residual')) + liquidity_residual_currency = sum( + liquidity_lines.mapped( + 'amount_residual_currency' if payment_currency != company_currency else 'amount_residual' + ) + ) + + if company_currency.is_zero(residual) and not company_currency.is_zero(liquidity_residual): + residual = liquidity_residual + if payment_currency.is_zero(residual_currency) and not payment_currency.is_zero(liquidity_residual_currency): + residual_currency = liquidity_residual_currency + pay.payment_residual = abs(residual) pay.payment_residual_currency = abs(residual_currency)