diff --git a/models/hr_expense_sheet.py b/models/hr_expense_sheet.py index 0f76e9f..4d1bfc4 100644 --- a/models/hr_expense_sheet.py +++ b/models/hr_expense_sheet.py @@ -18,11 +18,12 @@ class HrExpenseSheet(models.Model): super()._compute_state() for sheet in self: - # FIX: If we have moves but they are ALL canceled, Odoo super() incorrectly sets state='post'. - # We must force it back to approval_state or draft. - active_moves = sheet.account_move_ids.filtered(lambda m: m.state != 'cancel') - if not active_moves and sheet.state == 'post': - sheet.state = sheet.approval_state or 'draft' + # 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 (Approved) or draft. + active_moves = sheet.account_move_ids.filtered(lambda m: m.state == 'posted') + if not active_moves: + if sheet.state in ('post', 'done', 'wait_post'): + sheet.state = sheet.approval_state or 'draft' # Check for Company Account expenses 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') # 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' + if sheet.payment_state in ('paid', 'in_payment'): + 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': # Transitioned to 'Paid'