[IMP] odex_benefit: IMP benefit

This commit is contained in:
younes 2026-01-11 11:43:05 +01:00
parent f00f9cbeb8
commit f5db75f449
8 changed files with 72 additions and 26 deletions

View File

@ -391,7 +391,7 @@ class GrantBenefitProfile(models.Model):
total_income = fields.Float('Total Income', compute="get_total_income", store=True) total_income = fields.Float('Total Income', compute="get_total_income", store=True)
benefit_member_count = fields.Integer(string="Members count", compute="get_members_count") benefit_member_count = fields.Integer(string="Members count", compute="get_members_count")
non_member_count = fields.Integer(string="Non Benefit Members count", compute="get_non_members_count") non_member_count = fields.Integer(string="Non Benefit Members count", compute="get_non_members_count")
member_income = fields.Integer(string="Member Income Average", compute="get_member_income",store=True,tracking=True) member_income = fields.Float(string="Member Income Average", compute="get_member_income",store=True,tracking=True)
request_activity_id = fields.Many2one('mail.activity') request_activity_id = fields.Many2one('mail.activity')
state = fields.Selection([ state = fields.Selection([
('draft', 'Draft'), ('draft', 'Draft'),
@ -646,6 +646,15 @@ class GrantBenefitProfile(models.Model):
) )
current_rent_contract_id = fields.Many2one('rent.contract',string='Current Active Rent Contract',compute='_compute_current_rent_contract',store=True,) current_rent_contract_id = fields.Many2one('rent.contract',string='Current Active Rent Contract',compute='_compute_current_rent_contract',store=True,)
notes = fields.Html(string='Notes', tracking=True) notes = fields.Html(string='Notes', tracking=True)
color = fields.Integer(string="Color Index",related='benefit_category_id.color')
decoration_color = fields.Selection([
('danger', 'Red'),
('success', 'Green'),
('warning', 'Orange'),
('info', 'Blue'),
('primary', 'Primary'),
('muted', 'Muted'),
], default='info',related='benefit_category_id.decoration_color')
_sql_constraints = [ _sql_constraints = [
('unique_code', "unique (code) WHERE state NOT IN ('draft', 'new')", 'This code already exists') ('unique_code', "unique (code) WHERE state NOT IN ('draft', 'new')", 'This code already exists')
@ -1617,7 +1626,7 @@ class GrantBenefitProfile(models.Model):
self.partner_id.send_sms_notification(message, self.phone) self.partner_id.send_sms_notification(message, self.phone)
for rec in self: for rec in self:
visits = self.env['visit.location'].search([('benefit_id', '=', rec.id),('state', 'not in', ['close', 'done'])]) visits = self.env['visit.location'].search([('benefit_id', '=', rec.id),('state', 'not in', ['close', 'done'])])
if rec.action_type == 'new' and not rec.benefit_category_id.is_benefit: if not rec.benefit_category_id.is_benefit:
raise ValidationError(_("The procedure cannot be continued; the family is not a beneficiary.")) raise ValidationError(_("The procedure cannot be continued; the family is not a beneficiary."))
if rec.action_type == 'new' and visits: if rec.action_type == 'new' and visits:
raise ValidationError(_("Please complete your pending visits before proceeding.")) raise ValidationError(_("Please complete your pending visits before proceeding."))
@ -2301,14 +2310,16 @@ class GrantBenefitProfile(models.Model):
@api.depends('benefit_member_count','total_income','total_expenses') @api.depends('benefit_member_count','total_income','total_expenses')
def get_member_income(self): def get_member_income(self):
for ben in self: for ben in self:
income = 0.0
family_income = ben.total_income - ben.total_expenses family_income = ben.total_income - ben.total_expenses
if ben.benefit_member_count: if ben.benefit_member_count:
if ben.benefit_member_count > 3: if ben.benefit_member_count > 3:
ben.member_income = family_income / ben.benefit_member_count income = family_income / ben.benefit_member_count
elif ben.benefit_member_count <= 3: elif ben.benefit_member_count <= 3:
ben.member_income = family_income / 3 income = family_income / 3
else: else:
ben.member_income = family_income income = family_income
ben.member_income = income
@api.depends("member_income") @api.depends("member_income")
def get_benefit_category(self): def get_benefit_category(self):

View File

@ -29,6 +29,16 @@ class BenefitCategory(models.Model):
state = fields.Selection([('draft', 'Draft'), state = fields.Selection([('draft', 'Draft'),
('approve', 'Approved'), ('approve', 'Approved'),
('rejected', 'Rejected'), ], default='draft') ('rejected', 'Rejected'), ], default='draft')
color = fields.Integer(string="Color Index", default=0)
decoration_color = fields.Selection([
('danger', 'Red'),
('success', 'Green'),
('warning', 'Orange'),
('info', 'Blue'),
('primary', 'Primary'),
('muted', 'Muted'),
])
def get_benefits_total(self): def get_benefits_total(self):
for rec in self: for rec in self:
@ -754,6 +764,7 @@ class SuspendReason(models.Model):
need_service_manager_approval = fields.Boolean( need_service_manager_approval = fields.Boolean(
string="Needs Service Manager Approval" string="Needs Service Manager Approval"
) )
check_all_members_non_benefit = fields.Boolean(string="Check All Members Non-Benefit",default=False)
class ReturnReason(models.Model): class ReturnReason(models.Model):
_name = "return.reason" _name = "return.reason"
@ -1024,8 +1035,8 @@ class RentContract(models.Model):
('1', 'Yearly'), ('1', 'Yearly'),
('2', 'Half-yearly'), ('2', 'Half-yearly'),
('4', 'Quarterly'), ('4', 'Quarterly'),
('5', 'Monthly'), ('12', 'Monthly'),
], string='Payment Type', required=True) ], string='Payment Type', required=True, default='2')
rent_amount = fields.Float(string='Rent Amount', required=True) rent_amount = fields.Float(string='Rent Amount', required=True)
contract_attachment = fields.Many2many( contract_attachment = fields.Many2many(
'ir.attachment', 'rent_contract_attachment_rel', 'ir.attachment', 'rent_contract_attachment_rel',

View File

@ -437,14 +437,10 @@ class ServiceRequest(models.Model):
else: else:
rec.has_money_field_is_appearance = False rec.has_money_field_is_appearance = False
@api.depends('family_id.mother_marital_conf', 'family_id.replacement_mother_marital_conf') @api.depends('family_id.mother_marital_conf')
def _compute_is_orphan(self): def _compute_is_orphan(self):
for rec in self: for rec in self:
if not rec.family_id.add_replacement_mother: rec.is_orphan = bool(getattr(rec.family_id.mother_marital_conf, 'is_dead', False))
mother_dead = bool(getattr(rec.family_id.mother_marital_conf, 'is_dead', False))
else:
mother_dead = bool(getattr(rec.family_id.replacement_mother_marital_conf, 'is_dead', False))
rec.is_orphan = mother_dead
def _expand_states(self, states, domain, order): def _expand_states(self, states, domain, order):
return [key for key, val in type(self).state.selection] return [key for key, val in type(self).state.selection]

View File

@ -40,9 +40,14 @@
<!-- <field name="age_to" attrs="{'readonly':[('state','!=','draft')],'required':True}"/>--> <!-- <field name="age_to" attrs="{'readonly':[('state','!=','draft')],'required':True}"/>-->
<!-- <p>Year</p>--> <!-- <p>Year</p>-->
<!-- </group>--> <!-- </group>-->
<group>
<group> <group>
<field name="is_benefit" string="Is Benefit" widget="boolean_toggle"/> <field name="is_benefit" string="Is Benefit" widget="boolean_toggle"/>
</group> </group>
<group>
<field name="decoration_color"/>
</group>
</group>
<group invisible="1"> <group invisible="1">
<field name="expenses_ids"> <field name="expenses_ids">
<tree editable="bottom"> <tree editable="bottom">
@ -918,6 +923,8 @@
attrs="{'invisible': [('is_stop_reason','=',False),('is_resume_reason','=',False)]}"/> attrs="{'invisible': [('is_stop_reason','=',False),('is_resume_reason','=',False)]}"/>
<field name="suspend_type" <field name="suspend_type"
attrs="{'invisible': [('is_stop_reason','=',False)]}"/> attrs="{'invisible': [('is_stop_reason','=',False)]}"/>
<field name="check_all_members_non_benefit" widget="boolean_toggle"
attrs="{'invisible': [('is_stop_reason','=',False)]}"/>
<field name="days_before_final_suspend" <field name="days_before_final_suspend"
attrs="{'invisible': [('suspend_type','!=','temporarily_suspend')]}"/> attrs="{'invisible': [('suspend_type','!=','temporarily_suspend')]}"/>
<field name="allow_service" widget="boolean_toggle"/> <field name="allow_service" widget="boolean_toggle"/>
@ -1530,7 +1537,7 @@
</group> </group>
<group> <group>
<field name="state"/> <field name="state"/>
<field name="payment_type"/> <field name="payment_type" invisible="1"/>
<field name="rent_amount"/> <field name="rent_amount"/>
<field name="contract_attachment" widget="many2many_attachment_preview"/> <field name="contract_attachment" widget="many2many_attachment_preview"/>
<field name="electricity_bill_attachment" widget="many2many_attachment_preview"/> <field name="electricity_bill_attachment" widget="many2many_attachment_preview"/>

View File

@ -435,16 +435,31 @@
<button name="action_resume_first_accept" type="object" <button name="action_resume_first_accept" type="object"
string="Resume Approval by Operations Head" class="oe_highlight" string="Resume Approval by Operations Head" class="oe_highlight"
attrs="{'invisible': ['|',('action_type','not in',['resume_from_final','resume_from_temporary']),('state', 'not in', ['waiting_approve'])]}" attrs="{'invisible': ['|',('action_type','not in',['resume_from_final','resume_from_temporary']),('state', 'not in', ['waiting_approve'])]}"
groups="odex_benefit.group_benefit_woman_commitee,odex_benefit.group_benefit_manager" groups="odex_benefit.group_benefit_woman_commitee"
/>
<button name="action_reject_resume" type="object"
string="Reject Resume" class="btn btn-danger"
groups="odex_benefit.group_benefit_woman_commitee"
attrs="{'invisible': ['|',('action_type','not in',['resume_from_final','resume_from_temporary']),('state', '!=', 'waiting_approve')]}"
/> />
<button name="action_resume_second_accept" type="object" <button name="action_resume_second_accept" type="object"
string="Resume Approval by Branch Manager" class="oe_highlight" string="Resume Approval by Branch Manager" class="oe_highlight"
groups="odex_benefit.group_benefit_branch_manager,odex_benefit.group_benefit_manager" groups="odex_benefit.group_benefit_branch_manager"
attrs="{'invisible': ['|',('action_type','not in',['resume_from_final','resume_from_temporary']),('state', 'not in', ['first_approve'])]}"/> attrs="{'invisible': ['|',('action_type','not in',['resume_from_final','resume_from_temporary']),('state', 'not in', ['first_approve'])]}"/>
<button name="action_reject_resume" type="object"
string="Reject Resume" class="btn btn-danger"
groups="odex_benefit.group_benefit_branch_manager"
attrs="{'invisible': ['|',('action_type','not in',['resume_from_final','resume_from_temporary']),('state', '!=', 'first_approve')]}"
/>
<button name="action_resume_third_accept" type="object" <button name="action_resume_third_accept" type="object"
string="Resume Approval by Family Services Manager" class="oe_highlight" string="Resume Approval by Family Services Manager" class="oe_highlight"
groups="odex_benefit.group_benefit_manager" groups="odex_benefit.group_benefit_manager"
attrs="{'invisible': ['|',('action_type','not in',['resume_from_final','resume_from_temporary']),('state', 'not in', ['family_services_manager'])]}"/> attrs="{'invisible': ['|',('action_type','not in',['resume_from_final','resume_from_temporary']),('state', 'not in', ['family_services_manager'])]}"/>
<button name="action_reject_resume" type="object"
string="Reject Resume" class="btn btn-danger"
groups="odex_benefit.group_benefit_manager"
attrs="{'invisible': ['|',('action_type','not in',['resume_from_final','resume_from_temporary']),('state', '!=', 'family_services_manager')]}"
/>
<button name="action_resume_family" string="Resume Family Service" <button name="action_resume_family" string="Resume Family Service"
type="object" class="btn btn-success" type="object" class="btn btn-success"
attrs="{'invisible': [('state', 'not in', ['temporary_suspended', 'suspended_second_approve'])]}" attrs="{'invisible': [('state', 'not in', ['temporary_suspended', 'suspended_second_approve'])]}"
@ -453,10 +468,6 @@
string="Final Suspension" class="btn btn-danger" string="Final Suspension" class="btn btn-danger"
attrs="{'invisible': [('state', '!=', 'temporary_suspended')]}" attrs="{'invisible': [('state', '!=', 'temporary_suspended')]}"
groups="odex_benefit.group_benefit_manager"/> groups="odex_benefit.group_benefit_manager"/>
<button name="action_reject_resume" type="object"
string="Reject Resume" class="btn btn-danger"
attrs="{'invisible': ['|',('action_type','not in',['resume_from_final','resume_from_temporary']),('state', 'not in', ['waiting_approve','first_approve','family_services_manager'])]}"
/>
<button name="action_suspend_refuse" type="object" <button name="action_suspend_refuse" type="object"
string="Suspend Refuse" class="oe_highlight" string="Suspend Refuse" class="oe_highlight"
attrs="{'invisible': ['|',('action_type','!=','suspended'),('state', 'not in', ['waiting_approve','first_approve','family_services_manager','suspended_second_approve'])]}" attrs="{'invisible': ['|',('action_type','!=','suspended'),('state', 'not in', ['waiting_approve','first_approve','family_services_manager','suspended_second_approve'])]}"
@ -2082,10 +2093,16 @@
<field name="name">grant.benefit.tree</field> <field name="name">grant.benefit.tree</field>
<field name="model">grant.benefit</field> <field name="model">grant.benefit</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string=" Benefit" create="0"> <tree string=" Benefit" create="0" decoration-danger="decoration_color == 'danger'"
decoration-success="decoration_color == 'success'"
decoration-warning="decoration_color == 'warning'"
decoration-info="decoration_color == 'info'"
decoration-primary="decoration_color == 'primary'"
decoration-muted="decoration_color == 'muted'">
<field name="decoration_color" invisible="1"/>
<field name="code" string="Family Code" decoration-bf="1"/> <field name="code" string="Family Code" decoration-bf="1"/>
<field name="benefit_partner_name"/> <field name="benefit_partner_name"/>
<field name="benefit_category_id"/> <field name="benefit_category_id" decoration-bf="1"/>
<field name="create_date" optional="hide"/> <field name="create_date" optional="hide"/>
<field name="approve_date" optional="hide"/> <field name="approve_date" optional="hide"/>
<field name="meal_card" optional="hide"/> <field name="meal_card" optional="hide"/>

View File

@ -177,7 +177,7 @@
<button name="action_open_related_move_records" <button name="action_open_related_move_records"
class="oe_stat_button" class="oe_stat_button"
icon="fa-file-text-o" icon="fa-file-text-o"
type="object" attrs="{'invisible': [('total_moves', '=', 0)]}"> type="object" attrs="{'invisible': ['|',('total_moves', '=', 0),('payment_order_count','!=','0')]}">
<field name="total_moves" widget="statinfo" string="Total Moves"/> <field name="total_moves" widget="statinfo" string="Total Moves"/>
</button> </button>
</div> </div>

View File

@ -89,6 +89,10 @@ class SuspendReasonWizard(models.TransientModel):
'resume_notes': rec.suspend_description, 'resume_notes': rec.suspend_description,
} }
else: else:
if rec.suspend_reason.check_all_members_non_benefit:
if benefit.benefit_member_count > 0:
raise UserError(
_("Operation not allowed: The family has %s benefit member(s). All members must be non-benefit to proceed.") % benefit.benefit_member_count)
benefit.member_ids.write({ benefit.member_ids.write({
'is_excluded_suspension': False, 'is_excluded_suspension': False,
'is_member_workflow': False, 'is_member_workflow': False,

View File

@ -13,7 +13,7 @@
<field name="suspend_description"/> <field name="suspend_description"/>
</group> </group>
<group> <group>
<field name="suspend_attachment" required="1"/> <field name="suspend_attachment"/>
<field name="final_suspend_date" readonly="1" force_save="1"/> <field name="final_suspend_date" readonly="1" force_save="1"/>
</group> </group>
</group> </group>
@ -39,7 +39,7 @@
<field name="suspend_description"/> <field name="suspend_description"/>
</group> </group>
<group> <group>
<field name="suspend_attachment" required="1"/> <field name="suspend_attachment"/>
<field name="final_suspend_date" readonly="1" force_save="1"/> <field name="final_suspend_date" readonly="1" force_save="1"/>
</group> </group>
</group> </group>