odex25_standard/odex25_benefit/odex_benefit/models/benefit_config.py

1060 lines
38 KiB
Python

# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from random import randint
from datetime import date
import logging
import os
import re
SAUDI_MOBILE_PATTERN = "(^(05|5)(5|0|3|6|4|9|1|8|7)([0-9]{7})$)"
_logger = logging.getLogger(__name__)
class BenefitCategory(models.Model):
_name = 'benefit.category'
_description = "Benefits - category"
name = fields.Char(string="Category Name")
description = fields.Char(string="Description")
gender = fields.Selection(selection=[('male', _('Male')), ('female', _('Female')) ,('both', _('Both'))], string="Gender")
age_from = fields.Integer(string="From")
age_to = fields.Integer(string="To")
benefit_ids = fields.One2many('grant.benefit', 'benefit_category_id', string="Category Benefits")
benefits_total = fields.Integer(string="Benefit Total", compute="get_benefits_total")
mini_income_amount = fields.Float(string="Min Income Amount")
max_income_amount = fields.Float(string="Max Income Amount")
expenses_ids = fields.One2many('expenses.line', 'category_id')
is_benefit = fields.Boolean(string="Is Benefit",default=True)
color = fields.Integer(string="Color Index", default=0)
decoration_color = fields.Selection([
('danger', 'Red'),
('success', 'Green'),
('warning', 'Orange'),
('info', 'Blue'),
('primary', 'Primary'),
('muted', 'Muted'),
])
def get_benefits_total(self):
for rec in self:
rec.benefits_total = len(rec.benefit_ids)
def open_benefits(self):
return {
'name': _("Benefits"),
'view_type': 'form',
'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')],
'res_model': 'grant.benefit',
'type': 'ir.actions.act_window',
'domain': [('id', 'in', self.benefit_ids.ids)],
'target': 'current',
}
class GrantFamily(models.Model):
_name = 'benefit.family'
_description = "Benefits - family"
name = fields.Char(
string='',
required=False)
responsible_benefit_id = fields.Many2one(
'grant.benefit',
domain="[('is_responsible','=',True),('family_id','=',id)]")
housing_id = fields.Many2one(
'benefit.housing')
loan_ids = fields.Many2many('benefit.loans', 'family_id')
total_expenses = fields.Float(
compute='get_total_needs_percent',
string='Total Expenses of Family',
required=False)
total_income = fields.Float(
compute='get_total_needs_percent',
string='Total Income of Family',
required=False)
benefit_needs_percent = fields.Float(
compute='get_total_needs_percent',
string='',
store=True,
required=False)
is_producer = fields.Boolean(string='Producer')
description = fields.Char(string="Description")
benefits_total = fields.Integer(string="Benefit Total", compute="get_benefits_total", store=True)
benefit_ids = fields.One2many('grant.benefit', 'family_id', string="Benefits")
@api.depends("benefit_ids")
def get_benefits_total(self):
for rec in self:
rec.benefits_total = len(rec.benefit_ids)
def get_total_needs_percent(self):
for rec in self:
if rec.benefit_ids:
percent = 0.0
for amount in rec.benefit_ids:
rec.total_income += amount.total_income
rec.total_expenses += amount.total_expenses
percent += amount.benefit_needs_percent
rec.benefit_needs_percent = percent / len(rec.benefit_ids)
else:
rec.benefit_needs_percent = 0.0
rec.total_income = 0.0
rec.total_expenses = 0.0
def open_benefits(self):
return {
'name': "Benefits",
'view_type': 'form',
'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')],
'res_model': 'grant.benefit',
'type': 'ir.actions.act_window',
'domain': "[('family_id','=',%s)]" % (self.id),
'target': 'current',
}
class SportLine(models.Model):
_name = 'sport.line'
_description = "Benefits - sport"
benefit_id = fields.Many2one(
'grant.benefit')
sport_type = fields.Many2one(
'sport.type')
sport_attendance = fields.Boolean(
string='',
required=False)
Subtype = fields.Selection(
string='Subtype',
selection=[('daily', 'daily'),
('monthly', 'Monthly'),
('yearly', 'yearly'),
], )
sport_time = fields.Selection(
string='Sport Time',
selection=[('morning', 'Morning'),
('day', 'day'),
('evening', 'evening'),
],
required=False, )
sport_club = fields.Char(
string='',
required=False)
sport_amount = fields.Float(
string='',
required=False)
sport_clothing = fields.Char(
string='',
required=False)
sport_equipment = fields.Char(
string='',
required=False)
class SportType(models.Model):
_name = 'sport.type'
_description = "Benefits - sport Type"
name = fields.Char(
string='',
required=False)
description = fields.Char(
string='Description',
required=False)
class CraftSkills(models.Model):
_name = 'craft.skills'
_description = "Benefits - sport"
name = fields.Char(
string='',
required=False)
benefit_id = fields.Many2one(
'grant.benefit')
is_invested = fields.Boolean(
string='',
required=False)
skill_rating = fields.Float(
string='',
required=False)
is_development = fields.Boolean(
string='',
required=False)
is_capital = fields.Boolean(
string='',
required=False)
is_work_place = fields.Boolean(
string='',
required=False)
work_history = fields.Char(
string='',
required=False)
achievements = fields.Char(
string='',
required=False)
certificates = fields.Binary(string="")
# Awards and certificates # TODO#
class inclination(models.Model):
_name = 'training.inclinations'
_description = "Benefits - inclination"
name = fields.Char(
string='',
required=False)
benefit_id = fields.Many2one(
'grant.benefit')
training_type_id = fields.Many2one('training.type',
string='',
required=False)
is_invested = fields.Boolean(
string='',
required=False)
training_rating = fields.Float(
string='',
required=False)
is_development = fields.Boolean(
string='',
required=False)
is_capital = fields.Boolean(
string='',
required=False)
training_history = fields.Char(
string='',
required=False)
book_history = fields.Char(
string='What books has he read?',
required=False)
courses = fields.Char(
string='What courses did he take?',
required=False)
steps = fields.Char(
string='',
required=False)
training_future = fields.Char(
string='',
required=False)
training_site = fields.Char(
string='',
required=False)
training_records = fields.Char(
string='',
required=False)
achievements = fields.Char()
certificates = fields.Binary(string="")
# Awards and certificates
class BenefitBehaviors(models.Model):
_name = 'benefit.behaviors'
_description = "Benefits - behaviors"
name = fields.Char(
related='behavior_id.name')
benefit_id = fields.Many2one(
'grant.benefit')
behavior_id = fields.Many2one(
'benefit.behaviors.type')
behavior_date = fields.Date(
string='',
required=False)
need_help = fields.Boolean(
string='',
required=False)
class BenefitBehaviorsType(models.Model):
_name = 'benefit.behaviors.type'
_description = "Benefits - behaviors type"
name = fields.Char(
string='',
required=False)
type = fields.Selection(
string='',
selection=[('negative', 'Negative'),
('positive', 'Positive'), ],
required=False, )
class Salary(models.Model):
_name = 'salary.line'
_description = "Benefits - Salary line"
benefit_id = fields.Many2one(
'grant.benefit')
mother_benefit_id = fields.Many2one('grant.benefit', string="Mother Benefit", ondelete='cascade')
currency_id = fields.Many2one('res.currency', related='benefit_id.currency_id')
salary_type = fields.Char()
income_type = fields.Many2one('attachments.settings',string='Income Type',domain="[('attach_type','=','income_attach')]")
salary_amount = fields.Float(
string='Income Amount',
required=False)
salary_attach = fields.Many2many('ir.attachment',string="Attachment")
attach_start_date = fields.Date(string='Attach Start Date')
attach_end_date = fields.Date(string='Attach End Date')
is_required = fields.Boolean(string='Is Required?')
is_mother_salary = fields.Boolean(string="Is Mother Salary", default=False)
approved = fields.Boolean(string="Is Approved", default=False)
is_default = fields.Boolean(string='Is Default?')
state = fields.Selection(string='Status',selection=[('waiting', 'Waiting'),('accepted', 'Accepted'),('refused', 'Refused')],default="waiting")
note = fields.Char(string="Note")
# total_salary = fields.Float(string="Total Salary", compute='_compute_total_salary',store=True)
# @api.depends('salary_amount','state')
# def _compute_total_salary(self):
# total = 0
# for record in self:
# # Apply your custom condition here
# records = self.env['salary.line'].search([('state', '=', 'accepted')])
# for rec in records:
# total += rec.salary_amount
# record.total_salary = total
@api.model
def create(self, vals):
if 'state' not in vals or vals.get('state') not in ['accepted', 'refused']:
vals['state'] = 'waiting'
return super(Salary, self).create(vals)
def write(self, vals):
if 'state' not in vals:
for rec in self:
if rec.state not in ['accepted', 'refused']:
vals['state'] = 'waiting'
break
return super(Salary, self).write(vals)
def action_accept(self):
self.state = 'accepted'
def action_refuse(self):
self.state = 'refused'
def get_salary_attachment_name(self):
"""Return salary attachment name without extension."""
if self.salary_attach:
return os.path.splitext(self.salary_attach.name)[0]
return ''
def get_notification_emails(self):
"""Return a list of valid emails to notify, removing False values."""
emails = self.benefit_id.researcher_id.employee_id.mapped('work_email') or []
emails.extend([
self.benefit_id.branch_custom_id.branch.manager_id.work_email,
self.benefit_id.branch_custom_id.branch.operation_manager_id.work_email
])
# Remove False or None values
emails = list(filter(None, emails)) # Filters out None and False values
return ','.join(emails) if emails else 'admin@example.com'
def action_send_attachment_expiry_email(self):
"""Send email notifications for attachments expiring today and log the body in the chatter."""
today = date.today()
salary_lines = self.search([('attach_end_date', '=', today)])
mail_template = self.env.ref('odex_benefit.email_salary_attachment_expiry')
if not mail_template:
raise ValidationError("Salary Attachment Expiry Mail template not found!")
for salary_line in salary_lines:
# Render the email body
email_body = mail_template._render_field('body_html', [salary_line.id], compute_lang=True)[salary_line.id]
# Send the email
mail_template.send_mail(salary_line.id, force_send=True)
# Post the email body in the chatter of benefit_id
if salary_line.benefit_id:
salary_line.benefit_id.message_post(
body=email_body,
subtype_xmlid="mail.mt_note" # Log as a note in the chatter
)
class ibanBanks(models.Model):
_inherit = 'res.bank'
_description = "Add iban details in bank screen"
iban = fields.Char("IBAN")
code = fields.Char(string='Code')
class benefitsExpensesLine(models.Model):
_name = 'benefit.expenses'
_description = "Benefits - expenses"
name = fields.Char()
benefit_id = fields.Many2one('grant.benefit')
expenses_type = fields.Selection(
string='',
selection=[('governmental', 'Governmental Expenses'),
('medical', 'Medical Expenses'),
('transportation', 'Transportation Expenses'),
('debts', 'Debts Expenses'),
('pandemics', 'Pandemics Expenses'),
('living', 'Living Expenses'),
('educational', 'Educational Expenses'),
('clothing', 'Clothing Expenses'),
],
required=False, )
expenses_fees_type = fields.Selection(
string='Fees Type',
selection=[('fixed', 'Fixed'),
('dynamic', 'dynamic')], required=False, )
medicine_type = fields.Selection(
string='Medicine Type',
selection=[('pills', 'pills'),
('drink', 'drink'),
('inhalation', 'inhalation')], required=False, )
diseases_type = fields.Selection(
string='Diseases Type',
selection=[('chronic', 'chronic'),
('psycho', 'psycho'),
('organic', 'organic')], required=False, )
trans_type = fields.Selection(
string='trans Type',
selection=[('general', 'General'),
('especially', 'Especially')], required=False, )
debt_reason = fields.Char(string='', required=False)
attach = fields.Binary(string="",attachment=True )
debt_type = fields.Selection(selection=[('necessary', 'Necessary'),
('need', 'Need'),
('improve', 'to improve'),
('case', 'case or not'),
('Installed', 'Installed or not'),
])
pandemics_explain = fields.Char(string='pandemics explain', required=False)
amount = fields.Float()
state = fields.Selection([('draft', 'Draft'),
('accreditation', 'Accreditation'),
], string='state', default="draft", tracking=True)
def action_accepted(self):
for i in self:
i.state = 'accreditation'
class cloth(models.Model):
_name = 'benefit.cloth'
name = fields.Char()
benefit_id = fields.Many2one('grant.benefit')
cloth_type = fields.Many2one('cloth.type')
cloth_size = fields.Many2one('cloth.size')
cloth_note = fields.Char()
class ClothType(models.Model):
_name = 'cloth.type'
name = fields.Char()
class ClothSize(models.Model):
_name = 'cloth.size'
name = fields.Char()
class ExpensesLine(models.Model):
_name = 'expenses.line'
category_id = fields.Many2one(
'benefit.category')
benefit_id = fields.Many2one('grant.benefit')
mother_benefit_id = fields.Many2one('grant.benefit',string="Mother Benefit",ondelete='cascade')
currency_id = fields.Many2one('res.currency', related='benefit_id.currency_id')
#expenses_type_custom = fields.Many2one('expenses.type')
expenses_type_custom = fields.Many2one('attachments.settings', string='Expenses Type Custom',
domain="[('attach_type','=','expense_attach')]")
expenses_type = fields.Selection(
string='',
selection=[('governmental', 'Governmental Expenses'),
('medical', 'Medical Expenses'),
('transportation', 'Transportation Expenses'),
('debts', 'Debts Expenses'),
('pandemics', 'Pandemics Expenses'),
('living', 'Living Expenses'),
('educational', 'Educational Expenses'),
('clothing', 'Clothing Expenses'),
],
required=False, )
amount = fields.Float()
note = fields.Char()
state = fields.Selection(string='Status', selection=[('waiting', 'Waiting'),('accepted', 'Accepted'), ('refused', 'Refused')],default="waiting")
expense_attachments = fields.Many2many('ir.attachment','expenses_line_attachment_rel','expense_line_id','attachment_id',string="Attachment")
deduct_from_family_income = fields.Boolean(string="Deduct from Family Income")
def action_accept(self):
# self.benefit_id.get_member_income()
self.state = 'accepted'
def action_refuse(self):
self.state = 'refused'
class EntityRefuseReason(models.Model):
_name = 'entity.refuse_reason'
name = fields.Text("Refuse Reason")
user_id = fields.Many2one('res.users', 'Assigned to', default=lambda self: self.env.user, index=True)
entity_id = fields.Many2one('grant.benefit', 'Benefit Id')
date = fields.Datetime(string='Refuse Date', default=fields.Datetime.now)
class specialization(models.Model):
_name = 'specialization.specialization'
name = fields.Char(
string='',
required=False)
description = fields.Char(
string='Description',
required=False)
is_scientific_specialty = fields.Boolean('Is Scientific Specialty?')
is_medical_specialty = fields.Boolean('Is Medical Specialty?')
class OtherAssociations(models.Model):
_name = 'other.associations'
name = fields.Char(
string='',
required=False)
city_id = fields.Many2one(
'res.country.city')
description = fields.Char(
string='Description',
required=False)
class Associations(models.Model):
_name = 'associations.line'
benefit_id = fields.Many2one(
'grant.benefit')
associations_ids = fields.Many2one(
'other.associations',
string='Other Associations',
required=False)
support_type = fields.Selection(
string='',
selection=[('material', 'Material'),
('cash', 'cash'),
('both', 'Both'),
],
required=False, )
support_amount = fields.Float(
string='',
required=False)
associations_description = fields.Text(
string="",
required=False)
class Hospital(models.Model):
_name = 'hospital.hospital'
name = fields.Char(
string='',
required=False)
Location = fields.Char(
string='',
required=False)
class InsuranceCompany(models.Model):
_name = 'insurance.company'
name = fields.Char(
string='',
required=False)
description = fields.Char(
string='Description',
required=False)
class InsuranceType(models.Model):
_name = 'insurance.type'
name = fields.Char(
string='',
required=False)
description = fields.Char(
string='Description',
required=False)
class Cars(models.Model):
_name = 'cars.line'
name = fields.Char()
benefit_id = fields.Many2one('grant.benefit')
is_driver_family_member = fields.Boolean(string="Is Driver Family Member?", default=True)
driver_name = fields.Char(string="Driver Name")
member_id = fields.Many2one('family.member',domain="[('benefit_id','=',benefit_id)]", string="Member")
car_model = fields.Many2one('benefit.vehicle.model', ondelete='restrict')
status = fields.Selection(
string='',
selection=[('good', 'Good'),
('bad', 'bad'), ],
required=False,default='good' ) # TODO
purchased_by_association = fields.Boolean(
string="Purchased by the Association?",
default=False,
help="Indicates whether the car was purchased by the association"
)
application_form = fields.Many2many('ir.attachment','cars_application_form_rel', 'cars_id','attachment_id',string="Application Form")
driving_license = fields.Many2many('ir.attachment','cars_driving_license_rel','cars_id','attachment_id',string="Driving License")
owner_identity = fields.Many2many('ir.attachment','cars_owner_identity_rel','cars_id', 'attachment_id',string="Owner Identity")
@api.onchange('is_driver_family_member')
def _onchange_is_driver_family_member(self):
for rec in self:
if rec.is_driver_family_member:
rec.driver_name = False
else:
rec.member_id = False
class TrainingType(models.Model):
_name = 'training.type'
name = fields.Char()
class Committees(models.Model):
_name = 'committees.line'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Char()
employee_id = fields.Many2many('hr.employee',domain="[('branch_name','=',branch_id)]", string="Employee")
type = fields.Selection(
string='',
selection=[('male', 'Men'),
('female', 'women'),
('both', 'combined'),
],
required=False, )
branch_custom_id = fields.Many2one("branch.settings", string="Branch")
branch_id = fields.Many2one('hr.department',string='Branch',related='branch_custom_id.branch',store=True)
active = fields.Boolean('Active', default=True)
benefit_count = fields.Integer(compute="get_benefit_count")
mobile = fields.Char(string="Mobile Number")
@api.constrains('mobile')
def _check_mobile(self):
for rec in self:
if rec.mobile and not re.match(SAUDI_MOBILE_PATTERN, rec.mobile):
raise ValidationError(
_("Please enter a valid Saudi mobile number (example: 05xxxxxxxx).")
)
def get_benefit_count(self):
for record in self:
benefit_ids = self.env['grant.benefit'].search([('researcher_id', 'in', record.ids)])
record.benefit_count = len(benefit_ids)
def action_view_benefits(self):
return {
'name': _('Benefits'),
'type': 'ir.actions.act_window',
'res_model': 'grant.benefit',
'view_mode': 'tree,form',
'domain': [('researcher_id', 'in', self.ids)],
'target': 'current',
}
class ResDistricts(models.Model):
_name = 'res.districts'
name = fields.Char(string="Name")
meal_card = fields.Boolean(string='Meal Card')
city_id = fields.Many2one('res.country.city')
branch_custom_id = fields.Many2one("branch.settings", string="Branch")
class VisitsSettings(models.Model):
_name = 'visits.types'
name = fields.Char(string="Name", required=True)
creation_method = fields.Selection(
[('manual', 'Manual'),('automatic', 'Automatic')],
string="Creation Method",
default='manual',
required=True,
help="Whether the visit is entered manually or created automatically"
)
recurrence_interval = fields.Integer(
string="Recurrence Interval",
default=1,
help="Determines how often visits are created automatically"
)
recurrence_period = fields.Selection([
('days', 'Days'),
('weeks', 'Weeks'),
('months', 'Months')
], string="Recurrence Period", default='days',
help="Time unit for recurrence")
otp_verification = fields.Boolean(
string="OTP Verification",
default=False,
help="Whether this visit requires OTP confirmation from the family"
)
otp_validity_minutes = fields.Integer(
string="OTP Validity (Minutes)",
default=5,
help="OTP code validity duration in minutes"
)
active = fields.Boolean(
string="Active",
default=True
)
survey_id = fields.Many2one(
'survey.survey',
string="Evaluation Survey"
)
class SurveySetting(models.Model):
_name = 'survey.setting'
survey_url = fields.Char("Survey URL")
class SuspendReason(models.Model):
_name = 'suspend.reason'
_description = "Suspend - Reason"
name = fields.Char(string="Name", required=True)
is_stop_reason = fields.Boolean(string="Stop Reason",default=False)
is_reject_reason = fields.Boolean(string="Reject Reason",default=False)
is_return_reason = fields.Boolean(string="Return Reason",default=False)
is_resume_reason = fields.Boolean(string="Resume Reason", default=False)
is_family_return_reason = fields.Boolean(string="Family Return Reason",default=False)
is_incomplete_visit_reason = fields.Boolean(string="Incomplete Visit Reason",default=False)
active = fields.Boolean(default=True)
entity_type = fields.Selection([('family', 'Family'),('member', 'Member')],string='Entity Type')
allow_service = fields.Boolean(string="Allow Service Use", default=False)
days_before_final_suspend = fields.Integer(string="Days Before Final Suspension",
default=0,help="Number of days before the suspension becomes final.")
suspend_type = fields.Selection(
selection=[('temporarily_suspend', 'Temporarily Suspended'), ('suspend', 'Suspend')], string="Suspend Type",)
need_service_manager_approval = fields.Boolean(
string="Needs Service Manager Approval"
)
check_all_members_non_benefit = fields.Boolean(string="Check All Members Non-Benefit",default=False)
class ReturnReason(models.Model):
_name = "return.reason"
_description = "Return Reasons"
name = fields.Char(string="Name", required=True)
active = fields.Boolean(string="Active", default=True)
class BranchSettings(models.Model):
_name = 'branch.settings'
_description = "Branch Settings"
name = fields.Char(related='branch.name')
branch = fields.Many2one('hr.department',string='Branch',domain =[('is_branch', '=', True)])
manager_id = fields.Many2one('hr.employee', related='branch.manager_id')
operation_manager_id = fields.Many2one('hr.employee', related='branch.operation_manager_id')
branch_type = fields.Selection(
selection=[
('branches', 'Branches'),
('governorates', 'Governorates')],
string='Branch Type')
city_id = fields.Many2one('res.country.city')
has_employees = fields.Boolean('Has Employees' ,defualt=True)
replacement_branch_id = fields.Many2one(
'branch.settings',
string="Replacement Branch"
)
class RelationSettings(models.Model):
_name = 'relation.settings'
_description = "Relation Settings"
name = fields.Char(string='name')
relation_type = fields.Selection(
[('son', _('Son')), ('daughter', _('Daughter')),('mother', _('Mother')),('replacement_mother', _('Replacement Mother')),('other relation', _('Other Relation'))])
age_difference = fields.Integer()
grace_period_days = fields.Integer(
string="Grace Period After Age Limit (Days)",
default=0,
help="Number of days the member remains eligible for benefits after reaching the configured age limit."
)
class LocationSettings(models.Model):
_name = 'location.settings'
_description = "Location Settings"
name = fields.Char(string='name')
location_type = fields.Selection([('member', _('Member')), ('mother_location', _('Mother Location'))])
is_benefit = fields.Boolean(string='Is Benefit?')
is_far_from_family = fields.Boolean(string='Is Far From Family?')
class AttachmentsSettings(models.Model):
_name = 'attachments.settings'
_description = "Attachments Settings"
_order = 'family_appearance_seq,member_appearance_seq,income_appearance_seq asc'
name = fields.Char(string='name')
hobby_id = fields.Many2one('hobbies.settings',string='Hobbies')
diseases_id = fields.Many2one('diseases.settings',string='Diseases')
disabilities_id = fields.Many2one('disabilities.settings',string='Disabilities')
attach_type = fields.Selection(
[('family_attach', _('Family Attach')), ('member_attach', _('Member Attach')), ('hobbies_attach', _('Hobbies Attach')),
('diseases_attach', _('Diseases Attach')), ('disabilities_attach', _('Disabilities Attach')), ('income_attach', _('Income Attach')), ('expense_attach', _('Expense Attach')), ('exams_attach', _('Exams Attach'))])
is_required = fields.Boolean(string='Is Required?')
is_default = fields.Boolean(string='Is Default?')
show_in_portal = fields.Boolean(default=True)
family_appearance_seq = fields.Integer(string='Appearance Sequence')
member_appearance_seq = fields.Integer(string='Appearance Sequence')
income_appearance_seq = fields.Integer(string='Appearance Sequence')
is_mother_salary = fields.Boolean(string="Is Mother Salary", default=False)
parent_id = fields.Many2one('attachments.settings',string='Parent')
child_ids = fields.One2many('attachments.settings','parent_id',string='Children')
@api.constrains('parent_id')
def _check_no_recursive_parent(self):
for rec in self:
parent = rec.parent_id
while parent:
if parent == rec:
raise ValidationError(
"Recursive hierarchy is not allowed."
)
parent = parent.parent_id
class EducationIlliterateReason(models.Model):
_name = 'education.illiterate.reason'
_description = "Education Illiterate Reason"
name = fields.Char(string='name')
class EducationDelayReason(models.Model):
_name = 'education.delay.reason'
_description = "Education Delay Reason"
name = fields.Char(string='Name', required=True)
class IncomeType(models.Model):
_name = 'income.type'
_description = "Income Type"
name = fields.Char(string='name')
class LoanGiver(models.Model):
_name = 'loan.giver'
_description = "LoanGiver"
name = fields.Char(string='name')
class LoanReason(models.Model):
_name = 'loan.reason'
_description = "Loan Reason"
name = fields.Char(string='name')
class HobbiesSettings(models.Model):
_name = 'hobbies.settings'
name = fields.Char(string="Name")
class DiseasesSettings(models.Model):
_name = 'diseases.settings'
name = fields.Char(string="Name")
class DisabilitiesSettings(models.Model):
_name = 'disabilities.settings'
name = fields.Char(string="Name")
class ExceptionReason(models.Model):
_name = 'exception.reason'
name = fields.Char(string="Name")
class MaritalStatus(models.Model):
_name = 'marital.status'
name = fields.Char(string="Name")
is_benefit = fields.Boolean(string='Is Benefit?')
is_dead = fields.Boolean(string='Is Dead?')
class AgeCategory(models.Model):
_name = 'age.category'
min_age = fields.Integer(string="From")
max_age = fields.Integer(string="To")
name = fields.Char(string="Name", compute="_compute_name", store=True)
@api.depends('min_age', 'max_age')
def _compute_name(self):
for record in self:
if record.min_age is not None and record.max_age is not None:
record.name = f"[{record.min_age}:{record.max_age}]"
else:
record.name = ""
class ComplaintsCategory(models.Model):
_name = 'complaints.category'
def _get_default_color(self):
return randint(1, 11)
name = fields.Char('Category Name', required=True, translate=True)
color = fields.Integer('Color', default=_get_default_color)
class ServiceAttachmentsSettings(models.Model):
_name = 'service.attachments.settings'
_description = "Service Attachments Settings"
name = fields.Char(string='name')
service_attach = fields.Many2many('ir.attachment','rel_service_attachments', 'service_id', 'attach_id',string="Attachment")
service_type = fields.Selection(
[('rent', 'Rent'), ('home_restoration', 'Home Restoration'), ('alternative_housing', 'Alternative Housing'),
('home_maintenance', 'Home Maintenance'), ('complete_building_house', 'Complete Building House'), ('electrical_devices', 'Electrical Devices'),
('home_furnishing', 'Home furnishing')
, ('electricity_bill', 'Electricity bill'), ('water_bill', 'Water bill'), ('buy_car', 'Buy Car'),
('recruiting_driver', 'Recruiting Driver')
, ('transportation_insurance', 'Transportation Insurance'), ('debits', 'Debits'),
('health_care', 'Health Care'),
('providing_medicines_medical_devices_and_needs_the_disabled',
'Providing Medicines Medical Devices And Needs The Disabled'),
('recruiting_domestic_worker_or_nurse', 'Recruiting a domestic worker or nurse'), ('marriage', 'Marriage'),
('eid_gift', 'Eid gift'),
('winter_clothing', 'Winter clothing'), ('ramadan_basket', 'Ramadan basket'),
('natural_disasters', 'Natural disasters'), ('legal_arguments', 'Legal arguments')],string='Service Type',related="service_id.service_type")
service_id = fields.Many2one('services.settings',string='Service')
service_request_id = fields.Many2one('service.request',string='Service Request')
previous_service_attachment_settings_id = fields.Many2one('service.attachments.settings', readonly=True)
notes = fields.Text(string='Notes')
state = fields.Selection(selection=[
('draft', 'Draft'),
('waiting_family', 'Waiting Family'),
('researcher', 'Researcher'),
('waiting_approve', 'Waiting for Operation Manager'),
('first_approve', 'Waiting for Branch Manager'),
('family_services_manager', 'Waiting Family Services Manager'),
('legal_department', 'Waiting Legal Department'),
('projects_department', 'Waiting Projects Department'),
('gm_assistant', 'Waiting Assistant General Manager'),
('accounting_approve', 'Accounting Approve'),
('return_to_bank', 'Return to Bank'),
('approval_of_beneficiary_services', 'Approval of beneficiary services'),
('send_request_to_supplier', 'Send Request To Supplier'),
('family_received_device', 'Family Received Device'),
('refused', 'Refused')
], string='State', default='waiting_family')
class HomeMaintenanceItems(models.Model):
_name = 'home.maintenance.items'
maintenance_items_id = fields.Many2one('home.maintenance.lines', string="Maintenance Items")
service_request_id = fields.Many2one('service.request',string='Service Request')
class HomeFurnishingItems(models.Model):
_name = 'home.furnishing.items'
home_furnishing_items = fields.Many2one('home.furnishing.lines', string='Furnishing Items')
furnishing_cost = fields.Float(string='Furnishing Cost')
price_first = fields.Float(string='Price First')
price_first_attach = fields.Many2many('ir.attachment','rel_first_price_attachments', 'furnishing_id', 'attach_id',string="First Price Attachment")
price_second = fields.Float(string='Price Second')
price_second_attach = fields.Many2many('ir.attachment','rel_second_price_attachments', 'furnishing_id', 'attach_id',string="Second Price Attachment")
service_request_id = fields.Many2one('service.request',string='Service Request')
class PropertyTypeSettings(models.Model):
_name = 'property.type.settings'
_description = 'Property Type Settings'
_order = 'name'
name = fields.Char(string="Name", required=True)
type = fields.Selection([
('ownership', 'Ownership'),
('rent', 'Rent')
], string="Property Type", required=True)
is_shared = fields.Boolean(string="Shared", default=False)
active = fields.Boolean(string="Active", default=True)
unavailable_service_ids = fields.Many2many(
'services.settings',
string="Unavailable Services",
help="Services that are not available for families or members with this property type"
)
class RentContract(models.Model):
_name = 'rent.contract'
_description = 'Rent Contract'
_inherit = ['mail.thread', 'mail.activity.mixin']
_order = 'create_date desc, id desc'
name = fields.Char(string='Contract Number',required=True,copy=False,tracking=True)
family_id = fields.Many2one('grant.benefit',string='Family',required=True,ondelete='cascade')
member_id = fields.Many2one('family.member',string='Member (Tenant)',
domain="""[
('benefit_id', '=', family_id),
('education_status', '=', 'educated'),
('member_education_status_ids', '!=', False),
('member_education_status_ids.case_study', '=', 'continuous')
]"""
)
contract_type = fields.Selection([
('fixed', 'Fixed Term'),
('unlimited', 'Indefinite'),
], string='Contract Type', required=True, default='fixed', tracking=True)
start_date = fields.Date(string='Start Date', required=True)
end_date = fields.Date(string='End Date')
payment_type = fields.Selection([
('1', 'Yearly'),
('2', 'Half-yearly'),
('4', 'Quarterly'),
('12', 'Monthly'),
], string='Payment Type', required=True, default='2')
rent_amount = fields.Float(string='Rent Amount', required=True)
contract_attachment = fields.Many2many(
'ir.attachment', 'rent_contract_attachment_rel',
'contract_id', 'attachment_id',
string='Contract Attachment'
)
electricity_bill_attachment = fields.Many2many(
'ir.attachment', 'rent_electricity_bill_rel',
'contract_id', 'attachment_id',
string='Electricity Bill Attachment'
)
state = fields.Selection([
('active', 'Active'),
('expired', 'Expired'),
], string='Status', default='active', tracking=True)
landlord_type = fields.Selection([
('family', 'Family'),
('member', 'Member / Student'),
], string='Landlord Type', default='family', required=True)
@api.onchange('end_date', 'start_date')
def _onchange_contract_dates(self):
if self.end_date and self.start_date and self.end_date < self.start_date:
raise ValidationError(_("End Date cannot be before Start Date."))
@api.onchange('landlord_type')
def _onchange_landlord_type(self):
for rec in self:
if rec.landlord_type == 'family':
rec.member_id = False