From 78ad0d2a487b29795587f70d941089202f04e9f1 Mon Sep 17 00:00:00 2001 From: eman Date: Tue, 5 Nov 2024 15:37:17 +0200 Subject: [PATCH] Rent Customization --- odex25_ensan/odex_benefit/__manifest__.py | 2 +- odex25_ensan/odex_benefit/models/benefit.py | 1 + .../odex_benefit/models/service_request.py | 135 ++++++++++++++++-- .../odex_benefit/security/security_view.xml | 7 +- .../odex_benefit/views/benefit_view.xml | 1 + .../odex_benefit/views/service_request.xml | 62 ++++++-- .../odex_benefit/views/services_settings.xml | 14 +- .../models/service_request.py | 2 +- 8 files changed, 192 insertions(+), 32 deletions(-) diff --git a/odex25_ensan/odex_benefit/__manifest__.py b/odex25_ensan/odex_benefit/__manifest__.py index 3e929e6b9..427c769aa 100644 --- a/odex25_ensan/odex_benefit/__manifest__.py +++ b/odex25_ensan/odex_benefit/__manifest__.py @@ -8,7 +8,7 @@ 'license': 'GPL-3', 'author': 'Expert Ltd', 'depends': ['base', 'takaful_core', 'website', 'account', 'report_xlsx', 'sale', 'product', 'stock', 'hr', - 'purchase','web_google_maps'], + 'purchase','web_google_maps','odex25_account_payment_fix'], 'data': [ 'security/security_view.xml', 'security/ir.model.access.csv', diff --git a/odex25_ensan/odex_benefit/models/benefit.py b/odex25_ensan/odex_benefit/models/benefit.py index f52895639..0d0fa686d 100644 --- a/odex25_ensan/odex_benefit/models/benefit.py +++ b/odex25_ensan/odex_benefit/models/benefit.py @@ -408,6 +408,7 @@ class GrantBenefitProfile(models.Model): rent_start_date = fields.Date(string='Rent Start Date') rent_end_date = fields.Date(string='Rent End Date') rent_attachment = fields.Many2many('ir.attachment','rel_rent_attachment_attachment','benefit_id','attachment_id',string='Rent Attachment') + payment_type = fields.Selection([('1', 'Yearly'),('2', 'Half Year'),('4', 'Quarterly')],string='Payment Type') housing_cat = fields.Selection([ ('excellent', 'Excellent'), ('good', 'Good'), diff --git a/odex25_ensan/odex_benefit/models/service_request.py b/odex25_ensan/odex_benefit/models/service_request.py index 1b3373e90..b302168c6 100644 --- a/odex25_ensan/odex_benefit/models/service_request.py +++ b/odex25_ensan/odex_benefit/models/service_request.py @@ -1,3 +1,4 @@ +from gevent.os import nb_write from odoo import fields, models, api, _ from odoo.exceptions import UserError, ValidationError from datetime import timedelta @@ -26,16 +27,38 @@ class ServiceRequest(models.Model): service_cat = fields.Many2one('services.settings',string='Service Cat.') service_attach = fields.Many2many('ir.attachment', 'rel_service_attachment_service_request', 'service_request_id','attachment_id', string='Service Attachment') requested_service_amount = fields.Float(string="Requested Service Amount") + #yearly Estimated Rent Amount estimated_rent_amount = fields.Float(string="Estimated Rent Amount",compute="_get_estimated_rent_amount") + #The value of payment by payment method(yearly-half-quartarly) + estimated_rent_amount_payment = fields.Float(string="Estimated Rent Amount Payment",compute="_get_estimated_rent_amount_payment") paid_rent_amount = fields.Float(string="Paid Rent Amount",compute="_get_paid_rent_amount") service_type = fields.Selection([('rent', 'Rent')],string='Service Type',related='service_cat.service_type') # is_alternative_housing = fields.Boolean(string='Is Alternative Housing?') - rent_contract_number = fields.Char(string="Rent Contract Number",related ="family_id.contract_num") - rent_start_date = fields.Date(string='Rent Start Date',related ="family_id.rent_start_date") - rent_end_date = fields.Date(string='Rent End Date' ,related ="family_id.rent_end_date") - rent_amount = fields.Float(string='Rent Amount',related ="family_id.rent_amount") - rent_attachment = fields.Many2many('ir.attachment', 'rel_rent_attachment_service_request', 'service_request_id', 'attachment_id',string='Rent Attachment',related ="family_id.rent_attachment") + rent_contract_number = fields.Char(string="Rent Contract Number",compute='_compute_rent_details',store=True) + rent_start_date = fields.Date(string='Rent Start Date',compute='_compute_rent_details',store=True) + rent_end_date = fields.Date(string='Rent End Date' ,compute='_compute_rent_details',store=True) + rent_amount = fields.Float(string='Rent Amount',compute='_compute_rent_details',store=True) + rent_amount_payment = fields.Float(string='Rent Amount Payment',compute ='_get_rent_amount_payment') + payment_type = fields.Selection([('1', 'Yearly'),('2', 'Half Year'),('4', 'Quarterly')],string='Payment Type',compute='_compute_rent_details',store=True) + rent_attachment = fields.Many2many('ir.attachment', 'rel_rent_attachment_service_request', 'service_request_id', 'attachment_id',string='Rent Attachment',compute='_compute_rent_details',store=True) rent_payment_date = fields.Date(string='Rent Payment Date') + rent_payment_date_exception = fields.Boolean(string='Rent Payment Date Exception?') + start = fields.Date(string="Start Date") + end = fields.Date(string='End Date') + #New Rent Contract + new_rent_contract = fields.Boolean(string='New Rent Contract?') + new_start = fields.Date(string="Start Date") + new_end = fields.Date(string='End Date') + new_rent_contract_number = fields.Char(string="Rent Contract Number") + new_rent_start_date = fields.Date(string='Rent Start Date') + new_rent_end_date = fields.Date(string='Rent End Date') + new_rent_amount = fields.Float(string='Rent Amount') + new_rent_amount_payment = fields.Float(string='New Rent Amount Payment',compute='_get_new_rent_amount_payment') + new_payment_type = fields.Selection([('1', 'Yearly'), ('2', 'Half Year'), ('4', 'Quarterly')], string='Payment Type') + new_rent_attachment = fields.Many2many('ir.attachment', 'rel_rent_attachment_service_request', 'service_request_id', + 'attachment_id', string='Rent Attachment') + new_rent_payment_date = fields.Date(string='Rent Payment Date') + new_rent_payment_date_exception = fields.Boolean(string='Rent Payment Date Exception?') # Rent details for member member_rent_contract_number = fields.Char(string="Rent Contract Number") member_rent_start_date = fields.Date(string='Rent Start Date') @@ -64,6 +87,13 @@ class ServiceRequest(models.Model): ('refused', 'Refused'), ], string='state', default="draft", tracking=True) + @api.model + def search(self, args, offset=0, limit=None, order=None, count=False): + if self.env.user and self.env.user.id and self.env.user.has_group( + "odex_benefit.group_benefit_accountant_accept"): + args += [('accountant_id', '=', self.env.user.id)] + return super(ServiceRequest, self).search(args, offset, limit, order, count) + @api.model def create(self, vals): res = super(ServiceRequest, self).create(vals) @@ -71,12 +101,59 @@ class ServiceRequest(models.Model): res.name = self.env['ir.sequence'].sudo().next_by_code('service.request.sequence') or _('New') return res + def write(self, vals): + # Define the list of fields you want to check + new_rent_fields = ['new_rent_contract_number', 'new_rent_start_date', 'new_rent_end_date', 'new_rent_amount', + 'new_payment_type', 'new_rent_attachment'] + + # Call the original write method + result = super(ServiceRequest, self).write(vals) + + # Prepare values for family_id write, only if any of the fields are present in vals + update_values = {} + if any(field in vals for field in new_rent_fields): + # Use `get` to avoid KeyError if a field is missing in vals + update_values = { + 'contract_num': vals.get('new_rent_contract_number'), + 'rent_start_date': vals.get('new_rent_start_date'), + 'rent_end_date': vals.get('new_rent_end_date'), + 'rent_amount': vals.get('new_rent_amount'), + 'payment_type': vals.get('new_payment_type'), + } + + # Check if 'new_rent_attachment' exists in vals before updating + if 'new_rent_attachment' in vals: + update_values['rent_attachment'] = vals['new_rent_attachment'] + + # Write the prepared update values to `family_id` + self.family_id.write(update_values) + + return result + def unlink(self): for request in self: if request.state not in ['draft']: raise UserError(_('You cannot delete this record')) return super(ServiceRequest, self).unlink() + @api.depends('family_id') + def _compute_rent_details(self): + for rec in self: + # Compute values only if they are not already set + if rec.family_id: + if not rec.rent_contract_number: + rec.rent_contract_number = rec.family_id.contract_num + if not rec.rent_start_date: + rec.rent_start_date = rec.family_id.rent_start_date + if not rec.rent_end_date: + rec.rent_end_date = rec.family_id.rent_end_date + if not rec.rent_amount: + rec.rent_amount = rec.family_id.rent_amount + if not rec.payment_type: + rec.payment_type = rec.family_id.payment_type + if not rec.rent_attachment: + rec.rent_attachment = rec.family_id.rent_attachment + def _get_estimated_rent_amount(self): for rec in self: rec.estimated_rent_amount = 0.0 # Default value @@ -100,9 +177,31 @@ class ServiceRequest(models.Model): rec.estimated_rent_amount = item.estimated_rent_governorate * ( item.discount_rate_shared_housing if is_shared_rent else 1) + def _get_estimated_rent_amount_payment(self): + for rec in self: + if rec.estimated_rent_amount and rec.payment_type: + rec.estimated_rent_amount_payment = rec.estimated_rent_amount / int(rec.payment_type) + elif rec.estimated_rent_amount and rec.new_payment_type: + rec.estimated_rent_amount_payment = rec.estimated_rent_amount / int(rec.new_payment_type) + else: + rec.estimated_rent_amount_payment = 0.0 + + def _get_rent_amount_payment(self): + for rec in self: + if rec.rent_amount and rec.payment_type: + rec.rent_amount_payment = rec.rent_amount / int(rec.payment_type) + else: + rec.rent_amount_payment = 0.0 + def _get_new_rent_amount_payment(self): + for rec in self: + if rec.new_rent_amount and rec.new_payment_type: + rec.new_rent_amount_payment = rec.new_rent_amount / int(rec.new_payment_type) + else: + rec.new_rent_amount_payment = 0.0 + def _get_paid_rent_amount(self): for rec in self: - rec.paid_rent_amount = min(rec.estimated_rent_amount, rec.requested_service_amount) + rec.paid_rent_amount = min(rec.estimated_rent_amount_payment, rec.requested_service_amount) def _get_added_amount_if_mother_dead(self): for rec in self: @@ -161,14 +260,18 @@ class ServiceRequest(models.Model): if rec.service_cat.service_type == 'home_restoration' and rec.family_id.property_type != 'ownership' and rec.family_id.property_type != 'ownership_shared' and rec.family_id.property_type != 'charitable' and rec.benefit_type == 'family': raise UserError(_("You cannot benefit from this service (property type not ownership)")) - @api.onchange('rent_payment_date') + @api.onchange('rent_payment_date','new_rent_payment_date') def onchange_rent_payment_date(self): today_date = fields.Date.today() for rec in self: - if rec.rent_payment_date : + if rec.rent_payment_date and not rec.rent_payment_date_exception and not rec.new_rent_payment_date: month_before_rent_payment_date = rec.rent_payment_date - timedelta(days=30) if today_date > month_before_rent_payment_date: raise UserError(_("You Should request At least a month ago rent payment date")) + if rec.new_rent_payment_date and not rec.new_rent_payment_date_exception: + new_month_before_rent_payment_date = rec.new_rent_payment_date - timedelta(days=30) + if today_date > new_month_before_rent_payment_date: + raise UserError(_("You Should request At least a month ago rent payment date")) @api.onchange('requested_service_amount','benefit_type','date') def onchange_requested_service_amount(self): for rec in self: @@ -191,6 +294,22 @@ class ServiceRequest(models.Model): if rec.member_id and rec.member_id.member_location != 'study_inside_saudi_arabia': raise UserError(_("You Cannot request Service if you not study inside Saudi Arabia")) + @api.onchange('start', 'end', 'rent_start_date', 'rent_end_date','new_start', 'new_end', 'new_rent_start_date', 'new_rent_end_date', 'new_rent_contract') + def _check_date_range(self): + for rec in self: + # Ensure both start and end dates are set + if rec.start and rec.end and rec.rent_start_date and rec.rent_end_date and not rec.new_rent_contract: + # Check if `start` and `end` are within `rent_start_date` and `rent_end_date` + if not (rec.rent_start_date <= rec.start <= rec.rent_end_date and + rec.rent_start_date <= rec.end <= rec.rent_end_date): + raise UserError( + "The Start Date and End Date must be within the Rent Start Date and Rent End Date range.") + if rec.new_start and rec.new_end and rec.new_rent_start_date and rec.new_rent_end_date and rec.new_rent_contract : + # Check if `start` and `end` are within `rent_start_date` and `rent_end_date` + if not (rec.new_rent_start_date <= rec.new_start <= rec.new_rent_end_date and + rec.new_rent_start_date <= rec.new_end <= rec.new_rent_end_date): + raise UserError( + "The Start Date and End Date must be within the Rent Start Date and Rent End Date range.") @api.onchange('family_category', 'sub_service_category') def _onchange_service_cat_domain(self): diff --git a/odex25_ensan/odex_benefit/security/security_view.xml b/odex25_ensan/odex_benefit/security/security_view.xml index b71e1bcc4..da4f2cae8 100644 --- a/odex25_ensan/odex_benefit/security/security_view.xml +++ b/odex25_ensan/odex_benefit/security/security_view.xml @@ -60,13 +60,16 @@ Accounting Accept - + + + + Accountant Accept + Accept income and expenses - diff --git a/odex25_ensan/odex_benefit/views/benefit_view.xml b/odex25_ensan/odex_benefit/views/benefit_view.xml index 26b4bebbe..c2f6affb1 100644 --- a/odex25_ensan/odex_benefit/views/benefit_view.xml +++ b/odex25_ensan/odex_benefit/views/benefit_view.xml @@ -766,6 +766,7 @@ + diff --git a/odex25_ensan/odex_benefit/views/service_request.xml b/odex25_ensan/odex_benefit/views/service_request.xml index 6e0cb4e5b..c6390f420 100644 --- a/odex25_ensan/odex_benefit/views/service_request.xml +++ b/odex25_ensan/odex_benefit/views/service_request.xml @@ -41,26 +41,26 @@ - - - + + + - + - + - - - - - - - + + + + + + + @@ -82,26 +82,62 @@
- + + +

+
+ + + +
+ + + + + +
+ + +
diff --git a/odex25_ensan/odex_benefit/views/services_settings.xml b/odex25_ensan/odex_benefit/views/services_settings.xml index b76a49fa0..65dce0637 100644 --- a/odex25_ensan/odex_benefit/views/services_settings.xml +++ b/odex25_ensan/odex_benefit/views/services_settings.xml @@ -10,15 +10,15 @@ - - - + + + + - - - - + + + diff --git a/odex25_ensan/odex_benefit_project/models/service_request.py b/odex25_ensan/odex_benefit_project/models/service_request.py index c1d126500..f25a733c7 100644 --- a/odex25_ensan/odex_benefit_project/models/service_request.py +++ b/odex25_ensan/odex_benefit_project/models/service_request.py @@ -18,7 +18,7 @@ class ServiceRequestInherit(models.Model): 'name': (_('Home Restoration Service')) +"/"+ rec.family_id.name +"/"+ rec.family_id.code, 'partner_id': rec.service_producer_id.id, 'beneficiary_id': rec.family_id.partner_id.id, - 'category_id' : rec.service_cat.category_id, + 'category_id' : rec.service_cat.category_id.id, 'requested_service_amount' : rec.requested_service_amount, 'restoration_max_amount' : rec.restoration_max_amount, 'has_money_field_is_appearance': rec.has_money_field_is_appearance,