From a97ac8900429701e0cf415d85d4299042ff76bbd Mon Sep 17 00:00:00 2001 From: younes Date: Sun, 21 Dec 2025 19:04:42 +0100 Subject: [PATCH 1/2] [IMP] odex_benefit: IMP benefit --- odex25_benefit/odex_benefit/models/benefit.py | 57 +++++++++ .../odex_benefit/models/benefit_config.py | 1 + .../odex_benefit/models/family_members.py | 55 +++++++++ .../odex_benefit/models/seasonal_service.py | 2 +- .../views/benefit_config_view.xml | 4 +- .../odex_benefit/views/benefit_view.xml | 53 +++++++- .../odex_benefit/views/family_members.xml | 25 ++++ .../wizards/suspend_reason_wizard.py | 113 +++++++++++++----- .../wizards/suspend_reason_wizard.xml | 57 ++++++--- 9 files changed, 313 insertions(+), 54 deletions(-) diff --git a/odex25_benefit/odex_benefit/models/benefit.py b/odex25_benefit/odex_benefit/models/benefit.py index f75b4fda0..546f90687 100644 --- a/odex25_benefit/odex_benefit/models/benefit.py +++ b/odex25_benefit/odex_benefit/models/benefit.py @@ -608,6 +608,8 @@ class GrantBenefitProfile(models.Model): ('edit_info', 'Edit Information'), ('approved', 'Approved'), ('suspended', 'Suspended'), + ('resume_from_temporary', 'Resume from Temporary Suspension'), + ('resume_from_final', 'Resume from Final Suspension'), ('exception', 'Exception'), ], string='Action Type', default='new', tracking=True) contact_type = fields.Selection([ @@ -626,6 +628,11 @@ class GrantBenefitProfile(models.Model): total_mother_families = fields.Integer(string="Mother Families", compute='_compute_total_families') total_replacement_mother_families = fields.Integer(string="Replacement Mother Families", compute='_compute_total_families') final_suspend_date = fields.Date(string="Final Suspend Date") + resume_reason_id = fields.Many2one('suspend.reason', string='Return Reason') + resume_date = fields.Date(string="Return Date") + resume_notes = fields.Text(string="Return Notes") + + _sql_constraints = [ ('unique_code', "unique (code) WHERE state NOT IN ('draft', 'new')", 'This code already exists') @@ -1683,10 +1690,28 @@ class GrantBenefitProfile(models.Model): 'target': 'new', } + def action_resume_family(self): + ctx = dict(self.env.context or {}) + ctx['resume_family'] = True + return { + 'name': _('Resume Reason Wizard'), + 'view_mode': 'form', + 'view_type': 'form', + 'type': 'ir.actions.act_window', + 'res_model': 'suspend.reason.wizard', + 'view_id': self.env.ref('odex_benefit.view_resume_reason_wizard_form').id, + 'target': 'new', + 'context': ctx, + } + def action_suspend_first_accept(self): for rec in self: rec.state = 'first_approve' + def action_resume_first_accept(self): + for rec in self: + rec.state = 'first_approve' + def action_suspend_second_accept(self): for rec in self: rec.action_type = 'suspended' @@ -1697,6 +1722,14 @@ class GrantBenefitProfile(models.Model): else: rec.state = 'suspended_second_approve' + def action_resume_second_accept(self): + for rec in self: + if rec.suspend_reason.need_service_manager_approval: + rec.state = 'family_services_manager' + else: + rec.state = 'second_approve' + rec.action_type = 'approved' + def action_suspend_third_accept(self): for rec in self: if rec.suspend_reason.suspend_type == 'temporarily_suspend': @@ -1704,6 +1737,22 @@ class GrantBenefitProfile(models.Model): else: rec.state = 'suspended_second_approve' + def action_resume_third_accept(self): + for rec in self: + rec.state = 'second_approve' + rec.action_type = 'approved' + + def action_final_suspend(self): + today = fields.Date.today() + for rec in self: + if rec.final_suspend_date and today >= rec.final_suspend_date: + rec.write({ + 'state': 'suspended_second_approve', + 'suspend_type': 'suspend', + }) + else: + raise UserError(_("Final suspension cannot be executed until after the specified final suspension date.")) + def action_auto_suspend(self): # Fetch grants in second approval state that are not excluded from suspension grants = self.env["grant.benefit"].search( @@ -1743,6 +1792,14 @@ class GrantBenefitProfile(models.Model): rec.action_type = 'approved' rec.get_member_income() + def action_reject_resume(self): + for rec in self: + if rec.action_type == 'resume_from_temporary': + rec.state = 'temporary_suspended' + elif rec.action_type == 'resume_from_final': + rec.state = 'suspended_second_approve' + rec.action_type = 'suspended' + #Excption Work flow def action_exception(self): return { diff --git a/odex25_benefit/odex_benefit/models/benefit_config.py b/odex25_benefit/odex_benefit/models/benefit_config.py index 9f6b14790..3339994f8 100644 --- a/odex25_benefit/odex_benefit/models/benefit_config.py +++ b/odex25_benefit/odex_benefit/models/benefit_config.py @@ -723,6 +723,7 @@ class SuspendReason(models.Model): is_stop_reason = fields.Boolean(string="Stop Reason",default=False) is_reject_reason = fields.Boolean(string="Reject Reason",default=False) is_return_reason = fields.Boolean(string="Return Reason",default=False) + is_resume_reason = fields.Boolean(string="Resume Reason", default=False) is_family_return_reason = fields.Boolean(string="Family Return Reason",default=False) is_incomplete_visit_reason = fields.Boolean(string="Incomplete Visit Reason",default=False) active = fields.Boolean(default=True) diff --git a/odex25_benefit/odex_benefit/models/family_members.py b/odex25_benefit/odex_benefit/models/family_members.py index 526b36411..a7bea4e46 100644 --- a/odex25_benefit/odex_benefit/models/family_members.py +++ b/odex25_benefit/odex_benefit/models/family_members.py @@ -239,6 +239,8 @@ class FamilyMemberProfile(models.Model): ('edit_info', 'Edit Information'), ('approved', 'Approved'), ('suspended', 'Suspended'), + ('resume_from_temporary', 'Resume from Temporary Suspension'), + ('resume_from_final', 'Resume from Final Suspension'), ('exception', 'Exception'), ], string='Action Type', default='new', tracking=True) member_status = fields.Selection(selection=[ @@ -276,6 +278,9 @@ class FamilyMemberProfile(models.Model): non_benefit_reason = fields.Text(string="Non Benefit Reason", tracking=True) final_suspend_date = fields.Date(string="Final Suspend Date") active = fields.Boolean(string='Active', default=True) + resume_reason_id = fields.Many2one('suspend.reason', string='Return Reason') + resume_date = fields.Date(string="Return Date") + resume_notes = fields.Text(string="Return Notes") # def create(self, vals): # for line_vals in vals: @@ -828,10 +833,39 @@ class FamilyMemberProfile(models.Model): 'target': 'new', } + def action_resume_member(self): + ctx = dict(self.env.context or {}) + ctx['resume_family'] = True + return { + 'name': _('Resume Reason Wizard'), + 'view_mode': 'form', + 'view_type': 'form', + 'type': 'ir.actions.act_window', + 'res_model': 'suspend.reason.wizard', + 'view_id': self.env.ref('odex_benefit.view_resume_reason_wizard_form').id, + 'target': 'new', + 'context': ctx, + } + + def action_final_suspend(self): + today = fields.Date.today() + for rec in self: + if rec.final_suspend_date and today >= rec.final_suspend_date: + rec.write({ + 'state': 'suspended_second_approve', + 'suspend_type': 'suspend', + }) + else: + raise UserError(_("Final suspension cannot be executed until after the specified final suspension date.")) + def action_suspend_first_accept(self): for rec in self: rec.state_a = 'first_approve' + def action_resume_first_accept(self): + for rec in self: + rec.state_a = 'first_approve' + def action_suspend_second_accept(self): for rec in self: if rec.suspend_reason.need_service_manager_approval: @@ -841,6 +875,14 @@ class FamilyMemberProfile(models.Model): else: rec.state_a = 'suspended_second_approve' + def action_resume_second_accept(self): + for rec in self: + if rec.suspend_reason.need_service_manager_approval: + rec.state_a = 'family_services_manager' + else: + rec.state_a = 'second_approve' + rec.action_type = 'approved' + def action_suspend_third_accept(self): for rec in self: if rec.suspend_reason.suspend_type == 'temporarily_suspend': @@ -848,11 +890,24 @@ class FamilyMemberProfile(models.Model): else: rec.state_a = 'suspended_second_approve' + def action_resume_third_accept(self): + for rec in self: + rec.state_a = 'second_approve' + rec.action_type = 'approved' + def action_suspend_refuse(self): for rec in self: rec.state_a = 'second_approve' rec.is_member_workflow = False + def action_reject_resume(self): + for rec in self: + if rec.action_type == 'resume_from_temporary': + rec.state = 'temporary_suspended' + elif rec.action_type == 'resume_from_final': + rec.state = 'suspended_second_approve' + rec.action_type = 'suspended' + # Excption Work flow def action_exception(self): for rec in self: diff --git a/odex25_benefit/odex_benefit/models/seasonal_service.py b/odex25_benefit/odex_benefit/models/seasonal_service.py index f36fdd84b..d055db968 100644 --- a/odex25_benefit/odex_benefit/models/seasonal_service.py +++ b/odex25_benefit/odex_benefit/models/seasonal_service.py @@ -247,7 +247,7 @@ class SeasonalService(models.Model): 'price_unit': request.requested_service_amount, }) line_ids.append(invoice_line) - vendor_bill = self.env['account.move'].create({ + vendor_bill = self.env['account.move'].sudo().create({ 'move_type': 'in_invoice', 'partner_id': rec.service_type_id.service_producer_id.id, 'journal_id': validation_setting.journal_id.id, diff --git a/odex25_benefit/odex_benefit/views/benefit_config_view.xml b/odex25_benefit/odex_benefit/views/benefit_config_view.xml index 95b083c69..0956492cf 100644 --- a/odex25_benefit/odex_benefit/views/benefit_config_view.xml +++ b/odex25_benefit/odex_benefit/views/benefit_config_view.xml @@ -943,10 +943,11 @@ + + attrs="{'invisible': [('is_stop_reason','=',False),('is_resume_reason','=',False)]}"/> + diff --git a/odex25_benefit/odex_benefit/views/benefit_view.xml b/odex25_benefit/odex_benefit/views/benefit_view.xml index 07c2c216a..0308d9b34 100644 --- a/odex25_benefit/odex_benefit/views/benefit_view.xml +++ b/odex25_benefit/odex_benefit/views/benefit_view.xml @@ -431,6 +431,32 @@ string="Third Approve" class="oe_highlight" groups="odex_benefit.group_benefit_manager" attrs="{'invisible': ['|',('action_type','!=','suspended'),('state', 'not in', ['family_services_manager'])]}"/> + +