diff --git a/odex25_benefit/odex_benefit/MODULE_REVIEW.md b/odex25_benefit/odex_benefit/MODULE_REVIEW.md
index 45686a709..5227af4b3 100644
--- a/odex25_benefit/odex_benefit/MODULE_REVIEW.md
+++ b/odex25_benefit/odex_benefit/MODULE_REVIEW.md
@@ -305,7 +305,7 @@
- `recurrence_period`: فترة التكرار (months/years)
- `recurrence_interval`: فترة التكرار
- `max_limit_type`: نوع الحد الأقصى (none/fixed/category/amount_person/etc.)
- - `max_limit_period`: فترة الحد الأقصى (request/individual/month/year/recurrence_period)
+ - `max_limit_period`: فترة الحد الأقصى (request/individual/month/year)
- **الموافقات:**
- `needs_beneficiary_manager_approval`: يحتاج موافقة مدير المستفيدين؟
diff --git a/odex25_benefit/odex_benefit/i18n/ar_001.po b/odex25_benefit/odex_benefit/i18n/ar_001.po
index 5e62a85f8..6affb6760 100644
--- a/odex25_benefit/odex_benefit/i18n/ar_001.po
+++ b/odex25_benefit/odex_benefit/i18n/ar_001.po
@@ -16531,16 +16531,6 @@ msgstr "للفرد"
msgid "Per Month"
msgstr "للشهر"
-#. module: odex_benefit
-#: model:ir.model.fields.selection,name:odex_benefit.selection__services_settings__max_limit_period__year
-msgid "Per Year"
-msgstr "للسنة"
-
-#. module: odex_benefit
-#: model:ir.model.fields.selection,name:odex_benefit.selection__services_settings__max_limit_period__recurrence_period
-msgid "For Allowed Recurrence Period"
-msgstr "لفترة التكرار المسموح"
-
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_services_settings__max_months_limit
msgid "Maximum Number of Months"
diff --git a/odex25_benefit/odex_benefit/models/family_expense_line.py b/odex25_benefit/odex_benefit/models/family_expense_line.py
index e7254e2de..cb996bdb0 100644
--- a/odex25_benefit/odex_benefit/models/family_expense_line.py
+++ b/odex25_benefit/odex_benefit/models/family_expense_line.py
@@ -13,7 +13,7 @@ class BenefitExpenseLine(models.Model):
confirm_expense_id = fields.Many2one(comodel_name='confirm.benefit.expense', string='Confirm Benefit Expense',
ondelete='cascade')
- return_confirm_id = fields.Many2one('confirm.benefit.expense', string="Return Confirm", ondelete="set null", )
+ return_confirm_id = fields.Many2one('confirm.benefit.expense', string="Return Confirm", ondelete='cascade', )
family_id = fields.Many2one(comodel_name='grant.benefit', string='Family', required=True)
branch_id = fields.Many2one(comodel_name='branch.settings', string='Branch')
family_category_id = fields.Many2one(comodel_name='benefit.category', string='Family Category')
diff --git a/odex25_benefit/odex_benefit/models/service_request.py b/odex25_benefit/odex_benefit/models/service_request.py
index 1d21218b8..e9484c39e 100644
--- a/odex25_benefit/odex_benefit/models/service_request.py
+++ b/odex25_benefit/odex_benefit/models/service_request.py
@@ -1,8 +1,8 @@
from odoo import fields, models, api, _
from odoo.exceptions import UserError, ValidationError
-from datetime import datetime, timedelta
+from datetime import date,datetime, timedelta
from dateutil.relativedelta import relativedelta
-from odoo.tools import html_escape
+from odoo.tools import html_escape,html2plaintext
class ServiceRequest(models.Model):
@@ -39,7 +39,7 @@ class ServiceRequest(models.Model):
store=True)
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")
+ requested_service_amount = fields.Float(string="Requested Service Amount",copy=False)
# 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)
@@ -209,6 +209,9 @@ class ServiceRequest(models.Model):
compute='_compute_related_information_html', store=True, )
researcher_opinion = fields.Html(string='Specialist Opinion',tracking=True)
+ def action_create_project(self):
+ pass
+
@api.depends('service_cat', 'family_id', 'member_id', 'benefit_type')
def _compute_related_information_html(self):
for rec in self:
@@ -550,7 +553,7 @@ class ServiceRequest(models.Model):
def action_researcher_send_request(self):
for rec in self:
- if not rec.researcher_opinion or not rec.researcher_opinion.strip():
+ if not html2plaintext(rec.researcher_opinion or '').strip():
raise ValidationError(
_('Please write the specialist opinion before completing the action.')
)
@@ -582,6 +585,7 @@ class ServiceRequest(models.Model):
if rec.service_cat.needs_legal_approval:
rec.state = 'legal_department'
elif rec.service_cat.needs_project_management_approval:
+ rec.action_create_project()
rec.state = 'projects_department'
elif rec.service_cat.needs_beneficiary_manager_approval or rec.exception:
rec.state = 'gm_assistant'
@@ -591,6 +595,7 @@ class ServiceRequest(models.Model):
def action_legal_department_approve(self):
for rec in self:
if rec.service_cat.needs_project_management_approval:
+ rec.action_create_project()
rec.state = 'projects_department'
elif rec.service_cat.needs_beneficiary_manager_approval or rec.exception:
rec.state = 'gm_assistant'
@@ -762,7 +767,7 @@ class ServiceRequest(models.Model):
interval = rec.service_cat.recurrence_interval or 1
period = rec.service_cat.recurrence_period or 'months'
max_limit_type = rec.service_cat.max_limit_type
- special_services = ['home_furnishing', 'electrical_devices', 'alternative_housing']
+ special_services = ['electrical_devices', 'alternative_housing']
base_domain = [('family_id', '=', family_id), ('service_cat', '=', rec.service_cat.id),
('id', '!=', rec._origin.id), ('state', '!=', 'refused')]
if rec.benefit_type == "member":
@@ -968,20 +973,41 @@ class ServiceRequest(models.Model):
_("You cannot request this service for more than %s months.") % rec.service_cat.max_months_limit
)
rec.service_max_amount *= num_months
- elif rec.max_limit_period == "year":
- before_year_domain = base_domain + [('date', '>', date_before_year)]
- existing_requests_within_year = Service.search(before_year_domain)
- total_spent = sum(existing_requests_within_year.mapped('requested_service_amount'))
+ elif rec.max_limit_period == "calendar_year":
+ current_date = rec.date.date() if isinstance(rec.date, datetime) else rec.date
+ allowed_years = rec.service_cat.allowed_period or 1
+ start_year = current_date.year - (allowed_years - 1)
+ end_year = current_date.year
+
+ year_start = date(start_year, 1, 1)
+ year_end = date(end_year, 12, 31)
+
+ calendar_year_domain = base_domain + [
+ ('date', '>=', datetime.combine(year_start, datetime.min.time())),
+ ('date', '<=', datetime.combine(year_end, datetime.max.time())),
+ ]
+
+ existing_requests = Service.search(calendar_year_domain)
+ total_spent = sum(existing_requests.mapped('requested_service_amount'))
+ remaining_amount = rec.service_cat.max_amount - total_spent
+
+ rec.service_max_amount = max(remaining_amount, 0.0)
+ elif rec.max_limit_period == "year_from_request":
+ current_date = rec.date.date() if isinstance(rec.date, datetime) else rec.date
+ allowed_years = rec.service_cat.allowed_period or 1
+ period_start_date = current_date - relativedelta(years=allowed_years)
+ period_end_date = current_date
+
+ year_from_request_domain = base_domain + [
+ ('date', '>=', datetime.combine(period_start_date, datetime.min.time())),
+ ('date', '<=', datetime.combine(period_end_date, datetime.max.time())),
+ ]
+
+ existing_requests = Service.search(year_from_request_domain)
+ total_spent = sum(existing_requests.mapped('requested_service_amount'))
rec.service_max_amount = rec.service_cat.max_amount - total_spent
elif rec.max_limit_period == "individual":
rec.service_max_amount *= rec.service_benefit_count
- elif rec.max_limit_period == "recurrence_period":
- prev_requests = Service.search(base_domain)
- total_spent = sum(prev_requests.mapped('requested_service_amount'))
- remaining = rec.service_cat.max_amount - total_spent
- if remaining < 0:
- remaining = 0
- rec.service_max_amount = remaining
if rec.service_cat.service_type == 'marriage':
if rec.marriage_contract_date and rec.date:
request_date = rec.date.date() if isinstance(rec.date, datetime) else rec.date
diff --git a/odex25_benefit/odex_benefit/models/services_settings.py b/odex25_benefit/odex_benefit/models/services_settings.py
index e067e4b98..be5f40710 100644
--- a/odex25_benefit/odex_benefit/models/services_settings.py
+++ b/odex25_benefit/odex_benefit/models/services_settings.py
@@ -8,60 +8,69 @@ class ServicesSettings(models.Model):
service_name = fields.Char(string='Service Name')
benefit_type = fields.Selection(string='Benefit Type', selection=[('family', 'Family'), ('member', 'Member')])
- parent_service = fields.Many2one('services.settings',string='Parent Service')
+ parent_service = fields.Many2one('services.settings', string='Parent Service')
is_main_service = fields.Boolean(string='Is Main Service?')
is_service_producer = fields.Boolean(string='Is Service Producer?')
- service_producer_id = fields.Many2one('res.partner',string='Service Producer')
+ service_producer_id = fields.Many2one('res.partner', string='Service Producer')
is_this_service_for_student = fields.Boolean(string='Is Service For Student?')
- 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'),('buy_home','Buy Home'),('main_service','Main Service'),('normal_service', 'Normal Service')]
- ,string='Service Type')
+ 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'), ('buy_home', 'Buy Home'), ('main_service', 'Main Service'),
+ ('normal_service', 'Normal Service')]
+ , string='Service Type')
raise_amount_for_orphan = fields.Float(string='Raise Amount For Orphan')
- rent_lines = fields.One2many('rent.lines','services_settings_id')
- attachment_lines = fields.One2many('service.attachments.settings','service_id')
- #Fields for home restoration
- category_amount_lines = fields.One2many('category.amount.line','services_settings_id')
+ rent_lines = fields.One2many('rent.lines', 'services_settings_id')
+ attachment_lines = fields.One2many('service.attachments.settings', 'service_id')
+ # Fields for home restoration
+ category_amount_lines = fields.One2many('category.amount.line', 'services_settings_id')
rent_amount_for_alternative_housing = fields.Float(string='Rent Amount For Alternative Housing')
rent_period = fields.Integer('Rent Period')
- home_maintenance_lines = fields.One2many('home.maintenance.lines','services_settings_id')
+ home_maintenance_lines = fields.One2many('home.maintenance.lines', 'services_settings_id')
benefit_category_ids = fields.Many2many('benefit.category', string='Allowed Categories')
- account_id = fields.Many2one('account.account',string='Expenses Account',domain="[('user_type_id.id','=',15)]")
- accountant_id = fields.Many2one('res.users',string='Accountant')
- #For Electrical Devices
- electrical_devices_lines = fields.One2many('electrical.devices','services_settings_id')
- #Home Furnishing
- home_furnishing_lines = fields.One2many('home.furnishing.lines','services_settings_id')
+ account_id = fields.Many2one('account.account', string='Expenses Account', domain="[('user_type_id.id','=',15)]")
+ accountant_id = fields.Many2one('res.users', string='Accountant')
+ # For Electrical Devices
+ electrical_devices_lines = fields.One2many('electrical.devices', 'services_settings_id')
+ # Home Furnishing
+ home_furnishing_lines = fields.One2many('home.furnishing.lines', 'services_settings_id')
max_furnishing_amount_if_exception = fields.Float(string='Max Furnishing Amount (Exception)')
bill_lines = fields.One2many('bill.lines', 'services_settings_id')
min_count_member = fields.Integer(string='Mini Count Member')
member_max_payroll = fields.Float(string='Member Max Payroll')
fatherless_member_amount = fields.Float(string='Fatherless Member Amount')
orphan_member_amount = fields.Float(string='Orphan Member Amount')
- #Buy Home
+ # Buy Home
limit_person_line_ids = fields.One2many('service.limit.person.line', 'services_settings_id')
buy_home_max_total_amount = fields.Float(string='Buy Home Max Total Amount')
home_age = fields.Integer(string='Home Age')
required_attach = fields.Boolean(string='Required Attach')
is_seasonal_service = fields.Boolean(string='Is Seasonal Service?')
active = fields.Boolean('Active', default=True)
- show_in_portal = fields.Boolean(string="Show in Portal",copy=False)
- service_number = fields.Char(string="Service Number",copy=False)
+ show_in_portal = fields.Boolean(string="Show in Portal", copy=False)
+ service_number = fields.Char(string="Service Number", copy=False)
service_category = fields.Selection([
('emergency', 'Emergency'),
('permanent', 'Permanent'),
('exceptional', 'Exceptional'),
('seasonal', 'Seasonal'),
- ], string="Service Category",copy=False)
+ ], string="Service Category", copy=False)
company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.user.company_id)
currency_id = fields.Many2one('res.currency', string="Currency", related='company_id.currency_id')
- max_amount = fields.Monetary(string="Maximum Amount", currency_field='currency_id',copy=False)
- max_age = fields.Integer(string="Maximum Age",copy=False)
+ max_amount = fields.Monetary(string="Maximum Amount", currency_field='currency_id', copy=False)
+ max_age = fields.Integer(string="Maximum Age", copy=False)
service_description = fields.Text(string="Service Description")
service_conditions = fields.Html(string="Service Conditions")
allowed_recurrence = fields.Selection([
@@ -71,7 +80,7 @@ class ServicesSettings(models.Model):
], string="Allowed Recurrence", default='once')
recurrence_period = fields.Selection([
('months', 'Months'),
- ('years', 'Years'),],
+ ('years', 'Years'), ],
string="Recurrence Period", default='months'
)
recurrence_interval = fields.Integer(
@@ -100,9 +109,13 @@ class ServicesSettings(models.Model):
('request', 'Per Request'),
('individual', 'Per Individual'),
('month', 'Per Month'),
- ('year', 'Per Year'),
- ('recurrence_period', 'For Allowed Recurrence Period'),
+ ('year_from_request', 'Year from date of request'),
+ ('calendar_year', 'Calendar year'),
], string='Maximum Limit Period')
+ allowed_period = fields.Integer(
+ string='Maximum Allowed Period', default=1,
+ help='Specify the maximum allowed number of months or years based on the selected period type.'
+ )
max_months_limit = fields.Integer(
string='Maximum Number of Months',
help='Specify the maximum allowed number of months when the period type is monthly.'
@@ -112,7 +125,7 @@ class ServicesSettings(models.Model):
('none', 'None'),
('payment_order', 'Payment Order'),
('invoice', 'Invoice'),
- ], string='Payment Method',default="payment_order")
+ ], string='Payment Method', default="payment_order")
family_related_fields = fields.Many2many(
comodel_name='ir.model.fields',
relation='services_settings_family_field_rel',
@@ -138,6 +151,10 @@ class ServicesSettings(models.Model):
if self.benefit_type != 'member':
self.member_related_fields = [(5, 0, 0)]
+ @api.onchange('max_limit_period')
+ def _onchange_max_limit_period(self):
+ if self.max_limit_period not in ['year_from_request', 'calendar_year']:
+ self.allowed_period = 0
class RentLines(models.Model):
@@ -166,6 +183,7 @@ class CategoryAmountLine(models.Model):
services_settings_id = fields.Many2one('services.settings', string='Services Settings')
max_amount = fields.Float(string='Max Amount')
+
class HomeMaintenanceLines(models.Model):
_name = 'home.maintenance.lines'
_rec_name = 'maintenance_name'
@@ -173,6 +191,7 @@ class HomeMaintenanceLines(models.Model):
services_settings_id = fields.Many2one('services.settings', string='Services Settings')
maintenance_name = fields.Char(string='Maintenance Name')
+
class ElectricalDevices(models.Model):
_name = 'electrical.devices'
_rec_name = 'device_name'
@@ -181,10 +200,11 @@ class ElectricalDevices(models.Model):
max_count_member = fields.Integer(string='To')
device_name = fields.Char(string="Device Name")
allowed_quantity = fields.Integer(string='Allowed Quantity')
- account_id = fields.Many2one('account.account',string='Expenses Account',domain="[('user_type_id.id','=',15)]")
+ account_id = fields.Many2one('account.account', string='Expenses Account', domain="[('user_type_id.id','=',15)]")
services_settings_id = fields.Many2one('services.settings')
price_unit = fields.Float()
+
class HomeFurnishingLines(models.Model):
_name = 'home.furnishing.lines'
@@ -192,6 +212,7 @@ class HomeFurnishingLines(models.Model):
name = fields.Char(string="Furnishing Name")
max_furnishing_amount = fields.Float(string='Furnishing Amount')
+
class BillLines(models.Model):
_name = 'bill.lines'
@@ -201,10 +222,11 @@ class BillLines(models.Model):
max_amount_for_bill = fields.Float(string='Max Amount For Bill')
services_settings_id = fields.Many2one('services.settings', string='Services Settings')
+
class ServiceLimitByPersonLine(models.Model):
_name = 'service.limit.person.line'
min_count_member = fields.Integer(string='Minimum Number of Persons')
max_count_member = fields.Integer(string='Maximum Number of Persons')
amount = fields.Float(string='Amount')
- services_settings_id = fields.Many2one('services.settings', string='Services Settings')
\ No newline at end of file
+ services_settings_id = fields.Many2one('services.settings', string='Services Settings')
diff --git a/odex25_benefit/odex_benefit/views/benefit_view.xml b/odex25_benefit/odex_benefit/views/benefit_view.xml
index bee23f155..eb9281025 100644
--- a/odex25_benefit/odex_benefit/views/benefit_view.xml
+++ b/odex25_benefit/odex_benefit/views/benefit_view.xml
@@ -1677,7 +1677,7 @@
+ />
diff --git a/odex25_benefit/odex_benefit/views/family_expense_line_view.xml b/odex25_benefit/odex_benefit/views/family_expense_line_view.xml
index 4ea4307ca..a61c4b26b 100644
--- a/odex25_benefit/odex_benefit/views/family_expense_line_view.xml
+++ b/odex25_benefit/odex_benefit/views/family_expense_line_view.xml
@@ -18,6 +18,7 @@
+
diff --git a/odex25_benefit/odex_benefit/views/services_settings.xml b/odex25_benefit/odex_benefit/views/services_settings.xml
index ac95db2da..fef62ccf7 100644
--- a/odex25_benefit/odex_benefit/views/services_settings.xml
+++ b/odex25_benefit/odex_benefit/views/services_settings.xml
@@ -50,6 +50,11 @@
attrs="{'invisible':[('service_type','!=','marriage')]}"/>
+
+
+
@@ -67,9 +72,6 @@
-
-
diff --git a/odex25_benefit/odex_benefit/wizards/researcher_wizard.py b/odex25_benefit/odex_benefit/wizards/researcher_wizard.py
index 28d56a31d..f53958a45 100644
--- a/odex25_benefit/odex_benefit/wizards/researcher_wizard.py
+++ b/odex25_benefit/odex_benefit/wizards/researcher_wizard.py
@@ -62,6 +62,7 @@ class ReasearcherFamilyWizard(models.TransientModel):
assignment_type = fields.Selection([
('researcher', 'Assign Researcher'),
('assigned_researcher', 'Assign Assigned Researcher'),
+ ('end_assignment', 'End Assignment'),
], string='Assignment Type', default='researcher')
@api.depends('benefit_ids')
@@ -108,6 +109,8 @@ class ReasearcherFamilyWizard(models.TransientModel):
update_vals['researcher_id'] = self.researcher_team.id
elif self.assignment_type == 'assigned_researcher':
update_vals['assigned_researcher_id'] = self.researcher_team.id
+ elif self.assignment_type == 'end_assignment':
+ update_vals['assigned_researcher_id'] = False
benefit.with_context(bypass_attachments_requirement=True).write(update_vals)
specialist_name = self.researcher_team.name or _('Not Specified')
diff --git a/odex25_benefit/odex_benefit/wizards/researcher_wizard.xml b/odex25_benefit/odex_benefit/wizards/researcher_wizard.xml
index 40585e276..53494287c 100644
--- a/odex25_benefit/odex_benefit/wizards/researcher_wizard.xml
+++ b/odex25_benefit/odex_benefit/wizards/researcher_wizard.xml
@@ -61,10 +61,10 @@
+
-