fix: update expense sheet state synchronization on payment changes and adjust UI visibility for wait_post status
This commit is contained in:
parent
c9c5a45837
commit
d436c336b9
@ -34,3 +34,22 @@ class AccountPayment(models.Model):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
return super()._synchronize_to_moves(changed_fields)
|
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
|
||||||
|
|||||||
@ -20,13 +20,15 @@ class HrExpenseSheet(models.Model):
|
|||||||
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')
|
||||||
|
|
||||||
if company_paid:
|
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':
|
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')
|
realizations = company_paid.mapped('realization_ids')
|
||||||
has_posted_realization = realizations and all(r.state == 'posted' for r in realizations)
|
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:
|
if sheet.receipt_status != 'received' or not has_posted_realization:
|
||||||
sheet.state = 'wait_post'
|
sheet.state = 'wait_post'
|
||||||
|
|
||||||
@ -134,3 +136,30 @@ class HrExpenseSheet(models.Model):
|
|||||||
sheet.receipt_status = 'received'
|
sheet.receipt_status = 'received'
|
||||||
else:
|
else:
|
||||||
sheet.receipt_status = 'pending'
|
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()
|
||||||
|
|||||||
@ -136,13 +136,25 @@
|
|||||||
<field name="model">hr.expense.sheet</field>
|
<field name="model">hr.expense.sheet</field>
|
||||||
<field name="inherit_id" ref="hr_expense.view_hr_expense_sheet_form"/>
|
<field name="inherit_id" ref="hr_expense.view_hr_expense_sheet_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<!-- Restrict Posting to Accountants -->
|
<!-- Update standard Reset to Draft and Cancel buttons to include 'wait_post' -->
|
||||||
<xpath expr="//button[@name='action_register_payment']" position="attributes">
|
<xpath expr="//header//button[@name='action_reset_expense_sheets']" position="attributes">
|
||||||
<attribute name="groups">account.group_account_invoice</attribute>
|
<attribute name="invisible">state not in ['approve', 'post', 'done', 'cancel', 'wait_post']</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<xpath expr="//header//button[@name='action_refuse_expense_sheets']" position="attributes">
|
||||||
|
<attribute name="invisible">state not in ['submit', 'approve', 'post', 'wait_post']</attribute>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
<xpath expr="//field[@name='state']" position="attributes">
|
<xpath expr="//field[@name='state']" position="attributes">
|
||||||
<attribute name="statusbar_visible">draft,submit,approve,post,wait_post,done</attribute>
|
<attribute name="statusbar_visible">draft,submit,approve,post,wait_post,done</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<xpath expr="//header" position="inside">
|
||||||
|
<button name="_compute_state"
|
||||||
|
string="Recompute Status"
|
||||||
|
type="object"
|
||||||
|
groups="base.group_erp_manager"
|
||||||
|
class="btn btn-secondary"
|
||||||
|
help="Force refresh the report status based on current payments and receipts."/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
<xpath expr="//field[@name='expense_line_ids']/tree/field[@name='name']" position="before">
|
<xpath expr="//field[@name='expense_line_ids']/tree/field[@name='name']" position="before">
|
||||||
<field name="sequence_name" column_invisible="not parent.id"/>
|
<field name="sequence_name" column_invisible="not parent.id"/>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user