odex25_standard/odex25_ensan/odex_benefit/models/family_members.py

897 lines
50 KiB
Python

# -*- coding: utf-8 -*-
import logging
from datetime import datetime, date
from dateutil.relativedelta import relativedelta as rd
from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
import qrcode
import base64
from io import BytesIO
SAUDI_MOBILE_PATTERN = "(^(05|5)(5|0|3|6|4|9|1|8|7)([0-9]{7})$)"
ALPHABETIC_PATTERN = "^[\u0600-\u065F\u066A-\u06EF\u06FA-\u06FFA-Za-z ]+$"
import re
_logger = logging.getLogger(__name__)
class FamilyMemberProfile(models.Model):
_name = 'family.member'
_description = "Member - Profiles"
_inherit = ['mail.thread', 'mail.activity.mixin']
# _inherits = {'res.partner': 'partner_id'}
_order = 'age desc'
def _default_benefit(self):
return self._context.get('active_id')
member_first_name = fields.Char(string="Member First Name")
member_second_name = fields.Char(string="Member Second Name",related="benefit_id.father_name")
member_third_name = fields.Char(string="Member Third Name",related="benefit_id.father_second_name")
member_family_name = fields.Char(string="Member Family Name",related="benefit_id.father_family_name")
mother_first_name = fields.Char(string="Mother First Name")
mother_second_name = fields.Char(string="Mother Second Name")
mother_third_name = fields.Char(string="Mother Third Name")
mother_family_name = fields.Char(string="MotherFamily Name")
name = fields.Char(string="Name", compute='get_partner_name', store=True,readonly = False)
member_id_number = fields.Char(string="Member Id Number")
benefit_id = fields.Many2one("grant.benefit",string="Responsable",default=_default_benefit)
gender = fields.Selection(selection=[('male', 'Male'), ('female', 'Female')], string="Gender")
member_phone = fields.Char(string="Member Phone")
member_location = fields.Selection(selection=[('with_family', 'With Family'), ('with_relative', 'with a relative'),
('study_inside_saudi_arabia', 'Study Inside Saudi Arabia'),('study_outside_saudi_arabia', 'Study Outside Saudi Arabia'),
('rehabilitation_center_for_the_disabled', 'Rehabilitation center for the disabled'),('house_of_social_observations', 'House of Social Observations'),
('girls_home','Girls Home'),('university_housing','University Housing'),('with_husband','With_husband'),('work_inside_saudi_arabia','Work Inside Saudi Arabia')], string="Member Location")
member_location_conf = fields.Many2one('location.settings',string='Member Location',domain="[('location_type','=','member')]")
# member_location = fields.Many2one('member.location', string="Member Location")
birth_date = fields.Date(string="Birth Date")
age = fields.Integer(string="Age", compute='_compute_get_age_date',store=True)
age_status = fields.Selection(
[('minor', 'Minor'), ('non_minor', 'Non-Minor')],
string='Age Status',
default='non_minor', compute='_compute_get_age_status',store=True
)
is_work = fields.Boolean('Is Work?')
salary_certificate = fields.Many2many('ir.attachment','member_salary_cert_rel','member_id','attachment_id',string="Salary Certificate")
is_dead = fields.Boolean('Is Dead?')
death_certificate = fields.Many2many('ir.attachment','member_death_cert_rel','member_id','attachment_id',string="Death Certificate")
member_income = fields.Float('Member Income')
is_married = fields.Boolean('Is Married?')
marriage_certificate = fields.Many2many('ir.attachment','member_marriage_cert_rel','member_id','attachment_id',string="Marriage Certificate")
relationn = fields.Many2one('relation.settings',domain="['|',('relation_type','=','son'),('relation_type','=','daughter')]",string="Relation")
relation = fields.Selection(
[('son', _('Son')), ('daughter', _('Daughter'))])
mother_marital = fields.Selection(
[('married', _('Married')), ('widower', _('Widower')), ('divorced', _('Divorced')),
('divorced_from_another_man', _('Divorced From Another Man')), ('prisoner', _('Prisoner')), ('dead', _('Dead')), ('hanging', _('Hanging'))],
_('Marital Status'))
mother_marital_conf = fields.Many2one('marital.status',string='Mother Marital')
mother_location = fields.Selection(
[('with_husband_and_children', _('With Husband And Children')), ('with_children', _('With Children')),
('not_live_with_children', _('Not live with children'))], string='Mother Location')
mother_location_conf = fields.Many2one('location.settings',string='Mother Location',domain="[('location_type','=','mother_location')]")
attachment_ids = fields.One2many("ir.attachment",'member_id',domain=[('hobbies_id', '=', False),('diseases_id', '=', False),('disabilities_id', '=', False)])
hobbies_attachment_ids = fields.One2many('ir.attachment', 'member_id', string='Hobbies Attachments',domain=[('hobbies_id', '!=', False)])
diseases_attachment_ids = fields.One2many('ir.attachment', 'member_id', string='Diseases Attachments',domain=[('diseases_id', '!=', False)])
disabilities_attachment_ids = fields.One2many('ir.attachment','member_id', string='Disabilities Attachments',domain=[('disabilities_id', '!=', False)])
hobbies_ids = fields.One2many("member.hobbies",'member_id')
diseases_ids = fields.One2many("member.diseases",'member_id')
disabilities_ids = fields.One2many("member.disabilities",'member_id')
is_scientific_specialty = fields.Boolean('Is Scientific Specialty?',related="specialization_ids.is_scientific_specialty")
is_medical_specialty = fields.Boolean('Is Medical Specialty?',related="specialization_ids.is_medical_specialty")
minor_siblings = fields.Boolean('minor siblings?',compute="_compute_minor_siblings",store=True)
# Education_data
member_education_status_ids = fields.One2many('education.status', 'family_member_id')
education_status = fields.Selection(
string='Education Status',
selection=[('educated', 'educated'), ('illiterate', 'illiterate'),('under_study_age', 'Under Study Age')],
default='under_study_age',
)
case_study = fields.Selection(string='Case Study',
selection=[('continuous', 'continuous'), ('intermittent', 'intermittent'),
('graduate', 'Graduate')])
illiterate_reason = fields.Char(string='Illiterate Reason')
intermittent_reason = fields.Many2one('education.illiterate.reason',string='Intermittent Reason')
educational_certificate = fields.Binary(attachment=True,string='Educational Certificate')
education_entity = fields.Selection(string='Education Entity', selection=[('governmental', 'Governmental'),
('special', 'Special')])
last_education_entity = fields.Selection(string='Last Education Entity',
selection=[('governmental', 'Governmental'),
('special', 'Special')])
entities = fields.Many2one("education.entities", string='Entity')
last_entities = fields.Many2one("education.entities", string='Last Entity')
education_levels = fields.Many2one("education.level", string='Education Levels')
last_education_levels = fields.Many2one("education.level", string='Last Education Levels')
nearest_literacy_school = fields.Char(string='The Nearest Literacy School', required=False)
literacy_school_note = fields.Text(string="Literacy School Note", required=False)
classroom = fields.Many2one('education.classroom', string='Classroom')
last_classroom = fields.Many2one('education.classroom', string='Last Classroom')
last_educational_certificate = fields.Binary(attachment=True,string='Last Educational Certificate')
degree = fields.Many2one('education.result', string='Degree')
last_degree = fields.Many2one('education.result', string='Last Degree')
percentage = fields.Float(string="Percentage%")
last_percentage = fields.Float(string="Last Percentage%")
education_start_date = fields.Date(string='Education Start Date')
education_end_date = fields.Date(string='Education End Date')
end_date = fields.Date('End Date')
specialization_ids = fields.Many2one('specialization.specialization', string='specialization')
last_specialization_ids = fields.Many2one('specialization.specialization', string='Last Specialization')
last_education_start_date = fields.Date(string='Last Education Start Date')
last_education_end_date = fields.Date(string='Last Education End Date')
weak_study = fields.Many2many('study.material', string='Weak Study')
is_want_education = fields.Boolean(string='is Want Education', required=False)
is_quran_memorize = fields.Boolean('memorize the quran ?')
partner_id = fields.Many2one('res.partner')
# Replacement Mother
add_replacement_mother = fields.Boolean('Add Replacement Mother?')
# replacement_mother_name = fields.Char(string="Replacement Mother Name", tracking=True)
# replacement_mother_second_name = fields.Char(string="Replacement Mother Second Name", tracking=True)
# replacement_mother_third_name = fields.Char(string="Replacement Mother Third Name", tracking=True)
# replacement_mother_family_name = fields.Char(string="Replacement Mother Family Name", tracking=True)
# replacement_mother_country_id = fields.Many2one('res.country', 'Replacement Mother Nationality', tracking=True)
# replacement_mother_id_number = fields.Char(string="Replacement Mother Id Number", tracking=True)
# replacement_mother_marital_conf = fields.Many2one('marital.status', string='Replacement Mother Marital')
# replacement_mother_location = fields.Selection(
# [('with_husband_and_children', _('With Husband And Children')), ('with_children', _('With Children')),
# ('not_live_with_children', _('Not live with children'))], string='Replacement Mother Location')
# replacement_is_mother_work = fields.Boolean('Is Replacement Mother Work?')
# replacement_mother_income = fields.Float("Replacement Mother Income")
# replacement_mother_birth_date = fields.Date(string="Replacement Mother Birth Date")
# replacement_mother_age = fields.Integer(string="Replacement Mother Age",
# compute='_compute_get_replacement_mother_age')
# replacement_mother_city_id = fields.Many2one('res.country.city', string='City')
# replacement_mother_dead_reason = fields.Char(string='Dead Reason', required=False)
# replacement_mother_dead_date = fields.Date(string="Certificate Date")
# replacement_mother_dead_city_id = fields.Many2one('res.country.city', string='Dead City')
# replacement_mother_status = fields.Selection(selection=[
# ('benefit', 'Benefit'),
# ('non_benefit', 'Non Benefit'),
# ], string='Replacement Mother Status', compute="check_replacement_mother_status", store=True, default=False)
# # Education_data for replacement mother
# replacement_education_status = fields.Selection(string='Education Status',
# selection=[('educated', 'educated'), ('illiterate', 'illiterate')])
# replacement_case_study = fields.Selection(string='Mother Case Study',
# selection=[('continuous', 'continuous'), ('intermittent', 'intermittent'),
# ('graduate', 'Graduate')])
# replacement_illiterate_reason = fields.Char(string='Illiterate Reason')
# replacement_intermittent_reason = fields.Many2one('education.illiterate.reason',
# string='Intermittent Reason')
# replacement_education_entity = fields.Selection(string='Education Entity',
# selection=[('governmental', 'Governmental'),
# ('special', 'Special')])
# replacement_entities = fields.Many2one("education.entities", string='Entity')
# replacement_specialization_ids = fields.Many2one('specialization.specialization', string='specialization')
# replacement_classroom = fields.Many2one('education.classroom', string='Classroom')
# replacement_degree = fields.Many2one('education.result', string='Degree')
# replacement_percentage = fields.Float(string="Percentage%")
# replacement_education_start_date = fields.Date(string='Education Start Date')
# replacement_education_end_date = fields.Date(string='Education End Date')
#
# replacement_last_education_entity = fields.Selection(string='Last Education Entity',
# selection=[('governmental', 'Governmental'),
# ('special', 'Special')])
# replacement_last_entities = fields.Many2one("education.entities", string='Last Entity')
# replacement_education_levels = fields.Many2one("education.level", string='Education Levels')
# replacement_last_education_levels = fields.Many2one("education.level", string='Last Education Levels')
# replacement_last_specialization_ids = fields.Many2one('specialization.specialization', string='Last Specialization')
#
# replacement_last_classroom = fields.Many2one('education.classroom', string='Last Classroom')
# replacement_last_degree = fields.Many2one('education.result', string='Last Degree')
# replacement_last_percentage = fields.Float(string="Last Percentage%")
# replacement_last_education_start_date = fields.Date(string='Last Education Start Date')
# replacement_last_education_end_date = fields.Date(string='Last Education End Date')
# replacement_last_educational_certificate = fields.Binary(attachment=True, string='Last Educational Certificate')
# replacement_weak_study = fields.Many2many('study.material', string='Weak Study')
state = fields.Selection([
('draft', 'Draft'),
('new', 'Researcher Assignment'),
('complete_info', 'Waiting for Researcher'),
('waiting_approve', 'Waiting for Operation Manager'),
('first_approve', 'Waiting for Branch Manager'),
('first_refusal', 'First Refusal'),
('second_approve', 'Second Approved'),
('refused', 'Refused'),
('suspended_second_approve', 'Suspended Second Approved'),
('exception_second_approve', 'Waiting for General Manager'),
('black_list', 'Black List'),
], string='state', tracking=True,compute='_get_state',store = True)
state_a = fields.Selection([
('draft', 'Draft'),
('new', 'Researcher Assignment'),
('complete_info', 'Waiting for Researcher'),
('waiting_approve', 'Waiting for Operation Manager'),
('first_approve', 'Waiting for Branch Manager'),
('first_refusal', 'First Refusal'),
('second_approve', 'Second Approved'),
('refused', 'Refused'),
('suspended_second_approve', 'Suspended Second Approved'),
('exception_second_approve', 'Waiting for General Manager'),
('black_list', 'Black List'),
], string='stateA', default="draft", tracking=True)
action_type = fields.Selection(selection=[
('new', 'New'),
('edit_info', 'Edit Information'),
('approved', 'Approved'),
('suspended', 'Suspended'),
('exception', 'Exception'),
], string='Action Type', default='new', tracking=True)
member_status = fields.Selection(selection=[
('benefit', 'Benefit'),
('non_benefit', 'Non Benefit'),
], string='Benefit Status', compute="check_member_status",default = False,store=True)
suspend_reason = fields.Many2one('suspend.reason', string='Suspend Reason')
reason = fields.Text(string='Reason')
suspend_description = fields.Text(string='Suspend Description')
suspend_attachment = fields.Binary(string='Suspend Attachment', attachment=True)
suspend_type = fields.Selection(
selection=[('temporarily_suspend', 'Temporarily Suspended'), ('suspend', 'Suspend')], string="Suspend Type")
suspend_method = fields.Selection(selection=[('manual', 'Manual'), ('auto', 'Auto')], string="Suspend Method",default='auto')
is_member_workflow = fields.Boolean('Is Member Workflow?')
# sponsor_id = fields.Many2one('res.partner', string='Sponsor Partner',domain="[('account_type','=','sponsor')]")
sponsor_id = fields.Many2one('res.partner', string='Sponsor Partner',domain="[('is_sponsor_portal', '=', True)]")
sponsor_related_id = fields.Many2one('takaful.sponsor', string='Sponsor')
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')
# Exception fields
exception_reason = fields.Many2one('exception.reason', string='Exception Reason')
exception_description = fields.Text(string='Exception Description')
exception_type = fields.Selection(
selection=[('temporarily_exception', 'Temporarily Exception'), ('permanent_exception', 'Permanent Exception')],
string="Exception Type")
exception_attachment = fields.Binary(string='Exception Attachment', attachment=True)
exception_start_date = fields.Datetime(string='Exception Start Date')
exception_end_date = fields.Datetime(string='Exception End Date')
is_excluded_suspension = fields.Boolean('Excluded from suspension?')
is_mother = fields.Boolean('Is Mother?')
total_member_service_requests = fields.Integer(compute='_get_total_member_service_requests')
# def create(self, vals):
# for line_vals in vals:
# if line_vals.get("education_status", False) == "educated" and "member_education_status_ids" not in line_vals:
# raise ValidationError(
# _("You should at least insert one current/previous education status!")
# )
# return super(FamilyMemberProfile, self).create(vals)
# def write(self, vals):
# education_status = vals.get("education_status", False) or self.education_status
# if education_status == "educated" and "member_education_status_ids" not in vals and not len(self.member_education_status_ids):
# raise ValidationError(
# _("You should at least insert one current/previous education status!")
# )
# return super(FamilyMemberProfile, self).write(vals)
@api.depends('age_status', 'is_dead','benefit_id.member_ids.age_status','benefit_id.member_ids.is_dead')
def _compute_minor_siblings(self):
for member in self:
member.minor_siblings = any(
m.age_status == 'minor' and not m.is_dead
for m in member.benefit_id.member_ids
)
@api.constrains('is_dead', 'death_certificate')
def _check_death_certificate_required(self):
for rec in self:
if rec.is_dead and not rec.death_certificate:
raise ValidationError(_(
"Death Certificate is required for member '%s' when marked as deceased."
) % rec.name)
@api.constrains('is_work', 'age', 'member_income', 'salary_certificate')
def _check_salary_certificate_required(self):
for rec in self:
if rec.age >= 18 and rec.is_work:
if rec.member_income <= 0:
raise ValidationError(_(
"Income must be greater than 0 for member '%s' when working and age is greater than or equal to 18."
) % rec.name)
if not rec.salary_certificate:
raise ValidationError(_(
"Salary Certificate is required for member '%s' when working and age is greater than or equal to 18."
) % rec.name)
@api.constrains('is_mother', 'is_married', 'marriage_certificate')
def _check_marriage_certificate_required(self):
for rec in self:
if not rec.is_mother and rec.is_married and not rec.marriage_certificate:
raise ValidationError(_(
"Marriage Certificate is required for member '%s' when marked as married and not a mother."
) % rec.name)
@api.constrains('member_first_name')
def _check_names_alphabetic(self):
char_fields = {
'member_first_name': _('Member First Name'),
}
for record in self:
for field_name, field_label in char_fields.items():
field_value = getattr(record, field_name)
if field_value and not re.match(ALPHABETIC_PATTERN, field_value.strip()):
raise ValidationError(
_("%s must contain only alphabetic characters and spaces. "
"Numbers and special characters are not allowed.") % field_label
)
@api.depends('age')
def _compute_get_age_status(self):
for rec in self:
current_education_status_id = rec.member_education_status_ids.filtered(
lambda r: r.education_status_type == 'current')
if rec.relationn.relation_type == 'son' and rec.age <= 18:
rec.age_status = 'minor'
elif rec.relationn.relation_type == 'daughter' and rec.age <= 26:
rec.age_status = 'minor'
elif rec.relationn.relation_type == 'son' and rec.age <= 22 and (current_education_status_id.specialization_ids.is_scientific_specialty or current_education_status_id.specialization_ids.is_medical_specialty):
rec.age_status = 'minor'
else:
rec.age_status = 'non_minor'
@api.constrains('birth_date')
def _check_dates(self):
today = date.today()
for rec in self:
# Check that dates are not in the future
if rec.birth_date and rec.birth_date > today:
raise ValidationError("Member's Birth Date cannot be in the future.")
def unlink(self):
for order in self:
if order.state not in ['draft']:
raise UserError(_('You cannot delete this record'))
self.env['ir.attachment'].search([('member_id', '=', order.id)]).unlink()
if order.hobbies_ids:
order.hobbies_ids.unlink()
if order.diseases_ids:
order.diseases_ids.unlink()
if order.disabilities_ids:
order.disabilities_ids.unlink()
if order.member_education_status_ids:
order.member_education_status_ids.unlink()
return super(FamilyMemberProfile, self).unlink()
@api.depends('is_member_workflow', 'benefit_id.state','state_a')
def _get_state(self):
for rec in self:
if not rec.is_member_workflow:
rec.state = rec.benefit_id.state
else:
rec.state = rec.state_a
@api.depends('member_first_name', 'member_second_name', 'member_third_name', 'member_family_name')
def get_partner_name(self):
for rec in self:
rec.name = ''
if all([rec.member_second_name, rec.member_first_name, rec.member_third_name, rec.member_family_name]):
rec.name = rec.member_first_name + " " + rec.member_second_name + " " + rec.member_third_name + " " + rec.member_family_name
elif all([rec.mother_second_name, rec.mother_first_name, rec.mother_third_name, rec.mother_family_name]):
rec.name = rec.mother_first_name + " " + rec.mother_second_name + " " + rec.mother_third_name + " " + rec.mother_family_name
else:
rec.name = ''
@api.model
def default_get(self, fields):
res = super(FamilyMemberProfile, self).default_get(fields)
# Get default attachments
default_attachment = self.env["attachments.settings"].search([('is_default', '=', True)])
# Prepare the list of default attachments for the one2many field
default_attachments_data = []
for attach in default_attachment:
if attach.attach_type == 'member_attach':
if not attach.name: # Ensure name is set
raise ValidationError('The attachment name is missing.')
default_attachments_data.append((0, 0, {
'name': attach.name,
'attach_id':attach.id,
'is_required': attach.is_required,
'is_default': attach.is_default,
'show_in_portal': attach.show_in_portal
}))
# Add the default attachments to the res dictionary for attachment_ids
if 'attachment_ids' in fields:
res['attachment_ids'] = default_attachments_data
return res
def _get_total_member_service_requests(self):
for rec in self:
rec.total_member_service_requests = self.env['service.request'].search_count([('benefit_type', '=', 'member'), ('member_id', '=', rec.id)])
def action_open_related_member_service_requests(self):
""" Opens a tree view with related records filtered by a dynamic domain """
member_service_requests = self.env['service.request'].search([
('benefit_type', '=', 'member'),
('member_id', '=', self.id)
]).ids
action = {
'type': 'ir.actions.act_window',
'name': _('Service Requests'),
'res_model': 'service.request',
'view_mode': 'tree,form',
'domain': [('id', 'in', member_service_requests)],
'target': 'current',
}
return action
@api.depends('attachment_ids')
def get_required_attach(self):
for rec in self.attachment_ids:
if rec.is_required and not rec.datas:
self.required_attach = None
break
elif rec.is_required and rec.datas:
self.required_attach = 'true'
elif rec.is_default and not rec.is_required and (rec.datas or not rec.datas):
self.required_attach = 'true'
else:
self.required_attach = 'true'
# def create_member_partner(self):
# self.partner_id.write({
# 'email': self.email,
# 'phone': self.phone,
# 'account_type': 'benefit',
# 'is_benefit': True,
# 'code': self.benefit_id.code,
# })
@api.depends(
'member_education_status_ids',
'member_education_status_ids.specialization_ids',
'member_education_status_ids.education_status',
'member_education_status_ids.case_study',
'relationn',
'birth_date',
'is_married',
'minor_siblings',
'member_income',
'is_married',
'member_location_conf',
'state',
'is_dead'
)
def check_member_status(self):
for rec in self:
current_education_status_id = rec.member_education_status_ids.filtered(lambda r: r.education_status_type == 'current')
if rec.state == 'second_approve' and rec.is_excluded_suspension:
rec.member_status = 'benefit'
continue
if rec.birth_date:
validation_setting = self.env["family.validation.setting"].search([], limit=1)
female_benefit_age = validation_setting.female_benefit_age
male_benefit_age = validation_setting.male_benefit_age
exceptional_age_scientific_specialty = validation_setting.exceptional_age_scientific_specialty
exceptional_age_medical_specialty = validation_setting.exceptional_age_medical_specialty
minor_siblings_age = validation_setting.minor_siblings_age
max_income_for_benefit = validation_setting.max_income_for_benefit
rec.member_status = 'benefit' # Default to benefit
if rec.relationn.relation_type == 'mother':
rec.member_status = rec.benefit_id.mother_status
if rec.relationn.relation_type == 'replacement_mother':
rec.member_status = rec.benefit_id.replacement_mother_status
if rec.state == 'suspended_second_approve':
rec.member_status = 'non_benefit'
# continue # Skip further checks for mothers
# Gender-specific checks
if rec.relationn.relation_type == 'son':
if rec.age > male_benefit_age:
if current_education_status_id.specialization_ids.is_scientific_specialty and rec.age > exceptional_age_scientific_specialty and not rec.minor_siblings :
rec.member_status = 'non_benefit'
elif current_education_status_id.specialization_ids.is_medical_specialty and rec.age > exceptional_age_medical_specialty and not rec.minor_siblings:
rec.member_status = 'non_benefit'
elif not any([current_education_status_id.specialization_ids.is_scientific_specialty, current_education_status_id.specialization_ids.is_medical_specialty]):
rec.member_status = 'non_benefit'
if not rec.minor_siblings:
rec.member_status = 'non_benefit'
if rec.is_work:
if rec.member_income > max_income_for_benefit:
rec.member_status = 'non_benefit'
if not rec.is_married and current_education_status_id.education_status in ['illiterate']:
rec.member_status = 'non_benefit'
if not rec.is_married and current_education_status_id.education_status in ['educated'] and current_education_status_id.case_study in [
'graduate', 'intermittent']:
rec.member_status = 'non_benefit'
if not rec.member_location_conf.is_benefit:
rec.member_status = 'non_benefit'
if rec.state == 'suspended_second_approve' or rec.is_dead == True:
rec.member_status = 'non_benefit'
elif rec.relationn.relation_type == 'daughter':
if rec.age < female_benefit_age and rec.is_married:
rec.member_status = 'non_benefit'
if rec.age < female_benefit_age and rec.is_work and current_education_status_id.education_status not in ['educated'] and current_education_status_id.case_study != 'continuous':
rec.member_status = 'non_benefit'
if rec.age > female_benefit_age:
if rec.age > minor_siblings_age and not rec.minor_siblings:
rec.member_status = 'non_benefit'
elif not rec.minor_siblings:
rec.member_status = 'non_benefit'
elif rec.minor_siblings and rec.age > minor_siblings_age:
rec.member_status = 'non_benefit'
# elif rec.is_work and current_education_status_id.education_status in ['illiterate'] and current_education_status_id.case_study in [
# 'graduate', 'intermittent']:
# rec.member_status = 'non_benefit'
elif rec.is_married:
rec.member_status = 'non_benefit'
# elif not rec.minor_siblings:
# rec.member_status = 'non_benefit'
if rec.is_work and rec.member_income > max_income_for_benefit and current_education_status_id.education_status in ['educated'] and current_education_status_id.case_study == 'continuous':
rec.member_status = 'non_benefit'
if rec.is_work and current_education_status_id.education_status in ['illiterate'] :
rec.member_status = 'non_benefit'
if rec.is_work and current_education_status_id.education_status in ['educated'] and current_education_status_id.case_study in [
'graduate', 'intermittent']:
rec.member_status = 'non_benefit'
if not rec.member_location_conf.is_benefit:
rec.member_status = 'non_benefit'
if rec.state == 'suspended_second_approve' or rec.is_dead == True:
rec.member_status = 'non_benefit'
# General checks for all members
# if rec.is_work:
# if rec.member_income > max_income_for_benefit:
# rec.member_status = 'non_benefit'
# if not rec.is_married and current_education_status_id.education_status in ['illiterate'] and current_education_status_id.case_study in [
# 'graduate', 'intermittent']:
# rec.member_status = 'non_benefit'
# if rec.member_location in ['with_relative', 'study_outside_saudi_arabia']:
# rec.member_status = 'non_benefit'
else:
rec.member_status = False
# @api.depends('relationn','birth_date', 'is_scientific_specialty', 'is_medical_specialty', 'has_disabilities', 'is_married',
# 'minor_siblings','member_income','is_married','member_location_conf','education_status','case_study','state','is_dead')
# def check_member_status(self):
# for rec in self:
# if rec.state == 'second_approve' and rec.is_excluded_suspension:
# rec.member_status = 'benefit'
# continue
# if rec.birth_date:
# validation_setting = self.env["family.validation.setting"].search([], limit=1)
# female_benefit_age = validation_setting.female_benefit_age
# male_benefit_age = validation_setting.male_benefit_age
# exceptional_age_scientific_specialty = validation_setting.exceptional_age_scientific_specialty
# exceptional_age_medical_specialty = validation_setting.exceptional_age_medical_specialty
# exceptional_age_has_disabilities = validation_setting.exceptional_age_has_disabilities
# minor_siblings_age = validation_setting.minor_siblings_age
# max_income_for_benefit = validation_setting.max_income_for_benefit
# rec.member_status = 'benefit' # Default to benefit
# if rec.relationn.relation_type == 'mother':
# rec.member_status = rec.benefit_id.mother_status
# if rec.relationn.relation_type == 'replacement_mother':
# rec.member_status = rec.benefit_id.replacement_mother_status
# if rec.state == 'suspended_second_approve':
# rec.member_status = 'non_benefit'
# # continue # Skip further checks for mothers
# # Gender-specific checks
# if rec.relationn.relation_type == 'son':
# if rec.age > male_benefit_age:
# if rec.has_disabilities and rec.age > exceptional_age_has_disabilities:
# rec.member_status = 'non_benefit'
# elif rec.is_scientific_specialty and rec.age > exceptional_age_scientific_specialty and not rec.has_disabilities and not rec.minor_siblings :
# rec.member_status = 'non_benefit'
# elif rec.is_medical_specialty and rec.age > exceptional_age_medical_specialty and not rec.has_disabilities and not rec.minor_siblings:
# rec.member_status = 'non_benefit'
# elif not any([rec.is_scientific_specialty, rec.is_medical_specialty, rec.has_disabilities]):
# rec.member_status = 'non_benefit'
# if rec.is_work:
# if rec.member_income > max_income_for_benefit:
# rec.member_status = 'non_benefit'
# if not rec.is_married and rec.education_status in ['illiterate']:
# rec.member_status = 'non_benefit'
# if not rec.is_married and rec.education_status in ['educated'] and rec.case_study in [
# 'graduate', 'intermittent']:
# rec.member_status = 'non_benefit'
# if not rec.member_location_conf.is_benefit:
# rec.member_status = 'non_benefit'
# if rec.state == 'suspended_second_approve' or rec.is_dead == True:
# rec.member_status = 'non_benefit'
# elif rec.relationn.relation_type == 'daughter':
# if rec.age < female_benefit_age and rec.is_married:
# rec.member_status = 'non_benefit'
# if rec.age < female_benefit_age and rec.is_work and rec.education_status not in ['educated'] and rec.case_study != 'continuous':
# rec.member_status = 'non_benefit'
# if rec.age > female_benefit_age:
# if rec.age > minor_siblings_age and not rec.minor_siblings:
# rec.member_status = 'non_benefit'
# elif not rec.minor_siblings:
# rec.member_status = 'non_benefit'
# elif rec.minor_siblings and rec.age > minor_siblings_age:
# rec.member_status = 'non_benefit'
# # elif rec.is_work and rec.education_status in ['illiterate'] and rec.case_study in [
# # 'graduate', 'intermittent']:
# # rec.member_status = 'non_benefit'
# elif rec.is_married:
# rec.member_status = 'non_benefit'
# # elif not rec.minor_siblings:
# # rec.member_status = 'non_benefit'
# if rec.is_work and rec.member_income > max_income_for_benefit and rec.education_status in ['educated'] and rec.case_study == 'continuous':
# rec.member_status = 'non_benefit'
# if rec.is_work and rec.education_status in ['illiterate'] :
# rec.member_status = 'non_benefit'
# if rec.is_work and rec.education_status in ['educated'] and rec.case_study in [
# 'graduate', 'intermittent']:
# rec.member_status = 'non_benefit'
# if not rec.member_location_conf.is_benefit:
# rec.member_status = 'non_benefit'
# if rec.state == 'suspended_second_approve' or rec.is_dead == True:
# rec.member_status = 'non_benefit'
# # General checks for all members
# # if rec.is_work:
# # if rec.member_income > max_income_for_benefit:
# # rec.member_status = 'non_benefit'
# # if not rec.is_married and rec.education_status in ['illiterate'] and rec.case_study in [
# # 'graduate', 'intermittent']:
# # rec.member_status = 'non_benefit'
# # if rec.member_location in ['with_relative', 'study_outside_saudi_arabia']:
# # rec.member_status = 'non_benefit'
# else:
# rec.member_status = False
@api.depends('birth_date')
def _compute_get_age_date(self):
for rec in self:
if rec.birth_date:
today = date.today()
day = datetime.strptime(str(rec.birth_date), DEFAULT_SERVER_DATE_FORMAT)
age = rd(today, day)
rec.age = age.years
else:
rec.age = 0
@api.onchange("member_id_number")
def onchange_member_id_number(self):
for rec in self:
if rec.member_id_number:
# Check if the value is numeric
if not rec.member_id_number.isdigit():
raise ValidationError(_("The ID number should contain only digits."))
# Check if the ID number contains exactly 10 digits
if len(rec.member_id_number) != 10:
raise ValidationError(_("The ID number must contain exactly 10 digits."))
# Check if the father ID and mother ID are the same on the same record
if rec.member_id_number == rec.benefit_id.mother_id_number or rec.member_id_number == rec.benefit_id.father_id_number or rec.member_id_number == rec.benefit_id.replacement_mother_id_number:
raise ValidationError(_("ID number cannot be the same with mother or replacement mother or father id number"))
# Check if the ID number exists in other records or in family members
exist = self.search([
('member_id_number', '=', rec.member_id_number)
],limit=1)
exist_in_family = self.env["grant.benefit"].search([
'|','|',
('father_id_number', '=', rec.member_id_number),
('mother_id_number', '=', rec.member_id_number),
('replacement_mother_id_number', '=', rec.member_id_number),
],limit=1)
if exist or exist_in_family:
if exist_in_family:
raise ValidationError(_("The ID Number already exists in Family with code %s")%exist_in_family.code)
if exist :
raise ValidationError(
_("The ID Number already exists in Family with code %s") % exist.benefit_id.code)
# @api.onchange("member_id_number")
# def onchange_member_id_number(self):
# for rec in self:
# if rec.member_id_number:
# exist = self.search([('member_id_number', '=', rec.member_id_number)])
# if exist:
# raise ValidationError(
# _('The ID Number Already Exist!'))
@api.onchange('relationn','member_status','gender','birth_date', 'is_scientific_specialty', 'is_medical_specialty', 'is_married',
'minor_siblings','member_income','is_married','member_location_conf','education_status','case_study')
def onchange_member_status(self):
res ={}
for rec in self:
if rec.member_status == 'non_benefit':
res['warning'] = {'title': _('ValidationError'),
'message': _('Not Benefit')}
return res
#Member Suspend Manual
def action_suspend(self):
for rec in self :
rec.is_member_workflow = True
rec.is_excluded_suspension = False
return {
'name': _('Suspend Reason Wizard'),
'view_mode': 'form',
'view_type': 'form',
'type': 'ir.actions.act_window',
'res_model': 'suspend.reason.wizard',
'view_id': self.env.ref('odex_benefit.view_suspend_member_reason_wizard_form').id,
'target': 'new',
}
def action_suspend_first_accept(self):
for rec in self:
rec.state_a = 'first_approve'
def action_suspend_second_accept(self):
for rec in self:
rec.state_a = 'suspended_second_approve'
def action_suspend_refuse(self):
for rec in self:
rec.state_a = 'second_approve'
rec.is_member_workflow = False
# Excption Work flow
def action_exception(self):
for rec in self:
rec.is_member_workflow = True
return {
'name': _('Exception Wizard'),
'view_mode': 'form',
'view_type': 'form',
'type': 'ir.actions.act_window',
'res_model': 'exception.wizard',
'view_id': self.env.ref('odex_benefit.view_exception_member_wizard_form').id,
'target': 'new',
}
def action_exception_first_accept(self):
for rec in self:
rec.state_a = 'first_approve'
def action_exception_second_accept(self):
for rec in self:
rec.is_excluded_suspension = True
rec.state_a = 'exception_second_approve'
# rec.is_member_workflow = False
def action_exception_final_accept(self):
for rec in self:
rec.is_excluded_suspension = True
rec.state_a = 'second_approve'
rec.is_member_workflow = False
def action_auto_exception(self):
obj = self.env["family.member"].search(
[('state', '=', 'second_approve'), ('is_excluded_suspension', '=', True)])
for rec in obj:
if rec.exception_end_date and rec.exception_end_date <= fields.Datetime.now():
rec.is_excluded_suspension = False
rec.state = 'suspended_second_approve'
def action_exception_refuse(self):
for rec in self:
rec.state_a = 'suspended_second_approve'
# Methods for Work flow for Member
def complete_data(self):
# message = self.create_message('complete_info')
# self.partner_id.send_sms_notification(message, self.phone)
self.state_a = 'complete_info'
return {
'name': _('Rerearcher Wizard'),
'view_mode': 'form',
'view_type': 'form',
'type': 'ir.actions.act_window',
'res_model': 'researcher.member.wizard',
'view_id': self.env.ref('odex_benefit.view_resarcher_member_wizard_form').id,
'target': 'new',
}
def finish_complete_data(self):
message = self.create_message('waiting_approve')
# self.partner_id.send_sms_notification(message, self.phone)
self.state_a = 'waiting_approve'
def action_accepted(self):
"""Accept registration"""
self.state_a = "second_approve"
def action_first_refusal(self):
"""First refusal to entity registration"""
domain = []
context = {}
context = dict(self.env.context or {})
context['state_a'] = "first_refusal"
# self.partner_id.send_sms_notification("First Refusal", self.phone)
context['active_id'] = self.id
return {
'name': _('Refuse Reason Wizard'),
'view_mode': 'form',
'view_type': 'form',
'type': 'ir.actions.act_window',
'res_model': 'entity.refused.reason.wizard',
'view_id': self.env.ref('odex_benefit.view_entity_refused_reason_wizard_form').id,
'target': 'new',
'domain': domain,
'context': context,
}
def action_refuse(self):
"""Refuse entity registration"""
domain = []
context = dict(self.env.context or {})
context['state'] = "refused"
context['active_id'] = self.id
return {
'name': _('Refuse Reason Wizard'),
'view_mode': 'form',
'view_type': 'form',
'type': 'ir.actions.act_window',
'res_model': 'entity.refused.reason.wizard',
'view_id': self.env.ref('odex_benefit.view_entity_final_refused_reason_wizard_form').id,
'target': 'new',
'domain': domain,
'context': context,
}
def action_black_list(self):
"""Move benefit to black list"""
domain = []
context = dict(self.env.context or {})
context['state'] = "black_list"
context['active_id'] = self.id
return {
'name': _('Black List Wizard'),
'view_mode': 'form',
'view_type': 'form',
'type': 'ir.actions.act_window',
'res_model': 'entity.black.list.wizard',
'view_id': self.env.ref('odex_benefit.view_entity_black_list_wizard_form').id,
'target': 'new',
'domain': domain,
'context': context,
}
def action_edit_info(self):
self.state = 'complete_info'
def action_finish_edit(self):
for rec in self:
# group_e = self.env.ref('odex_benefit.group_benefit_edit', False)
# group_e.write({'users': [(3, self.user_id.id)]})
rec.state_a = rec.old_stage
def create_manual_visit(self):
self.env['visit.location'].create({
'benefit_id': self.id,
'visit_date': date.today(),
'visit_types': 2,
# 'selector': 'researcher',
'researcher_id': self.researcher_id.id,
# 'researcher_team': rec.researcher_team.id,
'state': 'draft'
})
@api.onchange('member_phone')
def _onchange_member_phone_validation(self):
if self.member_phone:
if self.member_phone.startswith('+966'):
member_phone = self.member_phone[4:]
self.member_phone = member_phone
if re.match(SAUDI_MOBILE_PATTERN, self.member_phone) == None:
raise ValidationError(
_('Enter a valid Saudi mobile number'))
exist = self.search([('member_phone', '=', self.member_phone)])
if exist:
raise ValidationError(
_('This Phone Already Exist!'))
# Check if the father ID and mother ID are the same on the same record
if self.member_phone == self.benefit_id.phone or self.member_phone == self.benefit_id.phone2 or self.member_phone == self.benefit_id.sms_phone:
raise ValidationError(
_("Phone number cannot be the same in The Family"))
# Check if the ID number exists in other records or in family members
exist = self.search([
('member_phone', '=', self.member_phone)
], limit=1)
exist_in_family = self.env["grant.benefit"].search([
'|', '|',
('phone', '=', self.member_phone),
('phone2', '=', self.member_phone),
('sms_phone', '=', self.member_phone),
], limit=1)
if exist or exist_in_family:
if exist_in_family:
raise ValidationError(
_("The phone Number already exists in Family with code %s") % exist_in_family.code)
if exist:
raise ValidationError(
_("The phone Number already exists in Family with code %s") % exist.benefit_id.code)