From f45aca23db0ff4371112105bad7aefe3548202fd Mon Sep 17 00:00:00 2001 From: MahmoudSalahEXP Date: Mon, 20 Oct 2025 20:51:24 +0300 Subject: [PATCH] sponsorship_multi_editings --- odex25_ensan/odex_benefit/i18n/ar_001.po | 10 + .../odex_benefit/models/family_members.py | 1 + .../odex_benefit/models/service_request.py | 44 ++- .../odex_benefit/models/services_settings.py | 2 +- .../odex_benefit/views/family_members.xml | 1 + .../odex_benefit/views/service_request.xml | 4 +- .../odex_takaful/models/account_move.py | 15 +- .../models/donation_details_lines.py | 374 +++++++++++++----- .../models/takaful_payment_method.py | 14 + .../models/takaful_sponorship_model.py | 12 +- .../views/takaful_payment_method.xml | 23 +- .../views/takaful_sponorship_view.xml | 10 +- .../views/takaful_sponsor_view.xml | 3 +- 13 files changed, 379 insertions(+), 134 deletions(-) diff --git a/odex25_ensan/odex_benefit/i18n/ar_001.po b/odex25_ensan/odex_benefit/i18n/ar_001.po index 1c34c65cd..9a018b006 100644 --- a/odex25_ensan/odex_benefit/i18n/ar_001.po +++ b/odex25_ensan/odex_benefit/i18n/ar_001.po @@ -15880,6 +15880,11 @@ msgstr "شروط الاستحقاق" msgid "Family Service Receipt" msgstr "الاستلام الاسرة للخدمة" +#. module: odex_benefit +#: model:ir.model.fields.selection,name:odex_benefit.selection__services_settings__benefit_type__both +msgid "Both" +msgstr "مشترك" + #. module: odex_benefit #: model:ir.model.fields,field_description:odex_benefit.field_services_settings__allow_non_beneficiary msgid "Allow Non Beneficiary" @@ -16488,3 +16493,8 @@ msgstr "اعتماد مساعد المدير العام" msgid "Researcher Supervisor" msgstr "مشرف الأخصائي" +#. module: odex_benefit +#: model:ir.model.fields,field_description:odex_benefit.field_family_member__sponsorship_end_date +msgid "Sponsorship End Date" +msgstr "تاريخ إنتهاء الكفالة" + diff --git a/odex25_ensan/odex_benefit/models/family_members.py b/odex25_ensan/odex_benefit/models/family_members.py index 098211ed9..ca4d3e52c 100644 --- a/odex25_ensan/odex_benefit/models/family_members.py +++ b/odex25_ensan/odex_benefit/models/family_members.py @@ -255,6 +255,7 @@ class FamilyMemberProfile(models.Model): sponsorship_id = fields.Many2one('takaful.sponsorship', string='Sponsorship') required_attach = fields.Selection(selection=[('true', 'True'), ('false', 'False')], compute='get_required_attach', store=True, string='Member Required Attach') + sponsorship_end_date = fields.Date(string='Sponsorship End Date') # Exception fields exception_reason = fields.Many2one('exception.reason', string='Exception Reason') exception_description = fields.Text(string='Exception Description') diff --git a/odex25_ensan/odex_benefit/models/service_request.py b/odex25_ensan/odex_benefit/models/service_request.py index d8bb0b821..392df0d07 100644 --- a/odex25_ensan/odex_benefit/models/service_request.py +++ b/odex25_ensan/odex_benefit/models/service_request.py @@ -10,7 +10,7 @@ class ServiceRequest(models.Model): name = fields.Char(string='Reference', required=True, copy=False, readonly=True, index=True,default=lambda self: _('New')) benefit_type = fields.Selection(string='Benefit Type',selection=[('family', 'Family'),('member', 'Member')]) date = fields.Datetime(string='Request Date',default=fields.Datetime.now) - family_id = fields.Many2one('grant.benefit',string='Family',domain="['|',('state','=','second_approve'),'&',('state','in',['waiting_approve','first_approve']),('action_type','=','suspended')]") + family_id = fields.Many2one('grant.benefit',string='Family',domain="['|',('state','=','gm_assistant'),'&',('state','in',['waiting_approve','first_approve']),('action_type','=','suspended')]") researcher_id = fields.Many2one("committees.line", string="Researcher", related="family_id.researcher_id",store=True) family_category = fields.Many2one('benefit.category',string='Family Category',related='family_id.benefit_category_id') benefit_member_count = fields.Integer(string="Benefit Member count", related='family_id.benefit_member_count') @@ -533,7 +533,6 @@ class ServiceRequest(models.Model): def _onchange_member(self): for rec in self: if rec.family_id: - rec.benefit_type = rec.service_cat.benefit_type if rec.benefit_type == 'family' and rec.service_type == 'eid_gift': rec.requested_service_amount = rec.eid_gift_benefit_count * rec.service_cat.eid_gift_member_amount if rec.benefit_type == 'member' and rec.service_type == 'eid_gift': @@ -730,19 +729,19 @@ class ServiceRequest(models.Model): if max_limit_type == 'fixed': rec.service_max_amount = rec.service_cat.max_amount elif max_limit_type == 'category': - rec.service_max_amount = rec.service_cat.category_amount_lines and max(rec.service_cat.category_amount_lines.filtered( + rec.service_max_amount = max(rec.service_cat.category_amount_lines.filtered( lambda r: r.benefit_category_id.id == rec.family_category.id).mapped('max_amount'), - default=0.0) or 0 + default=0.0) elif max_limit_type == 'category_person': - rec.service_max_amount = rec.service_cat.bill_lines and max(rec.service_cat.bill_lines.filtered( + rec.service_max_amount = max(rec.service_cat.bill_lines.filtered( lambda x: x.benefit_category_id.id == rec.family_category.id and x.min_count_member <= rec.benefit_member_count <= x.max_count_member).mapped( - 'max_amount_for_bill'), default=0.0) or 0 + 'max_amount_for_bill'), default=0.0) elif max_limit_type == 'service': pass elif max_limit_type == 'amount_person': - rec.service_max_amount = rec.service_cat.limit_person_line_ids and max(rec.service_cat.limit_person_line_ids.filtered( - lambda x: x.min_count_member <= rec.benefit_member_count <= x.max_count_member)).amount or 0 + rec.service_max_amount = max(rec.service_cat.limit_person_line_ids.filtered( + lambda x: x.min_count_member <= rec.benefit_member_count <= x.max_count_member)).amount if service_type == 'transportation_insurance': if rec.service_reason_id and rec.requested_service_amount > rec.max_amount: @@ -854,17 +853,28 @@ class ServiceRequest(models.Model): raise UserError( "The Start Date and End Date must be within the Rent Start Date and Rent End Date range.") - @api.depends('family_category') + @api.depends('family_category','member_id') def _compute_available_service_cats(self): for rec in self: - domain = [('service_type', '!=', 'main_service'),('benefit_category_ids', 'in', [rec.family_category.id])] - if rec.family_id.property_type not in ['ownership','ownership_shared','charitable']: - domain.append(('service_type','!=','home_restoration')) - else: - domain.append(('service_type', '!=', 'buy_home')) - rec.available_service_cats = rec.available_service_cats.sudo().search(domain) - #if rec.member_id.member_status != 'benefit': - # domain.append(('allow_non_beneficiary','=',True)) + if rec.benefit_type: + if rec.benefit_type == 'family': + domain = [('service_type', '!=', 'main_service'),('benefit_type','!=','member'),('benefit_category_ids', 'in', [rec.family_category.id])] + if rec.family_id.property_type not in ['ownership','ownership_shared','charitable']: + domain.append(('service_type','!=','home_restoration')) + else: + domain.append(('service_type', '!=', 'buy_home')) + rec.available_service_cats = rec.available_service_cats.sudo().search(domain) + elif rec.benefit_type == 'member' and rec.member_id: + domain = [ + ('service_type', '!=', 'main_service'), + ('benefit_type', '!=', 'family'), + ('benefit_category_ids', 'in', [rec.family_category.id]) + ] + if rec.member_id.member_status != 'benefit': + domain.append(('allow_non_beneficiary','=',True)) + rec.available_service_cats = rec.available_service_cats.sudo().search(domain) + else: + rec.available_service_cats = False def action_set_to_draft(self): for rec in self: diff --git a/odex25_ensan/odex_benefit/models/services_settings.py b/odex25_ensan/odex_benefit/models/services_settings.py index 321187b83..178936366 100644 --- a/odex25_ensan/odex_benefit/models/services_settings.py +++ b/odex25_ensan/odex_benefit/models/services_settings.py @@ -7,7 +7,7 @@ class ServicesSettings(models.Model): _order = 'service_number' service_name = fields.Char(string='Service Name') - benefit_type = fields.Selection(string='Benefit Type', selection=[('family', 'Family'), ('member', 'Member')]) + benefit_type = fields.Selection(string='Benefit Type', selection=[('family', 'Family'), ('member', 'Member'), ('both', 'Both')],default='both') parent_service = fields.Many2one('services.settings',string='Parent Service') is_main_service = fields.Boolean(string='Is Main Service?') is_service_producer = fields.Boolean(string='Is Service Producer?') diff --git a/odex25_ensan/odex_benefit/views/family_members.xml b/odex25_ensan/odex_benefit/views/family_members.xml index 295f0222a..1acadd44b 100644 --- a/odex25_ensan/odex_benefit/views/family_members.xml +++ b/odex25_ensan/odex_benefit/views/family_members.xml @@ -158,6 +158,7 @@ + diff --git a/odex25_ensan/odex_benefit/views/service_request.xml b/odex25_ensan/odex_benefit/views/service_request.xml index e553f2e49..cceb1aad8 100644 --- a/odex25_ensan/odex_benefit/views/service_request.xml +++ b/odex25_ensan/odex_benefit/views/service_request.xml @@ -170,7 +170,9 @@ - + diff --git a/odex25_ensan/odex_takaful/models/account_move.py b/odex25_ensan/odex_takaful/models/account_move.py index 10457989d..1e8adf1b5 100644 --- a/odex25_ensan/odex_takaful/models/account_move.py +++ b/odex25_ensan/odex_takaful/models/account_move.py @@ -346,13 +346,22 @@ class AccountRegisterPayment(models.TransientModel): if line.record_type != 'sponsorship': continue if line.sponsorship_type == 'group': - line.benefit_ids.write({'sponsor_related_id': line.sponsorship_mechanism_id.sponsor_id.id, 'sponsorship_id': line.sponsorship_mechanism_id.id}) + line.benefit_ids.write({ + 'sponsor_related_id': line.sponsorship_mechanism_id.sponsor_id.id, + 'sponsorship_id': line.sponsorship_mechanism_id.id, + 'sponsorship_end_date': line.end_date if line.end_date else False + }) if line.sponsorship_type == 'person': - line.benefit_id.write({'sponsor_related_id': line.sponsorship_mechanism_id.sponsor_id.id, 'sponsorship_id': line.sponsorship_mechanism_id.id}) + line.benefit_id.write({ + 'sponsor_related_id': line.sponsorship_mechanism_id.sponsor_id.id, + 'sponsorship_id': line.sponsorship_mechanism_id.id, + 'sponsorship_end_date': line.end_date if line.end_date else False + }) line.sponsorship_mechanism_id.sponsor_id.sudo().is_sponsor_portal = True states = all_lines.mapped('state') - if any(state in ['draft', 'waiting', 'active'] for state in states): + # if any(state in ['draft', 'waiting', 'active'] for state in states): + if any(state in ['draft'] for state in states): sponsorship.state = 'wait_pay' else: sponsorship.state = 'paid' diff --git a/odex25_ensan/odex_takaful/models/donation_details_lines.py b/odex25_ensan/odex_takaful/models/donation_details_lines.py index 5da1694c5..ae68f102e 100644 --- a/odex25_ensan/odex_takaful/models/donation_details_lines.py +++ b/odex25_ensan/odex_takaful/models/donation_details_lines.py @@ -1,16 +1,18 @@ from odoo import models, fields, api, _ -from odoo.exceptions import ValidationError,UserError +from odoo.exceptions import ValidationError, UserError import re import requests import logging from datetime import datetime, date from dateutil.relativedelta import relativedelta +import json _logger = logging.getLogger(__name__) + class DonationsDetailsLines(models.Model): _name = "donations.details.lines" - _inherit = ['mail.thread'] + _inherit = ['mail.thread'] name = fields.Text(string="Note") display_type = fields.Selection([ @@ -18,36 +20,49 @@ class DonationsDetailsLines(models.Model): ('line_note', "Note")], default=False, help="Technical field for UX purpose.") sequence = fields.Integer(string='Sequence', default=10) sequence_no = fields.Char(default='/', readonly=True, copy=False) - donation_type = fields.Selection([('donation', 'Donation'), ('waqf', 'Waqf'), ('sponsorship', 'Sponsorship'), ],string='Donation Type') - donation_types = fields.Selection([('donation', 'Donation'), ('waqf', 'Waqf')],string='Donation Type') + donation_type = fields.Selection([('donation', 'Donation'), ('waqf', 'Waqf'), ('sponsorship', 'Sponsorship'), ], + string='Donation Type') + donation_types = fields.Selection([('donation', 'Donation'), ('waqf', 'Waqf')], string='Donation Type') product_template_id = fields.Many2one('product.template', string="Donation Name", required=True) product_id = fields.Many2one('product.product', compute='_compute_product_id') sponsorship_id = fields.Many2one('takaful.sponsorship', string="Sponsorship") sponsorship_mechanism_id = fields.Many2one('takaful.sponsorship', string="Sponsorship") sponsorship_creation_date = fields.Datetime() donation_amount = fields.Float(string='Donation Amount', compute="_compute_donation_amount", store=True) - donation_mechanism = fields.Selection([('with_conditions', _('With Conditions')),('without_conditions', _('Without Conditions'))],string='Donation Mechanism', readonly=True) - benefit_type = fields.Selection([('orphan', 'Orphans'),('widow', 'Widows'),('both', 'Both')],string='Sponsorship Beneficiary Type',tracking=True) - sponsorship_type = fields.Selection([('person', 'Individual'),('group', 'Group')],string='Sponsorship Type',tracking=True) + donation_mechanism = fields.Selection( + [('with_conditions', _('With Conditions')), ('without_conditions', _('Without Conditions'))], + string='Donation Mechanism', readonly=True) + benefit_type = fields.Selection([('orphan', 'Orphans'), ('widow', 'Widows'), ('both', 'Both')], + string='Sponsorship Beneficiary Type', tracking=True) + sponsorship_type = fields.Selection([('person', 'Individual'), ('group', 'Group')], string='Sponsorship Type', + tracking=True) gender = fields.Selection(selection=[('male', 'Male'), ('female', 'Female')], string="Gender") age_category_id = fields.Many2one('age.category', string='Age Category') - education_status = fields.Selection(string='Education Status',selection=[('educated', 'educated'), ('illiterate', 'illiterate'),('under_study_age', 'Under Study Age')]) + education_status = fields.Selection(string='Education Status', + selection=[('educated', 'educated'), ('illiterate', 'illiterate'), + ('under_study_age', 'Under Study Age')]) education_level = fields.Many2one("education.level", string='Education Levels') - members_domain_ids = fields.Many2many(comodel_name='family.member', compute='_compute_domain_ids') - benefit_id = fields.Many2one('family.member',string='Beneficiary Name',ondelete='set null',domain = "[('sponsor_related_id', '=', False), ('id', 'in',members_domain_ids)]", tracking=True) - family_id = fields.Many2one('grant.benefit',string='Family',ondelete='set null',related="benefit_id.benefit_id") - benefit_ids = fields.Many2many('family.member',string='Beneficiaries Names', tracking=True,domain = "[('sponsor_related_id', '=', False)]") - sponsorship_duration = fields.Selection([('temporary', 'Temporary'),('permanent', 'Permanent')],string='Sponsorship Type') + # members_domain_ids = fields.Many2many(comodel_name='family.member', compute='_compute_domain_ids') + members_domain_ids = fields.Many2many('family.member', 'members_domain_ids_rel', 'member_id', 'line_id', compute='_compute_benefit_members_text_domain', store=False) + benefit_id = fields.Many2one('family.member', string='Beneficiary Name', ondelete='set null', domain="[('id', 'in', members_domain_ids)]", + tracking=True) + family_id = fields.Many2one('grant.benefit', string='Family', ondelete='set null', related="benefit_id.benefit_id") + benefit_ids = fields.Many2many('family.member', string='Beneficiaries Names', tracking=True, + domain="[('sponsor_related_id', '=', False)]") + sponsorship_duration = fields.Selection([('temporary', 'Temporary'), ('permanent', 'Permanent')], + string='Sponsorship Type') start_date = fields.Date(string="Sponsorship Start Date", copy=False, default=fields.Date.today()) - end_date = fields.Date(string="Sponsorship End Date",compute='_compute_end_date', store=True) + end_date = fields.Date(string="Sponsorship End Date", compute='_compute_end_date', store=True) payment_option = fields.Selection([('month', 'Monthly'), ('once', 'For Once')], string='Payment Option') payment_month_count = fields.Integer(string='Payment Month Count', default=1) - fixed_value = fields.Boolean(string='Is Fixed Value?',related='product_template_id.fixed_value') - benefits_count = fields.Integer(string='Benefits Count',compute='_get_benefits_count') - total_donation_amount = fields.Float(string='Total Donation Amount',compute='_get_total_donation_amount') + fixed_value = fields.Boolean(string='Is Fixed Value?', related='product_template_id.fixed_value') + benefits_count = fields.Integer(string='Benefits Count', compute='_get_benefits_count') + total_donation_amount = fields.Float(string='Total Donation Amount', compute='_get_total_donation_amount') sponsorships_computed = fields.Boolean(copy=False, readonly=True) - payment_method_id = fields.Many2one('takaful.payment.method', string="Payment Method", domain="[('id', 'in', allowed_payment_method_ids)]") - allowed_payment_method_ids = fields.Many2many('takaful.payment.method', compute='_compute_allowed_payment_method_ids') + payment_method_id = fields.Many2one('takaful.payment.method', string="Payment Method", + domain="[('id', 'in', allowed_payment_method_ids)]") + allowed_payment_method_ids = fields.Many2many('takaful.payment.method', + compute='_compute_allowed_payment_method_ids') payment_method = fields.Selection(related="payment_method_id.payment_method") benefit_id_number = fields.Char("Benefit ID Number") benefit_family_code = fields.Char("Benefit Family Code") @@ -55,10 +70,13 @@ class DonationsDetailsLines(models.Model): sponsor_id = fields.Many2one('takaful.sponsor', related='sponsorship_id.sponsor_id') sponsor_phone = fields.Char(related='sponsorship_id.sponsor_id.mobile') branch_custom_id = fields.Many2one('branch.settings', related='sponsorship_id.branch_custom_id') - record_type = fields.Selection([('sponsorship', 'Sponsorship'),('donation', 'Donation')], compute='_compute_record_type', store=True, readonly=True) - state = fields.Selection([('draft', 'To Pay'),('waiting', 'Waiting'), ('active', 'Active'),('closed', 'Closed'),('extended', 'Extended'), ('paid', 'Paid')], string='State', default='draft') + record_type = fields.Selection([('sponsorship', 'Sponsorship'), ('donation', 'Donation')], + compute='_compute_record_type', store=True, readonly=True) + state = fields.Selection([('draft', 'To Pay'), ('waiting', 'Waiting'), ('active', 'Active'), ('closed', 'Closed'), + ('extended', 'Extended'), ('paid', 'Paid')], string='State', default='draft') sponsorship_scheduling_line_ids = fields.One2many('sponsorship.scheduling.line', 'donation_detail_linked_id') - extension_history_ids = fields.One2many('donation.extension.history', 'donation_detail_id', string='Extension History') + extension_history_ids = fields.One2many('donation.extension.history', 'donation_detail_id', + string='Extension History') extension_count = fields.Integer(string='Extensions', compute='_compute_extension_count') show_extend_button = fields.Boolean(string='Show Extend Button', compute='_compute_show_extend_button') is_paid = fields.Boolean(string="Is Paid", default=False) @@ -69,32 +87,35 @@ class DonationsDetailsLines(models.Model): def _compute_extension_count(self): for rec in self: rec.extension_count = len(rec.extension_history_ids) - + @api.depends('payment_method', 'end_date') def _compute_show_extend_button(self): today = fields.Date.today() for rec in self: show_extend_button = ( - ((rec.record_type == 'donation' and rec.payment_method == 'direct_debit') or rec.record_type == 'sponsorship') and - rec.end_date and - rec.end_date >= today + (( + rec.record_type == 'donation' and rec.payment_method == 'direct_debit') or rec.record_type == 'sponsorship') and + rec.end_date and + rec.end_date >= today ) rec.show_extend_button = show_extend_button - + @api.depends('sponsorship_duration', 'payment_method_id', 'record_type', 'start_date') def _compute_hide_beneficiary_group(self): for rec in self: - if rec.sponsorship_duration == 'temporary' and rec.payment_method == 'direct_debit' and rec.record_type == 'sponsorship' and rec.start_date != fields.Date.context_today(rec): + if rec.sponsorship_duration == 'temporary' and rec.payment_method == 'direct_debit' and rec.record_type == 'sponsorship' and rec.start_date != fields.Date.context_today( + rec): rec.hide_beneficiary_group = True else: rec.hide_beneficiary_group = False - @api.depends('sponsorship_id','sponsorship_mechanism_id') + @api.depends('sponsorship_id', 'sponsorship_mechanism_id') def _compute_parent_state(self): for rec in self: rec.parent_state = rec.sponsorship_id.state if rec.sponsorship_id else rec.sponsorship_mechanism_id.state - @api.depends('sponsorship_id','sponsorship_mechanism_id', 'sponsorship_id.record_type', 'sponsorship_mechanism_id.record_type') + @api.depends('sponsorship_id', 'sponsorship_mechanism_id', 'sponsorship_id.record_type', + 'sponsorship_mechanism_id.record_type') def _compute_record_type(self): for rec in self: rec.record_type = rec.sponsorship_id.record_type if rec.sponsorship_id else rec.sponsorship_mechanism_id.record_type @@ -115,14 +136,15 @@ class DonationsDetailsLines(models.Model): rec.product_id = rec.product_template_id._get_first_possible_variant_id() else: rec.product_id = False - + def onset_benefit_id(self): for rec in self: - if rec.state == 'waiting' and (rec.benefit_id or rec.benefit_ids): + if rec.state == 'waiting' and (rec.benefit_id or rec.benefit_ids): rec.state = 'active' sponsor_id = rec.sponsorship_mechanism_id.sponsor_id.id if rec.sponsorship_mechanism_id else rec.sponsorship_id.sponsor_id.id - (rec.benefit_id + rec.benefit_ids).write({'sponsor_related_id': sponsor_id}) - + (rec.benefit_id + rec.benefit_ids).write( + {'sponsor_related_id': sponsor_id, "sponsorship_end_date": rec.end_date if rec.end_date else False}) + @api.model def run_check_all_end_dates(self): lines = self.search([('end_date', '!=', False)]) @@ -131,7 +153,7 @@ class DonationsDetailsLines(models.Model): @api.depends('payment_month_count', 'product_template_id', 'sponsorship_duration') def _compute_donation_amount(self): for rec in self.with_context(recursive_onchanges=False): - rec.donation_amount = rec.product_template_id.list_price * rec.payment_month_count + rec.donation_amount = rec.product_template_id.list_price * rec.payment_month_count def check_end_date(self): for record in self: @@ -140,19 +162,19 @@ class DonationsDetailsLines(models.Model): end_date = record.end_date days_difference = (today - record.end_date).days if days_difference == 30: - record.action_send_whatsapp(30,end_date) + record.action_send_whatsapp(30, end_date) elif days_difference == 16: - record.action_send_whatsapp(16,end_date) + record.action_send_whatsapp(16, end_date) elif days_difference == 4: - record.action_send_whatsapp(4,end_date) + record.action_send_whatsapp(4, end_date) return False - - def action_send_whatsapp(self,duration,end_date): + def action_send_whatsapp(self, duration, end_date): if duration == 30: notification = self.env['takaful.notification'].sudo().search( - [('notification_type', '=', 'before_finish'), ('message_type_ids.tool_type', '=', 'app'),('duration', '=', 30)], + [('notification_type', '=', 'before_finish'), ('message_type_ids.tool_type', '=', 'app'), + ('duration', '=', 30)], limit=1 ) expiry_date_str = end_date.strftime('%d-%m-%Y') if end_date else 'N/A' @@ -161,7 +183,8 @@ class DonationsDetailsLines(models.Model): elif duration == 16: notification = self.env['takaful.notification'].sudo().search( - [('notification_type', '=', 'before_finish'), ('message_type_ids.tool_type', '=', 'app'),('duration', '=', 16)], + [('notification_type', '=', 'before_finish'), ('message_type_ids.tool_type', '=', 'app'), + ('duration', '=', 16)], limit=1 ) message = notification.message or _("No message found in 'Before Kafala End Date' notification.") @@ -171,7 +194,8 @@ class DonationsDetailsLines(models.Model): elif duration == 4: notification = self.env['takaful.notification'].sudo().search( - [('notification_type', '=', 'before_finish'), ('message_type_ids.tool_type', '=', 'app'),('duration', '=', 4)], + [('notification_type', '=', 'before_finish'), ('message_type_ids.tool_type', '=', 'app'), + ('duration', '=', 4)], limit=1 ) expiry_date_str = end_date.strftime('%d-%m-%Y') if end_date else 'N/A' @@ -187,18 +211,18 @@ class DonationsDetailsLines(models.Model): from_whatsapp = config.get_param('odex_takaful.twilio_from_whatsapp') if not account_sid or not auth_token or not from_whatsapp: - raise ValidationError(_("Twilio configuration is missing. Please configure Twilio SID, Auth Token, and WhatsApp number in General Configurations.")) + raise ValidationError( + _("Twilio configuration is missing. Please configure Twilio SID, Auth Token, and WhatsApp number in General Configurations.")) from_cleaned_mobile = re.sub(r'[^\d+]', '', from_whatsapp) from_whatsapp_number = f'whatsapp:{from_cleaned_mobile}' # Search for the notification message for 'create_kafala' - # Use the message from the notification amount = self.donation_amount if hasattr(self, 'donation_amount') else 0.0 for partner in self: - sponsorship_id = partner.sponsorship_mechanism_id or partner.sponsorship_id + sponsorship_id = partner.sponsorship_mechanism_id or partner.sponsorship_id mobile = sponsorship_id.sponsor_id.mobile if sponsorship_id.sponsor_id else sponsorship_id.member_id.mobile if mobile: # Clean the number (keep + and digits only) @@ -303,25 +327,24 @@ class DonationsDetailsLines(models.Model): return sol_ = sol_object.search( - [('sponsorship_id', '=', sponsorship_id.id), ('product_template_id', '=', product_id.id), ]) # ("cart_flag", "=", True) + [('sponsorship_id', '=', sponsorship_id.id), + ('product_template_id', '=', product_id.id), ]) # ("cart_flag", "=", True) if operation == "remove": sol_.unlink() return - def user_input_qty_sol(self, _qty, product_id, sponsorship_id): sol_object = self.env["donations.details.lines"] product_object = self.env["product.template"] cart_product_details = sol_object.search( [('sponsorship_id', "=", sponsorship_id), ("product_template_id", "=", product_id) - ]) # ("cart_flag", "=", True) + ]) # ("cart_flag", "=", True) if product_id.payment_method_id: payment_method = product_id.payment_method_id.id else: payment_method = self.env["takaful.payment.method"].search([('payment_method', '=', 'cash')], limit=1).id - donation_id = product_object.search([('id', '=', product_id)]) sol_data = dict() sol_data["product_template_id"] = donation_id.id @@ -333,7 +356,6 @@ class DonationsDetailsLines(models.Model): so = sol_object.create(sol_data) return - @api.onchange('benefit_id_number', 'sponsorship_type', 'benefit_type') def _onchange_benefit_id_number(self): for rec in self: @@ -344,7 +366,6 @@ class DonationsDetailsLines(models.Model): else: rec.benefit_id = False - @api.constrains('payment_month_count') def _check_payment_month_count(self): for rec in self: @@ -405,13 +426,13 @@ class DonationsDetailsLines(models.Model): for rec in self: rec.benefits_count = len(rec.benefit_ids) - @api.depends('benefits_count','donation_amount') + @api.depends('benefits_count', 'donation_amount') def _get_total_donation_amount(self): for rec in self: - if rec.sponsorship_type == 'group': - rec.total_donation_amount = rec.benefits_count * rec.donation_amount - else : - rec.total_donation_amount = rec.donation_amount + if rec.sponsorship_type == 'group': + rec.total_donation_amount = rec.benefits_count * rec.donation_amount + else: + rec.total_donation_amount = rec.donation_amount def _get_already_sponsored_beneficiaries(self, rec): """ @@ -420,23 +441,24 @@ class DonationsDetailsLines(models.Model): """ # Search for all donation lines with active sponsorships all_lines = self.env['donations.details.lines'].sudo().search([('sponsorship_mechanism_id', '!=', False)]) - + # Filter for active/waiting/draft sponsorships active_lines = all_lines.filtered( lambda line: ((line.sponsorship_mechanism_id and line.sponsorship_mechanism_id.state == 'paid') - ) and line.state == 'active' + ) and line.state == 'active' ) - + # Exclude current record if editing existing line if rec.id: active_lines = active_lines.filtered(lambda line: line.id != rec.id) - + # Get all benefit_ids from these active lines (both single and group) sponsored_ids = active_lines.mapped('benefit_id') + active_lines.mapped('benefit_ids') - + return sponsored_ids # Remove duplicates - @api.depends('gender', 'education_status', 'education_level', 'sponsorship_type', 'benefit_type', 'age_category_id', 'benefit_family_code') + @api.depends('gender', 'education_status', 'education_level', 'sponsorship_type', 'benefit_type', 'age_category_id', + 'benefit_family_code') def _compute_domain_ids(self): for rec in self: # Create a domain @@ -457,7 +479,8 @@ class DonationsDetailsLines(models.Model): if rec.benefit_type == 'orphan' and rec.sponsorship_type: base_domain = \ [ - '|', ('state', '=', 'second_approve'), '&',('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended'), + '|', ('state', '=', 'second_approve'), '&', + ('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended'), ('member_status', '=', 'benefit'), '|', ('relationn.relation_type', '=', 'daughter'), @@ -467,11 +490,12 @@ class DonationsDetailsLines(models.Model): if rec.gender == 'female': base_domain = [ '|', ('state', '=', 'second_approve'), '&', - ('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended'), + ('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended'), ('member_status', '=', 'benefit'), ('relationn.relation_type', '=', 'daughter')] if rec.gender == 'male': base_domain = [ - '|', ('state', '=', 'second_approve'), '&',('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended'), + '|', ('state', '=', 'second_approve'), '&', + ('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended'), ('member_status', '=', 'benefit'), ('relationn.relation_type', '=', 'son')] if rec.education_status: base_domain.append(('education_status', '=', rec.education_status)) @@ -480,7 +504,7 @@ class DonationsDetailsLines(models.Model): if rec.age_category_id: base_domain.append(('age', '<=', rec.age_category_id.max_age)) base_domain.append(('age', '>=', rec.age_category_id.min_age)) - + # Exclude already sponsored beneficiaries if sponsored_benefit_ids: base_domain.append(('id', 'not in', sponsored_benefit_ids.ids)) @@ -489,7 +513,8 @@ class DonationsDetailsLines(models.Model): domain = {'benefit_id': [('id', 'in', rec.members_domain_ids.ids)]} return {'domain': domain} if rec.benefit_type == 'widow' and rec.sponsorship_type: - base_domain = ['|',('state','=','second_approve'),'&',('state','in',('waiting_approve','first_approve')),('action_type','=','suspended'), + base_domain = ['|', ('state', '=', 'second_approve'), '&', + ('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended'), ('member_status', '=', 'benefit'), '|', ('relationn.relation_type', '=', 'mother'), ('relationn.relation_type', '=', 'replacement_mother')] if rec.education_status: @@ -499,7 +524,7 @@ class DonationsDetailsLines(models.Model): if rec.age_category_id: base_domain.append(('age', '<=', rec.age_category_id.max_age)) base_domain.append(('age', '>=', rec.age_category_id.min_age)) - + # Exclude already sponsored beneficiaries if sponsored_benefit_ids: base_domain.append(('id', 'not in', sponsored_benefit_ids.ids)) @@ -508,7 +533,8 @@ class DonationsDetailsLines(models.Model): domain = {'benefit_id': [('id', 'in', rec.members_domain_ids.ids)]} return {'domain': domain} if rec.benefit_type == 'both' and rec.sponsorship_type: - base_domain = ['|',('state','=','second_approve'),'&',('state','in',('waiting_approve','first_approve')),('action_type','=','suspended'), + base_domain = ['|', ('state', '=', 'second_approve'), '&', + ('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended'), ('member_status', '=', 'benefit')] if rec.education_status: base_domain.append(('education_status', '=', rec.education_status)) @@ -517,16 +543,159 @@ class DonationsDetailsLines(models.Model): if rec.age_category_id: base_domain.append(('age', '<=', rec.age_category_id.max_age)) base_domain.append(('age', '>=', rec.age_category_id.min_age)) - + # Exclude already sponsored beneficiaries if sponsored_benefit_ids: base_domain.append(('id', 'not in', sponsored_benefit_ids.ids)) - + rec.members_domain_ids = self.env['family.member'].sudo().search(base_domain) domain = {'benefit_id': [('id', 'in', rec.members_domain_ids.ids)]} # return {'domain': domain} - @api.onchange('product_template_id','donation_types','donation_type','sponsorship_duration') + @api.depends("sponsorship_id", + "sponsorship_mechanism_id", + "sponsorship_id.record_type", + "sponsorship_mechanism_id.record_type", + "sponsorship_duration", + "payment_method_id", + "payment_method_id.payment_method", + "payment_month_count", + "gender", + "education_status", + "education_level", + "benefit_id_number", + "benefit_family_code", + ) + def _compute_benefit_members_text_domain(self): + for rec in self: + domain = [] + benefit_age_limit = 18 + + # Extract values safely + sponsorship = rec.sponsorship_id | rec.sponsorship_mechanism_id + record_type = sponsorship.record_type if rec.record_type else None + duration = rec.sponsorship_duration + payment_method = rec.payment_method_id.payment_method if rec.payment_method_id else None + month_count = rec.payment_month_count or 0 + + # Sponsorship logic + if record_type == "donation": + domain.append(('sponsor_related_id', '=', False)) + elif record_type == "sponsorship": + if duration == "permanent": + domain.append(('sponsor_related_id', '=', False)) + elif duration == "temporary": + domain.append(('sponsor_related_id', '=', False)) + if payment_method == "direct_debit": + benefit_age_limit = 16 + # if month_count >= 6: + # domain.append(('sponsor_related_id', '=', False)) + if month_count < 6: + domain.append(('age', '>=', benefit_age_limit)) + + # Optional filters — only added if value exists + if rec.gender: + domain.append(('gender', '=', rec.gender)) + if rec.education_status: + domain.append(('education_status', '=', rec.education_status)) + if rec.education_level: + domain.append(('education_levels', '=', rec.education_level.id)) + if rec.benefit_id_number: + domain.append(('member_id_number', '=', rec.benefit_id_number)) + if rec.benefit_family_code: + domain.append(('benefit_id.code', '=', rec.benefit_family_code)) + + # Store domain as string (or use it in a search if needed) + # rec.benefit_members_text_domain = json.dumps(domain) + + members_domain_ids = self.env['family.member'].sudo().search(domain) + rec.members_domain_ids = members_domain_ids if members_domain_ids else self.env['family.member'].sudo().browse() + domain = {'benefit_id': [('id', 'in', rec.members_domain_ids.ids)]} + return {'domain': domain} + + @api.onchange('members_domain_ids') + def _onchange_members_domain_ids(self): + print(self.members_domain_ids) + if self.members_domain_ids: + return { + 'domain': { + 'benefit_id': [('id', 'in', self.members_domain_ids.ids)] + } + } + else: + return { + 'domain': { + 'benefit_id': [('id', '=', 0)] + } + } + + # @api.onchange("sponsorship_id", + # "sponsorship_mechanism_id", + # "sponsorship_id.record_type", + # "sponsorship_mechanism_id.record_type", + # "sponsorship_duration", + # "payment_method_id", + # "payment_method_id.payment_method", + # "payment_month_count", + # "gender", + # "education_status", + # "education_level", + # "benefit_id_number", + # "benefit_family_code", + # ) + # def _onchange_benefit_members_text_domain(self): + # for rec in self: + # domain = [] + # benefit_age_limit = 18 + # + # # Extract values safely + # sponsorship = rec.sponsorship_id | rec.sponsorship_mechanism_id + # record_type = sponsorship.record_type if rec.record_type else None + # duration = rec.sponsorship_duration + # payment_method = rec.payment_method_id.payment_method if rec.payment_method_id else None + # month_count = rec.payment_month_count or 0 + # + # # Sponsorship logic + # if record_type == "donation": + # domain.append(('sponsor_related_id', '=', False)) + # elif record_type == "sponsorship": + # if duration == "permanent": + # domain.append(('sponsor_related_id', '=', False)) + # elif duration == "temporary": + # domain.append(('sponsor_related_id', '=', False)) + # if payment_method == "direct_debit": + # benefit_age_limit = 16 + # # if month_count >= 6: + # # domain.append(('sponsor_related_id', '=', False)) + # if month_count < 6: + # domain.append(('age', '>=', benefit_age_limit)) + # + # # Optional filters — only added if value exists + # if rec.gender: + # domain.append(('gender', '=', rec.gender)) + # if rec.education_status: + # domain.append(('education_status', '=', rec.education_status)) + # if rec.education_level: + # domain.append(('education_levels', '=', rec.education_level.id)) + # if rec.benefit_id_number: + # domain.append(('member_id_number', '=', rec.benefit_id_number)) + # if rec.benefit_family_code: + # domain.append(('benefit_id.code', '=', rec.benefit_family_code)) + # + # # Store domain as string (or use it in a search if needed) + # # rec.benefit_members_text_domain = json.dumps(domain) + # + # members_domain_ids = self.env['family.member'].sudo().search(domain) + # if members_domain_ids: + # return {'domain': { + # 'benefit_id': [('id', 'in', members_domain_ids.ids)], + # }} + # else: + # return {'domain': { + # 'benefit_id': [('id', 'in', [0])], + # }} + + @api.onchange('product_template_id', 'donation_types', 'donation_type', 'sponsorship_duration') def onchange_product_template_id(self): for rec in self: # Process both donation details and mechanism details @@ -535,11 +704,14 @@ class DonationsDetailsLines(models.Model): selected_donations = [] if rec.sponsorship_id or rec.sponsorship_mechanism_id: all_donation_lines = ( - (rec.sponsorship_id.donations_details_lines if rec.sponsorship_id else self.env['donations.details.lines']) | - (rec.sponsorship_mechanism_id.donations_details_lines_mechanism_ids if rec.sponsorship_mechanism_id else self.env['donations.details.lines']) + (rec.sponsorship_id.donations_details_lines if rec.sponsorship_id else self.env[ + 'donations.details.lines']) | + ( + rec.sponsorship_mechanism_id.donations_details_lines_mechanism_ids if rec.sponsorship_mechanism_id else + self.env['donations.details.lines']) ) selected_donations = all_donation_lines.mapped('product_template_id.id') - domain = [('id', 'not in', selected_donations),('sale_ok', '=', True)] + domain = [('id', 'not in', selected_donations), ('sale_ok', '=', True)] # Apply condition based on record type record_type = rec.sponsorship_id.record_type if rec.sponsorship_id else rec.sponsorship_mechanism_id.record_type @@ -560,7 +732,7 @@ class DonationsDetailsLines(models.Model): for rec in self: if rec.donation_type == 'sponsorship': rec.donation_mechanism = 'with_conditions' - + def compute_sponsorships_lines(self): for rec in self: @@ -601,7 +773,7 @@ class DonationsDetailsLines(models.Model): 'amount': amount, 'scheduled_date': scheduled_date }) - + rec.sponsorships_computed = True def action_delegate_to_catalog(self): @@ -616,9 +788,9 @@ class DonationsDetailsLines(models.Model): cart_object = self.env["donations.details.lines"] product_object = self.env["product.template"] cart_products_details = cart_object.search( - [('sponsorship_id', "=", self.sponsorship_id.id)]) # , ("cart_flag", "=", True) + [('sponsorship_id', "=", self.sponsorship_id.id)]) # , ("cart_flag", "=", True) product_object_data = product_object.search( - [("_quantity", "!=", 0)]) + [("_quantity", "!=", 0)]) assign_quantity = 0 for rec in product_object_data: rec._quantity = 0 @@ -644,7 +816,7 @@ class DonationsDetailsLines(models.Model): 'res_model': 'product.template', 'views': [(kanban_view.id, 'kanban')], 'domain': [('id', 'not in', all_donation_lines.mapped('product_template_id').ids), - ('donation_category', '=', 'donation')], + ('donation_category', '=', 'donation')], 'context': { # '_quantity_change': True, 'sponsorship_id': self.id, @@ -655,7 +827,6 @@ class DonationsDetailsLines(models.Model):

""") } - @api.model # @api.model_create_multi def create(self, vals): @@ -679,7 +850,6 @@ class DonationsDetailsLines(models.Model): ) return record - def write(self, vals): res = False for rec in self: @@ -701,7 +871,7 @@ class DonationsDetailsLines(models.Model): message = _("Benefit changed from %s to %s in a donation item.") % ( old_benefit or 'None', new_benefit) sponsorship.message_post(body=message) - + # Auto-trigger state change when benefit is assigned to waiting line if 'benefit_ids' in vals: @@ -732,7 +902,7 @@ class DonationsDetailsLines(models.Model): self.ensure_one() wizard = self.env['replacement.wiz'].create({ - 'replacement_line_ids':[(0, 0, { + 'replacement_line_ids': [(0, 0, { 'sponsorship_type': self.sponsorship_type, 'from_benefit_id': self.benefit_id.id if self.sponsorship_type == 'person' else False, 'from_benefit_ids': [(6, 0, self.benefit_ids.ids)] if self.sponsorship_type == 'group' else False @@ -750,7 +920,7 @@ class DonationsDetailsLines(models.Model): def action_view_scheduling_lines(self): self.ensure_one() - + return { 'name': 'Sponsorship Scheduling Lines', 'type': 'ir.actions.act_window', @@ -795,7 +965,7 @@ class DonationsDetailsLines(models.Model): def unlink(self): self.product_template_id._quantity = 0 return super().unlink() - + @api.model def cron_send_direct_debit_end_date_reminders(self): """ @@ -806,39 +976,39 @@ class DonationsDetailsLines(models.Model): reminder_sms_template = company.reminder_sms_template_id ended_sms_template = company.ended_sms_template_id bot = self.env.ref('base.partner_root').id - + if not reminder_sms_template: _logger.warning("No SMS reminder template configured in settings.") return - + today = date.today() reminder_days = [30, 15, 3] - + for days in reminder_days: target_date = today + relativedelta(days=days) - + donation_lines = self.search([ ('state', '=', 'active'), ('payment_method_id.payment_method', '=', 'direct_debit'), ('end_date', '=', target_date), ]) - + for line in donation_lines: sponsor = line.sponsor_id - + if not sponsor or not sponsor.mobile: _logger.warning( "No sponsor or mobile number found for donation line ID %s", line.id ) continue - + try: line._message_sms_with_template( - template=reminder_sms_template, - put_in_queue=True, - partner_ids=sponsor.partner_id.ids, - author_id=bot + template=reminder_sms_template, + put_in_queue=True, + partner_ids=sponsor.partner_id.ids, + author_id=bot ) _logger.info( "SMS reminder sent to sponsor %s for donation line %s (end date: %s, days remaining: %s)", @@ -854,7 +1024,7 @@ class DonationsDetailsLines(models.Model): line.sequence_no, str(e) ) - + ended_lines = self.search([('end_date', '!=', False), ('end_date', '<', today)]) ended_lines.write({ 'state': 'closed' @@ -876,7 +1046,7 @@ class DonationsDetailsLines(models.Model): Open wizard to extend donation detail line """ self.ensure_one() - + return { 'type': 'ir.actions.act_window', 'name': _('Extend Donation'), @@ -889,13 +1059,13 @@ class DonationsDetailsLines(models.Model): 'default_amount': self.product_template_id.list_price, }, } - + def action_view_extension_history(self): """ View extension history for this donation detail line """ self.ensure_one() - + return { 'type': 'ir.actions.act_window', 'name': _('Extension History'), diff --git a/odex25_ensan/odex_takaful/models/takaful_payment_method.py b/odex25_ensan/odex_takaful/models/takaful_payment_method.py index 69f8a4a9d..9b5cc9fa7 100644 --- a/odex25_ensan/odex_takaful/models/takaful_payment_method.py +++ b/odex25_ensan/odex_takaful/models/takaful_payment_method.py @@ -7,6 +7,20 @@ class TakafulPaymentMethod(models.Model): _name = 'takaful.payment.method' name = fields.Char(required=True) + payment_method = fields.Selection(selection=[("cash", "Cash"),("card", "Card"),("check", "Check"),("credit_card", "Credit Card"),("bank_transfer", "Bank Transfer"),("direct_debit", "Direct Debit")]) journal_id = fields.Many2one('account.journal', string="Journal") bank_id = fields.Many2one('res.partner.bank', string="Sponsor Bank Number") + points_of_sale = fields.Many2one('points.of.sale.custom', string="Point OF sale") + check_number = fields.Char(string='Check Number') + bank_journal_id = fields.Many2one( + 'account.journal', + string="Sponsor Bank Journal", + readonly=False, + domain="[('type', '=', 'bank')]" + ) + charity_bank_id = fields.Many2one('account.journal', string="charity Bank") + sponsor_account_number = fields.Char(string='Sponsor Account Number') + direct_debit_start_date = fields.Date(string='Direct Debit Start Date') + direct_debit_end_date = fields.Date(string='Direct Debit End Date') + sa_iban = fields.Char('SA', default='SA', readonly=True) diff --git a/odex25_ensan/odex_takaful/models/takaful_sponorship_model.py b/odex25_ensan/odex_takaful/models/takaful_sponorship_model.py index b441f7693..8d4094d6a 100644 --- a/odex25_ensan/odex_takaful/models/takaful_sponorship_model.py +++ b/odex25_ensan/odex_takaful/models/takaful_sponorship_model.py @@ -50,6 +50,7 @@ class TakafulSponsorship(models.Model): _order = 'id desc' sponsor_id = fields.Many2one('takaful.sponsor',string='Sponsor Name',domain="[('id', 'in', allowed_sponsor_ids)]") + preferred_communication = fields.Many2one('preferred.communication', string="Preferred Communication", related="sponsor_id.preferred_communication") allowed_sponsor_ids = fields.Many2many('takaful.sponsor', compute='_compute_allowed_sponsor_ids') member_id = fields.Many2one('res.partner',string='Member Name',domain="[('is_member', '=', True)]") is_gift = fields.Selection([('no', 'No'),('yes', 'Yes')],string='Is Gift To Person') @@ -67,7 +68,8 @@ class TakafulSponsorship(models.Model): branch_custom_id = fields.Many2one('branch.settings', string="Branch", default=lambda self: self._default_branch_custom_id(), required=True, tracking=True) sponsorship_creation_date = fields.Datetime(string="Sponsorship Creation Date", default=fields.Datetime.now, required=True, copy=False) sponsor_note = fields.Text(string='Sponsor Note') - sponsor_or_donor_type = fields.Selection(string='Sponsor / Donor Type',selection=[('registered', 'Registered'), ('new_sponsor', 'New Sponsor'),('not_registered', 'Not Registered'),('unknown', 'Unknown')], required=True) + sponsor_or_donor_type = fields.Selection(string='Sponsor / Donor Type',selection=[('registered', 'Registered'), ('not_registered', 'Not Registered'), ('new_sponsor', 'New Sponsor'), ('unknown', 'Unknown')], required=True) + # ('not_registered', 'Not Registered'), sponsor_donor_type = fields.Selection(string='Sponsor / Donor Type',selection=[('registered', 'Registered'), ('new_sponsor', 'New Sponsor')]) sponsor_name = fields.Char(string="Sponsor Name") sponsor_phone = fields.Char(string="Sponsor Phone", compute='_compute_sponsor_phone', store=True, readonly=False) @@ -1974,18 +1976,16 @@ class SponsorshipSchedulingLine(models.Model): scheduled_lines = self.search([ ('scheduled_date', '<=', today), ('status', '=', 'unpaid'), + ('sponsorship_state', 'in', ['confirmed', 'wait_pay']) ]) _logger.info(f"Found {len(scheduled_lines)} scheduling lines scheduled for {today}") for line in scheduled_lines: - donation_line = line.donation_detail_linked_id - sponsorship = donation_line.sponsorship_id or donation_line.sponsorship_mechanism_id - try: if line.payment_method == 'direct_debit': invoice_id = self.env['account.move'].sudo().search([ - ('takaful_sponsorship_id', '=', sponsorship.id), + ('takaful_sponsorship_id', '=', line.sponsorship_id.id), ('move_type', '=', 'out_invoice'), ('state', '=', 'posted'), ('payment_state', 'in', ['not_paid', 'partial']) @@ -2021,7 +2021,7 @@ class SponsorshipSchedulingLine(models.Model): ).create(payment_register_vals) payment_register.action_create_payments() - line.status = 'paid' + _logger.info(f"Successfully processed scheduled payment for line {line.sequence_no}") else: _logger.warning(f"Scheduling line {line.sequence_no} payment method is not direct debit, skipping auto-payment") diff --git a/odex25_ensan/odex_takaful/views/takaful_payment_method.xml b/odex25_ensan/odex_takaful/views/takaful_payment_method.xml index e41cc0f94..dff6184f0 100644 --- a/odex25_ensan/odex_takaful/views/takaful_payment_method.xml +++ b/odex25_ensan/odex_takaful/views/takaful_payment_method.xml @@ -9,9 +9,30 @@ + + + + - + + diff --git a/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml b/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml index fe87dabda..21264efbe 100644 --- a/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml +++ b/odex25_ensan/odex_takaful/views/takaful_sponorship_view.xml @@ -113,8 +113,13 @@ 'required':[('sponsor_or_donor_type','=','registered')], 'readonly':[('state','!=','draft')]}" force_save="1" options="{'no_create': True, 'no_create_edit': True}"/> + + + + attrs="{'invisible': [('sponsor_or_donor_type','=', False)], 'readonly': [('record_type', '!=', 'donation'), ('sponsor_or_donor_type', '!=', 'registered')]}"/> @@ -207,6 +212,7 @@ @@ -269,6 +275,7 @@ attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')]}"/> + 'invisible': [('company_type', '!=', 'person')]}" />