From d436c336b980f003191e6135d972970fc320c5c5 Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Mon, 6 Apr 2026 10:56:18 +0700 Subject: [PATCH] fix: update expense sheet state synchronization on payment changes and adjust UI visibility for wait_post status --- models/account_payment.py | 19 +++++++++++++++++++ models/hr_expense_sheet.py | 35 ++++++++++++++++++++++++++++++++--- views/hr_expense_views.xml | 18 +++++++++++++++--- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/models/account_payment.py b/models/account_payment.py index c9327b4..8008a9a 100644 --- a/models/account_payment.py +++ b/models/account_payment.py @@ -34,3 +34,22 @@ class AccountPayment(models.Model): return res return super()._synchronize_to_moves(changed_fields) + + def action_cancel(self): + res = super().action_cancel() + for payment in self: + if payment.expense_sheet_id: + payment.expense_sheet_id._compute_state() + # Also check if it's linked via realization + if payment.realization_id and payment.realization_id.expense_sheet_id: + payment.realization_id.expense_sheet_id._compute_state() + return res + + def action_draft(self): + res = super().action_draft() + for payment in self: + if payment.expense_sheet_id: + payment.expense_sheet_id._compute_state() + if payment.realization_id and payment.realization_id.expense_sheet_id: + payment.realization_id.expense_sheet_id._compute_state() + return res diff --git a/models/hr_expense_sheet.py b/models/hr_expense_sheet.py index 104aa3b..1b0ae73 100644 --- a/models/hr_expense_sheet.py +++ b/models/hr_expense_sheet.py @@ -20,13 +20,15 @@ class HrExpenseSheet(models.Model): company_paid = sheet.expense_line_ids.filtered(lambda e: e.payment_mode == 'company_account') if company_paid: - # If Odoo thought it was 'done' (paid), we might need to hold it at 'wait_post' + # If Odoo thought it was 'done' (fully or partially paid/in_payment), + # we may need to hold it at 'wait_post' until realization is complete. if sheet.state == 'done': - # All receipts must be marked received (checked earlier by _compute_receipt_status) - # We also check if at least one realization exists and all are posted realizations = company_paid.mapped('realization_ids') has_posted_realization = realizations and all(r.state == 'posted' for r in realizations) + # Also consider payment state: if it's NOT paid or in_payment, it should definitely stay in the state super() set (e.g. 'posted') + # Standard Odoo sets state='done' when payment_state is 'paid' or 'in_payment'. + if sheet.receipt_status != 'received' or not has_posted_realization: sheet.state = 'wait_post' @@ -134,3 +136,30 @@ class HrExpenseSheet(models.Model): sheet.receipt_status = 'received' else: sheet.receipt_status = 'pending' + + def action_reset_expense_sheets(self): + """ + Overriding reset to handle realizations. + If a realization is posted, we should probably warn or at least prevent + resetting if we want strict audit. For now, we'll allow it but + cancel any draft/confirmed realizations. + """ + for sheet in self: + realizations = sheet.expense_line_ids.mapped('realization_ids') + posted_realizations = realizations.filtered(lambda r: r.state == 'posted') + if posted_realizations: + raise UserError(_("You cannot reset this report because it has one or more Posted Realizations (%s). Please reverse or cancel the realization journal entries first.") % ", ".join(posted_realizations.mapped('name'))) + + # Reset draft/confirmed ones back to draft if resetting the sheet + realizations.filtered(lambda r: r.state != 'posted').write({'state': 'draft'}) + + return super().action_reset_expense_sheets() + + def action_refuse_expense_sheets(self): + """ Handle realizations on refusal as well. """ + for sheet in self: + realizations = sheet.expense_line_ids.mapped('realization_ids') + if realizations.filtered(lambda r: r.state == 'posted'): + raise UserError(_("You cannot refuse this report because it has Posted Realizations. Revert them first.")) + realizations.write({'state': 'draft'}) + return super().action_refuse_expense_sheets() diff --git a/views/hr_expense_views.xml b/views/hr_expense_views.xml index a74ff89..bc6691d 100644 --- a/views/hr_expense_views.xml +++ b/views/hr_expense_views.xml @@ -136,13 +136,25 @@ hr.expense.sheet - - - account.group_account_invoice + + + state not in ['approve', 'post', 'done', 'cancel', 'wait_post'] + + state not in ['submit', 'approve', 'post', 'wait_post'] + + draft,submit,approve,post,wait_post,done + +