sponsorship_multi_editings

This commit is contained in:
MahmoudSalahEXP 2025-10-20 20:51:24 +03:00
parent 31411d7f78
commit f45aca23db
13 changed files with 379 additions and 134 deletions

View File

@ -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 "تاريخ إنتهاء الكفالة"

View File

@ -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')

View File

@ -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:

View File

@ -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?')

View File

@ -158,6 +158,7 @@
<group>
<field name="sponsor_related_id"
readonly="1"/>
<field name="sponsorship_end_date" readonly="1"/>
<field name="sponsor_id"
attrs="{'readonly':[('state','not in',['draft','complete_info'])]}"
invisible="1"/>

View File

@ -170,7 +170,9 @@
<field name="date"
attrs="{'readonly':[('state','not in',['draft','researcher','waiting_approve'])]}"
required="1"/>
<field name="benefit_type" readonly="1" force_save="1"/>
<field name="benefit_type"
attrs="{'readonly':[('state','not in',['draft','researcher','waiting_approve'])]}"
required="1"/>
<field name="family_id"
attrs="{'readonly':[('state','not in',['draft','researcher','waiting_approve'])]}"
required="1"/>

View File

@ -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'

View File

@ -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):
</p>""")
}
@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 <b>%s</b> to <b>%s</b> 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'),

View File

@ -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)

View File

@ -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")

View File

@ -9,9 +9,30 @@
<group>
<field name="name"/>
<field name="payment_method"/>
<field name="direct_debit_start_date"
attrs="{'invisible': [('payment_method','!=','direct_debit')]}"/>
<field name="direct_debit_end_date"
attrs="{'invisible': [('payment_method','!=','direct_debit')]}"/>
<field name="check_number" attrs="{'invisible': [('payment_method','!=','check')]}"/>
<field name="bank_id"
attrs="{'invisible': ['|',('payment_method','=','cash'),('payment_method','=',False)]}"/>
<field name="journal_id"/>
<field name="charity_bank_id"
attrs="{'invisible': [('payment_method','!=','bank_transfer'),('payment_method','!=','direct_debit')]}"/>
<label for="sponsor_account_number"
attrs="{'invisible': [('payment_method','!=','bank_transfer'),('payment_method','!=','direct_debit')]}"/>
<div class="o_row"
attrs="{'invisible': [('payment_method','!=','bank_transfer'),('payment_method','!=','direct_debit')]}">
<field name="sponsor_account_number" width="100%"/>
<field name="sa_iban"/>
</div>
<field name="journal_id"
attrs="{'invisible': [('payment_method','!=','cash'),('payment_method','!=','check')]}"/>
<field name="points_of_sale"
attrs="{'invisible': [('payment_method','!=','card'),('payment_method','!=','credit_card')]}"/>
</group>
</sheet>
</form>

View File

@ -113,8 +113,13 @@
'required':[('sponsor_or_donor_type','=','registered')],
'readonly':[('state','!=','draft')]}"
force_save="1" options="{'no_create': True, 'no_create_edit': True}"/>
<field name="preferred_communication"
attrs="{'invisible': [('sponsor_id','=',False), ('sponsor_or_donor_type','!=','registered')]}"
force_save="1" options="{'no_create': True, 'no_create_edit': True}"/>
<!-- <field name="sponsor_phone"-->
<!-- attrs="{'invisible': [('sponsor_or_donor_type','=', False)], 'readonly': [('sponsor_id', '!=', False)]}"/>-->
<field name="sponsor_phone"
attrs="{'invisible': [('sponsor_or_donor_type','=', False)], 'readonly': [('sponsor_id', '!=', False)]}"/>
attrs="{'invisible': [('sponsor_or_donor_type','=', False)], 'readonly': [('record_type', '!=', 'donation'), ('sponsor_or_donor_type', '!=', 'registered')]}"/>
<field name="is_widow_orphan" invisible="1"/>
<field name="cancel_refund" invisible="1"/>
<field name="donate_for_another_person" widget="boolean_toggle"/>
@ -207,6 +212,7 @@
<field name="sponsorship_type"
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')]}"/>
<field name="benefit_id"
domain="[('id', 'in', members_domain_ids)]"
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')]}"/>
<field name="payment_month_count"
attrs="{'invisible': [('payment_method', '!=', 'direct_debit')]}"/>
@ -269,6 +275,7 @@
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')]}"/>
<field name="members_domain_ids" invisible="1"/>
<field name="benefit_id"
domain="[('id', 'in', members_domain_ids)]"
attrs="{'column_invisible': [('parent.donation_mechanism','!=','with_conditions'),('parent.record_type','!=','sponsorship')]}"/>
<field name="sponsorship_duration" invisible="1"/>
<field name="payment_option"
@ -400,6 +407,7 @@
<!-- attrs="{'invisible': ['|', ('sponsorship_type','!=','person'), ('donation_mechanism','!=','with_conditions')], 'required': [('donation_mechanism','=','with_conditions'), '|', '|', '|', ('members_domain_ids', '!=', []), ('sponsorship_type','=','person'), ('hide_beneficiary_group','=', False), ('state', 'in', ['active', 'closed', 'extended'])]}"-->
<!-- options="{'no_create': True, 'no_create_edit':True, 'no_open': True}"/>-->
<field name="benefit_id"
domain="[('id', 'in', members_domain_ids)]"
attrs="{'invisible': ['|', ('sponsorship_type','!=','person'), ('donation_mechanism','!=','with_conditions')], 'required': [('donation_mechanism','=','with_conditions'), ('parent.record_type','=','donation')]}"
options="{'no_create': True, 'no_create_edit':True, 'no_open': True}"/>
<field name="family_id"

View File

@ -108,8 +108,7 @@
<field name="mobile" required="1"/>
<field name="id_number" attrs="{
'invisible': [('company_type', '!=', 'person')],
'required': [('company_type', '=', 'person')]}" />
'invisible': [('company_type', '!=', 'person')]}" />
<field name="gender" attrs="{'invisible': [('company_type', '!=', 'person')]}"/>
<field name="street" attrs="{'invisible': [('company_type', '=', 'person')]}"/>