This commit is contained in:
admin.suherdy 2025-11-24 15:48:49 +07:00
parent 0bdbede031
commit f2d8f2c7e3

View File

@ -1,6 +1,8 @@
from odoo import api, fields, models, _ from odoo import api, fields, models, _
class AccountPayment(models.Model): class AccountPayment(models.Model):
_inherit = 'account.payment' _inherit = 'account.payment'
@ -23,48 +25,48 @@ class AccountPayment(models.Model):
@api.depends('move_id.line_ids.amount_residual', @api.depends('move_id.line_ids.amount_residual',
'move_id.line_ids.amount_residual_currency', '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') 'is_matched')
def _compute_payment_residual(self): def _compute_payment_residual(self):
"""Compute the residual amount from payment journal items """Compute the residual amount for payments.
Shows 0 residual when payment is matched with bank statement. Matched payments always display zero residual.
Otherwise shows the residual from all reconcilable lines except liquidity accounts. 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: for pay in self:
# If payment is matched with bank statement, no residual to show if pay.is_matched or not pay.move_id:
if pay.is_matched:
pay.payment_residual = 0.0 pay.payment_residual = 0.0
pay.payment_residual_currency = 0.0 pay.payment_residual_currency = 0.0
continue continue
if not pay.move_id: company_currency = pay.company_id.currency_id
pay.payment_residual = 0.0 payment_currency = pay.currency_id or company_currency
pay.payment_residual_currency = 0.0
continue liquidity_lines, counterpart_lines, writeoff_lines = pay._seek_for_lines()
reconcilable_lines = (counterpart_lines + writeoff_lines).filtered(lambda l: l.account_id.reconcile)
# Get all reconcilable lines except liquidity accounts
# This includes receivable, payable, and other reconcilable accounts residual = sum(reconcilable_lines.mapped('amount_residual'))
# but excludes bank/cash accounts that get matched with statements residual_currency = sum(
reconcilable_lines = pay.move_id.line_ids.filtered( reconcilable_lines.mapped(
lambda line: line.account_id.reconcile and 'amount_residual_currency' if payment_currency != company_currency else 'amount_residual'
line.account_id.account_type not in ('asset_cash', 'liability_credit_card') )
) )
# Calculate residual based on currency liquidity_residual = sum(liquidity_lines.mapped('amount_residual'))
residual = 0.0 liquidity_residual_currency = sum(
residual_currency = 0.0 liquidity_lines.mapped(
'amount_residual_currency' if payment_currency != company_currency else 'amount_residual'
for line in reconcilable_lines: )
# Always add to company currency residual )
residual += line.amount_residual
if company_currency.is_zero(residual) and not company_currency.is_zero(liquidity_residual):
# For foreign currency, use amount_residual_currency residual = liquidity_residual
if line.currency_id and line.currency_id != pay.company_id.currency_id: if payment_currency.is_zero(residual_currency) and not payment_currency.is_zero(liquidity_residual_currency):
residual_currency += line.amount_residual_currency residual_currency = liquidity_residual_currency
else:
residual_currency += line.amount_residual
# Store absolute values
pay.payment_residual = abs(residual) pay.payment_residual = abs(residual)
pay.payment_residual_currency = abs(residual_currency) pay.payment_residual_currency = abs(residual_currency)