2790 lines
138 KiB
Python
2790 lines
138 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
|
||
import re
|
||
from odoo.osv import expression
|
||
|
||
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 ]+$"
|
||
|
||
_logger = logging.getLogger(__name__)
|
||
|
||
|
||
class GrantBenefitProfile(models.Model):
|
||
_name = 'grant.benefit'
|
||
_description = "Benefits - Profiles"
|
||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||
_inherits = {'res.partner': 'partner_id'}
|
||
_order = 'create_date desc'
|
||
def get_url(self):
|
||
return "wwww"
|
||
|
||
#def name_get(self):
|
||
# result = []
|
||
# for rec in self:
|
||
# if rec.name and rec.code:
|
||
# display_name = f"{rec.code} - {rec.name}"
|
||
# result.append((rec.id, display_name))
|
||
# else:
|
||
# result.append((rec.id, rec.name or rec.code or ""))
|
||
# return result
|
||
|
||
@api.model
|
||
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
|
||
args = args or []
|
||
name = name.strip() if name else ""
|
||
|
||
if operator == "ilike" and not name:
|
||
domain = []
|
||
else:
|
||
domain = ["|", "|", "|",
|
||
("name", operator, name),
|
||
("code", operator, name),
|
||
("sms_phone", operator, name),
|
||
("father_id_number", operator, name),
|
||
]
|
||
return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)
|
||
|
||
profile_step_count = fields.Integer()
|
||
complete_registration_step = fields.Char(string="Complete Registration Step")
|
||
complete_registration_done = fields.Boolean('Does Complete Registration Done ?')
|
||
partner_id = fields.Many2one('res.partner', string='partner', required=True, ondelete="cascade")
|
||
code = fields.Char(string="Code", copy=False, default=lambda x: _('New'))
|
||
benefit_type = fields.Selection([('benefit', 'benefit'), ('orphan', 'orphan'), ('widow', 'widow')
|
||
], string='Benefit Type', tracking=True)
|
||
mother_status = fields.Selection(string='Mother Status', related="mother_family_member_id.member_status")
|
||
mother_salary_certificate = fields.Many2many('ir.attachment', 'mother_member_salary_cert_rel', 'mother_grant_benefit_id', 'attachment_id',
|
||
string="Salary Certificate")
|
||
phone2 = fields.Char(string="Phone2")
|
||
relative_phone = fields.Char(string="Relative Phone")
|
||
relative_relation = fields.Char(string="Relative Relation")
|
||
sms_phone = fields.Char(string="Contact Phone",tracking=True)
|
||
name_in_bank = fields.Char()
|
||
family_bank = fields.Many2one('res.partner.bank')
|
||
acc_number = fields.Char('Account Number',copy=False,tracking=True)
|
||
acc_holder_name = fields.Char('Account Holder Name')
|
||
acc_holder_id_number = fields.Char(string="Account Holder ID Number")
|
||
bank_id = fields.Many2one("res.bank",string='Bank')
|
||
account_relation = fields.Many2one('relation.settings',string="Account Owner Relation")
|
||
orphan_status = fields.Selection(
|
||
selection=[('father', 'Father-Orphan'), ('mother', 'Mother-Orphan'), ('parent', 'Parent-Orphan'), ],
|
||
compute="_compute_orphan_Type", store=True)
|
||
iban_attach = fields.Many2many('ir.attachment',
|
||
relation="ir_iban_attach_rel",
|
||
column1="iban",
|
||
column2="name",
|
||
string="Iban Attach")
|
||
id_number_attach = fields.Many2many('ir.attachment',
|
||
relation="ir_id_number_attach_rel",
|
||
column1="id_number",
|
||
column2="name",
|
||
string="Id Number Attach")
|
||
instrument_number = fields.Char()
|
||
instrument_attach = fields.Many2many('ir.attachment',
|
||
relation="ir_instrument_attach_rel",
|
||
column1="instrument_number",
|
||
column2="name",
|
||
string="Instrument Attach")
|
||
step = fields.Integer('Step')
|
||
has_needs = fields.Boolean(compute='_onchange_is_has_needs',
|
||
store=True) # This boolean filed for check if benefit has need in
|
||
# Job
|
||
job_position = fields.Char()
|
||
job_department = fields.Char()
|
||
job_company = fields.Char()
|
||
# login info
|
||
user_id = fields.Many2one('res.users', string="User")
|
||
password = fields.Char('Password')
|
||
# Category And Family
|
||
benefit_category_id = fields.Many2one('benefit.category', string='Benefit Category', compute="get_benefit_category",store=True,tracking=True)
|
||
benefit_category_old = fields.Many2one('benefit.category', string='Family category in the old system')
|
||
family_id = fields.Many2one('benefit.family', string='Benefit Family')
|
||
# address
|
||
housing_id = fields.Many2one('benefit.housing', string='Benefit Housing')
|
||
lat = fields.Float(string='Lat', digits=(16, 5))
|
||
lon = fields.Float(string='Long', digits=(16, 5))
|
||
block = fields.Char(string='block')
|
||
street = fields.Char(string='street')
|
||
house_number = fields.Char(string='house number')
|
||
floor = fields.Char(string='floor')
|
||
housing_number = fields.Char(string='housing number')
|
||
rent_amount = fields.Float(string='Rent Amount',compute='_compute_rent_from_contract',store=True)
|
||
estimated_rent_amount = fields.Float(string="Estimated Rent Amount", compute="_compute_estimated_rent_amount",store=True)
|
||
housing_type = fields.Selection([
|
||
('apartment', 'apartment'),
|
||
('villa', 'villa'),
|
||
('popular_house', 'popular house'),
|
||
('tent', 'tent'),
|
||
('Appendix', 'Appendix'), ], default='apartment',tracking=True)
|
||
property_instrument_number = fields.Char(string='Property Instrument number')
|
||
property_instrument_attach = fields.Many2many('ir.attachment','rel_property_instrument_attach_attachment','benefit_id','attachment_id',string='Property Instrument Attach')
|
||
electricity_attach = fields.Many2many('ir.attachment','rel_electricity_attach_attachment','benefit_id','attachment_id',string='Electricity Attach',compute='_compute_rent_from_contract',store=True,)
|
||
property_instrument_date = fields.Date(string='Property Instrument Date')
|
||
location_url = fields.Char(string='Location URL')
|
||
location = fields.Char(string='location')
|
||
rooms_number = fields.Integer('Rooms Number')
|
||
water_bill_account_number = fields.Char(string='water Bill Account Number', )
|
||
electricity_bill_account_number = fields.Char(string='Electricity Bill Account Number')
|
||
domestic_labor_ids = fields.Many2many('domestic.labor')
|
||
responsible = fields.Selection(string='responsible', selection=[('father', 'Father'),
|
||
('mother', 'mother'),
|
||
('other', 'other')], required=False, )
|
||
responsible_id = fields.Many2one('grant.benefit', domain="[('is_responsible','=',True)]", string='', required=False)
|
||
qr_code = fields.Binary( attachment=True, compute='_compute_qr_code')
|
||
## car data
|
||
car_ids = fields.One2many('cars.line', 'benefit_id')
|
||
car_count = fields.Integer(compute='_onchange_car_count')
|
||
# compute = 'count_car'
|
||
####clothing data #
|
||
cloth_ids = fields.One2many('benefit.cloth', 'benefit_id')
|
||
expenses_request_ids = fields.One2many('benefit.expenses', 'benefit_id')
|
||
expenses_ids = fields.One2many('expenses.line', 'benefit_id')
|
||
mother_expenses_ids = fields.One2many('expenses.line','mother_benefit_id',string="Mother Commitments / Expenses")
|
||
# Father's case and his data # Birth Date # Address # dead data
|
||
# Father's case and his data
|
||
# family_name = fields.Char(string="Family Name", tracking=True)
|
||
benefit_partner_name = fields.Char(string="Name",related='partner_id.name',store=True)
|
||
# father_name = fields.Char(string="Father First Name", tracking=True)
|
||
# father_second_name = fields.Char(string="Father Second Name", tracking=True)
|
||
# father_third_name = fields.Char(string="Father Third Name", tracking=True)
|
||
# father_family_name = fields.Char(string="Father Family Name", tracking=True)
|
||
father_id_number = fields.Char(string="Id Number", tracking=True)
|
||
father_marital = fields.Selection(
|
||
[('single', _('Single')), ('married', _('Married')), ('widower', _('Widower')), ('divorced', _('Divorced'))],
|
||
_('Marital Status'), default='single', tracking=True)
|
||
father_job_id = fields.Many2one('job.settings')
|
||
father_job_id_not_defined = fields.Boolean(related="father_job_id.not_defined")
|
||
father_job = fields.Char(string='Father Job')
|
||
father_id_number_type = fields.Selection([('citizen', _('Citizen')),('resident', _('Resident')),('visitor', _('Visitor'))],string='Father ID number type')
|
||
father_birth_date = fields.Date(string="Birth Date")
|
||
father_age = fields.Integer(string="Age", compute='_compute_get_father_age')
|
||
father_country_id = fields.Many2one('res.country', 'Father Nationality', tracking=True)
|
||
father_city_id = fields.Many2one('res.country.city', string='City')
|
||
father_dead_reason_id = fields.Many2one('death.reason.settings', string='Dead Reason', required=False)
|
||
father_dead_reason_id_not_defined = fields.Boolean(related='father_dead_reason_id.not_defined')
|
||
father_dead_reason = fields.Char(string='Dead Reason', required=False)
|
||
father_dead_date = fields.Date(string="Father Dead Date")
|
||
father_dead_country_id = fields.Many2one('res.country', string='Father Dead Country', tracking=True)
|
||
father_dead_country_id_code = fields.Char(related='father_dead_country_id.code')
|
||
father_dead_city_id = fields.Many2one('res.country.city', string='Father Dead City',domain="[('country_id', '=', father_dead_country_id)]")
|
||
father_dead_res_city_id = fields.Many2one('res.country.city', string='Father Dead City',domain="['|', ('country_id', '=', father_dead_country_id), ('country_id', '=', False)]")
|
||
father_dead_city = fields.Char(string='Father Dead City')
|
||
father_dead_certificate = fields.Many2many('ir.attachment', 'rel_father_dead_attachment','benefit_id','attachment_id',string='Father Dead Certificate')
|
||
# Mother's case and her data # Birth Date # Address # dead data
|
||
mother_relation = fields.Selection(
|
||
[('mother', _('Mother')), ('replacement_mother', _('Replacement Mother'))])
|
||
mother_relationn = fields.Many2one('relation.settings',domain="['|',('relation_type','=','mother'),('relation_type','=','replacement_mother')]")
|
||
replacement_mother_relation = fields.Many2one('relation.settings',domain="[('relation_type','=','replacement_mother')]")
|
||
mother_id = fields.Many2one('grant.benefit', domain="[('benefit_type','!=','orphan'),('gender','=','female')]")
|
||
mother_name = fields.Char(string="Mother Name", tracking=True)
|
||
mother_second_name = fields.Char(string="Mother Second Name", tracking=True)
|
||
mother_third_name = fields.Char(string="Mother Third Name", tracking=True)
|
||
mother_family_name = fields.Char(string="MotherFamily Name", tracking=True)
|
||
mother_country_id = fields.Many2one('res.country', 'Mother Nationality', tracking=True)
|
||
mother_id_number = fields.Char(string="Id Number", tracking=True)
|
||
mother_id_number_type = fields.Selection([('citizen', _('Citizen')),('resident', _('Resident')),('visitor', _('Visitor'))],string='Mother ID number type')
|
||
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_is_dead = fields.Boolean(string='Mother Is Dead?',related='mother_marital_conf.is_dead')
|
||
mother_dead_country_id = fields.Many2one('res.country', string='Mother Dead Country', tracking=True)
|
||
mother_dead_country_id_code = fields.Char(related='mother_dead_country_id.code')
|
||
mother_dead_city_id = fields.Many2one('res.country.city', string='Mother Dead City',domain="[('country_id', '=', mother_dead_country_id)]")
|
||
mother_dead_reason_id = fields.Many2one('death.reason.settings', string='Mother Dead Reason', required=False)
|
||
mother_dead_reason_id_not_defined = fields.Boolean(related='mother_dead_reason_id.not_defined')
|
||
mother_dead_reason = fields.Char(string='Mother Dead Reason', required=False)
|
||
mother_dead_res_city_id = fields.Many2one('res.country.city', string='Mother Dead City',domain="[('country_id', '=', mother_dead_country_id)]")
|
||
mother_dead_city = fields.Char(string='Mother Dead City')
|
||
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')]")
|
||
is_mother_work = fields.Boolean('Is Mother Work?')
|
||
mother_has_disabilities = fields.Boolean('Has Disabilities?')
|
||
mother_income = fields.Float("Mother Income", digits=(16, 0),compute='calculate_income', store=True,tracking=True)
|
||
mother_net_income = fields.Float(string="Mother Net Income",compute='_compute_mother_net_income',
|
||
store=True,help="Mother gross income minus her deducted expenses and monthly debt installments")
|
||
mother_birth_date = fields.Date(string="Birth Date")
|
||
mother_age = fields.Integer(string="Age", compute='_compute_get_mother_age')
|
||
mother_city_id = fields.Many2one('res.country.city', string='City')
|
||
mother_dead_reason = fields.Char(string='Dead Reason', required=False)
|
||
mother_dead_date = fields.Date(string="Mother Dead Date")
|
||
mother_dead_certificate = fields.Many2many('ir.attachment', 'rel_mother_dead_attachment','benefit_id','attachment_id',string='Mother Dead Certificate')
|
||
mother_family_member_id = fields.Many2one('family.member', string='Mother Family Member', domain="[('id','in',member_ids)]")
|
||
replacement_mother_family_member_id = fields.Many2one('family.member', string='Mother Family Member', domain="[('id','in',member_ids)]")
|
||
member_ids = fields.One2many('family.member', 'benefit_id')
|
||
# orphan
|
||
orphan_ids = fields.Many2many('grant.benefit', 'orphan_list', 'id_number', 'mother_id',
|
||
compute='_orphan_list_compute')
|
||
orphan_count = fields.Integer(
|
||
string='',
|
||
required=False)
|
||
# widows and divorcees
|
||
widows_ids = fields.One2many('widow.family', 'benefit_id', string='Widows', required=False)
|
||
divorcee_ids = fields.One2many('divorcee.family', 'benefit_id', string='divorcee', required=False)
|
||
# Husband info
|
||
husband_name = fields.Char('Husband')
|
||
husband_id = fields.Char('Husband ID')
|
||
date_death_husband = fields.Date()
|
||
date_divorcee = fields.Date()
|
||
# Education_data
|
||
mother_education_status_ids = fields.One2many('education.status', 'mother_grant_benefit_id')
|
||
mother_diseases_attachment_ids = fields.One2many('ir.attachment', 'mother_grant_benefit_id', string='Diseases Attachments',domain=[('diseases_id', '!=', False)])
|
||
mother_disabilities_attachment_ids = fields.One2many('ir.attachment', 'mother_grant_benefit_id', string='Disabilities Attachments',domain=[('disabilities_id', '!=', False)])
|
||
education_status = fields.Selection(
|
||
string='Education Status',
|
||
selection=[('educated', 'educated'), ('illiterate', 'illiterate')],
|
||
defualt='illiterate'
|
||
)
|
||
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')
|
||
education_entity = fields.Selection(string='Education Entity', selection=[('governmental', 'Governmental'),
|
||
('special', 'Special')])
|
||
education_start_date = fields.Date(string='Education Start Date')
|
||
education_end_date = fields.Date(string='Education End Date')
|
||
educational_certificate = fields.Many2many('ir.attachment','rel_educational_certificate_attachment','benefit_id','attachment_id',string='Educational Certificate')
|
||
last_education_entity = fields.Selection(string='Last Education Entity',
|
||
selection=[('governmental', 'Governmental'),
|
||
('special', 'Special')])
|
||
entities = fields.Many2one("res.partner", string='Entity')
|
||
last_entities = fields.Many2one("res.partner", 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')
|
||
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%")
|
||
last_education_start_date = fields.Date(string='Last Education Start Date')
|
||
last_education_end_date = fields.Date(string='Last Education End Date')
|
||
last_educational_certificate = fields.Many2many('ir.attachment','rel_last_educational_certificate_attachment','benefit_id','attachment_id',string='Last Educational Certificate')
|
||
end_date = fields.Date('End Date')
|
||
specialization_ids = fields.Many2one('specialization.specialization', string='specialization')
|
||
last_specialization_ids = fields.Many2one('specialization.specialization', string='Last Specialization')
|
||
weak_study = fields.Many2many('study.material',relation='grant_benefit_weak_study_rel',string='Weak Study')
|
||
educational_institution_information = fields.Char('Educational institution information')
|
||
graduation_status = fields.Selection(string='Education Status', selection=[('graduated', 'graduated'),
|
||
('ungraduated', 'ungraduated'),
|
||
('intermittent', 'intermittent')])
|
||
graduation_date = fields.Date('Graduation Date')
|
||
reasons_for_interruption = fields.Char('Reasons for interruption')
|
||
interruption_date = fields.Date('Interruption Date')
|
||
# attach
|
||
study_document_attached = fields.Many2many('ir.attachment','rel_study_document_attachment','benefit_id','attachment_id',string="Study Document Attached")
|
||
acadimec_regsteration_attached = fields.Binary(string="Acadimec Regsteration Attached",attachment=True )
|
||
Transcript_attached = fields.Binary(string="Transcript Attached",attachment=True )
|
||
# Quran memorize
|
||
quran_memorize_name = fields.Char(string='')
|
||
number_parts = fields.Integer(string='')
|
||
# is craft skills
|
||
craft_skill_ids = fields.One2many('craft.skills', 'benefit_id', string='Craft Skill')
|
||
training_inclinations_ids = fields.One2many('training.inclinations', 'benefit_id', string='Training Inclinations')
|
||
### alhaju , amra and zakat fitr ####
|
||
amra_date = fields.Date(string='')
|
||
######################
|
||
food_surplus_type = fields.Many2many('food.surplus.type', string='')
|
||
# Income and salary
|
||
salary_ids = fields.One2many('salary.line', 'benefit_id', string='')
|
||
mother_salary_ids = fields.One2many('salary.line', 'mother_benefit_id', string="Mother Income")
|
||
# Commercial Record
|
||
is_active = fields.Boolean(string='')
|
||
commercial_record_code = fields.Char(string='Commercial Record Code')
|
||
commercial_record_attach = fields.Binary(attachment=True)
|
||
commercial_record_amount = fields.Float(string='')
|
||
# other_associations
|
||
associations_ids = fields.One2many('associations.line', 'benefit_id', string='')
|
||
benefit_behavior_ids = fields.One2many('benefit.behaviors', 'benefit_id', string='')
|
||
# Refuse Reason
|
||
first_refusal_reason = fields.Text(string='First Refusal Reason', tracking=True)
|
||
first_refuse_date = fields.Date(tracking=True)
|
||
final_refusal_reason = fields.Text(string='Final Refusal Reason', tracking=True)
|
||
final_refuse_date = fields.Date(tracking=True)
|
||
black_list_reason = fields.Text(string='Black List Reason', tracking=True)
|
||
black_list_message = fields.Text(string='Black List Message')
|
||
# health information#
|
||
# diseases
|
||
hospital_id = fields.Many2one('hospital.hospital', string='')
|
||
hospital_attach = fields.Binary(attach=True)
|
||
diseases_type = fields.Selection(string='Diseases Type', selection=[('chronic', 'chronic'),
|
||
('psycho', 'psycho'),
|
||
('organic', 'organic')])
|
||
treatment_used = fields.Char(string='')
|
||
treatment_amount = fields.Float(string='')
|
||
is_treatment_amount_country = fields.Boolean(string='')
|
||
treatment_amount_country_Monthly = fields.Float(string='')
|
||
treatment_amount_country_description = fields.Text(string="")
|
||
treatment_amount_country_attach = fields.Binary(attachment=True)
|
||
# Hospital information
|
||
hospital_card = fields.Binary(attachment=True)
|
||
# disability
|
||
disability_type = fields.Char(string='')
|
||
disability_accessories = fields.Char(string='')
|
||
disability_attach = fields.Binary(attachment=True)
|
||
disability_amount = fields.Float()
|
||
# Medical Insurance
|
||
insurance_type = fields.Many2one('insurance.type')
|
||
insurance_company = fields.Many2one('insurance.company')
|
||
insurance_amount = fields.Float()
|
||
insurance_attach = fields.Binary(attachment=True)
|
||
insured_party = fields.Many2one('res.company')
|
||
# Weight rate
|
||
weight = fields.Float('Weight')
|
||
height = fields.Float('Height')
|
||
p_weight = fields.Float('Overweight', store=True, compute="_compute_obesity_rate", )
|
||
sport_ids = fields.One2many('sport.line', 'benefit_id')
|
||
wife_number = fields.Integer(string="Wife")
|
||
child_number = fields.Integer(string="Children")
|
||
old_stage = fields.Char(string='old Stage', tracking=True)
|
||
dead_certificate = fields.Binary(string="Certificate",attachment=True)
|
||
dead_certificate_date = fields.Date(string="Certificate Date")
|
||
approve_date = fields.Date(string="Approve Date")
|
||
benefit_needs_value = fields.Float()
|
||
benefit_needs_percent = fields.Float()
|
||
followers_total = fields.Integer(string="followers Total")
|
||
followers_out_total = fields.Integer(string="followers Total", )
|
||
expenses_total = fields.Integer(string="Expenses", compute="get_total_expenses",store=True)
|
||
#################################################################
|
||
# Boolean Fields to use in filters#TODO
|
||
#################################################################
|
||
is_responsible = fields.Boolean(string='') # Differentiate between a primary beneficiary and a dependent
|
||
father_is_life = fields.Boolean(string="Life")
|
||
mother_is_life = fields.Boolean(string="Life")
|
||
is_widows = fields.Boolean(string='is widows', required=False)
|
||
is_divorcee = fields.Boolean(string='is Divorcee', required=False)
|
||
is_want_education = fields.Boolean(string='is Want Education', required=False)
|
||
is_quran_memorize = fields.Boolean('memorize the quran ?')
|
||
is_craft = fields.Boolean(string='')
|
||
is_zakat_fitr = fields.Boolean(string='Zakat Al-Fitr')
|
||
has_car= fields.Boolean('Has Car?',compute='_onchange_car_count',store=True)
|
||
is_producer = fields.Boolean(string='Producer')
|
||
is_food_surplus = fields.Boolean(string='food surplus')
|
||
is_loans = fields.Boolean('loans')
|
||
is_al_al_bayt = fields.Boolean(string='Al al-Bayt')
|
||
is_commercial_record = fields.Boolean(string='Commercial Record')
|
||
is_other_associations = fields.Boolean(string='other associations?')
|
||
is_smoke = fields.Boolean('Smoke')
|
||
# health_status
|
||
is_diseases = fields.Boolean()
|
||
is_disability = fields.Boolean(string='')
|
||
is_insurance = fields.Boolean()
|
||
is_sport = fields.Boolean()
|
||
support_separation = fields.Boolean(string="Support Separation", tracking=True)
|
||
is_life = fields.Boolean(string="Life", default=True)
|
||
total_expenses = fields.Float('Total Expenses', compute="get_total_expenses",store=True,tracking=True)
|
||
total_income = fields.Float('Total Income', compute="get_total_income", store=True,tracking=True)
|
||
benefit_member_count = fields.Integer(string="Members count", compute="get_members_count",store=True)
|
||
non_member_count = fields.Integer(string="Non Benefit Members count", compute="get_members_count")
|
||
member_income = fields.Float(string="Member Income Average", compute="get_member_income",store=True,tracking=True)
|
||
request_activity_id = fields.Many2one('mail.activity')
|
||
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'),
|
||
('family_services_manager', 'Waiting Family Services Manager'),
|
||
('first_refusal', 'First Refusal'),
|
||
('second_approve', 'Second Approved'),
|
||
('refused', 'Refused'),
|
||
('temporary_suspended', 'Temporary Suspended'),
|
||
('suspended_second_approve', 'Suspended Second Approved'),
|
||
('exception_second_approve', 'Waiting for General Manager'),
|
||
('black_list', 'Black List'),
|
||
], string='state', default="draft", tracking=True, group_expand='_expand_states')
|
||
branch_custom_id = fields.Many2one('branch.settings', string="Branch",tracking=True)
|
||
branch_family_id = fields.Many2one('branch.settings', string="Family Branch",tracking=True)
|
||
branch_has_employees = fields.Boolean('Has Employees In branch',related="branch_custom_id.has_employees")
|
||
district_id = fields.Many2one('res.districts', string="District", domain="[('branch_custom_id','=',branch_custom_id)]",tracking=True)
|
||
meal_card = fields.Boolean(string="Meal Card",related="district_id.meal_card", store=True,related_sudo=True)
|
||
attachment_ids = fields.One2many('ir.attachment', 'benefit_id')
|
||
family_debits_ids = fields.One2many('family.debits', 'benefit_id')
|
||
mother_debits_ids = fields.One2many('family.debits','mother_benefit_id',string="Mother Debts")
|
||
researcher_id = fields.Many2one("committees.line", string="Researcher",tracking=True)
|
||
assigned_researcher_id = fields.Many2one('committees.line',string='Assigned Researcher',tracking=True)
|
||
auto_accept_for_member = fields.Boolean(string="Auto Accept For members", default=True)
|
||
last_visit_date = fields.Datetime(string='Last Visit Date')
|
||
# Benefit Housing Information
|
||
# housing_name = fields.Char(compute='_compute_get_name')
|
||
zip = fields.Char('Zip', change_default=True, readonly=False, store=True)
|
||
short_number = fields.Char(
|
||
readonly=False,
|
||
required=False,
|
||
states={
|
||
'second_approve': [('readonly', True)],
|
||
'complete_info': [('required', True)]
|
||
}
|
||
)
|
||
extra_code = fields.Char(
|
||
readonly=False,
|
||
required=False,
|
||
states={
|
||
'second_approve': [('readonly', True)],
|
||
}
|
||
)
|
||
zip = fields.Char('Zip', change_default=True, readonly=False, store=True)
|
||
# res_city_id = fields.Many2one('res.city', domain="[('country_city_id', '=', city_id)]")
|
||
# housing_city = fields.Char()
|
||
url = fields.Char()
|
||
url_html = fields.Html(
|
||
sanitize=False,
|
||
compute="get_html")
|
||
image = fields.Binary(string="", )
|
||
image_1 = fields.Binary(string="", )
|
||
image_2 = fields.Binary(string="", )
|
||
image_3 = fields.Binary(string="", )
|
||
image_4 = fields.Binary(string="", )
|
||
nearby_mosque = fields.Char(string='Nearby mosque')
|
||
housing_note = fields.Char(string='housing note')
|
||
note_neighborhood = fields.Char()
|
||
contract_num = fields.Char(string="Contract Number",compute='_compute_rent_from_contract',store=True)
|
||
rent_start_date = fields.Date(string='Rent Start Date',compute='_compute_rent_from_contract',store=True)
|
||
rent_end_date = fields.Date(string='Rent End Date',compute='_compute_rent_from_contract',store=True)
|
||
rent_attachment = fields.Many2many('ir.attachment','rel_rent_attachment_attachment','benefit_id','attachment_id',string='Rent Attachment',compute='_compute_rent_from_contract',store=True,)
|
||
national_address_attachment = fields.Many2many('ir.attachment','rel_national_address_attachment','benefit_id','attachment_id',string='National Address Attachment')
|
||
payment_type = fields.Selection(
|
||
[
|
||
('1', 'Yearly'),
|
||
('2', 'Half-yearly'),
|
||
('4', 'Quarterly'),
|
||
('12', 'Monthly')
|
||
],
|
||
string='Payment Type',
|
||
compute='_compute_rent_from_contract',store=True,
|
||
)
|
||
housing_cat = fields.Selection([
|
||
('excellent', 'Excellent'),
|
||
('good', 'Good'),
|
||
('bad', 'Bad'),
|
||
('collapsible', 'Collapsible'),
|
||
('collapsed', 'Collapsed')])
|
||
property_type = fields.Selection([
|
||
('ownership', 'ownership'),
|
||
('rent', 'rent'),
|
||
('charitable', 'charitable'),
|
||
('ownership_shared', 'Ownership Shared'),
|
||
('rent_shared', 'Rent Shared')])
|
||
property_type_id = fields.Many2one('property.type.settings',string="Property Type",tracking=True)
|
||
property_type_code = fields.Selection([
|
||
('ownership', 'Ownership'),
|
||
('rent', 'Rent')
|
||
], string="Property Type Code",related='property_type_id.type', store=True)
|
||
room_ids = fields.One2many('benefit.housing.rooms', inverse_name='housing_id')
|
||
request_producer_id = fields.Many2one('res.partner',string='Request Producer', compute='_compute_request_producer_id')
|
||
request_producer = fields.Many2one('res.partner',string='Request Producer',default=lambda self: self.env.user.partner_id)
|
||
request_producer_relation = fields.Many2one('relation.settings',string='Request Producer Relation',domain="[('relation_type','=','other relation')]")
|
||
# Suspend
|
||
is_excluded_suspension = fields.Boolean('Excluded from suspension?')
|
||
suspend_reason = fields.Many2one('suspend.reason', string='Suspend Reason')
|
||
reason = fields.Text(string='Reason')
|
||
suspend_description = fields.Text(string='Suspend Description')
|
||
suspend_attachment = fields.Many2many('ir.attachment','rel_suspend_attachment_attachment','benefit_id','attachment_id',string='Suspend Attachment')
|
||
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")
|
||
#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.Many2many('ir.attachment','rel_exception_attachment','benefit_id','attachment_id',string='Exception Attachment')
|
||
exception_start_date = fields.Datetime(string='Exception Start Date')
|
||
exception_end_date = fields.Datetime(string='Exception End Date')
|
||
|
||
# sponsor_id = fields.Many2one('res.partner', string='Sponsor',domain="[('account_type','=','sponsor')]")
|
||
sponsor_id = fields.Many2one('res.partner', string='Sponsor',domain="[('is_sponsor_portal', '=', True)]")
|
||
|
||
family_monthly_income = fields.Float(string="Family Monthly Income", compute='_get_family_monthly_values')
|
||
family_monthly_meals = fields.Float(string="Family Monthly Meals", compute='_get_family_monthly_values')
|
||
family_monthly_clotting = fields.Float(string="Family Monthly Clotting", compute='_get_family_monthly_values')
|
||
total_family_expenses = fields.Float(string="Total Family Expenses", compute='_get_family_monthly_values')
|
||
total_move_lines = fields.Float(string="Total Move Lines", compute='_get_total_move_lines')
|
||
visit_location_count = fields.Integer(string="Visit Location Count", compute='_compute_visit_location_count')
|
||
total_service_requests = fields.Integer(compute='_get_total_service_requests')
|
||
total_seasonal_service_requests = fields.Integer(compute='_get_total_seasonal_service_requests')
|
||
invoices_count = fields.Integer(string="Invoices Count", compute='_get_invoices_count')
|
||
required_attach = fields.Selection(selection=[('true', 'True'), ('false', 'False')],compute='get_required_attach',store=True)
|
||
income_required_attach = fields.Selection(selection=[('true', 'True'), ('false', 'False')],compute='get_income_required_attach',store=True)
|
||
sa_iban = fields.Char('SA',default='SA',readonly=True)
|
||
iban_document = fields.Many2many('ir.attachment', 'rel_iban_document', 'benefit_id', 'attachment_id')
|
||
#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_id_number_type = fields.Selection([('citizen', _('Citizen')),('resident', _('Resident')),('visitor', _('Visitor'))],string='Replacement Mother ID number type')
|
||
replacement_mother_marital_conf = fields.Many2one('marital.status', string='Replacement Mother Marital')
|
||
replacement_mother_is_dead = fields.Boolean(string='Replacement Mother Is Dead?',related='replacement_mother_marital_conf.is_dead')
|
||
replacement_mother_dead_country_id = fields.Many2one('res.country', string='Replacement Mother Dead Country', tracking=True)
|
||
replacement_dead_country_id_code = fields.Char(related='replacement_mother_dead_country_id.code')
|
||
replacement_mother_dead_city_id = fields.Many2one('res.country.city', string='Replacement Mother Dead City',domain="[('country_id', '=', replacement_mother_dead_country_id)]")
|
||
replacement_dead_reason_id = fields.Many2one('death.reason.settings', string='Replacement Mother Dead Reason', required=False)
|
||
replacement_dead_reason_id_not_defined = fields.Boolean(related='replacement_dead_reason_id.not_defined')
|
||
replacement_dead_reason = fields.Char(string='Replacement Mother Dead Reason', required=False)
|
||
replacement_dead_res_city_id = fields.Many2one('res.country.city', string='Replacement Mother Dead City',domain="[('country_id', '=', replacement_dead_country_id)]")
|
||
replacement_dead_city = fields.Char(string='Replacement Mother Dead City')
|
||
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_mother_location_conf = fields.Many2one('location.settings',string='Replacement Mother Location',domain="[('location_type','=','mother_location')]")
|
||
replacement_is_mother_work = fields.Boolean('Is Replacement Mother Work?')
|
||
replacement_mother_has_disabilities = fields.Boolean('Has Disabilities?')
|
||
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="Replacement Mother Dead Date")
|
||
replacement_mother_dead_certificate = fields.Many2many('ir.attachment', 'rel_replacement_mother_dead_attachment', 'benefit_id', 'attachment_id', string='Replacement Mother Dead Certificate')
|
||
replacement_mother_status = fields.Selection(string='Replacement Mother Status', related="replacement_mother_family_member_id.member_status")
|
||
replacement_mother_salary_certificate = fields.Many2many('ir.attachment', 'replacement_mother_member_salary_cert_rel',
|
||
'replacement_mother_grant_benefit_id', 'attachment_id',
|
||
string="Salary Certificate")
|
||
# Education_data for replacement mother
|
||
replacement_education_status_ids = fields.One2many('education.status', 'replacement_grant_benefit_id')
|
||
replacement_education_status = fields.Selection(
|
||
string='Education Status',
|
||
selection=[('educated', 'educated'), ('illiterate', 'illiterate')],
|
||
default='illiterate'
|
||
)
|
||
replacement_case_study = fields.Selection(string='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("res.partner", 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("res.partner", 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_educational_certificate = fields.Many2many('ir.attachment','rel_replacement_educational_certificate_attachment','benefit_id','attachment_id',string='Educational Certificate')
|
||
|
||
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.Many2many('ir.attachment','rel_replacement_last_educational__certificate_attachment','benefit_id','attachment_id',string='Last Educational Certificate')
|
||
replacement_weak_study = fields.Many2many('study.material',relation='grant_benefit_replacement_weak_study_rel',string='Weak Study')
|
||
replacement_mother_diseases_attachment_ids = fields.One2many('ir.attachment', 'replacement_mother_grant_benefit_id', string='Diseases Attachments',domain=[('diseases_id', '!=', False)])
|
||
replacement_mother_disabilities_attachment_ids = fields.One2many('ir.attachment', 'replacement_mother_grant_benefit_id',string='Disabilities Attachments',domain=[('disabilities_id', '!=', False)])
|
||
sponsorship_id = fields.Many2one('takaful.sponsorship',string='Sponsorship')
|
||
#check if Account Holder is Family memeber of not
|
||
is_family_member = fields.Boolean(string='Is Family member?' , help="check if Account Holder is Family memeber",default=True)
|
||
family_member_id = fields.Many2one('family.member', string='Account Holder Name', domain="[('id','in',member_ids)]")
|
||
owner_identity_attachment_ids = fields.Many2many('ir.attachment', 'rel_identity_attachment','benefit_id','attachment_id',string='Account holder identity')
|
||
family_approval_attachment_ids = fields.Many2many('ir.attachment', 'rel_approval_attachment','benefit_id','attachment_id',string='Family approval of transfer')
|
||
seasonal_service_id = fields.Many2one('seasonal.service', string="Seasonal Service")
|
||
is_from_portal = fields.Boolean(string='is Created from Portal?', default=False, readonly=True)
|
||
applicant_name = fields.Char(readonly=True)
|
||
doc_count = fields.Integer(compute='_compute_attached_docs_count', string="Number of documents attached")
|
||
action_type = fields.Selection(selection=[
|
||
('new', 'New'),
|
||
('edit_info', 'Edit Information'),
|
||
('approved', 'Approved'),
|
||
('suspended', 'Suspended'),
|
||
('resume_from_temporary', 'Resume from Temporary Suspension'),
|
||
('resume_from_final', 'Resume from Final Suspension'),
|
||
('exception', 'Exception'),
|
||
], string='Action Type', default='new', tracking=True)
|
||
contact_type = fields.Selection([
|
||
('email', 'Email'),
|
||
('sms', 'SMS'),
|
||
], string='Contact Type',default='sms')
|
||
company_id = fields.Many2one('res.company', default=lambda self: self.env.company)
|
||
currency_id = fields.Many2one(
|
||
comodel_name='res.currency',
|
||
string="Company Currency",
|
||
related='company_id.currency_id')
|
||
family_edit = fields.Boolean(string='Family Edit', default=False)
|
||
family_return_reason = fields.Text(string="Family Return Reason")
|
||
last_disbursement_date = fields.Date(string="Last disbursement date", readonly=True)
|
||
total_father_families = fields.Integer(string="Father Families", compute='_compute_total_families')
|
||
total_mother_families = fields.Integer(string="Mother Families", compute='_compute_total_families')
|
||
total_replacement_mother_families = fields.Integer(string="Replacement Mother Families", compute='_compute_total_families')
|
||
final_suspend_date = fields.Date(string="Final Suspend Date")
|
||
resume_reason_id = fields.Many2one('suspend.reason', string='Return Reason')
|
||
resume_date = fields.Date(string="Return Date")
|
||
resume_notes = fields.Text(string="Return Notes")
|
||
rent_contract_ids = fields.One2many('rent.contract', 'family_id',string='Rent Contracts')
|
||
rent_contract_count = fields.Integer(
|
||
string="Number of Rent Contracts",
|
||
compute='_compute_rent_contract_count',
|
||
store=True
|
||
)
|
||
current_rent_contract_id = fields.Many2one('rent.contract',string='Current Active Rent Contract',compute='_compute_current_rent_contract',store=True,)
|
||
notes = fields.Html(string='Notes', tracking=True)
|
||
color = fields.Integer(string="Color Index",related='benefit_category_id.color')
|
||
decoration_color = fields.Selection([
|
||
('danger', 'Red'),
|
||
('success', 'Green'),
|
||
('warning', 'Orange'),
|
||
('info', 'Blue'),
|
||
('primary', 'Primary'),
|
||
('muted', 'Muted'),
|
||
],related='benefit_category_id.decoration_color')
|
||
|
||
_sql_constraints = [
|
||
('unique_code', "unique (code) WHERE state NOT IN ('draft', 'new')", 'This code already exists')
|
||
]
|
||
|
||
@api.depends('rent_contract_ids')
|
||
def _compute_rent_contract_count(self):
|
||
for record in self:
|
||
record.rent_contract_count = len(record.rent_contract_ids)
|
||
|
||
def action_view_all_rent_contracts(self):
|
||
self.ensure_one()
|
||
ctx = self.env.context.copy()
|
||
ctx.update({
|
||
'default_family_id': self.id,
|
||
'default_landlord_type': 'family'
|
||
})
|
||
return {
|
||
'name': _('Rent Contracts - Full Details'),
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'rent.contract',
|
||
'view_mode': 'tree,form',
|
||
'domain': [('family_id', '=', self.id)],
|
||
'context': ctx,
|
||
'target': 'current',
|
||
}
|
||
|
||
@api.depends('rent_contract_ids', 'rent_contract_ids.state', 'rent_contract_ids.start_date')
|
||
def _compute_current_rent_contract(self):
|
||
for family in self:
|
||
if not family.rent_contract_ids:
|
||
family.current_rent_contract_id = False
|
||
continue
|
||
active_contracts = family.rent_contract_ids.filtered(
|
||
lambda c: c.state == 'active' and c.landlord_type == 'family'
|
||
).sorted('start_date', reverse=True)
|
||
|
||
family.current_rent_contract_id = active_contracts[:1] or False
|
||
|
||
@api.depends('member_ids', 'member_ids.member_status', 'add_replacement_mother',
|
||
'replacement_mother_family_member_id', 'replacement_mother_status', 'mother_family_member_id',
|
||
'mother_status','mother_marital_conf','mother_location_conf','mother_income')
|
||
def get_members_count(self):
|
||
for ben in self:
|
||
if ben.id:
|
||
ben.non_member_count = len(ben.member_ids.filtered(lambda x: x.member_status == 'non_benefit'))
|
||
ben.benefit_member_count = len(ben.member_ids.filtered(lambda x: x.member_status == 'benefit'))
|
||
if ben.add_replacement_mother and not ben.replacement_mother_family_member_id and ben.replacement_mother_status == 'benefit':
|
||
ben.benefit_member_count += 1
|
||
|
||
if not ben.mother_family_member_id and ben.mother_status == 'benefit':
|
||
ben.benefit_member_count += 1
|
||
else:
|
||
ben.benefit_member_count = 0.0
|
||
ben.non_member_count = 0.0
|
||
|
||
|
||
@api.depends('current_rent_contract_id')
|
||
def _compute_rent_from_contract(self):
|
||
for family in self:
|
||
contract = family.current_rent_contract_id
|
||
if contract:
|
||
family.contract_num = contract.name
|
||
family.rent_start_date = contract.start_date
|
||
family.rent_end_date = contract.end_date
|
||
family.rent_amount = contract.rent_amount
|
||
family.payment_type = contract.payment_type
|
||
family.rent_attachment = [(6, 0, contract.contract_attachment.ids)]
|
||
#family.electricity_attach = [(6, 0, contract.electricity_bill_attachment.ids)]
|
||
else:
|
||
family.contract_num = False
|
||
family.rent_start_date = False
|
||
family.rent_end_date = False
|
||
family.rent_amount = 0.0
|
||
family.payment_type = False
|
||
family.rent_attachment = [(5, 0, 0)]
|
||
#family.electricity_attach = [(5, 0, 0)]
|
||
|
||
def _sms_get_number_fields(self):
|
||
return ['sms_phone']
|
||
|
||
@api.onchange('family_member_id')
|
||
def _onchange_family_member_id(self):
|
||
for record in self:
|
||
if record.is_family_member and record.family_member_id:
|
||
record.acc_holder_name = record.family_member_id.name
|
||
record.acc_holder_id_number = record.family_member_id.member_id_number
|
||
else:
|
||
record.acc_holder_name = False
|
||
record.acc_holder_id_number = False
|
||
|
||
|
||
@api.depends('is_mother_work','mother_salary_ids','mother_expenses_ids','mother_debits_ids')
|
||
def _compute_mother_net_income(self):
|
||
for rec in self:
|
||
deductions = (
|
||
sum(rec.mother_expenses_ids.filtered('deduct_from_family_income').mapped('amount')) +
|
||
sum(rec.mother_debits_ids.filtered('deduct_from_family_income').mapped('monthly_installment'))
|
||
)
|
||
|
||
mother_income = sum(rec.mother_salary_ids.filtered(lambda e: e.approved and e.is_mother_salary).mapped('salary_amount'))
|
||
|
||
rec.mother_net_income = max(mother_income - deductions, 0.0)
|
||
|
||
def _compute_total_families(self):
|
||
for record in self:
|
||
record.total_father_families = self.search_count([('father_id_number','=',record.father_id_number),('id','!=',record.id)])
|
||
record.total_mother_families = self.search_count([('mother_id_number','=',record.mother_id_number),('id','!=',record.id)])
|
||
record.total_replacement_mother_families = self.search_count([('replacement_mother_id_number','=',record.replacement_mother_id_number),('id','!=',record.id)])
|
||
|
||
def action_open_related_father_families(self):
|
||
self.ensure_one()
|
||
return {
|
||
'name': _("Father Families"),
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'grant.benefit',
|
||
'view_mode': 'tree,form',
|
||
'views': [(self.env.ref(
|
||
'odex_benefit.grant_benefit_tree').id, 'tree'),
|
||
(self.env.ref('odex_benefit.grant_benefit_form').id, 'form')],
|
||
'domain': [('father_id_number','=',self.father_id_number),('id','!=',self.id)],
|
||
'context': {'create': False},
|
||
}
|
||
|
||
def action_open_related_mother_families(self):
|
||
self.ensure_one()
|
||
return {
|
||
'name': _("Mother Families"),
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'grant.benefit',
|
||
'view_mode': 'tree,form',
|
||
'views': [(self.env.ref(
|
||
'odex_benefit.grant_benefit_tree').id, 'tree'),
|
||
(self.env.ref('odex_benefit.grant_benefit_form').id, 'form')],
|
||
'domain': [('mother_id_number','=',self.mother_id_number),('id','!=',self.id)],
|
||
'context': {'create': False},
|
||
}
|
||
|
||
def action_open_related_replacement_mother_families(self):
|
||
self.ensure_one()
|
||
return {
|
||
'name': _("Replacement Mother Families"),
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'grant.benefit',
|
||
'view_mode': 'tree,form',
|
||
'views': [(self.env.ref(
|
||
'odex_benefit.grant_benefit_tree').id, 'tree'),
|
||
(self.env.ref('odex_benefit.grant_benefit_form').id, 'form')],
|
||
'domain': [('replacement_mother_id_number','=',self.replacement_mother_id_number),('id','!=',self.id)],
|
||
'context': {'create': False},
|
||
}
|
||
|
||
def _expand_states(self, states, domain, order):
|
||
return [key for key, val in type(self).state.selection]
|
||
|
||
@api.constrains('short_number')
|
||
def _check_short_number(self):
|
||
pattern = re.compile(r'^[A-Za-z]{4}[0-9]{4}$')
|
||
for record in self:
|
||
if record.short_number and not pattern.match(record.short_number):
|
||
raise ValidationError(_("Short Number must be 4 letters followed by 4 digits (e.g., ABCD1234)."))
|
||
|
||
|
||
@api.constrains('father_name', 'father_second_name', 'father_third_name', 'father_family_name',
|
||
'mother_name', 'mother_second_name', 'mother_third_name', 'mother_family_name',
|
||
'replacement_mother_name','replacement_mother_second_name','replacement_mother_third_name','replacement_mother_family_name')
|
||
def _check_names_alphabetic(self):
|
||
char_fields = {
|
||
'father_name': _('Father First Name'),
|
||
'father_second_name': _('Father Second Name'),
|
||
'father_third_name': _('Father Third Name'),
|
||
'father_family_name': _('Father Family Name'),
|
||
'mother_name': _('Mother Name'),
|
||
'mother_second_name': _('Mother Second Name'),
|
||
'mother_third_name':_('Mother Third Name'),
|
||
'mother_family_name': _('MotherFamily Name'),
|
||
'replacement_mother_name': _('Replacement Mother Name'),
|
||
'replacement_mother_second_name': _('Replacement Mother Second Name'),
|
||
'replacement_mother_third_name': _('Replacement Mother Third Name'),
|
||
'replacement_mother_family_name': _('Replacement Mother Family 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.constrains('active', 'state')
|
||
def _prevent_archive_unless_allowed(self):
|
||
for rec in self:
|
||
if not rec.active and rec.state not in ['refused', 'suspended_second_approve', 'black_list']:
|
||
raise ValidationError(_(
|
||
"You can only archive the family if its status is: Refused, Final Suspension, or Blacklisted."
|
||
))
|
||
|
||
@api.depends('rent_amount','property_type_id','benefit_member_count', 'branch_custom_id.branch_type')
|
||
def _compute_estimated_rent_amount(self):
|
||
for rec in self:
|
||
estimated_rent_amount = 0.0
|
||
rent_line = False
|
||
if rec.property_type_id and rec.property_type_code == 'rent':
|
||
if rec.branch_custom_id.branch_type == 'branches':
|
||
rent_line = self.env['rent.lines'].search(
|
||
[('benefit_count', '=', rec.benefit_member_count)], order="estimated_rent_branches desc",limit=1)
|
||
if rent_line:
|
||
estimated_rent_amount = rent_line.estimated_rent_branches
|
||
else:
|
||
rent_line = self.env['rent.lines'].search(
|
||
[('benefit_count', '=', rec.benefit_member_count)], order="estimated_rent_governorate desc",limit=1)
|
||
if rent_line:
|
||
estimated_rent_amount = rent_line.estimated_rent_governorate
|
||
|
||
if rec.property_type_id.is_shared and rent_line and rent_line.discount_rate_shared_housing:
|
||
discount = rent_line.discount_rate_shared_housing / 100.0
|
||
estimated_rent_amount *= discount
|
||
rec.estimated_rent_amount = estimated_rent_amount / 12.0
|
||
|
||
def assign_sequence_to_all(self):
|
||
sequence = self.env['ir.sequence'].search([('code', '=', 'benefit.sequence')], limit=1)
|
||
if not sequence:
|
||
raise UserError(_("Sequence with code 'benefit.sequence' not found"))
|
||
sequence.sudo().write({'number_next': 1})
|
||
|
||
records = self.search([], order='create_date')
|
||
|
||
for rec in records:
|
||
code = self.env['ir.sequence'].sudo().next_by_code('benefit.sequence')
|
||
rec.with_context(force_website=True).write({'code':code})
|
||
|
||
|
||
def action_set_waiting_if_needed(self):
|
||
records = self.env['grant.benefit'].browse(self._context.get('active_ids', []))
|
||
print("hh")
|
||
|
||
for rec in records:
|
||
if rec.salary_ids:
|
||
for recored in rec.salary_ids:
|
||
if recored.state not in ['accepted', 'refused']:
|
||
recored.state = 'waiting'
|
||
if rec.expenses_ids:
|
||
for recorede in rec.expenses_ids:
|
||
if recorede.state not in ['accepted', 'refused']:
|
||
recorede.state = 'waiting'
|
||
|
||
@api.depends('request_producer')
|
||
def _compute_request_producer_id(self):
|
||
for rec in self:
|
||
rec.request_producer_id = rec.user_id.partner_id if rec.request_producer.id == rec.env.ref('base.public_partner').id else rec.request_producer
|
||
|
||
def validate_attachments(self):
|
||
for rec in self:
|
||
if not rec.owner_identity_attachment_ids and rec.is_family_member == False and rec.state == 'first_approve':
|
||
raise ValidationError(_("Account Holder Identity Attachment is required."))
|
||
if not rec.family_approval_attachment_ids and rec.is_family_member == False and rec.state == 'first_approve':
|
||
raise ValidationError(_("Family approval of transfer Attachment is required."))
|
||
|
||
def _validate_required_attachments(self):
|
||
"""Validate required Many2many attachments"""
|
||
for rec in self:
|
||
if not rec.father_dead_certificate:
|
||
raise ValidationError(_("Father Dead Certificate is required."))
|
||
|
||
if rec.state not in ['draft', 'new', 'complete_info'] and not rec._context.get('bypass_attachments_requirement', False) and not rec.national_address_attachment:
|
||
raise ValidationError(_("National Address Attachment is required."))
|
||
|
||
@api.constrains('father_birth_date', 'father_dead_date', 'mother_birth_date', 'replacement_mother_birth_date')
|
||
def _check_dates(self):
|
||
today = date.today()
|
||
|
||
for rec in self:
|
||
# Check that dates are not in the future
|
||
if rec.father_birth_date and rec.father_birth_date > today:
|
||
raise ValidationError("Father's Birth Date cannot be in the future.")
|
||
|
||
if rec.father_dead_date and rec.father_dead_date > today:
|
||
raise ValidationError("Father's Death Date cannot be in the future.")
|
||
|
||
if rec.mother_birth_date and rec.mother_birth_date > today:
|
||
raise ValidationError("Mother's Birth Date cannot be in the future.")
|
||
|
||
if rec.replacement_mother_birth_date and rec.replacement_mother_birth_date > today:
|
||
raise ValidationError("Replacement Mother's Birth Date cannot be in the future.")
|
||
|
||
# Check that father_dead_date is after father_birth_date
|
||
if (
|
||
rec.father_birth_date
|
||
and rec.father_dead_date
|
||
and rec.father_dead_date < rec.father_birth_date
|
||
):
|
||
raise ValidationError("Father's Death Date must be after the Birth Date.")
|
||
|
||
# @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'
|
||
@api.depends('attachment_ids.datas', 'attachment_ids.is_required', 'attachment_ids.is_default')
|
||
def get_required_attach(self):
|
||
bypass_verify_backend_require_attachs = self._context.get('bypass_verify_backend_require_attachs', False)
|
||
for record in self:
|
||
required_missing = False
|
||
for att in record.attachment_ids:
|
||
if (not bypass_verify_backend_require_attachs or att.show_in_portal) and att.is_required and not att.datas:
|
||
required_missing = True
|
||
break
|
||
if required_missing:
|
||
record.required_attach = 'false'
|
||
else:
|
||
record.required_attach = 'true'
|
||
|
||
def get_attached_domain(self):
|
||
self.ensure_one()
|
||
visit_location = self.env['visit.location'].search([('benefit_id', '=', self.id)]).ids
|
||
service_requests = self.env['service.request'].search([('family_id', '=', self.id)]).ids
|
||
family_complaints = self.env['family.complaints'].search([('family_id', '=', self.id)]).ids
|
||
hobby_ids = self.member_ids.mapped('hobbies_ids').ids
|
||
member_education_status_ids = self.member_ids.mapped('member_education_status_ids').ids
|
||
diseases_ids = self.member_ids.mapped('diseases_ids').ids
|
||
disabilities_ids = self.member_ids.mapped('disabilities_ids').ids
|
||
return ['|', '|', '|','|','|','|','|','|','|','|','|','|','|',
|
||
'&', ('res_model', '=', 'grant.benefit'),
|
||
('res_id', 'in', self.ids),
|
||
('benefit_id', 'in', self.ids),
|
||
'&', ('res_model', '=', 'visit.location'),
|
||
('res_id', 'in', visit_location),
|
||
'&', ('res_model', '=', 'service.request'),
|
||
('res_id', 'in', service_requests),
|
||
'&', ('res_model', '=', 'family.complaints'),
|
||
('res_id', 'in', family_complaints),
|
||
'&', ('res_model', '=', 'education.status'),
|
||
('res_id', 'in', self.mother_education_status_ids.ids),
|
||
'&', ('res_model', '=', 'family.debits'),
|
||
('res_id', 'in', (self.family_debits_ids + self.mother_debits_ids).ids),
|
||
'&', ('res_model', '=', 'salary.line'),
|
||
('res_id', 'in', self.salary_ids.ids),
|
||
'&', ('res_model', '=', 'family.member'),
|
||
('res_id', 'in', self.member_ids.ids),
|
||
('member_id', 'in', self.member_ids.ids),
|
||
'&', ('res_model', '=', 'member.hobbies'),
|
||
('res_id', 'in', hobby_ids),
|
||
'&', ('res_model', '=', 'education.status'),
|
||
('res_id', 'in', member_education_status_ids),
|
||
'&', ('res_model', '=', 'member.diseases'),
|
||
('res_id', 'in', diseases_ids),
|
||
'&', ('res_model', '=', 'member.disabilities'),
|
||
('res_id', 'in', disabilities_ids),
|
||
]
|
||
def _compute_attached_docs_count(self):
|
||
Attachment = self.env['ir.attachment']
|
||
for benefit in self:
|
||
benefit.doc_count = Attachment.search_count(benefit.get_attached_domain())
|
||
|
||
def view_attachments(self):
|
||
action = self.env['ir.actions.act_window']._for_xml_id('base.action_attachment')
|
||
action['domain'] = str(self.get_attached_domain())
|
||
action['context'] = {'create': False}
|
||
return action
|
||
|
||
@api.depends('salary_ids')
|
||
def get_income_required_attach(self):
|
||
for rec in self.salary_ids:
|
||
if rec.is_required and not rec.salary_attach:
|
||
self.income_required_attach = None
|
||
break
|
||
elif rec.is_required and rec.salary_attach:
|
||
self.income_required_attach = 'true'
|
||
elif rec.is_default and not rec.is_required and (rec.salary_attach or not rec.salary_attach):
|
||
self.income_required_attach = 'true'
|
||
else:
|
||
self.income_required_attach = 'true'
|
||
|
||
def _get_invoices_count(self):
|
||
for rec in self:
|
||
rec.invoices_count = self.env['account.move'].search_count([
|
||
('benefit_family_ids', 'in', [rec.id]),('move_type','=','in_invoice')
|
||
])
|
||
|
||
|
||
def _get_total_move_lines(self):
|
||
for rec in self:
|
||
move_lines = self.env['account.move.line'].search([('benefit_family_id', '=', rec.id),('family_confirm_id','!=', False)])
|
||
rec.total_move_lines = sum(move_lines.mapped('debit')) - sum(move_lines.mapped('credit'))
|
||
|
||
def _compute_visit_location_count(self):
|
||
for rec in self:
|
||
rec.with_context(bypass_attachments_requirement=True).write({
|
||
'visit_location_count': self.env['visit.location'].search_count([('benefit_id', '=', rec.id)]),
|
||
})
|
||
|
||
def action_view_benefit_members(self):
|
||
self.ensure_one()
|
||
return {
|
||
'type': 'ir.actions.act_window',
|
||
'name': _('Benefit Members'),
|
||
'res_model': 'family.member',
|
||
'view_mode': 'tree,form',
|
||
'domain': [('id', 'in', self.member_ids.filtered(lambda m: m.member_status == 'benefit').ids)],
|
||
'target': 'current',
|
||
}
|
||
|
||
def action_view_non_benefit_members(self):
|
||
self.ensure_one()
|
||
action = {
|
||
'type': 'ir.actions.act_window',
|
||
'name': _('Non Benefit Members'),
|
||
'res_model': 'family.member',
|
||
'view_mode': 'tree,form',
|
||
'domain': [('id', 'in', self.member_ids.filtered(lambda m: m.member_status == 'non_benefit').ids)],
|
||
'target': 'current',
|
||
}
|
||
return action
|
||
|
||
def action_open_related_move_line_records(self):
|
||
""" Opens a tree view with related records filtered by a dynamic domain """
|
||
move_lines = self.env['account.move.line'].search([
|
||
('benefit_family_id', '=', self.id),('family_confirm_id','!=', False)
|
||
]).ids
|
||
|
||
action = {
|
||
'type': 'ir.actions.act_window',
|
||
'name': 'Move Lines',
|
||
'res_model': 'account.move.line',
|
||
'view_mode': 'tree,form',
|
||
'domain': [('id', 'in', move_lines)],
|
||
'target': 'current',
|
||
}
|
||
return action
|
||
|
||
def action_open_visit_location(self):
|
||
""" Opens a tree view with related records filtered by a dynamic domain """
|
||
visit_location = self.env['visit.location'].search([('benefit_id', '=', self.id)]).ids
|
||
action = {
|
||
'type': 'ir.actions.act_window',
|
||
'name': _('Visit Location'),
|
||
'res_model': 'visit.location',
|
||
'view_mode': 'tree,form',
|
||
'domain': [('id', 'in', visit_location)],
|
||
'target': 'current',
|
||
}
|
||
return action
|
||
|
||
def _get_total_service_requests(self):
|
||
for rec in self:
|
||
rec.total_service_requests = self.env['service.request'].search_count([('family_id', '=', rec.id),('is_seasonal','=',False)])
|
||
|
||
def action_open_related_service_requests(self):
|
||
""" Opens a tree view with related records filtered by a dynamic domain """
|
||
service_requests = self.env['service.request'].search([('family_id', '=', self.id),('is_seasonal','=',False)]).ids
|
||
|
||
action = {
|
||
'type': 'ir.actions.act_window',
|
||
'name': _('Service Requests'),
|
||
'res_model': 'service.request',
|
||
'view_mode': 'tree,form',
|
||
'domain': [('id', 'in', service_requests)],
|
||
'target': 'current',
|
||
}
|
||
return action
|
||
|
||
def _get_total_seasonal_service_requests(self):
|
||
for rec in self:
|
||
rec.total_seasonal_service_requests = len(self.env['service.request'].search([('family_id', '=', self.id), ('is_seasonal', '=', True)]))
|
||
|
||
def action_open_related_seasonal_service_requests(self):
|
||
""" Opens a tree view with related records filtered by a dynamic domain """
|
||
seasonal_service_requests = self.env['service.request'].search([('family_id', '=', self.id), ('is_seasonal', '=', True)]).ids
|
||
|
||
action = {
|
||
'type': 'ir.actions.act_window',
|
||
'name': _('Seasonal Service Requests'),
|
||
'res_model': 'service.request',
|
||
'view_mode': 'tree,form',
|
||
'domain': [('id', 'in', seasonal_service_requests)],
|
||
'target': 'current',
|
||
}
|
||
return action
|
||
|
||
def action_open_related_invoice_records(self):
|
||
""" Opens a tree view with related records filtered by a dynamic domain """
|
||
invoices = self.env['account.move'].search([
|
||
('benefit_family_ids', 'in', [self.id]),('move_type','=','in_invoice')
|
||
]).ids
|
||
action = {
|
||
'type': 'ir.actions.act_window',
|
||
'name': 'Invoices',
|
||
'res_model': 'account.move',
|
||
'view_mode': 'tree,form',
|
||
'domain': [('id', 'in', invoices)],
|
||
'target': 'current',
|
||
}
|
||
return action
|
||
|
||
def _get_family_monthly_values(self):
|
||
validation_setting = self.env["family.validation.setting"].search([], limit=1)
|
||
for rec in self:
|
||
if rec.benefit_category_id.id in validation_setting.benefit_category_ids.ids:
|
||
total_family_members = rec.benefit_member_count
|
||
rec.family_monthly_income = total_family_members * validation_setting.cash_expense
|
||
rec.family_monthly_meals = total_family_members * validation_setting.meal_expense
|
||
rec.family_monthly_clotting = total_family_members * validation_setting.clothing_expense
|
||
rec.total_family_expenses = rec.family_monthly_income + rec.family_monthly_meals + rec.family_monthly_clotting
|
||
else:
|
||
rec.family_monthly_income = 0
|
||
rec.family_monthly_meals = 0
|
||
rec.family_monthly_clotting = 0
|
||
rec.total_family_expenses = 0
|
||
|
||
def get_html(self):
|
||
for rec in self:
|
||
print(f'<iframe id="custom_src" height="500" width="500" src="{rec.url}"></iframe>')
|
||
rec.url_html = f'<iframe id="custom_src" height="500" width="500" src="{rec.url}"/>'
|
||
|
||
# @api.multi
|
||
def open_map(self):
|
||
for Location in self:
|
||
url = "http://maps.google.com/maps?oi=map&q="
|
||
if Location.street:
|
||
url += Location.street.replace(' ', ',')
|
||
if Location.city_id:
|
||
url += '+' + Location.district_id.name.replace(' ', ',')
|
||
# url += '+' + Location.city_id.name.replace(' ', ',')
|
||
url += '+' + Location.city_id.state_id.name.replace(' ', '')
|
||
url += '+' + Location.zip.replace(' ', ',')
|
||
url += '+' + Location.city_id.country_id.name.replace(' ', ',')
|
||
if Location.nearby_mosque:
|
||
url += Location.nearby_mosque.replace(' ', ',')
|
||
return {
|
||
'type': 'ir.actions.act_url',
|
||
'target': 'new',
|
||
'url': url
|
||
}
|
||
|
||
@api.onchange('url')
|
||
def onchange_image_url(self):
|
||
if self.image_url:
|
||
self.img_attach = '<img id="img" src="%s"/>' % self.url
|
||
|
||
def get_researchers_email(self):
|
||
email_ids = ''
|
||
for rec in self.researcher_id.employee_id:
|
||
if email_ids:
|
||
email_ids = email_ids + ',' + str(rec.work_email)
|
||
else:
|
||
email_ids = str(rec.work_email)
|
||
return email_ids
|
||
|
||
@api.depends('room_ids')
|
||
def get_rooms_total(self):
|
||
for rec in self:
|
||
if rec.id:
|
||
rooms = rec.env['benefit.housing.rooms'].sudo().search([('housing_id', '=', rec.id)])
|
||
rec.rooms_number = len(rooms)
|
||
|
||
@api.onchange('room_ids')
|
||
def onchange_room_ids(self):
|
||
res = {}
|
||
items_ids = []
|
||
for record in self:
|
||
items_ids.append(record.id)
|
||
res['domain'] = {'items': [('room_id', 'in', items_ids)]}
|
||
return res
|
||
|
||
@api.onchange('branch_family_id')
|
||
def _onchange_branch_family_id(self):
|
||
if self.branch_family_id:
|
||
branch = self.branch_family_id
|
||
if branch.has_employees:
|
||
chosen_branch = branch
|
||
else:
|
||
chosen_branch = branch.replacement_branch_id
|
||
|
||
self.branch_custom_id = chosen_branch
|
||
else:
|
||
self.branch_custom_id = False
|
||
|
||
@api.onchange("father_country_id", 'mother_country_id')
|
||
def onchange_father_mother_country_id(self):
|
||
res = {}
|
||
for rec in self:
|
||
if rec.father_country_id and rec.mother_country_id:
|
||
if rec.mother_country_id.code != 'SA' and rec.father_country_id.code != 'SA' and not rec.mother_country_id.is_excluded and not rec.father_country_id.is_excluded :
|
||
rec.mother_country_id = False
|
||
res['warning'] = {'title': _('ValidationError'),
|
||
'message': _('Non-Saudi mothers and fathers cannot register')}
|
||
return res
|
||
|
||
@api.constrains('acc_holder_id_number')
|
||
def _check_acc_holder_id_number(self):
|
||
for record in self:
|
||
id_number = record.acc_holder_id_number
|
||
if id_number:
|
||
if not re.match(r'^\d{10}$', id_number):
|
||
raise ValidationError(_("Account Holder ID Number must contain exactly 10 digits."))
|
||
|
||
@api.constrains('father_id_number', 'mother_id_number', 'replacement_mother_id_number')
|
||
def _onchange_id_numbers(self):
|
||
id_numbers = {
|
||
'رقم هوية الأب': self.father_id_number,
|
||
'رقم هوية الأم': self.mother_id_number,
|
||
'رقم هوية الأم البديلة': self.replacement_mother_id_number,
|
||
}
|
||
|
||
# Check each ID number for 10-digit format and uniqueness within the parent model
|
||
unique_ids = set()
|
||
for label, id_number in id_numbers.items():
|
||
if id_number == 'NULL' and label == 'رقم هوية الأم':
|
||
continue
|
||
if id_number:
|
||
if not re.match(r'^\d{10}$', id_number):
|
||
raise ValidationError(_("%s must contain exactly 10 digits.")%label)
|
||
if id_number in unique_ids:
|
||
raise ValidationError(_("%s must be unique within the same record.") % label)
|
||
if id_number.startswith('1') and label == 'رقم هوية الأب':
|
||
self.father_country_id = self.env["res.country"].search([('code','=','SA')],limit=1).id
|
||
self.father_id_number_type = 'citizen'
|
||
if id_number.startswith('1') and label == 'رقم هوية الأم':
|
||
self.mother_country_id = self.env["res.country"].search([('code','=','SA')],limit=1).id
|
||
self.mother_id_number_type = 'citizen'
|
||
if id_number.startswith('1') and label == 'رقم هوية الأم البديلة':
|
||
self.replacement_mother_country_id = self.env["res.country"].search([('code','=','SA')],limit=1).id
|
||
self.replacement_mother_id_number_type = 'citizen'
|
||
unique_ids.add(id_number)
|
||
|
||
# Check for uniqueness against `member_id_number` in child records and across database records
|
||
for member in self.member_ids:
|
||
if member.member_id_number == 'NULL':
|
||
continue
|
||
if member.member_id_number and member.member_id_number in unique_ids and member.id not in [self.mother_family_member_id.id,self.replacement_mother_family_member_id.id]:
|
||
raise ValidationError(_("The ID number %s in the Family Members list must be unique across the record.")%member.member_id_number)
|
||
for id_number in unique_ids:
|
||
if id_number == 'NULL':
|
||
continue
|
||
if id_number == self.father_id_number:
|
||
conflict = self.env['grant.benefit'].search([
|
||
('id', '!=', self._origin.id),
|
||
'|',
|
||
('mother_id_number', '=', id_number),
|
||
('replacement_mother_id_number', '=', id_number),
|
||
], limit=1)
|
||
if conflict:
|
||
raise ValidationError(
|
||
_("Father ID %s is already used in another family (as non-father) with code %s.") %
|
||
(id_number, conflict.code))
|
||
elif id_number == self.mother_id_number:
|
||
conflict = self.env['grant.benefit'].search([
|
||
('id', '!=', self._origin.id),
|
||
'|',
|
||
('father_id_number', '=', id_number),
|
||
('replacement_mother_id_number', '=', id_number),
|
||
], limit=1)
|
||
if conflict:
|
||
raise ValidationError(
|
||
_("Mother ID %s is already used in another family with code %s.") %
|
||
(id_number, conflict.code))
|
||
continue
|
||
elif id_number == self.replacement_mother_id_number:
|
||
conflict = self.env['grant.benefit'].search([
|
||
('id', '!=', self.id),
|
||
'|',
|
||
('father_id_number', '=', id_number),
|
||
('mother_id_number', '=', id_number),
|
||
], limit=1)
|
||
if conflict:
|
||
raise ValidationError(
|
||
_("Replacement Mother ID %s is already used in another family (as non-replacement) with code %s.") %
|
||
(id_number, conflict.code)
|
||
)
|
||
duplicate_record_members = self.env['family.member'].search([('member_id_number', '=', id_number)])
|
||
for member in duplicate_record_members:
|
||
if member.relationn and member.relationn.relation_type in ['mother', 'replacement_mother']:
|
||
continue
|
||
if member.benefit_id.id != self.id:
|
||
raise ValidationError(
|
||
_("The ID number %s already exists in family with code %s. Please enter a unique ID number.") %
|
||
(id_number, member.benefit_id.code)
|
||
)
|
||
|
||
@api.onchange("family_bank")
|
||
def onchange_family_bank(self):
|
||
for rec in self:
|
||
if rec.family_bank:
|
||
exist = self.search([('family_bank', '=', rec.family_bank.id)])
|
||
if exist:
|
||
raise ValidationError(
|
||
_('The Family Bank Already Exist!'))
|
||
|
||
@api.model
|
||
def _geo_localize(self, street='', zip='', city='', state='', country=''):
|
||
geo_obj = self.env['base.geocoder']
|
||
search = geo_obj.geo_query_address(
|
||
street=street, zip=zip, city=city, state=state, country=country
|
||
)
|
||
result = geo_obj.geo_find(search, force_country=country)
|
||
if result is None:
|
||
search = geo_obj.geo_query_address(
|
||
city=city, state=state, country=country
|
||
)
|
||
result = geo_obj.geo_find(search, force_country=country)
|
||
return result, search
|
||
|
||
def geo_localize(self):
|
||
for location in self.with_context(lang='en_US'):
|
||
result = self._geo_localize(
|
||
street=location.street,
|
||
zip=location.zip,
|
||
city=location.city_id.name,
|
||
state=location.state_id.name,
|
||
country=location.country_id.name,
|
||
)
|
||
if result:
|
||
location.write(
|
||
{
|
||
'lat': result[0][0],
|
||
'lon': result[0][1],
|
||
}
|
||
)
|
||
return True
|
||
|
||
def get_location_on_map(self):
|
||
for location in self.with_context(lang='en_US'):
|
||
url = "http://maps.google.com/maps/search/?api=1&query=%s,%s" % (location.lat, location.lon),
|
||
return {
|
||
'type': 'ir.actions.act_url',
|
||
'target': 'new',
|
||
'url': url
|
||
}
|
||
|
||
def check_mother_status(self):
|
||
validation_setting = self.env["family.validation.setting"].search([], limit=1)
|
||
mini_income_for_mother = validation_setting.mini_income_for_mother
|
||
max_income_for_mother = validation_setting.max_income_for_mother
|
||
for rec in self:
|
||
reasons = []
|
||
status = 'benefit'
|
||
if rec.mother_location_conf and rec.mother_marital_conf:
|
||
if not rec.mother_location_conf.is_benefit or not rec.mother_marital_conf.is_benefit or rec.state in ['suspended_second_approve','refused']:
|
||
reasons.append(_("The mother's marital or location conditions are not eligible."))
|
||
status = 'non_benefit'
|
||
elif rec.mother_marital_conf.is_benefit :
|
||
if rec.is_mother_work and rec.mother_country_id.code == 'SA' or (
|
||
rec.mother_country_id.code != 'SA' and rec.father_country_id.code == 'SA'):
|
||
if mini_income_for_mother < rec.mother_net_income <= max_income_for_mother:
|
||
reasons.append(_("The mother's income is between minimum and maximum thresholds."))
|
||
status = 'non_benefit'
|
||
elif rec.mother_net_income <= mini_income_for_mother:
|
||
status = 'benefit'
|
||
elif rec.mother_net_income > max_income_for_mother:
|
||
status = 'benefit'
|
||
elif not rec.is_mother_work and rec.mother_country_id.code == 'SA' or (
|
||
rec.mother_country_id.code != 'SA' and rec.father_country_id.code == 'SA'):
|
||
status = 'benefit'
|
||
return status, reasons
|
||
|
||
def check_replacement_mother_status(self):
|
||
for rec in self:
|
||
reasons = []
|
||
status = 'benefit'
|
||
if not rec.add_replacement_mother:
|
||
continue
|
||
if rec.state in ['suspended_second_approve', 'refused']:
|
||
status = 'non_benefit'
|
||
reasons.append(_("Family is suspended or refused."))
|
||
return status, reasons
|
||
|
||
if not rec.replacement_mother_marital_conf or not rec.replacement_mother_location_conf:
|
||
status = 'non_benefit'
|
||
reasons.append(_("Replacement mother marital or location information is missing."))
|
||
return status, reasons
|
||
|
||
if not rec.replacement_mother_marital_conf.replacement_mother_is_benefit:
|
||
status = 'non_benefit'
|
||
reasons.append(_("The replacement mother's marital status is not eligible for benefits."))
|
||
|
||
if not rec.replacement_mother_location_conf.replacement_mother_is_benefit:
|
||
status = 'non_benefit'
|
||
reasons.append(_("The replacement mother's location is not eligible for benefits."))
|
||
return status, reasons
|
||
|
||
def delete_from_db(self):
|
||
find_id = self.env['benefit.housing'].search([])
|
||
for r in find_id:
|
||
r.unlink()
|
||
|
||
@api.model
|
||
def default_get(self, fields):
|
||
res = super(GrantBenefitProfile, 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 = []
|
||
income_attachments_data = []
|
||
for attach in default_attachment:
|
||
if attach.attach_type == 'family_attach':
|
||
default_attachments_data.append((0, 0, {
|
||
'name': attach.name,
|
||
'is_required': attach.is_required,
|
||
'is_default': attach.is_default,
|
||
'show_in_portal': attach.show_in_portal
|
||
}))
|
||
if attach.attach_type == 'income_attach':
|
||
income_attachments_data.append((0, 0, {
|
||
'income_type': 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
|
||
if 'salary_ids' in fields:
|
||
res['salary_ids'] = income_attachments_data
|
||
return res
|
||
|
||
def write(self, vals):
|
||
res = super(GrantBenefitProfile, self).write(vals)
|
||
if "name" in vals and self.user_id:
|
||
self.user_id.sudo().write({"name": vals.get("name")})
|
||
if any(field in vals for field in ["name", "first_name", "second_name", "middle_name", "family_name",
|
||
"father_name", "father_second_name", "father_third_name",
|
||
"father_family_name"]):
|
||
for record in self:
|
||
for member in record.member_ids:
|
||
member.get_partner_name()
|
||
# record.partner_id.get_partner_name() # Force recomputation of name
|
||
if record.user_id:
|
||
record.sudo().user_id.write({"name": record.partner_id.name})
|
||
if 'active' in vals:
|
||
for rec in self:
|
||
rec.member_ids.write({'active': vals['active']})
|
||
#if not self.env.context.get('force_website', False) and not self.env.context.get('bypass_attachments_requirement', False):
|
||
# self._validate_required_attachments()
|
||
|
||
# Handle mother update/create
|
||
mother_fields = [
|
||
'mother_name', 'mother_second_name', 'mother_third_name', 'mother_family_name', 'mother_id_number',
|
||
'mother_birth_date', 'mother_marital_conf', 'mother_location_conf', 'is_mother_work',
|
||
'mother_net_income', 'mother_age','education_status','mother_diseases_attachment_ids',
|
||
'mother_education_status_ids','mother_disabilities_attachment_ids'
|
||
]
|
||
if any(field in vals for field in mother_fields):
|
||
for rec in self:
|
||
#rec.calculate_income(rec.mother_net_income, rec.mother_status, rec.salary_ids)
|
||
rec.add_or_replace_mother_as_member()
|
||
|
||
# Handle replacement mother update/create
|
||
replacement_fields = [
|
||
'replacement_mother_name', 'replacement_mother_second_name', 'replacement_mother_third_name',
|
||
'replacement_mother_family_name','replacement_mother_id_number',
|
||
'replacement_mother_birth_date', 'replacement_mother_marital_conf',
|
||
'replacement_mother_location_conf','replacement_mother_relation',
|
||
'replacement_is_mother_work', 'replacement_mother_income', 'replacement_education_status',
|
||
'replacement_mother_age','replacement_mother_disabilities_attachment_ids',
|
||
'replacement_education_status_ids', 'replacement_mother_diseases_attachment_ids'
|
||
]
|
||
if any(field in vals for field in replacement_fields):
|
||
for rec in self:
|
||
if rec.add_replacement_mother:
|
||
#rec.calculate_income(rec.replacement_mother_income, rec.replacement_mother_status, rec.salary_ids)
|
||
rec.add_or_replace_replacement_mother_as_member()
|
||
return res
|
||
|
||
@api.model
|
||
def create(self, vals):
|
||
res = super(GrantBenefitProfile, self).create(vals)
|
||
if "applicant_name" not in vals:
|
||
res.applicant_name = self.env.user.display_name
|
||
if "name" in vals and res.user_id:
|
||
res.user_id.sudo().write({"name": vals.get("name")})
|
||
if res.user_id:
|
||
res.sudo().user_id.write({"name": res.name})
|
||
#if not self.env.context.get('force_website', False):
|
||
##res._validate_required_attachments()
|
||
if not res.code or res.code == _('New'):
|
||
res.code = self.env['ir.sequence'].sudo().next_by_code('benefit.sequence') or _('New')
|
||
# Add mother
|
||
if res.mother_id_number:
|
||
#res.calculate_income(res.mother_net_income, res.mother_status, res.salary_ids)
|
||
res.add_or_replace_mother_as_member()
|
||
# Add replacement mother
|
||
if res.add_replacement_mother and res.replacement_mother_id_number:
|
||
#res.calculate_income(res.replacement_mother_income, res.replacement_mother_status, res.salary_ids)
|
||
res.add_or_replace_replacement_mother_as_member()
|
||
return res
|
||
|
||
def unlink(self):
|
||
users_to_delete = self.env['res.users']
|
||
skip_user = self.env.context.get('skip_user_unlink')
|
||
force_unlink = self.env.context.get('force_unlink', False)
|
||
|
||
for record in self:
|
||
if not force_unlink and record.state not in ['draft']:
|
||
raise UserError(_('You cannot delete this record'))
|
||
|
||
self.env['ir.attachment'].search([('benefit_id', '=', record.id)]).unlink()
|
||
if record.member_ids:
|
||
record.member_ids.unlink()
|
||
|
||
if not skip_user and record.user_id:
|
||
other_benefits = self.env['grant.benefit'].search([
|
||
('user_id', '=', record.user_id.id),
|
||
('id', '!=', record.id)
|
||
])
|
||
if other_benefits:
|
||
raise UserError(
|
||
_("Cannot delete user '%s': still linked to other benefit profiles.")
|
||
% record.user_id.name
|
||
)
|
||
users_to_delete |= record.user_id
|
||
|
||
res = super().unlink()
|
||
|
||
if not skip_user:
|
||
users_to_delete.unlink()
|
||
|
||
return res
|
||
|
||
def copy(self, default=None):
|
||
"""Override the copy method to prevent duplicating the record."""
|
||
raise UserError(_('You cannot Duplicate this record'))
|
||
|
||
def complete_data(self):
|
||
message = self.create_message('complete_info')
|
||
self.partner_id.send_sms_notification(message, self.phone)
|
||
ctx = dict(self.env.context or {})
|
||
ctx['create_visit'] = True
|
||
return {
|
||
'name': _('Rerearcher Wizard'),
|
||
'view_mode': 'form',
|
||
'view_type': 'form',
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'researcher.family.wizard',
|
||
'view_id': self.env.ref('odex_benefit.view_resarcher_family_wizard_form').id,
|
||
'target': 'new',
|
||
'context': ctx,
|
||
}
|
||
|
||
def action_assign_specialist_mass(self):
|
||
ctx = dict(self.env.context or {})
|
||
return {
|
||
'name': _('Rerearcher Wizard'),
|
||
'view_mode': 'form',
|
||
'view_type': 'form',
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'researcher.family.wizard',
|
||
'view_id': self.env.ref('odex_benefit.view_assigned_researcher_family_wizard_form').id,
|
||
'target': 'new',
|
||
'context': ctx,
|
||
}
|
||
|
||
def finish_complete_data(self):
|
||
message = self.create_message('waiting_approve')
|
||
self.partner_id.send_sms_notification(message, self.phone)
|
||
for rec in self:
|
||
visits = self.env['visit.location'].search([('benefit_id', '=', rec.id),('state', 'not in', ['close', 'done'])])
|
||
if not rec.benefit_category_id.is_benefit:
|
||
raise ValidationError(_("The procedure cannot be continued; the family is not a beneficiary."))
|
||
if rec.action_type == 'new' and visits:
|
||
raise ValidationError(_("Please complete your pending visits before proceeding."))
|
||
rec.validate_attachments()
|
||
self.state = 'waiting_approve'
|
||
|
||
def action_first_accepted(self):
|
||
"""Accept registration"""
|
||
for rec in self:
|
||
rec.state = "first_approve"
|
||
|
||
def action_second_accepted(self):
|
||
"""Accept registration"""
|
||
for rec in self:
|
||
messages = []
|
||
if rec.total_family_expenses:
|
||
if not rec.acc_number:
|
||
messages.append(_("Account Number is required."))
|
||
if not rec.bank_id:
|
||
messages.append(_("Bank is required."))
|
||
if rec.is_family_member and not rec.family_member_id:
|
||
messages.append(_("Family Member must be selected."))
|
||
if not rec.is_family_member and not rec.owner_identity_attachment_ids:
|
||
messages.append(_("Owner Identity Attachment is required."))
|
||
if not rec.is_family_member and not rec.family_approval_attachment_ids:
|
||
messages.append(_("Family Approval Attachment is required."))
|
||
if not rec.acc_holder_name:
|
||
messages.append(_("Account Holder Name is required."))
|
||
if not rec.acc_holder_id_number:
|
||
messages.append(_("Account Holder ID Number is required."))
|
||
|
||
if messages:
|
||
raise UserError("\n".join(messages))
|
||
|
||
#if not rec.user_id:
|
||
# self.sudo().create_user()
|
||
|
||
if rec.user_id:
|
||
rec.user_id.sudo().write({
|
||
'groups_id': [(3, self.env.ref('base.group_user', False).id)],
|
||
})
|
||
# rec.user_id.sudo().write({
|
||
# 'groups_id': [(4, self.env.ref('odex_benefit.group_benefit_user', False).id)],
|
||
# })
|
||
rec.user_id.sudo().write({
|
||
'groups_id': [(4, self.env.ref('base.group_portal', False).id)],
|
||
})
|
||
if rec.action_type == 'new':
|
||
rec.approve_date = datetime.now()
|
||
self.sudo().send_approval_benefit_email()
|
||
partner_ids = []
|
||
for id in self.message_follower_ids.ids:
|
||
partner_ids.append(self.env['mail.followers'].search([('id', '=', id)]).partner_id)
|
||
self.state = "second_approve"
|
||
self.action_type = "approved"
|
||
#self.sudo()._send_notification(partner_ids, rec.state)
|
||
# for member in self.member_ids:
|
||
# member.create_member_partner()
|
||
|
||
# @api.multi
|
||
def action_first_refusal(self):
|
||
"""First refusal to entity registration"""
|
||
domain = []
|
||
context = {}
|
||
context = dict(self.env.context or {})
|
||
context['state'] = "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_set_to_draft(self):
|
||
context = dict(self.env.context or {})
|
||
context['target_state'] = "draft"
|
||
context['active_id'] = self.id
|
||
return {
|
||
'name': _('Return Reason Wizard'),
|
||
'view_mode': 'form',
|
||
'view_type': 'form',
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'entity.return.reason.wizard',
|
||
'view_id': self.env.ref('odex_benefit.view_entity_return_reason_wizard_form').id,
|
||
'target': 'new',
|
||
'context': context,
|
||
}
|
||
|
||
def action_set_to_new(self):
|
||
context = dict(self.env.context or {})
|
||
context['target_state'] = "complete_info"
|
||
context['active_id'] = self.id
|
||
return {
|
||
'name': _('Return Reason Wizard'),
|
||
'view_mode': 'form',
|
||
'view_type': 'form',
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'entity.return.reason.wizard',
|
||
'view_id': self.env.ref('odex_benefit.view_entity_return_reason_wizard_form').id,
|
||
'target': 'new',
|
||
'context': context,
|
||
}
|
||
|
||
def action_set_waiting_approve(self):
|
||
context = dict(self.env.context or {})
|
||
context['target_state'] = "waiting_approve"
|
||
context['active_id'] = self.id
|
||
return {
|
||
'name': _('Return Reason Wizard'),
|
||
'view_mode': 'form',
|
||
'view_type': 'form',
|
||
'type': 'ir.actions.act_window',
|
||
'res_model': 'entity.return.reason.wizard',
|
||
'view_id': self.env.ref('odex_benefit.view_entity_return_reason_wizard_form').id,
|
||
'target': 'new',
|
||
'context': context,
|
||
}
|
||
|
||
|
||
# @api.multi
|
||
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,
|
||
}
|
||
|
||
# @api.multi
|
||
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,
|
||
}
|
||
|
||
# @api.multi
|
||
def action_edit_info(self):
|
||
#user = self.user_id
|
||
#if not user:
|
||
# user = self.env['res.users'].sudo().search(
|
||
# [('partner_id', '=', self.partner_id.id), ('active', '=', False)])
|
||
# if user:
|
||
# user.write({'active': True})
|
||
# else:
|
||
# user = self.create_user()
|
||
#group_e = self.env.ref('odex_benefit.group_benefit_edit', False)
|
||
try:
|
||
#group_e.sudo().write({'users': [(4, user.id)]})
|
||
self.old_stage = self.state
|
||
template = self.env.ref('odex_benefit.edit_benefit_email', False)
|
||
except:
|
||
pass
|
||
self.state = 'complete_info'
|
||
self.action_type = 'edit_info'
|
||
|
||
def action_suspend(self):
|
||
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_reason_wizard_form').id,
|
||
'target': 'new',
|
||
}
|
||
|
||
def action_resume_family(self):
|
||
ctx = dict(self.env.context or {})
|
||
ctx['resume_family'] = True
|
||
return {
|
||
'name': _('Resume 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_resume_reason_wizard_form').id,
|
||
'target': 'new',
|
||
'context': ctx,
|
||
}
|
||
|
||
def action_suspend_first_accept(self):
|
||
for rec in self:
|
||
rec.state = 'first_approve'
|
||
|
||
def action_resume_first_accept(self):
|
||
for rec in self:
|
||
rec.state = 'first_approve'
|
||
|
||
def action_suspend_second_accept(self):
|
||
for rec in self:
|
||
rec.action_type = 'suspended'
|
||
if rec.suspend_reason.need_service_manager_approval:
|
||
rec.state = 'family_services_manager'
|
||
elif rec.suspend_reason.suspend_type == 'temporarily_suspend':
|
||
rec.state = 'temporary_suspended'
|
||
else:
|
||
rec.state = 'suspended_second_approve'
|
||
|
||
def action_resume_second_accept(self):
|
||
for rec in self:
|
||
if rec.suspend_reason.need_service_manager_approval:
|
||
rec.state = 'family_services_manager'
|
||
else:
|
||
rec.state = 'second_approve'
|
||
rec.action_type = 'approved'
|
||
|
||
def action_suspend_third_accept(self):
|
||
for rec in self:
|
||
if rec.suspend_reason.suspend_type == 'temporarily_suspend':
|
||
rec.state = 'temporary_suspended'
|
||
else:
|
||
rec.state = 'suspended_second_approve'
|
||
|
||
def action_resume_third_accept(self):
|
||
for rec in self:
|
||
rec.state = 'second_approve'
|
||
rec.action_type = 'approved'
|
||
|
||
def action_final_suspend(self):
|
||
today = fields.Date.today()
|
||
for rec in self:
|
||
if rec.final_suspend_date and today >= rec.final_suspend_date:
|
||
rec.write({
|
||
'state': 'suspended_second_approve',
|
||
'suspend_type': 'suspend',
|
||
})
|
||
else:
|
||
raise UserError(_("Final suspension cannot be executed until after the specified final suspension date."))
|
||
|
||
def action_auto_suspend(self):
|
||
# Fetch grants in second approval state that are not excluded from suspension
|
||
#case_one :
|
||
grants = self.env["grant.benefit"].search(
|
||
[('state', '=', 'second_approve'), ('is_excluded_suspension', '=', False)]
|
||
)
|
||
|
||
for grant in grants:
|
||
# Check if there are no benefit members
|
||
if grant.benefit_member_count == 0:
|
||
grant.state = 'complete_info'
|
||
grant.suspend_method = 'auto'
|
||
grant.action_type = 'suspended'
|
||
|
||
#case two :
|
||
members = self.env["family.member"].search(
|
||
[('state', '=', 'second_approve'), ('is_excluded_suspension', '=', False), ('member_status', '=', 'non_benefit')]
|
||
)
|
||
for member in members:
|
||
member.state_a = 'complete_info'
|
||
member.suspend_method = 'auto'
|
||
member.action_type = 'suspended'
|
||
member.is_member_workflow = True
|
||
|
||
def check_actt(self):
|
||
# case_one :
|
||
grants = self.env["grant.benefit"].search(
|
||
[('state', '=', 'second_approve'), ('is_excluded_suspension', '=', False)]
|
||
)
|
||
for grant in grants:
|
||
# Check if any attachment of the grant is expired
|
||
for attachment in grant.attachment_ids:
|
||
if attachment.attach_status == 'expired':
|
||
# Change state to temporarily suspended if there are benefit members
|
||
if grant.benefit_member_count != 0:
|
||
grant.state = 'complete_info'
|
||
grant.action_type = 'suspended'
|
||
grant.suspend_method = 'auto'
|
||
break # Exit attachment loop after processing
|
||
|
||
# Check each member's attachments
|
||
for member in grant.member_ids:
|
||
for member_attachment in member.attachment_ids:
|
||
if member_attachment.attach_status == 'expired':
|
||
# Change state to temporarily suspended if there are benefit members
|
||
if grant.benefit_member_count != 0:
|
||
grant.state = 'complete_info'
|
||
grant.action_type = 'suspended'
|
||
grant.suspend_method = 'auto'
|
||
break # Exit member attachment loop after processing
|
||
|
||
def action_suspend_refuse(self):
|
||
for rec in self:
|
||
rec.state = 'second_approve'
|
||
rec.action_type = 'approved'
|
||
rec.get_member_income()
|
||
|
||
def action_reject_resume(self):
|
||
for rec in self:
|
||
if rec.action_type == 'resume_from_temporary':
|
||
rec.state = 'temporary_suspended'
|
||
elif rec.action_type == 'resume_from_final':
|
||
rec.state = 'suspended_second_approve'
|
||
rec.action_type = 'suspended'
|
||
|
||
#Excption Work flow
|
||
def action_exception(self):
|
||
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_wizard_form').id,
|
||
'target': 'new',
|
||
}
|
||
|
||
def action_exception_first_accept(self):
|
||
for rec in self:
|
||
rec.state = 'first_approve'
|
||
|
||
def action_exception_second_accept(self):
|
||
for rec in self:
|
||
rec.state = 'exception_second_approve'
|
||
def action_exception_final_accept(self):
|
||
for rec in self:
|
||
rec.is_excluded_suspension = True
|
||
rec.state = 'second_approve'
|
||
for member in self.member_ids:
|
||
member.is_excluded_suspension = True
|
||
rec.get_member_income()
|
||
|
||
def action_auto_exception(self):
|
||
obj = self.env["grant.benefit"].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'
|
||
rec.action_type = 'suspended'
|
||
for member in rec.member_ids:
|
||
member.is_excluded_suspension = False
|
||
|
||
def run_auto_final_suspend(self):
|
||
today = date.today()
|
||
records = self.search([
|
||
('state', '=', 'temporary_suspended'),
|
||
('final_suspend_date', '<=', today),
|
||
])
|
||
|
||
for rec in records:
|
||
rec.state = 'suspended_second_approve'
|
||
|
||
def action_exception_refuse(self):
|
||
for rec in self:
|
||
rec.state = 'suspended_second_approve'
|
||
rec.action_type = 'suspended'
|
||
|
||
# @api.multi
|
||
def action_remove_from_black_list(self):
|
||
"""Remove entity from black list"""
|
||
partner_ids = []
|
||
for entity in self:
|
||
if self.old_stage == 'draft':
|
||
entity.state = 'draft'
|
||
else:
|
||
entity.state = 'second_approve'
|
||
entity.black_list_message = False
|
||
user = self.env['res.users'].search([('partner_id', '=', entity.partner_id.id)], limit=1)
|
||
user.toggle_active()
|
||
# activate user
|
||
subject = _('Beneficiaries')
|
||
state_label = dict(entity.fields_get(allfields=['state'])['state']['selection'])[entity.state]
|
||
body = ' '.join(
|
||
(_(u'The Beneficial '), entity.name, _(u' State changed to '), state_label, u'.')).encode(
|
||
'utf-8')
|
||
partner_ids += [(6, 0, entity.message_follower_ids.ids)]
|
||
message_vals = {
|
||
'subject': subject,
|
||
'body': body,
|
||
'partner_ids': partner_ids,
|
||
}
|
||
# entity.message_post(body=body, subject=subject, message_type='email')
|
||
# entity.send_remove_from_black_list_email()
|
||
|
||
@api.depends('car_ids')
|
||
def _onchange_car_count(self):
|
||
for rec in self:
|
||
rec.car_count = len(rec.car_ids)
|
||
rec.has_car = any(line.member_id for line in rec.car_ids)
|
||
|
||
@api.onchange('is_diseases')
|
||
def onchange_is_diseases(self):
|
||
for rec in self:
|
||
rec.is_diseases = 'sick' if rec.is_diseases else 'healthy'
|
||
|
||
def _onchange_is_has_needs(self):
|
||
for rec in self:
|
||
benefits_needs = rec.env['benefits.needs'].sudo().search(['|',
|
||
('benefit_id', '=', rec.id),
|
||
('benefit_ids', 'in', rec.id)])
|
||
needs = []
|
||
for need in benefits_needs:
|
||
if need.state == 'published' and need.remaining_amount > 0.0:
|
||
needs.append(need.id)
|
||
if len(needs) > 0:
|
||
rec.sudo().has_needs = True
|
||
elif len(needs) == 0:
|
||
rec.sudo().has_needs = False
|
||
|
||
def _orphan_list_compute(self):
|
||
for rec in self:
|
||
benefits = rec.env['grant.benefit'].sudo().search([('mother_id', '=', rec.id)])
|
||
rec.orphan_ids = [(6, 0, benefits.ids)]
|
||
rec.orphan_count = len(rec.orphan_ids)
|
||
|
||
def _compute_orphan_Type(self):
|
||
for rec in self:
|
||
if rec.benefit_type == "orphan":
|
||
if not rec.father_is_life and not rec.mother_is_life:
|
||
rec.orphan_status = 'parent'
|
||
elif not rec.father_is_life:
|
||
rec.orphan_status = 'father'
|
||
elif not rec.mother_is_life:
|
||
rec.orphan_status = 'mother'
|
||
# TODO FIXME: i commented these lines because this field doen't exist in model grant.benefit
|
||
# else:
|
||
# rec.orphan_type = ''
|
||
# else:
|
||
# rec.orphan_type = ''
|
||
|
||
@api.onchange('birth_date')
|
||
def onchange_category(self):
|
||
for rec in self:
|
||
rec.expenses_ids = False
|
||
for expenses in rec.benefit_category_id:
|
||
if expenses.state == 'second_pprove':
|
||
for i in expenses.expenses_ids:
|
||
expenses = {}
|
||
expenses['expenses_type'] = i.expenses_type
|
||
expenses['amount'] = i.amount
|
||
rec.expenses_ids = [(0, 0, expenses)]
|
||
expenses = self.env['benefit.expenses'].sudo().search(
|
||
[('benefit_id', '=', self._origin.id), ('state', '=', 'accreditation')])
|
||
for expenses_extra in expenses:
|
||
expenses = {}
|
||
expenses['expenses_type'] = expenses_extra.expenses_type
|
||
expenses['amount'] = expenses_extra.amount
|
||
expenses['note'] = expenses_extra.name
|
||
rec.expenses_ids = [(0, 0, expenses)]
|
||
# Todo
|
||
|
||
def create_message(self, case):
|
||
sms_template = self.env['benefit.sms.configuration'].sudo().search([('state', '=', case)])
|
||
if sms_template:
|
||
message = sms_template.case_text
|
||
if '$اسم_المستفيد' in message:
|
||
if self.name:
|
||
message = message.replace("$اسم_المستفيد", self.name)
|
||
else:
|
||
raise ValidationError(_("عفواءً القالب المخصص يتوجب وجود اسم المستفيد"))
|
||
if '$رقم_الهوية' in message:
|
||
if self.id_number:
|
||
message = message.replace("$رقم_الهوية", self.id_number)
|
||
else:
|
||
raise ValidationError(_("عفواءً القالب المخصص يتوجب وجود رقم الهوية"))
|
||
if '$اسم_العائلة' in message:
|
||
if self.institution_id:
|
||
message = message.replace("$اسم_العائلة", self.institution_id.name)
|
||
else:
|
||
raise ValidationError(_("عفواءً القالب المخصص يتوجب وجود اسم العائلة"))
|
||
return message
|
||
|
||
def get_error_response(self, result):
|
||
if result == "105":
|
||
raise ValidationError(_("Sorry, there is not enough credit!"))
|
||
if result == "102":
|
||
raise ValidationError(_("Sorry, wrong username!"))
|
||
if result == "103":
|
||
raise ValidationError(_("Sorry, wrong password!"))
|
||
if result == "106":
|
||
raise ValidationError(_("Sorry, sender name is not available!"))
|
||
if result == "1013":
|
||
raise ValidationError(_("Sorry, no message has been posted!"))
|
||
if result == "1011":
|
||
raise ValidationError(_("Sorry, no message has been posted!"))
|
||
|
||
@api.depends('name')
|
||
def _compute_qr_code(self):
|
||
for rec in self:
|
||
qr = qrcode.QRCode(
|
||
version=1,
|
||
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
||
box_size=15,
|
||
border=4,
|
||
)
|
||
name = rec.name
|
||
qr.add_data(name)
|
||
qr.make(fit=True)
|
||
img = qr.make_image()
|
||
temp = BytesIO()
|
||
img.save(temp, format="PNG")
|
||
qr_image = base64.b64encode(temp.getvalue())
|
||
rec.qr_code = qr_image
|
||
|
||
@api.onchange('bank_id')
|
||
def _compute_prefix_iban(self):
|
||
if self.bank_id:
|
||
self.iban = self.bank_id.iban
|
||
|
||
@api.onchange('weight', 'height')
|
||
def _compute_obesity_rate(self):
|
||
for rec in self:
|
||
if rec.weight and rec.height:
|
||
height = (rec.height / 100)
|
||
rec.p_weight = (rec.weight / (height * height))
|
||
|
||
@api.depends(
|
||
'expenses_ids',
|
||
'estimated_rent_amount',
|
||
'expenses_ids.deduct_from_family_income',
|
||
'expenses_ids.amount',
|
||
'family_debits_ids',
|
||
'family_debits_ids.deduct_from_family_income',
|
||
'family_debits_ids.monthly_installment',
|
||
)
|
||
def get_total_expenses(self):
|
||
for ben in self:
|
||
followers = ben.env['benefit.followers'].sudo().search([('benefit_id', '=', ben.id)])
|
||
expenses = ben.env['expenses.line'].sudo().search([('benefit_id', '=', ben.id)])
|
||
total_expenses = 0.0
|
||
if ben.expenses_ids and ben.family_debits_ids:
|
||
total_expenses = sum(ben.expenses_ids.filtered(lambda e: e.deduct_from_family_income).mapped('amount')) + sum(ben.family_debits_ids.filtered(lambda e: e.deduct_from_family_income).mapped('monthly_installment'))
|
||
elif ben.expenses_ids and not ben.family_debits_ids:
|
||
total_expenses = sum(ben.expenses_ids.filtered(lambda e: e.deduct_from_family_income).mapped('amount'))
|
||
elif ben.family_debits_ids and not ben.expenses_ids:
|
||
total_expenses = sum(ben.family_debits_ids.filtered(lambda e: e.deduct_from_family_income).mapped('monthly_installment'))
|
||
if followers:
|
||
ben.followers_total = len(followers)
|
||
if expenses:
|
||
ben.expenses_total = len(expenses)
|
||
ben.total_expenses = total_expenses + ben.estimated_rent_amount
|
||
|
||
@api.depends('mother_net_income', 'mother_status')
|
||
def calculate_income(self):
|
||
validation_setting = self.env["family.validation.setting"].search([], limit=1)
|
||
max_income_for_mother = validation_setting.max_income_for_mother
|
||
for rec in self:
|
||
add_mother_net_income = (rec.mother_status == 'benefit' and rec.mother_net_income > max_income_for_mother)
|
||
if add_mother_net_income:
|
||
rec.mother_income = rec.mother_net_income
|
||
else:
|
||
rec.mother_income = 0.0
|
||
|
||
@api.depends(
|
||
'salary_ids',
|
||
'salary_ids.salary_amount',
|
||
'salary_ids.approved',
|
||
'mother_income',
|
||
)
|
||
def get_total_income(self):
|
||
for rec in self:
|
||
total = 0.0
|
||
rec.total_income = 0.0
|
||
if rec.mother_status == 'non_benefit':
|
||
total = sum(rec.salary_ids.filtered(lambda e: e.approved).mapped('salary_amount'))
|
||
elif rec.mother_status == 'benefit':
|
||
total = sum(rec.salary_ids.filtered(lambda e: e.approved).mapped('salary_amount')) + rec.mother_income
|
||
rec.total_income = total
|
||
|
||
def get_mother_name(self):
|
||
for rec in self:
|
||
name = ''
|
||
if all([rec.mother_name, rec.mother_second_name, rec.mother_third_name, rec.mother_family_name]):
|
||
name = rec.mother_name + " " + rec.mother_second_name + " " + rec.mother_third_name + " " + rec.mother_family_name
|
||
else:
|
||
name = name
|
||
return name
|
||
|
||
def get_replacement_mother_name(self):
|
||
for rec in self:
|
||
name = ''
|
||
if all([rec.replacement_mother_name, rec.replacement_mother_second_name, rec.replacement_mother_third_name,
|
||
rec.replacement_mother_family_name]):
|
||
name = rec.replacement_mother_name + " " + rec.replacement_mother_second_name + " " + rec.replacement_mother_third_name + " " + rec.replacement_mother_family_name
|
||
else:
|
||
name = name
|
||
return name
|
||
|
||
def add_or_replace_mother_as_member(self):
|
||
FamilyMember = self.env['family.member']
|
||
Relation = self.env['relation.settings'].search([('relation_type', '=', 'mother')], limit=1)
|
||
|
||
for rec in self:
|
||
mother_name = rec.get_mother_name()
|
||
val = {
|
||
'name': mother_name,
|
||
'mother_first_name': rec.mother_name,
|
||
'mother_second_name': rec.mother_second_name,
|
||
'mother_third_name': rec.mother_third_name,
|
||
'mother_family_name': rec.mother_family_name,
|
||
'member_id_number': rec.mother_id_number,
|
||
'is_mother': True,
|
||
'birth_date': rec.mother_birth_date,
|
||
'gender': 'female',
|
||
'relationn': Relation.id,
|
||
'mother_marital_conf': rec.mother_marital_conf.id,
|
||
'member_location_conf': rec.mother_location_conf.id,
|
||
'age': rec.mother_age,
|
||
'is_work': rec.is_mother_work,
|
||
'member_income': rec.mother_net_income,
|
||
'education_status': rec.education_status,
|
||
#'member_status': rec.mother_status,
|
||
'member_education_status_ids': [(5, 0)] + [(4, edu.id) for edu in rec.mother_education_status_ids],
|
||
'salary_certificate': [(6, 0, rec.mother_salary_certificate.ids)],
|
||
}
|
||
|
||
mother_family_member = rec.mother_family_member_id
|
||
if mother_family_member:
|
||
mother_family_member.write(val)
|
||
else:
|
||
val['benefit_id'] = rec.id
|
||
mother_family_member = FamilyMember.create(val)
|
||
rec.write({'mother_family_member_id': mother_family_member.id})
|
||
rec.mother_diseases_attachment_ids.write({'member_id': mother_family_member.id})
|
||
rec.mother_disabilities_attachment_ids.write({'member_id': mother_family_member.id})
|
||
|
||
def add_or_replace_replacement_mother_as_member(self):
|
||
FamilyMember = self.env['family.member']
|
||
|
||
for rec in self:
|
||
mother_name = rec.get_replacement_mother_name()
|
||
val = {
|
||
'name': mother_name,
|
||
'mother_first_name': rec.replacement_mother_name,
|
||
'mother_second_name': rec.replacement_mother_second_name,
|
||
'mother_third_name': rec.replacement_mother_third_name,
|
||
'mother_family_name': rec.replacement_mother_family_name,
|
||
'member_id_number': rec.replacement_mother_id_number,
|
||
'is_mother': False,
|
||
'birth_date': rec.replacement_mother_birth_date,
|
||
'gender': 'female',
|
||
'relationn': rec.replacement_mother_relation.id,
|
||
'mother_marital_conf': rec.replacement_mother_marital_conf.id,
|
||
'member_location_conf': rec.replacement_mother_location_conf.id,
|
||
'age': rec.replacement_mother_age,
|
||
'is_work': rec.replacement_is_mother_work,
|
||
'member_income': rec.replacement_mother_income,
|
||
'education_status': rec.replacement_education_status,
|
||
#'member_status': rec.replacement_mother_status,
|
||
'member_education_status_ids': [(5, 0)] + [(4, edu.id) for edu in rec.replacement_education_status_ids],
|
||
'salary_certificate': [(6, 0, rec.replacement_mother_salary_certificate.ids)],
|
||
}
|
||
|
||
if rec.replacement_mother_family_member_id:
|
||
rec.replacement_mother_family_member_id.write(val)
|
||
replacement_member = rec.replacement_mother_family_member_id
|
||
else:
|
||
val['benefit_id'] = rec.id
|
||
replacement_member = FamilyMember.create(val)
|
||
rec.write({'replacement_mother_family_member_id': replacement_member.id})
|
||
|
||
rec.replacement_mother_diseases_attachment_ids.write({'member_id': replacement_member.id})
|
||
rec.replacement_mother_disabilities_attachment_ids.write({'member_id': replacement_member.id})
|
||
|
||
|
||
@api.depends('benefit_member_count','total_income','total_expenses')
|
||
def get_member_income(self):
|
||
for ben in self:
|
||
income = 0.0
|
||
family_income = ben.total_income - ben.total_expenses
|
||
if ben.benefit_member_count:
|
||
if ben.benefit_member_count > 3:
|
||
income = family_income / ben.benefit_member_count
|
||
elif ben.benefit_member_count <= 3:
|
||
income = family_income / 3
|
||
else:
|
||
income = family_income
|
||
ben.member_income = round(income, 0)
|
||
|
||
@api.depends("member_income")
|
||
def get_benefit_category(self):
|
||
default_category = self.env['benefit.category'].sudo().search(
|
||
[('is_benefit', '=', False)], limit=1
|
||
)
|
||
for record in self:
|
||
if record.benefit_member_count <= 0:
|
||
record.benefit_category_id = default_category.id if default_category else False
|
||
continue
|
||
category = self.env['benefit.category'].sudo().search(
|
||
[
|
||
('mini_income_amount', '<=', record.member_income),
|
||
('max_income_amount', '>=', record.member_income)
|
||
],
|
||
limit=1
|
||
)
|
||
record.benefit_category_id = category.id if category else default_category.id
|
||
|
||
def open_followers(self):
|
||
context = {}
|
||
context['default_benefit_id'] = self.id
|
||
return {
|
||
'name': _('Benefit Followers'),
|
||
'view_type': 'form',
|
||
'view_mode': 'tree,form',
|
||
'views': [(self.env.ref(
|
||
'odex_benefit.benefit_followers_tree').id, 'tree'),
|
||
(self.env.ref('odex_benefit.benefit_followers_form').id, 'form')],
|
||
'res_model': 'benefit.followers',
|
||
'type': 'ir.actions.act_window',
|
||
'context': context,
|
||
'domain': "[('benefit_id','=',%s)]" % (self.id),
|
||
'target': 'current',
|
||
}
|
||
|
||
def open_expenses(self):
|
||
context = {}
|
||
context['default_benefit_id'] = self.id
|
||
return {
|
||
'name': _('Benefit Expenses'),
|
||
'view_type': 'form',
|
||
'view_mode': 'tree,form',
|
||
'views': [(self.env.ref(
|
||
'odex_benefit.benefit_expenses_tree').id, 'tree'),
|
||
(self.env.ref('odex_benefit.expenses_line_form').id, 'form')],
|
||
'res_model': 'benefit.expenses',
|
||
'type': 'ir.actions.act_window',
|
||
'context': context,
|
||
'domain': "[('benefit_id','=',%s)]" % (self.id),
|
||
'target': 'current',
|
||
}
|
||
|
||
@api.depends('father_birth_date')
|
||
def _compute_get_father_age(self):
|
||
for rec in self:
|
||
if rec.father_birth_date:
|
||
today = date.today()
|
||
day = datetime.strptime(str(rec.father_birth_date), DEFAULT_SERVER_DATE_FORMAT)
|
||
age = rd(today, day)
|
||
rec.father_age = age.years
|
||
else:
|
||
rec.father_age = 0
|
||
|
||
@api.depends('mother_birth_date')
|
||
def _compute_get_mother_age(self):
|
||
for rec in self:
|
||
if rec.mother_birth_date:
|
||
today = date.today()
|
||
day = datetime.strptime(str(rec.mother_birth_date), DEFAULT_SERVER_DATE_FORMAT)
|
||
age = rd(today, day)
|
||
rec.mother_age = age.years
|
||
else:
|
||
rec.mother_age = 0
|
||
|
||
@api.depends('replacement_mother_birth_date')
|
||
def _compute_get_replacement_mother_age(self):
|
||
for rec in self:
|
||
if rec.replacement_mother_birth_date:
|
||
today = date.today()
|
||
day = datetime.strptime(str(rec.replacement_mother_birth_date), DEFAULT_SERVER_DATE_FORMAT)
|
||
age = rd(today, day)
|
||
rec.replacement_mother_age = age.years
|
||
else:
|
||
rec.replacement_mother_age = 0
|
||
|
||
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 = rec.old_stage
|
||
|
||
# @api.multi
|
||
def edit_password(self):
|
||
if self.user_id:
|
||
self.user_id.sudo().action_reset_password()
|
||
|
||
def create_family_partner(self):
|
||
bank_val = {
|
||
'acc_number':self.acc_number,
|
||
'acc_holder_name':self.acc_holder_name,
|
||
'bank_id':self.bank_id.id,
|
||
}
|
||
partner = self.env['res.partner'].create({
|
||
'name': self.name,
|
||
'email': self.email,
|
||
'phone': self.phone,
|
||
# 'account_type':'family',
|
||
'is_family': True,
|
||
'code':self.code,
|
||
'bank_ids': [(0,0,bank_val)]
|
||
})
|
||
self.partner_id = partner.id
|
||
# def create_member_partner(self):
|
||
# # bank_val = {
|
||
# # 'acc_number':self.acc_number,
|
||
# # 'partner_id':self.account_holder,
|
||
# # 'bank_name':self.bank_name,
|
||
# # }
|
||
# partner = self.env['res.partner'].create({
|
||
# 'name': self.name,
|
||
# 'email': self.email,
|
||
# 'phone': self.phone,
|
||
# 'account_type':'member',
|
||
# 'code':self.code,
|
||
# # 'bank_ids': [(0,0,bank_val)]
|
||
# })
|
||
# self.partner_id = partner.id
|
||
|
||
def create_user(self):
|
||
bank_val = {
|
||
'acc_number':self.acc_number,
|
||
'acc_holder_name':self.acc_holder_name,
|
||
'bank_id':self.bank_id.id,
|
||
}
|
||
for follower in self['message_follower_ids']:
|
||
follower.sudo().unlink()
|
||
if not self.partner_id:
|
||
partner = self.create_family_partner()
|
||
self.partner_id.write({
|
||
'name': self.name,
|
||
'email': self.email,
|
||
'phone': self.phone,
|
||
# 'account_type': 'family',
|
||
'is_family': True,
|
||
'code': self.code,
|
||
})
|
||
if bank_val['acc_number'] and bank_val['acc_holder_name'] and bank_val['bank_id']:
|
||
self.partner_id.write({
|
||
'bank_ids': [(0,0,bank_val)]
|
||
})
|
||
user = self.env['res.users'].sudo().with_context(no_reset_password=True).create({
|
||
'name': self.name,
|
||
'login': self.sms_phone or self.email,
|
||
'partner_id': self.partner_id.id,
|
||
'active': True,
|
||
'otp_mobile_phone': self.sms_phone,
|
||
})
|
||
self.user_id = user.id
|
||
if self.password:
|
||
user.sudo().write({'password': self.password, })
|
||
|
||
user.sudo().write({
|
||
'groups_id': [(3, self.env.ref('base.group_user', False).id)],
|
||
})
|
||
user.sudo().write({
|
||
'groups_id': [(4, self.env.ref('base.group_portal', False).id)],
|
||
})
|
||
|
||
# @api.multi
|
||
def send_approval_benefit_email(self):
|
||
"""Send approval email when benefit registration is accepted"""
|
||
template = self.env.ref('odex_benefit.approval_benefit_email', False)
|
||
if not template:
|
||
return
|
||
template.with_context(lang=self.env.user.lang).send_mail(self.id, force_send=True, raise_exception=False)
|
||
|
||
# @api.multi
|
||
def _send_notification(self, partner_ids, state):
|
||
"""Send notification when entity state changes"""
|
||
subject = _('Beneficial')
|
||
state_label = dict(self.fields_get(allfields=['state'])['state']['selection'])[state]
|
||
body = ' '.join((_(u'The Beneficiaries '), self.name, _(u' State changed to '), state_label, u'.')).encode(
|
||
'utf-8')
|
||
partner_list_ids = []
|
||
for id in partner_ids:
|
||
partner_list_ids.append(id.id)
|
||
message_vals = {
|
||
'subject': subject,
|
||
'body': body,
|
||
'partner_ids': partner_list_ids,
|
||
# 'model': self._name,
|
||
# 'res_id': self.id,
|
||
}
|
||
test = self.sudo().message_post(message_type="notification", subtype_xmlid="mt_comment",
|
||
**message_vals)
|
||
|
||
def send_black_list_email(self):
|
||
"""Send black list email when entity black list"""
|
||
template = self.env.ref('odex_benefit.black_list_entity_email', False)
|
||
if not template:
|
||
return
|
||
template.with_context(lang=self.env.user.lang).send_mail(self.id, force_send=True, raise_exception=False)
|
||
|
||
# @api.multi
|
||
def send_remove_from_black_list_email(self):
|
||
"""Send black list email when entity black list"""
|
||
template = self.env.ref('odex_benefit.black_list_remove_benefit_email', False)
|
||
if not template:
|
||
return
|
||
template.with_context(lang=self.env.user.lang).send_mail(self.id, force_send=True, raise_exception=False)
|
||
|
||
# # Validation Opertaion
|
||
# @api.onchange('phone', 'phone2','sms_phone')
|
||
# def _onchange_mobile_validation(self):
|
||
# if self.phone:
|
||
# if self.phone.startswith('+966'):
|
||
# phone = self.phone[4:]
|
||
# self.phone = phone
|
||
# if re.match(SAUDI_MOBILE_PATTERN, self.phone) == None:
|
||
# raise ValidationError(
|
||
# _('Enter a valid Saudi mobile number'))
|
||
# if self.phone2:
|
||
# if self.phone2.startswith('+966'):
|
||
# phone2 = self.phone2[4:]
|
||
# self.phone2 = phone2
|
||
# if re.match(SAUDI_MOBILE_PATTERN, self.phone2) == None:
|
||
# raise ValidationError(
|
||
# _('Enter a valid Saudi mobile number'))
|
||
# if self.sms_phone:
|
||
# if self.sms_phone.startswith('+966'):
|
||
# sms_phone = self.sms_phone[4:]
|
||
# self.sms_phone = sms_phone
|
||
# if re.match(SAUDI_MOBILE_PATTERN, self.sms_phone) == None:
|
||
# raise ValidationError(
|
||
# _('Enter a valid Saudi mobile number'))
|
||
|
||
@api.constrains('phone', 'phone2','sms_phone')
|
||
def _onchange_phone_numbers(self):
|
||
phone_numbers = {
|
||
#'الهاتف': self.phone,
|
||
'رقم الجوال الثاني': self.phone2,
|
||
'رقم الجوال للتواصل': self.sms_phone,
|
||
}
|
||
|
||
# Check each ID number for 10-digit format and uniqueness within the parent model
|
||
unique_ids = set()
|
||
for label, phone_number in phone_numbers.items():
|
||
if phone_number:
|
||
if re.match(SAUDI_MOBILE_PATTERN,phone_number) == None:
|
||
raise ValidationError(
|
||
_('Enter a valid Saudi mobile number'))
|
||
if phone_number in unique_ids:
|
||
raise ValidationError(_("%s must be unique within the same record.") % label)
|
||
unique_ids.add(phone_number)
|
||
|
||
# Check for uniqueness against `member_phone` in child records and across database records
|
||
for member in self.member_ids:
|
||
if member.member_phone and member.member_phone in unique_ids:
|
||
raise ValidationError(
|
||
_("The Phone Number %s in the Family Members list must be unique across the record.") % member.member_phone)
|
||
# Check for duplicate IDs across records in the database
|
||
for phone_number in unique_ids:
|
||
duplicate_record_family = self.env['grant.benefit'].search([
|
||
'|', ('phone2', '=', phone_number),
|
||
('sms_phone', '=', phone_number), ('id', '!=', self._origin.id)
|
||
], limit=1)
|
||
duplicate_record_member = self.env['family.member'].search([('member_phone', '=', phone_number)], limit=1)
|
||
if duplicate_record_family:
|
||
raise ValidationError(
|
||
_("The phone number {} already exists in family with code {}.").format(
|
||
phone_number, duplicate_record_family.code))
|
||
if duplicate_record_member:
|
||
raise ValidationError(
|
||
_("The phone {} already exists in family with code {}.").format(
|
||
phone_number, duplicate_record_member.benefit_id.code))
|
||
|
||
@api.onchange('email')
|
||
def onchange_email(self):
|
||
if self.email:
|
||
for rec in self:
|
||
exist = self.search([('email', '=', rec.email)])
|
||
if exist:
|
||
raise ValidationError(
|
||
_('The Email Already Exist!'))
|
||
|
||
@api.onchange('sms_phone')
|
||
def onchange_sms_phone(self):
|
||
if self.sms_phone:
|
||
for rec in self:
|
||
exist = self.search([('sms_phone', '=', rec.sms_phone)])
|
||
if exist:
|
||
raise ValidationError(
|
||
_('The SMS phone Already Exist!'))
|
||
|
||
@api.onchange('acc_number')
|
||
def onchange_acc_number(self):
|
||
if self.acc_number:
|
||
# Check if the value is numeric before anything else
|
||
if not self.acc_number.isdigit():
|
||
raise ValidationError(_("The account number should contain only digits."))
|
||
|
||
# Check if the account number contains exactly 22 digits
|
||
if len(self.acc_number) != 22:
|
||
raise ValidationError(_("The IBAN number must contain exactly 22 digits."))
|
||
|
||
# Check if the account number already exists in the partner bank or benefit
|
||
#partner_exist = self.env['res.partner.bank'].search([('acc_number', '=', self.acc_number)], limit=1)
|
||
#benefit_exist = self.search([('acc_number', '=', self.acc_number)], limit=1)
|
||
|
||
#if partner_exist or benefit_exist:
|
||
# raise ValidationError(_("The account number already exists!"))
|
||
|
||
@api.onchange('mother_marital_conf', 'mother_location_conf', 'mother_net_income')
|
||
def _onchange_mother_info(self):
|
||
res = {}
|
||
if self.mother_status == 'non_benefit':
|
||
res['warning'] = {'title': _('ValidationError'),
|
||
'message': _('Not Benefit')}
|
||
return res
|
||
|
||
@api.onchange('replacement_mother_marital_conf', 'replacement_mother_location_conf')
|
||
def _onchange_replacement_mother_info(self):
|
||
res = {}
|
||
for rec in self:
|
||
if rec.replacement_mother_status == 'non_benefit':
|
||
res['warning'] = {'title': _('ValidationError'),
|
||
'message': _('Not Benefit')}
|
||
return res
|
||
|
||
def create_scheduled_visit(self):
|
||
records = self.env["grant.benefit"].search([('state', '=', 'second_approve')])
|
||
recurrence_visit_id = self.env.ref('odex_benefit.recurrence_visit')
|
||
period_unit = {
|
||
recurrence_visit_id.recurrence_period: recurrence_visit_id.recurrence_interval
|
||
}
|
||
for rec in records.filtered(lambda r: r.last_visit_date and (r.last_visit_date + rd(**period_unit)).date() <= fields.Date.context_today(self)):
|
||
self.env['visit.location'].create({
|
||
'benefit_id': rec.id,
|
||
'visit_date': date.today(),
|
||
'visit_types': recurrence_visit_id.id,
|
||
'selector': 'researcher',
|
||
'researcher_id': rec.researcher_id.id,
|
||
# 'researcher_team': rec.researcher_team.id,
|
||
'state': 'draft'
|
||
})
|
||
|
||
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'
|
||
})
|
||
def change_attachment_status(self):
|
||
obj = self.env["grant.benefit"].search([])
|
||
for attach in obj.attachment_ids:
|
||
attach.get_status()
|
||
|
||
# Notifications
|
||
def send_expiry_date_notification(self):
|
||
self.change_attachment_status()
|
||
obj = self.env["grant.benefit"].search([])
|
||
for rec in obj:
|
||
for attach in rec.attachment_ids:
|
||
if attach.attach_status == 'expired':
|
||
template = self.env.ref('odex_benefit.attachment_expiration_family_email_template', False)
|
||
if not template:
|
||
return
|
||
template.with_context(lang=self.env.user.lang).send_mail(rec.id, force_send=True,
|
||
raise_exception=False)
|
||
#Update data automatically daily
|
||
def update_data_automatically(self):
|
||
obj = self.env["grant.benefit"].search([])
|
||
for member in obj.member_ids:
|
||
# member._compute_get_age_date()
|
||
member.check_member_status()
|
||
self.action_auto_suspend()
|
||
|
||
|
||
class BenefitFollowers(models.Model):
|
||
_name = 'benefit.followers'
|
||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||
|
||
benefit_id = fields.Many2one('grant.benefit', )
|
||
name = fields.Many2one('grant.benefit', domain="[('is_responsible','=',False)]")
|
||
follower_type = fields.Selection(
|
||
[('benefit', 'benefit'), ('orphan', 'orphan'), ('widow', 'widow'), ('poor', 'poor'), ('other', 'other'),
|
||
], string='Benefit Type', tracking=True, related="name.benefit_type", )
|
||
birth_date = fields.Date(related="name.birth_date", string="Birth Date")
|
||
age = fields.Integer(string="Age", compute='_compute_get_age_date', store=True)
|
||
gender = fields.Selection(selection=[('male', 'Male'), ('female', 'Female')], string="Gender",
|
||
related="name.gender", )
|
||
is_live_with_family = fields.Boolean('Is Live With Family')
|
||
|
||
@api.depends('birth_date')
|
||
def _compute_get_age_date(self):
|
||
for rec in self:
|
||
if rec.birth_date:
|
||
today = date.today()
|
||
day = datetime.strptime(rec.birth_date, DEFAULT_SERVER_DATE_FORMAT)
|
||
age = rd(today, day)
|
||
rec.age = age.years
|
||
|
||
|
||
class WidowFamily(models.Model):
|
||
_name = 'widow.family'
|
||
|
||
benefit_id = fields.Many2one('grant.benefit')
|
||
widow_name = fields.Many2one('grant.benefit', domain="[('benefit_type','=','widow')]", string='Widow Name')
|
||
widows_husband = fields.Char('Widows Husband', related="widow_name.husband_name")
|
||
widows_husband_id = fields.Char('Widows Husband ID', related="widow_name.husband_id")
|
||
date_death_husband = fields.Date(related="widow_name.date_death_husband")
|
||
|
||
|
||
class divorceeFamily(models.Model):
|
||
_name = 'divorcee.family'
|
||
|
||
benefit_id = fields.Many2one('grant.benefit')
|
||
divorcee_name = fields.Many2one('grant.benefit', 'divorcee Name')
|
||
divorcee_husband = fields.Char('Widows Husband', related="divorcee_name.husband_name")
|
||
divorcee_husband_id = fields.Char('Widows Husband ID', related="divorcee_name.husband_id")
|
||
date_divorcee = fields.Date(related="divorcee_name.date_divorcee")
|
||
|
||
|
||
class ExternalBenefit(models.Model):
|
||
_name = 'external.benefits'
|
||
_inherits = {'res.partner': 'partner_id'}
|
||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||
|
||
location = fields.Char(string='location')
|
||
benefit_nationality = fields.Many2one('res.country', 'Benefit Nationality')
|
||
block = fields.Char('Benefit Block')
|
||
work = fields.Char()
|
||
partner_id = fields.Many2one('res.partner', string='partner', required=True, ondelete="cascade")
|
||
|
||
@api.onchange('first_name', 'second_name', 'middle_name', 'family_name')
|
||
def get_benefit_name(self):
|
||
for rec in self:
|
||
if rec.first_name and rec.second_name and rec.middle_name and rec.family_name:
|
||
rec.name = rec.first_name + " " + rec.second_name + " " + rec.middle_name + " " + rec.family_name
|
||
|
||
def create_partner(self):
|
||
partner = self.env['res.partner'].create({
|
||
'name': self.name,
|
||
'email': self.email,
|
||
'phone': self.phone,
|
||
# 'city': self.city_id.name if self.city_id else False,
|
||
# 'country_id': self.country_id.id,
|
||
})
|
||
self.partner_id = partner.id
|
||
|
||
|
||
# neighborhood representative
|
||
class Representative(models.Model):
|
||
_name = 'benefits.representative'
|
||
_inherits = {'res.partner': 'partner_id'}
|
||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||
|
||
location = fields.Char(string='location')
|
||
block = fields.Char('Benefit Block')
|
||
work = fields.Char()
|
||
partner_id = fields.Many2one('res.partner', string='partner', required=True, ondelete="cascade")
|