From 9159dbd18395a9f14f8e0e06b523ef8dc16bef23 Mon Sep 17 00:00:00 2001 From: younes Date: Mon, 19 Jan 2026 11:25:52 +0100 Subject: [PATCH 01/27] [IMP] odex_benefit: IMP benefit --- odex25_benefit/odex_benefit/i18n/ar_001.po | 6 +++- .../odex_benefit/models/family_members.py | 35 +++++++++++++------ .../odex_benefit/views/family_members.xml | 22 ++++++------ .../wizards/suspend_reason_wizard.py | 4 +++ 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/odex25_benefit/odex_benefit/i18n/ar_001.po b/odex25_benefit/odex_benefit/i18n/ar_001.po index 330cfca57..37743d6c2 100644 --- a/odex25_benefit/odex_benefit/i18n/ar_001.po +++ b/odex25_benefit/odex_benefit/i18n/ar_001.po @@ -18094,11 +18094,15 @@ msgid "Resume Approval by Family Services Manager" msgstr "اعتماد مديرة خدمات المستفيدين للإعادة" #. module: odex_benefit -#: model_terms:ir.ui.view,arch_db:odex_benefit.family_member_form #: model_terms:ir.ui.view,arch_db:odex_benefit.grant_benefit_form msgid "Resume Family Service" msgstr "إعادة الأسرة للخدمة" +#. module: odex_benefit +#: model_terms:ir.ui.view,arch_db:odex_benefit.family_member_form +msgid "Resume Member Service" +msgstr "إعادة الفرد للخدمة" + #. module: odex_benefit #: model_terms:ir.ui.view,arch_db:odex_benefit.family_member_form #: model_terms:ir.ui.view,arch_db:odex_benefit.grant_benefit_form diff --git a/odex25_benefit/odex_benefit/models/family_members.py b/odex25_benefit/odex_benefit/models/family_members.py index a34409bd2..e2ecf2073 100644 --- a/odex25_benefit/odex_benefit/models/family_members.py +++ b/odex25_benefit/odex_benefit/models/family_members.py @@ -567,6 +567,7 @@ class FamilyMemberProfile(models.Model): 'member_location_conf', 'state', 'is_dead', + 'is_work', 'benefit_id.member_ids.member_status', ) def check_member_status(self): @@ -698,8 +699,7 @@ class FamilyMemberProfile(models.Model): elif rec.minor_siblings and rec.age > minor_siblings_age: rec.member_status = 'non_benefit' reasons.append(_("She is over %s years of age.") % minor_siblings_age) - if rec.is_work and rec.member_income > max_income_for_benefit and rec.education_status in [ - 'educated'] and current_education_status_id.case_study == 'continuous': + if rec.is_work and rec.member_income > max_income_for_benefit: rec.member_status = 'non_benefit' reasons.append(_("She works with a salary greater than %s.") % max_income_for_benefit) if rec.is_work and rec.education_status in ['illiterate']: @@ -892,6 +892,11 @@ class FamilyMemberProfile(models.Model): # Member Suspend Manual def action_suspend(self): + ctx = dict(self.env.context or {}) + ctx.update({ + 'active_model': 'family.member', + 'active_id': self.id, + }) return { 'name': _('Suspend Reason Wizard'), 'view_mode': 'form', @@ -900,11 +905,17 @@ class FamilyMemberProfile(models.Model): 'res_model': 'suspend.reason.wizard', 'view_id': self.env.ref('odex_benefit.view_suspend_member_reason_wizard_form').id, 'target': 'new', + 'context': ctx, } def action_resume_member(self): ctx = dict(self.env.context or {}) - ctx['resume_family'] = True + #ctx['resume_family'] = True + ctx.update({ + 'resume_family': True, + 'active_model': 'family.member', + 'active_id': self.id, + }) return { 'name': _('Resume Reason Wizard'), 'view_mode': 'form', @@ -951,6 +962,7 @@ class FamilyMemberProfile(models.Model): rec.state_a = 'family_services_manager' else: rec.state_a = 'second_approve' + rec.is_member_workflow = False rec.action_type = 'approved' def action_suspend_third_accept(self): @@ -963,6 +975,7 @@ class FamilyMemberProfile(models.Model): def action_resume_third_accept(self): for rec in self: rec.state_a = 'second_approve' + rec.is_member_workflow = False rec.action_type = 'approved' def action_suspend_refuse(self): @@ -1136,28 +1149,28 @@ class FamilyMemberProfile(models.Model): for record in self: if not record.member_phone: continue - + phone = record.member_phone - + # Remove +966 prefix if present if phone.startswith('+966'): phone = phone[4:] record.member_phone = phone - + # Validate Saudi mobile pattern if re.match(SAUDI_MOBILE_PATTERN, phone) is None: raise ValidationError( _('Enter a valid Saudi mobile number')) - + # Check phone against family's main phones if record.benefit_id and phone in [ - record.benefit_id.phone, - record.benefit_id.phone2, + record.benefit_id.phone, + record.benefit_id.phone2, record.benefit_id.sms_phone ]: raise ValidationError( _("Phone number cannot be the same in The Family")) - + # Check for duplicate phone in other members (excluding current record) exist = self.search([ ('member_phone', '=', phone), @@ -1166,7 +1179,7 @@ class FamilyMemberProfile(models.Model): if exist: raise ValidationError( _("The phone Number already exists in Family with code %s") % exist.benefit_id.code) - + # Check if phone exists in grant.benefit exist_in_family = self.env["grant.benefit"].search([ '|', '|', diff --git a/odex25_benefit/odex_benefit/views/family_members.xml b/odex25_benefit/odex_benefit/views/family_members.xml index e62bd76b1..28578e741 100644 --- a/odex25_benefit/odex_benefit/views/family_members.xml +++ b/odex25_benefit/odex_benefit/views/family_members.xml @@ -13,44 +13,44 @@ confirm="Are you sure you want to move to Temporarily Suspended ?"/> @@ -276,7 +279,7 @@ ('exception', '=', False), '|', '&', - ('state', 'not in', ['draft', 'researcher', 'waiting_approve', 'first_approve', 'gm_assistant', 'accounting_approve']), + ('state', 'not in', ['draft', 'researcher']), ('service_type', 'in', ['marriage', 'eid_gift', 'winter_clothing', 'ramadan_basket']), ('service_type', 'in', ['electrical_devices', 'home_furnishing', 'rent']) ] @@ -320,7 +323,7 @@ - + From c74cb8f89dd3e457928c6dce201ca34b7515105b Mon Sep 17 00:00:00 2001 From: younes Date: Mon, 19 Jan 2026 15:33:53 +0100 Subject: [PATCH 04/27] [IMP] odex_benefit: IMP benefit --- odex25_benefit/odex_benefit/models/benefit.py | 57 +++++++------------ .../odex_benefit/models/benefit_config.py | 2 + .../views/benefit_config_view.xml | 14 ++++- .../odex_benefit/views/benefit_view.xml | 6 +- 4 files changed, 39 insertions(+), 40 deletions(-) diff --git a/odex25_benefit/odex_benefit/models/benefit.py b/odex25_benefit/odex_benefit/models/benefit.py index 2dd9ee776..e0e4ab0d5 100644 --- a/odex25_benefit/odex_benefit/models/benefit.py +++ b/odex25_benefit/odex_benefit/models/benefit.py @@ -750,10 +750,6 @@ class GrantBenefitProfile(models.Model): @api.depends('is_mother_work','mother_salary_ids','mother_expenses_ids','mother_debits_ids') def _compute_mother_net_income(self): for rec in self: - if not rec.is_mother_work: - rec.mother_net_income = 0.0 - continue - deductions = ( sum(rec.mother_expenses_ids.filtered('deduct_from_family_income').mapped('amount')) + sum(rec.mother_debits_ids.filtered('deduct_from_family_income').mapped('monthly_installment')) @@ -1424,30 +1420,28 @@ class GrantBenefitProfile(models.Model): return status, reasons def check_replacement_mother_status(self): - validation_setting = self.env["family.validation.setting"].search([], limit=1) - mini_income_for_mother = validation_setting.mini_income_for_mother - max_income_for_mother = validation_setting.max_income_for_mother for rec in self: reasons = [] status = 'benefit' if not rec.add_replacement_mother: continue - if not rec.replacement_mother_location_conf.is_benefit or not rec.replacement_mother_marital_conf.is_benefit or rec.state in ['suspended_second_approve','refused']: + if rec.state in ['suspended_second_approve', 'refused']: status = 'non_benefit' - reasons.append(_("The replacement mother's marital or location conditions are not eligible.")) - elif rec.replacement_mother_marital_conf.is_benefit: - if rec.replacement_is_mother_work and rec.replacement_mother_country_id.code == 'SA' or ( - rec.replacement_mother_country_id.code != 'SA' and rec.father_country_id.code == 'SA'): - if mini_income_for_mother < rec.replacement_mother_income <= max_income_for_mother: - status = 'non_benefit' - reasons.append(_("The replacement mother's income is between minimum and maximum thresholds.")) - elif rec.replacement_mother_income <= mini_income_for_mother: - status = 'benefit' - elif rec.replacement_mother_income > max_income_for_mother: - status = 'benefit' - elif not rec.replacement_is_mother_work and rec.replacement_mother_country_id.code == 'SA' or ( - rec.replacement_mother_country_id.code != 'SA' and rec.father_country_id.code == 'SA'): - status = 'benefit' + reasons.append(_("Family is suspended or refused.")) + return status, reasons + + if not rec.replacement_mother_marital_conf or not rec.replacement_mother_location_conf: + status = 'non_benefit' + reasons.append(_("Replacement mother marital or location information is missing.")) + return status, reasons + + if not rec.replacement_mother_marital_conf.replacement_mother_is_benefit: + status = 'non_benefit' + reasons.append(_("The replacement mother's marital status is not eligible for benefits.")) + + if not rec.replacement_mother_location_conf.replacement_mother_is_benefit: + status = 'non_benefit' + reasons.append(_("The replacement mother's location is not eligible for benefits.")) return status, reasons def delete_from_db(self): @@ -2212,18 +2206,11 @@ class GrantBenefitProfile(models.Model): for rec in self: total = 0.0 rec.total_income = 0.0 - if not rec.add_replacement_mother: - if rec.mother_status == 'non_benefit': - total = sum(rec.salary_ids.filtered(lambda e: e.approved).mapped('salary_amount')) - elif rec.mother_status == 'benefit': - total = sum(rec.salary_ids.filtered(lambda e: e.approved).mapped('salary_amount')) + rec.mother_income - rec.total_income = total - if rec.add_replacement_mother: - if rec.replacement_mother_status == 'non_benefit': - total = sum(rec.salary_ids.filtered(lambda e: e.approved).mapped('salary_amount')) - elif rec.replacement_mother_status == 'benefit': - total = sum(rec.salary_ids.filtered(lambda e: e.approved).mapped('salary_amount')) + rec.replacement_mother_income - rec.total_income += total + if rec.mother_status == 'non_benefit': + total = sum(rec.salary_ids.filtered(lambda e: e.approved).mapped('salary_amount')) + elif rec.mother_status == 'benefit': + total = sum(rec.salary_ids.filtered(lambda e: e.approved).mapped('salary_amount')) + rec.mother_income + rec.total_income = total def get_mother_name(self): for rec in self: @@ -2655,7 +2642,7 @@ class GrantBenefitProfile(models.Model): 'message': _('Not Benefit')} return res - @api.onchange('replacement_mother_marital_conf', 'replacement_mother_location_conf', 'replacement_mother_income') + @api.onchange('replacement_mother_marital_conf', 'replacement_mother_location_conf') def _onchange_replacement_mother_info(self): res = {} for rec in self: diff --git a/odex25_benefit/odex_benefit/models/benefit_config.py b/odex25_benefit/odex_benefit/models/benefit_config.py index acf02914e..b810e6d41 100644 --- a/odex25_benefit/odex_benefit/models/benefit_config.py +++ b/odex25_benefit/odex_benefit/models/benefit_config.py @@ -806,6 +806,7 @@ class LocationSettings(models.Model): location_type = fields.Selection([('member', _('Member')), ('mother_location', _('Mother Location'))]) is_benefit = fields.Boolean(string='Is Benefit?') is_far_from_family = fields.Boolean(string='Is Far From Family?') + replacement_mother_is_benefit = fields.Boolean(string="Replacement Mother Is Benefit?", default=True, ) class AttachmentsSettings(models.Model): _name = 'attachments.settings' @@ -897,6 +898,7 @@ class MaritalStatus(models.Model): name = fields.Char(string="Name") is_benefit = fields.Boolean(string='Is Benefit?') is_dead = fields.Boolean(string='Is Dead?') + replacement_mother_is_benefit = fields.Boolean(string="Replacement Mother Is Benefit?",default=True,) class AgeCategory(models.Model): _name = 'age.category' diff --git a/odex25_benefit/odex_benefit/views/benefit_config_view.xml b/odex25_benefit/odex_benefit/views/benefit_config_view.xml index 9a85a8a57..6f804938a 100644 --- a/odex25_benefit/odex_benefit/views/benefit_config_view.xml +++ b/odex25_benefit/odex_benefit/views/benefit_config_view.xml @@ -1016,9 +1016,13 @@ - + + + + + @@ -1033,6 +1037,7 @@ + @@ -1333,9 +1338,13 @@ - + + + + + @@ -1348,6 +1357,7 @@ + diff --git a/odex25_benefit/odex_benefit/views/benefit_view.xml b/odex25_benefit/odex_benefit/views/benefit_view.xml index 2e76c14b3..4cc7bb68c 100644 --- a/odex25_benefit/odex_benefit/views/benefit_view.xml +++ b/odex25_benefit/odex_benefit/views/benefit_view.xml @@ -909,7 +909,7 @@ - + @@ -929,7 +929,7 @@ - + - +
From f7b80a7332e24580b81b253b57902c6680a89517 Mon Sep 17 00:00:00 2001 From: younes Date: Mon, 19 Jan 2026 15:46:04 +0100 Subject: [PATCH 05/27] [IMP] odex_benefit: IMP benefit --- odex25_benefit/odex_benefit/i18n/ar_001.po | 33 ++++++++++++++++++- .../models/ir_attachment_inherit.py | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/odex25_benefit/odex_benefit/i18n/ar_001.po b/odex25_benefit/odex_benefit/i18n/ar_001.po index f05e4a111..2f7483c5a 100644 --- a/odex25_benefit/odex_benefit/i18n/ar_001.po +++ b/odex25_benefit/odex_benefit/i18n/ar_001.po @@ -18509,4 +18509,35 @@ msgstr "تجاوزت عمر %s وليس لديها اخوة قصر" #: code:addons/odex_benefit/models/family_members.py:0 #, python-format msgid "She is over %s years of age." -msgstr "تجاوزت عمر %s" \ No newline at end of file +msgstr "تجاوزت عمر %s" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_location_settings__replacement_mother_is_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_marital_status__replacement_mother_is_benefit +msgid "Replacement Mother Is Benefit?" +msgstr "هل الأم البديلة مستفيدة؟" + +#. module: odex_benefit +#: code:addons/odex_benefit/models/benefit.py:0 +#, python-format +msgid "Family is suspended or refused." +msgstr "توقفت الأسرة أو تم رفضها." + +#. module: odex_benefit +#: code:addons/odex_benefit/models/benefit.py:0 +#, python-format +msgid "Replacement mother marital or location information is missing." +msgstr "معلومات الحالة الاجتماعية أو موقع السكن للأم البديلة مفقودة." + +#. module: odex_benefit +#: code:addons/odex_benefit/models/benefit.py:0 +#, python-format +msgid "The replacement mother's marital status is not eligible for benefits." +msgstr "الحالة الاجتماعية للأم البديلة غير مؤهلة للاستفادة." + +#. module: odex_benefit +#: code:addons/odex_benefit/models/benefit.py:0 +#, python-format +msgid "The replacement mother's location is not eligible for benefits." +msgstr "مكان سكن الأم البديلة غير مؤهل للاستفادة." + diff --git a/odex25_benefit/odex_benefit/models/ir_attachment_inherit.py b/odex25_benefit/odex_benefit/models/ir_attachment_inherit.py index ed443109c..ce6457f33 100644 --- a/odex25_benefit/odex_benefit/models/ir_attachment_inherit.py +++ b/odex25_benefit/odex_benefit/models/ir_attachment_inherit.py @@ -18,7 +18,7 @@ class BenefitAttachment(models.Model): attach_id = fields.Many2one('attachments.settings', string="Attach",domain=[('attach_type', '=', 'member_attach')]) hobbies_id = fields.Many2one('attachments.settings', string="Hobby",domain=[('attach_type', '=', 'hobbies_attach')]) diseases_id = fields.Many2one('attachments.settings', string="Diseases",domain=[('attach_type', '=', 'diseases_attach'), ('parent_id','=',False)]) - diseases_child_id = fields.Many2one('attachments.settings',string="Sub Disease",domain="[('parent_id','=',diseases_id)]") + diseases_child_id = fields.Many2one('attachments.settings',string="Sub Disease",domain="[('attach_type', '=', 'diseases_attach'),('parent_id','=',diseases_id)]") disabilities_id = fields.Many2one('attachments.settings', string="Disabilities",domain=[('attach_type', '=', 'disabilities_attach'), ('parent_id','=',False)]) disabilities_child_id = fields.Many2one('attachments.settings',string="Sub Disability",domain="[('parent_id','=',disabilities_id)]") hobby_attach = fields.Binary(attachment=True, string="Hobby Attach") From 68c4c924a63c0f96d45548dcdc9876d15ad47ac4 Mon Sep 17 00:00:00 2001 From: younes Date: Tue, 20 Jan 2026 08:42:45 +0100 Subject: [PATCH 06/27] [IMP] odex_benefit: IMP benefit --- odex25_benefit/odex_benefit/i18n/ar_001.po | 21 ---------- .../odex_benefit/models/family_members.py | 38 ++++++++++--------- .../odex_benefit/views/benefit_view.xml | 8 ++-- 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/odex25_benefit/odex_benefit/i18n/ar_001.po b/odex25_benefit/odex_benefit/i18n/ar_001.po index 2f7483c5a..8305d40d2 100644 --- a/odex25_benefit/odex_benefit/i18n/ar_001.po +++ b/odex25_benefit/odex_benefit/i18n/ar_001.po @@ -18368,14 +18368,6 @@ msgid "" "specialization." msgstr "أكبر من %s سنة وغير منتظم بتخصص علمي أو مهني." -#. module: odex_benefit -#: code:addons/odex_benefit/models/family_members.py:0 -#, python-format -msgid "" -"The member is over %s years old and not enrolled in a scientific or " -"vocational specialization." -msgstr "أكبر من %s سنة وغير منتظم بتخصص علمي أو مهني." - #. module: odex_benefit #: code:addons/odex_benefit/models/benefit.py:0 #, python-format @@ -18498,19 +18490,6 @@ msgstr "الإجراء غير مسموح: الأسرة لديها %s فرد مس msgid "Governmental/Paid" msgstr "حكومي /مقابل مادي" -#. module: odex_benefit -#: code:addons/odex_benefit/models/family_members.py:0 -#: code:addons/odex_benefit/models/family_members.py:0 -#, python-format -msgid "She is over %s years of age and has no underage brothers." -msgstr "تجاوزت عمر %s وليس لديها اخوة قصر" - -#. module: odex_benefit -#: code:addons/odex_benefit/models/family_members.py:0 -#, python-format -msgid "She is over %s years of age." -msgstr "تجاوزت عمر %s" - #. module: odex_benefit #: model:ir.model.fields,field_description:odex_benefit.field_location_settings__replacement_mother_is_benefit #: model:ir.model.fields,field_description:odex_benefit.field_marital_status__replacement_mother_is_benefit diff --git a/odex25_benefit/odex_benefit/models/family_members.py b/odex25_benefit/odex_benefit/models/family_members.py index f3bb20b68..344f64eec 100644 --- a/odex25_benefit/odex_benefit/models/family_members.py +++ b/odex25_benefit/odex_benefit/models/family_members.py @@ -617,6 +617,17 @@ class FamilyMemberProfile(models.Model): benefiting_children = rec.benefit_id.member_ids.filtered( lambda m: m.relationn.relation_type in ['son', 'daughter'] and m.member_status == 'benefit' ) + has_benefiting_son = any( + m.relationn.relation_type == 'son' and m.member_status == 'benefit' + for m in rec.benefit_id.member_ids + ) + has_younger_benefiting_daughter = any( + m.relationn.relation_type == 'daughter' + and m.member_status == 'benefit' + and m.age < female_benefit_age + for m in rec.benefit_id.member_ids + if m.id != rec.id + ) if rec.relationn.relation_type == 'mother': if not benefiting_children: @@ -638,7 +649,8 @@ class FamilyMemberProfile(models.Model): # Gender-specific checks elif rec.relationn.relation_type == 'son': if age_exceeded: - if rec.age <= exceptional_age_has_disabilities and rec.disabilities_attachment_ids and rec.minor_siblings: + if rec.age <= exceptional_age_has_disabilities and rec.disabilities_attachment_ids and ( + has_benefiting_son or has_younger_benefiting_daughter): rec.member_status = 'benefit' else: if rec.age > exceptional_age_has_disabilities and rec.disabilities_attachment_ids: @@ -651,18 +663,12 @@ class FamilyMemberProfile(models.Model): _("Over %s years old and not enrolled in any educational institution.") % male_benefit_age ) elif current_education_status_id.case_study == 'continuous': - if current_education_status_id.specialization_ids.is_scientific_specialty and rec.age >= exceptional_age_scientific_specialty: + if rec.age >= exceptional_age_scientific_specialty: rec.member_status = 'non_benefit' reasons.append( _("Over %s years old and not enrolled in a scientific or vocational specialization.") % exceptional_age_scientific_specialty ) - if not current_education_status_id.specialization_ids.is_scientific_specialty: - rec.member_status = 'non_benefit' - reasons.append( - _("The member is over %s years old and not enrolled in a scientific or vocational specialization.") - % male_benefit_age - ) if rec.is_work: if rec.member_income > max_income_for_benefit: rec.member_status = 'non_benefit' @@ -694,17 +700,15 @@ class FamilyMemberProfile(models.Model): rec.member_status = 'non_benefit' reasons.append(_("She is employed and not enrolled in an educational institution.")) if age_exceeded: - if rec.age > minor_siblings_age and not rec.minor_siblings: + if has_benefiting_son or has_younger_benefiting_daughter: + rec.member_status = 'benefit' + else: rec.member_status = 'non_benefit' reasons.append( - _("She is over %s years of age and has no underage brothers.") % female_benefit_age) - elif not rec.minor_siblings: - rec.member_status = 'non_benefit' - reasons.append( - _("She is over %s years of age and has no underage brothers.") % female_benefit_age) - elif rec.minor_siblings and rec.age > minor_siblings_age: - rec.member_status = 'non_benefit' - reasons.append(_("She is over %s years of age.") % minor_siblings_age) + _("She exceeded the age limit (%s) and has no benefiting son " + "nor any younger benefiting daughter.") + % female_benefit_age + ) if rec.is_work and rec.member_income > max_income_for_benefit: rec.member_status = 'non_benefit' reasons.append(_("She works with a salary greater than %s.") % max_income_for_benefit) diff --git a/odex25_benefit/odex_benefit/views/benefit_view.xml b/odex25_benefit/odex_benefit/views/benefit_view.xml index 4cc7bb68c..be02fb3bf 100644 --- a/odex25_benefit/odex_benefit/views/benefit_view.xml +++ b/odex25_benefit/odex_benefit/views/benefit_view.xml @@ -528,7 +528,8 @@ @@ -234,6 +234,7 @@ + - - + + + + + + + + + + + + + diff --git a/odex25_benefit/odex_benefit/views/services_settings.xml b/odex25_benefit/odex_benefit/views/services_settings.xml index 745bc7fa6..71882e9c1 100644 --- a/odex25_benefit/odex_benefit/views/services_settings.xml +++ b/odex25_benefit/odex_benefit/views/services_settings.xml @@ -171,6 +171,7 @@ + From 59524b515e30300d783444e467dc1395c66215c3 Mon Sep 17 00:00:00 2001 From: younes Date: Thu, 22 Jan 2026 15:26:00 +0100 Subject: [PATCH 23/27] [IMP] odex_benefit: IMP benefit --- odex25_benefit/odex_benefit/i18n/ar_001.po | 68 ++++++++++++++++++- .../odex_benefit/models/service_request.py | 36 +++++----- 2 files changed, 86 insertions(+), 18 deletions(-) diff --git a/odex25_benefit/odex_benefit/i18n/ar_001.po b/odex25_benefit/odex_benefit/i18n/ar_001.po index 08a04cc93..247e92f45 100644 --- a/odex25_benefit/odex_benefit/i18n/ar_001.po +++ b/odex25_benefit/odex_benefit/i18n/ar_001.po @@ -9562,6 +9562,7 @@ msgstr "هل الأسرة منتجة؟" #: model:ir.model.fields,field_description:odex_benefit.field_receive_appliances_furniture__prod_id #: model:ir.model.fields,field_description:odex_benefit.field_receive_benefit_zkat__product_id #: model:ir.model.fields,field_description:odex_benefit.field_receive_food_basket__product_id +#: model:ir.model.fields,field_description:odex_benefit.field_electrical_device_line__product_id msgid "Product" msgstr "المنتج" @@ -9691,6 +9692,7 @@ msgstr "" #: model:ir.model.fields,field_description:odex_benefit.field_service_request__service_qty #: model:ir.model.fields,field_description:odex_benefit.field_zkat_line__quantity #: model_terms:ir.ui.view,arch_db:odex_benefit.benefit_food_surplus_form +#: model:ir.model.fields,field_description:odex_benefit.field_electrical_device_line__quantity msgid "Quantity" msgstr "الكمية" @@ -10734,12 +10736,14 @@ msgid "Service Name" msgstr "اسم الخدمة" #. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_branch_settings__service_producer_id #: model:ir.model.fields,field_description:odex_benefit.field_service_request__service_producer_id #: model:ir.model.fields,field_description:odex_benefit.field_services_settings__service_producer_id msgid "Service Producer" msgstr "جهة الدفع" #. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_electrical_device_line__service_request_id #: model:ir.model.fields,field_description:odex_benefit.field_home_furnishing_items__service_request_id #: model:ir.model.fields,field_description:odex_benefit.field_service_attachments_settings__service_request_id #: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_form @@ -16344,6 +16348,7 @@ msgid "Electrical Devices Service" msgstr "الأجهزة الكهربائية" #. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_electrical_device_line__device_id #: model:ir.model.fields,field_description:odex_benefit.field_service_request__device_id msgid "Device" msgstr "الجهاز" @@ -18592,4 +18597,65 @@ msgstr "%s سنة" #: code:addons/odex_benefit/models/family_members.py:0 #, python-format msgid "0 days" -msgstr "0 يوم" \ No newline at end of file +msgstr "0 يوم" + +#. module: odex_benefit +#: code:addons/odex_benefit/models/service_request.py:0 +#: model:ir.model,name:odex_benefit.model_electrical_device_line +#, python-format +msgid "Electrical Device Line" +msgstr "جهاز كهربائي" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_electrical_device_line__unit_price +msgid "Unit Price" +msgstr "سعر الوحدة" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_electrical_device_line__subtotal +msgid "Subtotal" +msgstr "المجموع" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_service_request__electrical_device_line_ids +#: model:ir.model.fields.selection,name:odex_benefit.selection__services_settings__service_type__electrical_devices +msgid "Electrical Devices" +msgstr "أجهزة كهربائية" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_electrical_devices__product_ids +#: model:ir.model.fields,field_description:odex_benefit.field_service_request__allowed_product_ids +msgid "Allowed Products" +msgstr "المنتجات المسموح بها" + +#. module: odex_benefit +#: code:addons/odex_benefit/models/service_request.py:0 +#, python-format +msgid "" +"Device '%s': Total quantity in this request (%s) exceeds the allowed limit " +"of %s units." +msgstr "الجهاز '%s': إجمالي الكمية في هذا الطلب (%s) يتجاوز الحد المسموح به وهو %s وحدة." + +#. module: odex_benefit +#: code:addons/odex_benefit/models/service_request.py:0 +#, python-format +msgid "" +"Device '%s': You cannot request more than %s units within %s %s. (Previous " +"requests: %s, Current request: %s, Total: %s)" +msgstr "الجهاز '%s': لا يمكنك طلب أكثر من %s وحدة خلال %s %s. (الطلبات السابقة: %s، الطلب الحالي: %s، المجموع: %s)" + +#. module: odex_benefit +#: code:addons/odex_benefit/models/service_request.py:0 +#, python-format +msgid "" +"Cannot create invoice: the following requests have no electrical device lines:\n" +"%s\n" +"All selected requests must contain at least one device line." +msgstr "لا يمكن إنشاء الفاتورة: الطلبات التالية لا تحتوي على أجهزة كهربائية:\n" + +#. module: odex_benefit +#: code:addons/odex_benefit/models/service_request.py:0 +#, python-format +msgid "No invoice lines could be created." +msgstr "لم يتم إنشاء أي بنود في الفاتورة." + diff --git a/odex25_benefit/odex_benefit/models/service_request.py b/odex25_benefit/odex_benefit/models/service_request.py index 36871d8df..3bca6d480 100644 --- a/odex25_benefit/odex_benefit/models/service_request.py +++ b/odex25_benefit/odex_benefit/models/service_request.py @@ -993,24 +993,26 @@ class ServiceRequest(models.Model): raise ValidationError(_( "Device '%s': Total quantity in this request (%s) exceeds the allowed limit of %s units." ) % (device.device_name, current_total_qty, allowed_qty)) - domain = base_domain + [ - ('date', '>', date_before), - ('electrical_device_line_ids.device_id', '=', device_id) - ] - existing_requests = Service.search(domain) - existing_device_lines = existing_requests.mapped( - 'electrical_device_line_ids').filtered( - lambda l: l.device_id.id == device_id - ) - total_previous_qty = sum(existing_device_lines.mapped('quantity')) - total_qty = total_previous_qty + current_total_qty + if not rec.exception_or_steal: + domain = base_domain + [ + ('date', '>', date_before), + ('electrical_device_line_ids.device_id', '=', device_id), + ('exception_or_steal', '=', False) + ] + existing_requests = Service.search(domain) + existing_device_lines = existing_requests.mapped( + 'electrical_device_line_ids').filtered( + lambda l: l.device_id.id == device_id + ) + total_previous_qty = sum(existing_device_lines.mapped('quantity')) + total_qty = total_previous_qty + current_total_qty - if total_qty > allowed_qty: - raise ValidationError(_( - "Device '%s': You cannot request more than %s units within %s %s. " - "(Previous requests: %s, Current request: %s, Total: %s)" - ) % (device.device_name, allowed_qty, interval, - period, total_previous_qty, current_total_qty, total_qty)) + if total_qty > allowed_qty: + raise ValidationError(_( + "Device '%s': You cannot request more than %s units within %s %s. " + "(Previous requests: %s, Current request: %s, Total: %s)" + ) % (device.device_name, allowed_qty, interval, + period, total_previous_qty, current_total_qty, total_qty)) else: last_request = Service.search(base_domain, order='date desc', limit=1) if last_request and last_request.date: From 9d591ddc069c674eec89d2bff8ce0620b1f7cb6e Mon Sep 17 00:00:00 2001 From: younes Date: Thu, 22 Jan 2026 15:37:13 +0100 Subject: [PATCH 24/27] [IMP] odex_benefit: IMP benefit --- odex25_benefit/odex_benefit/views/service_request.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/odex25_benefit/odex_benefit/views/service_request.xml b/odex25_benefit/odex_benefit/views/service_request.xml index 8b80ed3d0..35a69272f 100644 --- a/odex25_benefit/odex_benefit/views/service_request.xml +++ b/odex25_benefit/odex_benefit/views/service_request.xml @@ -404,7 +404,7 @@ - + From 0ad6a5f6cb64965b2da4d758998a26d9ad82cbac Mon Sep 17 00:00:00 2001 From: younes Date: Sun, 25 Jan 2026 10:14:42 +0100 Subject: [PATCH 25/27] [IMP] odex_benefit: IMP benefit --- .../odex_benefit/models/account_move_line.py | 13 ++++++++++++- .../odex_benefit/models/family_expense.py | 2 +- odex25_benefit/odex_benefit/views/benefit_view.xml | 6 ++++-- .../odex_benefit/views/service_request.xml | 6 +++--- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/odex25_benefit/odex_benefit/models/account_move_line.py b/odex25_benefit/odex_benefit/models/account_move_line.py index 3d6114822..3af199d46 100644 --- a/odex25_benefit/odex_benefit/models/account_move_line.py +++ b/odex25_benefit/odex_benefit/models/account_move_line.py @@ -49,4 +49,15 @@ class AccountMove(models.Model): 'domain': [('id', 'in', attachment_ids)], 'context': ctx, 'target': 'current', - } \ No newline at end of file + } + + def _get_name_invoice_report(self): + self.ensure_one() + has_benefit_family = any( + line.benefit_family_id or line.family_confirm_id + for line in self.invoice_line_ids + ) + + if has_benefit_family or self.benefit_family_ids or self.family_confirm_id: + return 'account.report_invoice_document' + return super()._get_name_invoice_report() \ No newline at end of file diff --git a/odex25_benefit/odex_benefit/models/family_expense.py b/odex25_benefit/odex_benefit/models/family_expense.py index 60aa7655c..ed094b80d 100644 --- a/odex25_benefit/odex_benefit/models/family_expense.py +++ b/odex25_benefit/odex_benefit/models/family_expense.py @@ -273,7 +273,7 @@ class ConfirmBenefitExpense(models.Model): # Define base domain for family selection base_domain = ['|', ('state', '=', 'second_approve'), '&', - ('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended')] + ('state', 'not in', ('temporary_suspended', 'suspended_second_approve')), ('action_type', '=', 'suspended')] if rec.branch_custom_ids: base_domain.append(('branch_custom_id', 'in', rec.branch_custom_ids.ids)) min_income = validation_setting.benefit_category_ids.mapped('mini_income_amount') diff --git a/odex25_benefit/odex_benefit/views/benefit_view.xml b/odex25_benefit/odex_benefit/views/benefit_view.xml index 5dbbd358e..5a6131ce0 100644 --- a/odex25_benefit/odex_benefit/views/benefit_view.xml +++ b/odex25_benefit/odex_benefit/views/benefit_view.xml @@ -1251,7 +1251,8 @@ attrs="{'invisible':[('is_mother','=',False)],'required':[('is_mother','=',True)]}"/> - + + @@ -1428,7 +1429,8 @@ - + + diff --git a/odex25_benefit/odex_benefit/views/service_request.xml b/odex25_benefit/odex_benefit/views/service_request.xml index 35a69272f..bd30a7539 100644 --- a/odex25_benefit/odex_benefit/views/service_request.xml +++ b/odex25_benefit/odex_benefit/views/service_request.xml @@ -152,16 +152,16 @@ string="Beneficiary Approve" class="oe_highlight" confirm="Are you sure you want to approve ?" states="gm_assistant" - groups="odex_benefit.group_benefit_branch_manager,odex_benefit.group_benefit_manager,odex_benefit.group_family_services_manager"/> + groups="odex_benefit.group_benefit_manager"/>