fix: refine expense sheet state transition logic to correctly handle canceled or draft account moves

This commit is contained in:
Suherdy Yacob 2026-04-06 11:39:53 +07:00
parent db722f001c
commit e659fe5edf

View File

@ -18,11 +18,12 @@ class HrExpenseSheet(models.Model):
super()._compute_state() super()._compute_state()
for sheet in self: for sheet in self:
# FIX: If we have moves but they are ALL canceled, Odoo super() incorrectly sets state='post'. # FIX: If we have moves but they are ALL canceled/draft, Odoo super() incorrectly sets state='post' or 'done'.
# We must force it back to approval_state or draft. # We must force it back to approval_state (Approved) or draft.
active_moves = sheet.account_move_ids.filtered(lambda m: m.state != 'cancel') active_moves = sheet.account_move_ids.filtered(lambda m: m.state == 'posted')
if not active_moves and sheet.state == 'post': if not active_moves:
sheet.state = sheet.approval_state or 'draft' if sheet.state in ('post', 'done', 'wait_post'):
sheet.state = sheet.approval_state or 'draft'
# Check for Company Account expenses # Check for Company Account expenses
company_paid = sheet.expense_line_ids.filtered(lambda e: e.payment_mode == 'company_account') company_paid = sheet.expense_line_ids.filtered(lambda e: e.payment_mode == 'company_account')
@ -37,8 +38,12 @@ class HrExpenseSheet(models.Model):
# Also consider payment state: if it's NOT paid or in_payment, it should definitely stay in the state super() set (e.g. 'posted') # 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'. # Standard Odoo sets state='done' when payment_state is 'paid' or 'in_payment'.
if sheet.receipt_status != 'received' or not has_posted_realization: if sheet.payment_state in ('paid', 'in_payment'):
sheet.state = 'wait_post' if sheet.receipt_status != 'received' or not has_posted_realization:
sheet.state = 'wait_post'
else:
# If not paid, it should drop back
sheet.state = sheet.approval_state or 'draft'
if original_states.get(sheet.id) != 'done' and sheet.state == 'done': if original_states.get(sheet.id) != 'done' and sheet.state == 'done':
# Transitioned to 'Paid' # Transitioned to 'Paid'