fix: improve expense payment computation logic and allow manual overrides in payment wizard

This commit is contained in:
Suherdy Yacob 2026-05-06 10:35:26 +07:00
parent 7da10ccb15
commit 8dccf0cd9a
3 changed files with 20 additions and 5 deletions

View File

@ -6,7 +6,7 @@ class HrExpensePaymentWizard(models.TransientModel):
_description = 'Expense Payment Wizard'
expense_sheet_id = fields.Many2one('hr.expense.sheet', required=True)
amount = fields.Monetary(string='Payment Amount', required=True, readonly=True)
amount = fields.Monetary(string='Payment Amount', required=True)
currency_id = fields.Many2one('res.currency', related='expense_sheet_id.currency_id')
company_id = fields.Many2one('res.company', related='expense_sheet_id.company_id')

View File

@ -155,7 +155,12 @@ class HrExpenseRealization(models.Model):
# Credit for Advance clearing
# We clear the remaining advance amount in the first realization for an expense.
original_paid = self.expense_id.total_amount
# Use proportional share of actual amount paid if payment was different from requested total
sheet = self.expense_id.sheet_id
if sheet.total_amount:
original_paid = self.expense_id.total_amount * (sheet.amount_paid / sheet.total_amount)
else:
original_paid = 0.0
# Find already cleared advance amount from previous posted moves targeting this expense and advance account
cleared_before = sum(self.env['account.move.line'].search([

View File

@ -81,7 +81,7 @@ class HrExpenseSheet(models.Model):
help="Total amount paid by the finance team (Total - Residual)."
)
@api.depends('account_move_ids.line_ids.matched_debit_ids', 'account_move_ids.line_ids.matched_credit_ids', 'total_amount', 'amount_residual')
@api.depends('account_move_ids.line_ids.matched_debit_ids', 'account_move_ids.line_ids.matched_credit_ids', 'account_move_ids.payment_id.amount', 'account_move_ids.payment_id.state', 'total_amount', 'amount_residual')
def _compute_amount_paid(self):
for sheet in self:
total_paid = 0.0
@ -120,6 +120,13 @@ class HrExpenseSheet(models.Model):
total_paid += abs(counterpart.balance)
seen_move_line_ids.add(counterpart.id)
# Direct payments linked to moves (handles non-reconciled company advances)
for move in sheet.account_move_ids:
if move.payment_id and move.payment_id.state not in ('draft', 'cancel'):
if move.payment_id.id not in seen_payment_ids:
total_paid += move.payment_id.amount
seen_payment_ids.add(move.payment_id.id)
# If no bank transactions found but report is clearly paid/partially paid,
# fall back to standard calculation for non-bank flows (e.g. manual journal reconciliation)
if not total_paid and sheet.total_amount != sheet.amount_residual:
@ -169,11 +176,14 @@ class HrExpenseSheet(models.Model):
payments = moves.mapped('payment_id')
unmatched_payments = payments.filtered(lambda p: not p.is_matched)
if unmatched_payments:
if sheet.amount_paid < sheet.total_amount:
sheet.payment_state = 'partial'
elif unmatched_payments:
sheet.payment_state = 'in_payment'
else:
sheet.payment_state = 'paid'
sheet.amount_residual = 0.
sheet.amount_residual = max(0.0, sheet.total_amount - sheet.amount_paid)
else:
sheet.payment_state = 'reversed'
sheet.amount_residual = sum(sheet.account_move_ids.mapped('amount_residual'))