From e2e8b884dc64ba4aded9e7324270be375d6fe06a Mon Sep 17 00:00:00 2001 From: odoo-syria-team Date: Thu, 13 Nov 2025 15:39:53 +0300 Subject: [PATCH 01/13] Add Domain on sponsership --- .../models/donation_details_lines.py | 37 ++++++++++++++++++- .../views/donations_details_lines.xml | 3 +- .../views/takaful_sponorship_view.xml | 5 ++- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/odex25_ensan/odex_takaful/models/donation_details_lines.py b/odex25_ensan/odex_takaful/models/donation_details_lines.py index e27f77206..414138f18 100644 --- a/odex25_ensan/odex_takaful/models/donation_details_lines.py +++ b/odex25_ensan/odex_takaful/models/donation_details_lines.py @@ -55,7 +55,7 @@ class DonationsDetailsLines(models.Model): family_domain_ids = fields.Many2many('grant.benefit', compute='_compute_family_domain_ids') benefit_id = fields.Many2one('family.member', string='Beneficiary Name', ondelete='restrict', domain="[('id', 'in', members_domain_ids)]", tracking=True) family_id = fields.Many2one('grant.benefit', string='Family', ondelete='restrict', domain="[('id', 'in', family_domain_ids)]", tracking=True) - benefit_ids = fields.Many2many('family.member', string='Beneficiaries Names', tracking=True, domain="[('id', 'in', members_domain_ids)]") + benefit_ids = fields.Many2many('family.member', string='Beneficiaries Names', tracking=True, domain="[('id', 'in', members_domain_ids) , ('age' , '<' , ages)]") sponsorship_duration = fields.Selection([('temporary', 'Temporary'), ('permanent', 'Permanent')], string='Sponsorship Type', default="temporary") start_date = fields.Date(string="Sponsorship Start Date", copy=False, default=fields.Date.today()) @@ -98,6 +98,7 @@ class DonationsDetailsLines(models.Model): debit_payment_attachment_file_name = fields.Char('Debit Payment File Name', required=False) journal_id = fields.Many2one('account.journal', string="Journal",domain="[('type','=','bank')]",default=_default_journal_id) benefit_status = fields.Selection(related='benefit_id.member_status') + ages = fields.Integer(compute='_compute_get_age_range' , store=True) # cheque_number = fields.Integer(string="Cheque Number") # cheque_due_date = fields.Date(string="Cheque Due Date") # cheque_file_attachment = fields.Binary(string='Cheque Attachment', attachment=True) @@ -106,6 +107,38 @@ class DonationsDetailsLines(models.Model): # bank_transfer_attachment_file_name = fields.Char('Bank Transfer File Name', required=False) + @api.depends('sponsorship_duration' , 'product_template_id' , 'payment_month_count' , 'direct_debit') + def _compute_get_age_range(self): + for rec in self: + x = [] + records = self.env['donations.details.lines'].search(['|' , ('state', '=', 'replace') , ('state', '=', 'waiting')]) + print('records >>> ' , records) + for i in records: + x.append(self.compute_donation_value(records)) + lowest_value = min(x) if x else None + rec.ages = lowest_value + + def compute_donation_value(self , records): + """ + Loop through donation detail lines and return a number based on conditions: + - If sponsorship_duration == 'permanent' → return 1 + - Else if not permanent and payment_month_count > 6 → return 1 + - Else if not permanent and payment_month_count < 6 and direct_debit == True → return 16 + - Else if not permanent and payment_month_count < 6 → return 18 + - Else → return 1 + """ + for record in records: + if record.sponsorship_duration == 'permanent': + return 1 + elif record.sponsorship_duration != 'permanent' and record.payment_month_count > 6: + return 1 + elif record.sponsorship_duration != 'permanent' and record.payment_month_count < 6 and record.direct_debit: + return 16 + elif record.sponsorship_duration != 'permanent' and record.payment_month_count < 6: + return 18 + else: + return 1 + return 1 @api.depends('extension_history_ids') def _compute_extension_count(self): for rec in self: @@ -1074,4 +1107,4 @@ class DonationsDetailsLines(models.Model): 'context': { 'default_donation_detail_id': self.id, }, - } \ No newline at end of file + } diff --git a/odex25_ensan/odex_takaful/views/donations_details_lines.xml b/odex25_ensan/odex_takaful/views/donations_details_lines.xml index ef0af919a..517ec2d1d 100644 --- a/odex25_ensan/odex_takaful/views/donations_details_lines.xml +++ b/odex25_ensan/odex_takaful/views/donations_details_lines.xml @@ -178,6 +178,7 @@ + @@ -373,4 +374,4 @@ {'create': False, 'delete': False, 'search_default_filter_replace': 1} - \ No newline at end of file + diff --git a/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml b/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml index a362da5a9..cc80be99d 100644 --- a/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml +++ b/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml @@ -509,6 +509,7 @@ + - + @@ -818,4 +819,4 @@ - \ No newline at end of file + From baa1ceebd0d9efa24afbc33dc7b97e29c1d74013 Mon Sep 17 00:00:00 2001 From: odoo-syria-team Date: Thu, 13 Nov 2025 16:07:39 +0300 Subject: [PATCH 02/13] Add Domain on sponsership --- odex25_ensan/odex_takaful/views/donations_details_lines.xml | 2 +- odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/odex25_ensan/odex_takaful/views/donations_details_lines.xml b/odex25_ensan/odex_takaful/views/donations_details_lines.xml index 517ec2d1d..5582f6347 100644 --- a/odex25_ensan/odex_takaful/views/donations_details_lines.xml +++ b/odex25_ensan/odex_takaful/views/donations_details_lines.xml @@ -178,7 +178,7 @@ - + diff --git a/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml b/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml index 345823c13..847aeb512 100644 --- a/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml +++ b/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml @@ -509,7 +509,7 @@ - + 6 → return 1 - - Else if not permanent and payment_month_count < 6 and direct_debit == True → return 16 - - Else if not permanent and payment_month_count < 6 → return 18 - - Else → return 1 - """ - for record in records: - if record.sponsorship_duration == 'permanent': - return 1 - elif record.sponsorship_duration != 'permanent' and record.payment_month_count > 6: - return 1 - elif record.sponsorship_duration != 'permanent' and record.payment_month_count < 6 and record.direct_debit: - return 16 - elif record.sponsorship_duration != 'permanent' and record.payment_month_count < 6: - return 18 - else: - return 1 - return 1 @api.depends('extension_history_ids') def _compute_extension_count(self): for rec in self: From e583014cc2726711bfb2f1c7c91f91751d4f775f Mon Sep 17 00:00:00 2001 From: younes Date: Thu, 13 Nov 2025 19:49:55 +0100 Subject: [PATCH 04/13] [IMP] odex_benefit: IMP benefit --- odex25_ensan/odex_benefit/i18n/ar_001.po | 20 -- .../odex_benefit/models/family_expense.py | 267 +++++++++--------- .../models/family_expense_line.py | 1 + .../views/family_expense_line_view.xml | 2 + .../views/family_expense_view.xml | 116 +++++--- .../odex_benefit/views/family_members.xml | 4 +- 6 files changed, 224 insertions(+), 186 deletions(-) diff --git a/odex25_ensan/odex_benefit/i18n/ar_001.po b/odex25_ensan/odex_benefit/i18n/ar_001.po index ee33246d1..23897a125 100644 --- a/odex25_ensan/odex_benefit/i18n/ar_001.po +++ b/odex25_ensan/odex_benefit/i18n/ar_001.po @@ -2690,7 +2690,6 @@ msgstr "المرتد" #: model:ir.model.fields,field_description:odex_benefit.field_service_request__branch_custom_id #: model_terms:ir.ui.view,arch_db:odex_benefit.grant_benefit_search #: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_search -#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_search msgid "Branch" msgstr "الفرع" @@ -5017,11 +5016,6 @@ msgstr "خدمات استثنائية" msgid "Excluded from suspension?" msgstr "مستثنى من إيقاف الخدمة" -#. module: odex_benefit -#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__expense_type -msgid "Expense Type" -msgstr "نوع الاجراء" - #. module: odex_benefit #: model:ir.model.fields,field_description:odex_benefit.field_benefit_category__expenses_ids #: model:ir.model.fields,field_description:odex_benefit.field_benefit_need__expenses_ids @@ -5203,11 +5197,6 @@ msgstr "ديون الأسرة" msgid "Family Domain" msgstr "" -#. module: odex_benefit -#: model:ir.model.fields.selection,name:odex_benefit.selection__confirm_benefit_expense__expense_type__family_expense -msgid "Family Expense" -msgstr "مصروف التغذية الشهرية" - #. module: odex_benefit #: code:addons/odex_benefit/models/family_expense.py:0 #: code:addons/odex_benefit/wizards/family_expense_move_wiz.py:0 @@ -5792,7 +5781,6 @@ msgstr "تاريخ التخرج" #. module: odex_benefit #: model_terms:ir.ui.view,arch_db:odex_benefit.grant_benefit_search #: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_search -#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_search msgid "Group By" msgstr "" @@ -7863,11 +7851,6 @@ msgstr "" msgid "Meal Card" msgstr "بطاقة الغذاء" -#. module: odex_benefit -#: model:ir.model.fields.selection,name:odex_benefit.selection__confirm_benefit_expense__expense_type__family_invoice -msgid "Meal Card Invoice" -msgstr "فاتورة كرت الغذاء" - #. module: odex_benefit #: model:ir.model.fields,field_description:odex_benefit.field_family_validation_setting__meal_expense msgid "Meal Expense" @@ -14445,7 +14428,6 @@ msgstr "أمر الصرف تم" #. module: odex_benefit #: model_terms:ir.ui.view,arch_db:odex_benefit.seasonal_service_form_view #: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_form -#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form msgid "Payment Done" msgstr "تم الدفع" @@ -16775,7 +16757,6 @@ msgstr "الحصول على دورة تأهيلية" #. module: odex_benefit #: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_form -#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form msgid "Total Moves" msgstr "القيد المحاسبي" @@ -16946,7 +16927,6 @@ msgstr "موافقة المسؤول" #. module: odex_benefit #: model_terms:ir.ui.view,arch_db:odex_benefit.seasonal_service_form_view #: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_form -#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form msgid "Payment Waiting" msgstr "في انتظار الدفع" diff --git a/odex25_ensan/odex_benefit/models/family_expense.py b/odex25_ensan/odex_benefit/models/family_expense.py index 8ee5af3ee..3e36d2052 100644 --- a/odex25_ensan/odex_benefit/models/family_expense.py +++ b/odex25_ensan/odex_benefit/models/family_expense.py @@ -35,10 +35,6 @@ class ConfirmBenefitExpense(models.Model): ('cancel', 'Cancelled'), ('confirm', 'Confirmed'), ], string='Status', default='draft', required=True, copy=False, tracking=True) - expense_type = fields.Selection(selection=[ - ('family_expense', 'Family Expense'), - ('family_invoice', 'Meal Card Invoice'), - ], string='Expense Type', default='family_expense', required=True) name = fields.Char(string="Name", states={'confirm': [('readonly', True)]}, copy=False) date = fields.Date(string="Date", default=fields.Date.context_today, required=False, states={'confirm': [('readonly', True)]}) @@ -57,13 +53,15 @@ class ConfirmBenefitExpense(models.Model): payment_order_id = fields.Many2one('payment.orders', string='Payment Order', ondelete="set null", copy=False) move_id = fields.Many2one('account.move', ondelete='cascade') available_payment_method_line_ids = fields.Many2many(comodel_name='account.payment.method.line') - total_moves = fields.Integer(string="Total Move", compute='_get_total_move_lines') - total_move_lines = fields.Integer(string="Total Move Lines", compute='_get_total_move_lines') - family_monthly_income = fields.Float(string="Total Monthly Income", compute='_get_family_monthly_values') - family_monthly_meals = fields.Float(string="Total Monthly Meals", compute='_get_family_monthly_values') - family_monthly_clotting = fields.Float(string="Total Monthly Clotting", compute='_get_family_monthly_values') - family_monthly_total = fields.Float(string="Total", compute='_get_family_monthly_values') - branch_custom_id = fields.Many2one(comodel_name='branch.settings', string="Branch") + family_monthly_income = fields.Float(string="Total Monthly Income", compute='_get_family_monthly_values', + store=True) + family_monthly_meals = fields.Float(string="Total Monthly Meals", compute='_get_family_monthly_values', store=True) + family_monthly_clotting = fields.Float(string="Total Monthly Clotting", compute='_get_family_monthly_values', + store=True) + family_monthly_othaime = fields.Float(string="Total Othaim", compute='_get_family_monthly_values', store=True) + family_monthly_total = fields.Float(string="Total", compute='_get_family_monthly_values', store=True) + branch_custom_ids = fields.Many2many(comodel_name='branch.settings', relation='confirm_benefit_expense_branch_rel', + column1='expense_id', column2='branch_id', string="Branches") family_domain_ids = fields.Many2many(comodel_name='grant.benefit', compute='_compute_domain_ids') company_id = fields.Many2one('res.company', default=lambda self: self.env.company) currency_id = fields.Many2one(comodel_name='res.currency', string="Company Currency", @@ -71,25 +69,41 @@ class ConfirmBenefitExpense(models.Model): payment_state = fields.Selection(string='Payment State', selection=[ ('none', 'None'), ('waiting', 'Waiting Payment'), - ('done', 'Done Payment'), ], copy=False, compute="_compute_payment_state", store=True) + ('done', 'Done Payment'), ], copy=False, compute="_compute_payment_move_state", store=True) + move_state = fields.Selection(string='Move State', selection=[ + ('none', 'None'), + ('waiting', 'Waiting Payment'), + ('done', 'Done Payment'), ], copy=False, compute="_compute_payment_move_state", store=True) + family_count_expense = fields.Integer(string="Family Count (Monthly Expense)", + compute='_get_family_monthly_values', store=True) + + family_count_othaim = fields.Integer(string="Family Count (Othaim)", compute='_get_family_monthly_values', + store=True) + member_count_expense = fields.Integer(string="Member Count (Monthly Expense)", compute='_get_family_monthly_values', + store=True, ) + + member_count_othaim = fields.Integer(string="Member Count (Othaim)", compute='_get_family_monthly_values', + store=True, ) @api.depends('payment_order_id', 'payment_order_id.state', 'move_id', 'move_id.state') - def _compute_payment_state(self): + def _compute_payment_move_state(self): for rec in self: payment_state = 'none' + move_state = 'none' if rec.payment_order_id: if rec.payment_order_id.state == "done": payment_state = "done" - rec.state = "confirm" else: payment_state = "waiting" - elif rec.move_id: + if rec.move_id: if rec.move_id.state == "posted": - payment_state = "done" - rec.state = "confirm" + move_state = "done" else: - payment_state = "waiting" + move_state = "waiting" + rec.move_state = move_state rec.payment_state = payment_state + if rec.move_state == 'done' and rec.payment_state == 'done': + rec.state = 'confirm' @api.model def create(self, vals): @@ -107,9 +121,14 @@ class ConfirmBenefitExpense(models.Model): income, meals, clotting = 0, 0, 0 if not family: continue - monthly_meals = family.family_monthly_meals - if self.expense_type == 'family_expense' and family.meal_card: - monthly_meals = 0.0 + monthly_meals = 0.0 if family.meal_card else family.family_monthly_meals + othaime = family.family_monthly_meals if family.meal_card else 0.0 + if self.cash_expense: + income = family.family_monthly_income + if self.meal_expense: + meals = monthly_meals + if self.cloth_expense: + clotting = family.family_monthly_clotting vals = { 'branch_id': family.branch_custom_id.id, 'family_category_id': family.benefit_category_id.id, @@ -117,25 +136,11 @@ class ConfirmBenefitExpense(models.Model): 'benefit_member_count': family.benefit_member_count, 'start_date': self.start_date, 'end_date': self.end_date, + 'family_monthly_income': income, + 'family_monthly_meals': meals, + 'family_monthly_clotting': clotting, + 'family_monthly_othaime': othaime, } - if self.expense_type == 'family_expense': - if self.cash_expense: - income = family.family_monthly_income - if self.meal_expense: - meals = monthly_meals - if self.cloth_expense: - clotting = family.family_monthly_clotting - vals.update({ - 'family_monthly_income': income, - 'family_monthly_meals': meals, - 'family_monthly_clotting': clotting, - }) - else: - vals.update({ - 'family_monthly_income': 0.0, - 'family_monthly_meals': monthly_meals, - 'family_monthly_clotting': 0.0, - }) line.write(vals) def action_calculate(self): @@ -147,9 +152,9 @@ class ConfirmBenefitExpense(models.Model): if not families: raise UserError(_("Please select at least one family to calculate.")) - if rec.expense_type == 'family_expense': - if not rec.cash_expense and not rec.meal_expense and not rec.cloth_expense: - raise UserError(_("At least one expense type should be selected.")) + # Todo ask awatif + if not rec.cash_expense and not rec.meal_expense and not rec.cloth_expense: + raise UserError(_("At least one expense type should be selected.")) rec.benefit_expense_line_ids.unlink() lines = [] @@ -172,45 +177,41 @@ class ConfirmBenefitExpense(models.Model): raise UserError(_("You can only recalculate when status is 'Calculated'.")) rec._update_benefit_expense_lines() - @api.depends('expense_type', 'date', 'branch_custom_id', 'start_date', 'end_date') + @api.depends('branch_custom_ids', 'start_date', 'end_date') def _compute_domain_ids(self): for rec in self: # Define base domain for family selection validation_setting = self.env["family.validation.setting"].search([], limit=1) base_domain = ['|', ('state', '=', 'second_approve'), '&', ('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended')] - if rec.branch_custom_id: - base_domain.append(('branch_custom_id', '=', rec.branch_custom_id.id)) + 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') max_income = validation_setting.benefit_category_ids.mapped('max_income_amount') base_domain.extend([('member_income', '>=', min(min_income)), ('member_income', '<=', max(max_income))]) base_domain.extend([('benefit_category_id', '!=', False)]) - if rec.expense_type == 'family_invoice': - base_domain.append(('meal_card', '=', True)) - - # if rec.date: if rec.start_date and rec.end_date: - # Calculate the start date for the past month range - # month_ago = rec.date - relativedelta(months=1) - - # Search for conflicting records of the same expense type within the past month conflicting_records = self.search([ ('id', '!=', rec._origin.id), ('start_date', '<=', rec.end_date), ('end_date', '>=', rec.start_date), - ('expense_type', '=', rec.expense_type), ]) if conflicting_records: - # Gather the family IDs that are already associated with the same expense type conflicting_family_ids = conflicting_records.mapped('family_ids').ids base_domain.append(('id', 'not in', conflicting_family_ids)) rec.family_domain_ids = self.env['grant.benefit'].search(base_domain) - @api.onchange('branch_custom_id') - def _onchange_branch_custom_id(self): - if self.branch_custom_id: + @api.onchange('branch_custom_ids') + def _onchange_branch_custom_ids(self): + if self.branch_custom_ids: + allowed_families = self.env['grant.benefit'].search([ + ('id', 'in', self.family_ids.ids), + ('branch_custom_id', 'in', self.branch_custom_ids.ids), + ]) + self.family_ids = [(6, 0, allowed_families.ids)] + else: self.family_ids = [(5, 0, 0)] def unlink(self): @@ -222,15 +223,26 @@ class ConfirmBenefitExpense(models.Model): @api.depends('benefit_expense_line_ids') def _get_family_monthly_values(self): for rec in self: - rec.family_monthly_income = sum(rec.benefit_expense_line_ids.mapped('family_monthly_income')) - rec.family_monthly_meals = sum(rec.benefit_expense_line_ids.mapped('family_monthly_meals')) - rec.family_monthly_clotting = sum(rec.benefit_expense_line_ids.mapped('family_monthly_clotting')) + lines = rec.benefit_expense_line_ids + rec.family_monthly_income = sum(lines.mapped('family_monthly_income')) + rec.family_monthly_meals = sum(lines.mapped('family_monthly_meals')) + rec.family_monthly_clotting = sum(lines.mapped('family_monthly_clotting')) + rec.family_monthly_othaime = sum(lines.mapped('family_monthly_othaime')) rec.family_monthly_total = rec.family_monthly_income + rec.family_monthly_meals + rec.family_monthly_clotting + expense_lines = lines.filtered(lambda l: not l.meal_card) + othaim_lines = lines.filtered('meal_card') + rec.family_count_expense = len(expense_lines.mapped('family_id')) + rec.member_count_expense = sum(expense_lines.mapped('benefit_member_count')) + + rec.family_count_othaim = len(othaim_lines.mapped('family_id')) + rec.member_count_othaim = sum(othaim_lines.mapped('benefit_member_count')) + def action_assistant_manager(self): - if self.expense_type != 'family_expense': - self.state = 'assistant_general_manager' - return + # Todo ask awatif + # if self.expense_type != 'family_expense': + # self.state = 'assistant_general_manager' + # return disbursement_date = False # if not disbursement_date: @@ -256,28 +268,13 @@ class ConfirmBenefitExpense(models.Model): self.state = 'cancel' def action_reset_to_draft(self): - self.benefit_expense_line_ids.unlink() self.payment_order_id.unlink() self.move_id.unlink() + self.benefit_expense_line_ids.unlink() self.state = 'draft' - def _get_total_move_lines(self): - for rec in self: - if self.expense_type == 'family_expense': - moves = self.payment_order_id.move_id - else: - moves = self.move_id - - rec.total_moves = len(moves) - rec.total_move_lines = len(moves.mapped('line_ids')) - def action_open_related_move_records(self): - """ Opens a tree view with related records filtered by a dynamic domain """ - if self.expense_type == 'family_expense': - moves = self.payment_order_id.move_id.ids - else: - moves = self.move_id.ids - + moves = self.move_id.ids return { 'name': _('Vendor Bills'), 'type': 'ir.actions.act_window', @@ -286,63 +283,77 @@ class ConfirmBenefitExpense(models.Model): 'domain': [('id', 'in', moves)], } + def action_open_related_payment_orders(self): + payment_orders = self.payment_order_id.ids + return { + 'name': _('Payment Orders'), + 'type': 'ir.actions.act_window', + 'res_model': 'payment.orders', + 'view_mode': 'tree,form', + 'domain': [('id', 'in', payment_orders)], + } + def action_accounting_transfer(self): for rec in self: validation_setting = self.env["family.validation.setting"].search([], limit=1) lines = rec.benefit_expense_line_ids if not lines: raise UserError(_("Please make sure you have benefit expense lines.")) - if rec.expense_type == 'family_expense': - families = lines.mapped('family_id') - invalid_families = families.filtered( - lambda f: f.state != 'second_approve' - or (f.state in ('waiting_approve', 'first_approve') and f.action_type == 'suspended') - ) - if invalid_families: - raise UserError(_( - "Some selected benefits are not in valid state or are suspended:\n%s" - ) % ", ".join(invalid_families.mapped('name'))) - if not validation_setting.cash_expense_account_id or not validation_setting.meal_expense_account_id or not validation_setting.clothing_expense_account_id: - raise UserError(_("Please configure the expense accounts in the validation settings.")) + families = lines.mapped('family_id') + invalid_families = families.filtered( + lambda f: f.state != 'second_approve' + or (f.state in ('waiting_approve', 'first_approve') and f.action_type == 'suspended') + ) + if invalid_families: + raise UserError(_( + "Some selected benefits are not in valid state or are suspended:\n%s" + ) % ", ".join(invalid_families.mapped('name'))) - credit_account_id = validation_setting.account_id.id + if not validation_setting.cash_expense_account_id or not validation_setting.meal_expense_account_id or not validation_setting.clothing_expense_account_id: + raise UserError(_("Please configure the expense accounts in the validation settings.")) - if not credit_account_id: - raise UserError(_("Please select credit account.")) + credit_account_id = validation_setting.account_id.id - payment_order = self.env['payment.orders'].create({ - 'state': 'draft', - 'accountant_id': validation_setting.accountant_id.id, - 'benefit_expense_line_ids': [(6, 0, rec.benefit_expense_line_ids.ids)], - 'type': 'benefit_expense', - }) - rec.payment_order_id = payment_order - else: - account_id = validation_setting.meal_expense_account_id - invoice_lines = [] - for line in lines: - family = line.family_id - invoice_lines.append((0, 0, { - 'name': f'{family.name}/{family.code}', - 'account_id': account_id.id, - 'quantity': 1, - 'benefit_family_id': family.id, - 'price_unit': line.family_monthly_meals, - 'analytic_account_id': family.branch_family_id.branch.analytic_account_id.id - })) - invoice_vals = { - 'move_type': 'in_invoice', - 'partner_id': validation_setting.meal_partner_id.id, - 'invoice_date': rec.date, - 'family_confirm_id': rec.id, - 'benefit_family_ids': [(6, 0, rec.benefit_expense_line_ids.mapped('family_id').ids)], - 'journal_id': validation_setting.journal_id.id, - 'invoice_line_ids': invoice_lines, - 'ref': rec.name, - } + if not credit_account_id: + raise UserError(_("Please select credit account.")) - invoice = self.env['account.move'].create(invoice_vals) - rec.move_id = invoice + # todo if have paymnet or move dont create again + + # Create Payment Order for Benefit Expense + payment_order = self.env['payment.orders'].create({ + 'state': 'draft', + 'accountant_id': validation_setting.accountant_id.id, + 'benefit_expense_line_ids': [(6, 0, rec.benefit_expense_line_ids.ids)], + 'type': 'benefit_expense', + }) + rec.payment_order_id = payment_order + + # Create Vendor Bill for Meal Card Invoice(othaime) + account_id = validation_setting.meal_expense_account_id + invoice_lines = [] + for line in lines.filtered(lambda l: l.meal_card): + family = line.family_id + invoice_lines.append((0, 0, { + 'name': f'{family.name}/{family.code}', + 'account_id': account_id.id, + 'quantity': 1, + 'benefit_family_id': family.id, + 'price_unit': line.family_monthly_othaime, + 'analytic_account_id': family.branch_family_id.branch.analytic_account_id.id + })) + invoice_vals = { + 'move_type': 'in_invoice', + 'partner_id': validation_setting.meal_partner_id.id, + 'invoice_date': rec.date, + 'family_confirm_id': rec.id, + 'benefit_family_ids': [(6, 0, rec.benefit_expense_line_ids.mapped('family_id').ids)], + 'journal_id': validation_setting.journal_id.id, + 'invoice_line_ids': invoice_lines, + 'ref': rec.name, + } + + invoice = self.env['account.move'].create(invoice_vals) + rec.move_id = invoice return True diff --git a/odex25_ensan/odex_benefit/models/family_expense_line.py b/odex25_ensan/odex_benefit/models/family_expense_line.py index cbd2e63ce..fb0d28df1 100644 --- a/odex25_ensan/odex_benefit/models/family_expense_line.py +++ b/odex25_ensan/odex_benefit/models/family_expense_line.py @@ -20,6 +20,7 @@ class BenefitExpenseLine(models.Model): family_monthly_income = fields.Float(string="Family Monthly Income") family_monthly_meals = fields.Float(string="Family Monthly Meals") family_monthly_clotting = fields.Float(string="Family Monthly Clotting") + family_monthly_othaime = fields.Float(string="Othaim Total Monthly") total_family_expenses = fields.Float(string="Total Family Expenses", compute='_compute_total_family_expenses') start_date = fields.Date(string='Start Date', ) end_date = fields.Date(string='End Date', ) diff --git a/odex25_ensan/odex_benefit/views/family_expense_line_view.xml b/odex25_ensan/odex_benefit/views/family_expense_line_view.xml index 72789dc73..1e2a0051e 100644 --- a/odex25_ensan/odex_benefit/views/family_expense_line_view.xml +++ b/odex25_ensan/odex_benefit/views/family_expense_line_view.xml @@ -16,6 +16,7 @@ + @@ -43,6 +44,7 @@ + diff --git a/odex25_ensan/odex_benefit/views/family_expense_view.xml b/odex25_ensan/odex_benefit/views/family_expense_view.xml index 49494cffe..351678a70 100644 --- a/odex25_ensan/odex_benefit/views/family_expense_view.xml +++ b/odex25_ensan/odex_benefit/views/family_expense_view.xml @@ -9,8 +9,7 @@ - - + @@ -59,25 +58,44 @@ - - -

@@ -97,52 +115,55 @@

- - +
- - + + + + + +
- - - - - - - - + attrs="{'invisible': [('cash_expense', '=', False)]}"/> + attrs="{'invisible': [('meal_expense', '=', False)]}"/> + attrs="{'invisible': [('cloth_expense', '=', False)]}"/> - + + + + + + + - + @@ -157,13 +178,39 @@ + + domain="[('id', 'in', family_domain_ids)]"> + + + + + + + + + + + + + + + + + + + + @@ -182,9 +229,6 @@ confirm.benefit.expense - - - diff --git a/odex25_ensan/odex_benefit/views/family_members.xml b/odex25_ensan/odex_benefit/views/family_members.xml index 2b401b16e..48b08d235 100644 --- a/odex25_ensan/odex_benefit/views/family_members.xml +++ b/odex25_ensan/odex_benefit/views/family_members.xml @@ -584,7 +584,7 @@ font-size:14px; "> + style="color:#198754; font-size:14px;"/>
@@ -618,7 +618,7 @@ + style="color:#9aa5a0; font-size:12px;"/>
From 1984a722c6131496b88c8a3d86ba00b1d18212dd Mon Sep 17 00:00:00 2001 From: younes Date: Thu, 13 Nov 2025 20:27:54 +0100 Subject: [PATCH 05/13] [IMP] odex_benefit: IMP benefit --- odex25_ensan/odex_benefit/i18n/ar_001.po | 64 ++++++++++++++++++- .../views/family_expense_view.xml | 7 +- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/odex25_ensan/odex_benefit/i18n/ar_001.po b/odex25_ensan/odex_benefit/i18n/ar_001.po index 23897a125..565a190fd 100644 --- a/odex25_ensan/odex_benefit/i18n/ar_001.po +++ b/odex25_ensan/odex_benefit/i18n/ar_001.po @@ -2715,6 +2715,11 @@ msgstr "نوع الفرع" msgid "Branches" msgstr "فروع الرياض" +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__branch_custom_ids +msgid "Branches" +msgstr "الفروع" + #. module: odex_benefit #: model:ir.model.fields,field_description:odex_benefit.field_benefits_representative__can_publish #: model:ir.model.fields,field_description:odex_benefit.field_external_benefits__can_publish @@ -11561,13 +11566,11 @@ msgid "Total Monthly Meals" msgstr "إجمالي مصروف الغذاء للأسر" #. module: odex_benefit -#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__total_move_lines #: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__total_move_lines msgid "Total Move Lines" msgstr "القيود اليومية" #. module: odex_benefit -#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__total_moves #: model:ir.model.fields,field_description:odex_benefit.field_service_request__total_moves msgid "Total Move" msgstr "القيود اليومية" @@ -16857,6 +16860,7 @@ msgid "Payment Order State" msgstr "حالة أمر الدفع" #. module: odex_benefit +#: model:ir.model.fields.selection,name:odex_benefit.selection__confirm_benefit_expense__move_state__none #: model:ir.model.fields.selection,name:odex_benefit.selection__confirm_benefit_expense__payment_state__none #: model:ir.model.fields.selection,name:odex_benefit.selection__seasonal_service__payment_order_state__none #: model:ir.model.fields.selection,name:odex_benefit.selection__service_request__payment_order_state__none @@ -16865,6 +16869,7 @@ msgid "None" msgstr "لا يوجد" #. module: odex_benefit +#: model:ir.model.fields.selection,name:odex_benefit.selection__confirm_benefit_expense__move_state__waiting #: model:ir.model.fields.selection,name:odex_benefit.selection__confirm_benefit_expense__payment_state__waiting #: model:ir.model.fields.selection,name:odex_benefit.selection__seasonal_service__payment_order_state__waiting #: model:ir.model.fields.selection,name:odex_benefit.selection__service_request__payment_order_state__waiting @@ -16872,6 +16877,7 @@ msgid "Waiting Payment" msgstr "في انتظار الدفع" #. module: odex_benefit +#: model:ir.model.fields.selection,name:odex_benefit.selection__confirm_benefit_expense__move_state__done #: model:ir.model.fields.selection,name:odex_benefit.selection__confirm_benefit_expense__payment_state__done #: model:ir.model.fields.selection,name:odex_benefit.selection__seasonal_service__payment_order_state__done #: model:ir.model.fields.selection,name:odex_benefit.selection__service_request__payment_order_state__done @@ -17038,9 +17044,16 @@ msgstr "يرجى اختيار دفتر اليومية قبل إنشاء القي #: model_terms:ir.ui.view,arch_db:odex_benefit.payment_orders_tree #: model_terms:ir.ui.view,arch_db:odex_benefit.view_family_bank_report_wizard_form #: model:ir.model.fields,field_description:odex_benefit.field_family_bank_report_wizard__payment_order_ids +#, python-format msgid "Payment Orders" msgstr "أوامر صرف الخدمات" +#. module: odex_benefit +#: code:addons/odex_benefit/models/family_expense.py:0 +#, python-format +msgid "Payment Orders" +msgstr "أوامر الصرف" + #. module: odex_benefit #: code:addons/odex_benefit/wizards/family_bank_report_wizard.py:0 #, python-format @@ -17088,4 +17101,49 @@ msgstr "فواتير الموردين" #. module: odex_benefit #: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_form msgid "Return to Family" -msgstr "إرجاع للأسرة" \ No newline at end of file +msgstr "إرجاع للأسرة" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__family_monthly_othaime +msgid "Total Othaim" +msgstr "إجمالي العثيم" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__move_state +msgid "Move State" +msgstr "حالة الفاتورة" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__family_count_expense +msgid "Family Count (Monthly Expense)" +msgstr "إجمالي عدد الأسر للمصروف الشهري" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__family_count_othaim +msgid "Family Count (Othaim)" +msgstr "إجمالي عدد الأسر للعثيم" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__member_count_expense +msgid "Member Count (Monthly Expense)" +msgstr "إجمالي عدد الأفراد للمصروف الشهري" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__member_count_othaim +msgid "Member Count (Othaim)" +msgstr "إجمالي عدد الأفراد للعثيم" + +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__family_monthly_othaime +msgid "Othaim Total Monthly" +msgstr "إجمالي العثيم الشهري" + +#. module: odex_benefit +#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form +msgid "Othaime Invoice" +msgstr "فاتورة العثيم" + +#. module: odex_benefit +#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form +msgid "Payment Orders" +msgstr "أوامر الصرف" \ No newline at end of file diff --git a/odex25_ensan/odex_benefit/views/family_expense_view.xml b/odex25_ensan/odex_benefit/views/family_expense_view.xml index 351678a70..32c081c51 100644 --- a/odex25_ensan/odex_benefit/views/family_expense_view.xml +++ b/odex25_ensan/odex_benefit/views/family_expense_view.xml @@ -25,6 +25,11 @@ decoration-warning="payment_state == 'waiting'" decoration-success="payment_state == 'done'" /> + @@ -88,7 +93,7 @@ Othaime Invoice From 072ea0b74767b18881aab4ccaea1c58c767550e9 Mon Sep 17 00:00:00 2001 From: younes Date: Sun, 16 Nov 2025 08:31:55 +0100 Subject: [PATCH 06/13] [FIX] odex_takaful: FIX bug --- .../odex_takaful/models/takaful_sponorship_model.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/odex25_ensan/odex_takaful/models/takaful_sponorship_model.py b/odex25_ensan/odex_takaful/models/takaful_sponorship_model.py index 4e301e05c..381b6f98e 100644 --- a/odex25_ensan/odex_takaful/models/takaful_sponorship_model.py +++ b/odex25_ensan/odex_takaful/models/takaful_sponorship_model.py @@ -1351,7 +1351,7 @@ class TakafulSponsorship(models.Model): current_invoice = self.journal_entry_ids.filtered(lambda r: r.move_type == 'out_invoice' and r.state == 'draft') if current_invoice: invoice_values['invoice_line_ids'] = [(5, 0, 0)] + invoice_line_vals - current_invoice.write(invoice_values) + current_invoice.sudo().write(invoice_values) invoice_id = current_invoice else: invoice_values.update({'invoice_line_ids': invoice_line_vals, 'name': self.env['ir.sequence'].next_by_code('account.move.accrsp')}) @@ -1365,7 +1365,7 @@ class TakafulSponsorship(models.Model): line.tax_ids = taxes line.product_uom_id = line._get_computed_uom() - invoice_id.action_post() + invoice_id.sudo().action_post() # Search for the notification message for 'create_kafala' notification = self.env['takaful.notification'].sudo().search( @@ -1776,7 +1776,7 @@ class TakafulSponsorship(models.Model): if rec.state != 'confirmed': raise ValidationError(_("You can only reset to draft a confirmed sponsorship.")) move_ids = rec.journal_entry_ids.filtered(lambda l: l.move_type == 'out_invoice') - move_ids.button_draft() + move_ids.sudo().button_draft() self.write({'state': 'draft'}) all_donation_lines = (self.donations_details_lines + self.donations_details_lines_mechanism_ids).filtered( lambda r: r.display_type == False) From 79facb44e4bd6011d0c9107385064b4b7309548e Mon Sep 17 00:00:00 2001 From: odoo-syria-team Date: Sun, 16 Nov 2025 12:38:02 +0300 Subject: [PATCH 07/13] [FIX] Solve issues --- .../models/donation_details_lines.py | 27 ++++-- .../views/takaful_sponorship_view.xml | 94 ++++++++++--------- 2 files changed, 67 insertions(+), 54 deletions(-) diff --git a/odex25_ensan/odex_takaful/models/donation_details_lines.py b/odex25_ensan/odex_takaful/models/donation_details_lines.py index 72aaa3834..e600b2a65 100644 --- a/odex25_ensan/odex_takaful/models/donation_details_lines.py +++ b/odex25_ensan/odex_takaful/models/donation_details_lines.py @@ -111,20 +111,26 @@ class DonationsDetailsLines(models.Model): def _compute_get_age_range(self): for rec in self: x = [] - records = self.env['donations.details.lines'].search(['|' , ('state', '=', 'replace') , ('state', '=', 'waiting')]) - for record in records: + branch_id = rec.branch_custom_id.id + records = self.env['donations.details.lines'].search(['|' , ('state', '=', 'replace') , ('state', '=', 'waiting') ]) + filtered_records = records.filtered(lambda r: r.sponsorship_mechanism_id.branch_custom_id.id == branch_id) - if record.sponsorship_duration == 'permanent': + for record in filtered_records: + if record.sponsorship_duration == 'permanent' : x.append(1) - elif record.sponsorship_duration != 'permanent' and record.payment_month_count > 6: - x.append(1) - elif record.sponsorship_duration != 'permanent' and record.payment_month_count < 6 and record.direct_debit: + elif record.sponsorship_duration != 'permanent' and record.payment_month_count < 6 and record.direct_debit : x.append(16) - elif record.sponsorship_duration != 'permanent' and record.payment_month_count < 6: - x.append(18) - else: + elif record.sponsorship_duration != 'permanent' and record.payment_month_count >= 6 : x.append(1) - lowest_value = min(x) if x else None + elif record.sponsorship_duration != 'permanent' and record.payment_month_count < 6 : + x.append(18) + + + if len(x) > 0 : + lowest_value = min(x) if x else None + else: + lowest_value = 100 + rec.ages = lowest_value @api.depends('extension_history_ids') @@ -495,6 +501,7 @@ class DonationsDetailsLines(models.Model): parent_record = self.env['takaful.sponsorship'].browse(parent_id) res['sponsorship_creation_date'] = parent_record.sponsorship_creation_date + res['branch_custom_id'] = parent_record.branch_custom_id # res['donation_mechanism'] = parent_record.donation_mechanism self._onchange_sponsorship_type() diff --git a/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml b/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml index 847aeb512..56a65fc41 100644 --- a/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml +++ b/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml @@ -79,18 +79,18 @@ - - - + + + - + - +
@@ -103,7 +103,7 @@ كفالة
- + @@ -111,9 +111,9 @@ groups="odex_takaful.branch_manager_group,odex_takaful.sponsorship_system_manager_group" attrs="{'readonly': [('state','!=','draft')]}"/> - + -
@@ -125,30 +125,32 @@ مشروط
- +
- + -
- أدخل بيانات المتبرع ثم حدد تفاصيل التبرع + + أدخل بيانات المتبرع ثم حدد تفاصيل التبرع
- -
- أدخل بيانات الكافل ثم انتقل لإضافة تفاصيل الكفالة + + أدخل بيانات الكافل ثم انتقل لإضافة تفاصيل الكفالة
- + - +