diff --git a/odex25_benefit/odex_benefit/i18n/ar_001.po b/odex25_benefit/odex_benefit/i18n/ar_001.po
index 635746491..5e62a85f8 100644
--- a/odex25_benefit/odex_benefit/i18n/ar_001.po
+++ b/odex25_benefit/odex_benefit/i18n/ar_001.po
@@ -2752,7 +2752,6 @@ msgstr "بإمكانه النشر "
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_suspend_reason_wizard_form
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_visit_skip_otp_wizard_form
#: model_terms:ir.ui.view,arch_db:odex_benefit.visit_location_otp_wizard_form
-#: model_terms:ir.ui.view,arch_db:odex_benefit.view_assign_supervisor_wizard_form
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_visit_location_refusal_reason_wizard_form
msgid "Cancel"
msgstr "إلغاء"
@@ -10058,6 +10057,7 @@ msgstr "إعادة جدولة"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_changes_requests__researcher_ids
+#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__researcher_id
#: model:ir.model.fields,field_description:odex_benefit.field_family_complaints__researcher_id
#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__researcher_id
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__researcher_id
@@ -17366,19 +17366,12 @@ msgid "Third Approve"
msgstr "اعتماد مديرة خدمات المستفيدين الإيقاف"
#. module: odex_benefit
+#: code:addons/odex_benefit/models/seasonal_service.py:0
#: code:addons/odex_benefit/models/family_expense.py:0
#, python-format
msgid "Reason for Return"
msgstr "سبب الإرجاع"
-#. module: odex_benefit
-#: code:addons/odex_benefit/models/family_expense_line.py:0
-#: model_terms:ir.ui.view,arch_db:odex_benefit.view_assign_supervisor_wizard_form
-#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form
-#, python-format
-msgid "Assign to Supervisor"
-msgstr "إسناد للمشرف"
-
#. module: odex_benefit
#: code:addons/odex_benefit/models/family_expense_line.py:0
#, python-format
@@ -17413,41 +17406,6 @@ msgstr ""
msgid "Benefit Expense Reset"
msgstr "إعادة تعيين مصروفات الاسر"
-#. module: odex_benefit
-#: model:ir.model,name:odex_benefit.model_assign_supervisor_wizard
-msgid "Assign Supervisor Wizard"
-msgstr "معالج إسناد المشرف"
-
-#. module: odex_benefit
-#: model:ir.model.fields,field_description:odex_benefit.field_assign_supervisor_wizard__supervisor_id
-msgid "Supervisor"
-msgstr "المشرف"
-
-#. module: odex_benefit
-#: code:addons/odex_benefit/wizards/researcher_wizard.py:0
-#, python-format
-msgid ""
-"Assigned to Supervisor
Supervisor: %s
Assigned "
-"By: %s"
-msgstr ""
-"تم الإسناد إلى المشرف
المشرف: %s
تم الإسناد بواسطة: %s"
-
-#. module: odex_benefit
-#: code:addons/odex_benefit/wizards/researcher_wizard.py:0
-#, python-format
-msgid "Assigned to Supervisor"
-msgstr "تم الإسناد إلى المشرف"
-
-#. module: odex_benefit
-#: model_terms:ir.ui.view,arch_db:odex_benefit.view_assign_supervisor_wizard_form
-msgid "Select a supervisor..."
-msgstr "اختر مشرفًا..."
-
-#. module: odex_benefit
-#: model_terms:ir.ui.view,arch_db:odex_benefit.view_assign_supervisor_wizard_form
-msgid "Confirm Assignment"
-msgstr "تأكيد الإسناد"
-
#. module: odex_benefit
#: code:addons/odex_benefit/models/family_expense.py:0
#, python-format
@@ -17466,11 +17424,6 @@ msgstr "بانتظار المعالجة"
msgid "Processing Done"
msgstr "تمت المعالجة"
-#. module: odex_benefit
-#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__assigned_supervisor_id
-msgid "Assigned Supervisor"
-msgstr "المشرف"
-
#. module: odex_benefit
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_benefit_expense_line_form
msgid "Process"
@@ -17663,4 +17616,67 @@ msgstr "رقم الجوال"
#: code:addons/odex_benefit/models/benefit_config.py:0
#, python-format
msgid "Please enter a valid Saudi mobile number (example: 05xxxxxxxx)."
-msgstr "رجاءً أدخل رقم جوال سعودي صالح (مثال: 05xxxxxxxx)."
\ No newline at end of file
+msgstr "رجاءً أدخل رقم جوال سعودي صالح (مثال: 05xxxxxxxx)."
+
+#. module: odex_benefit
+#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__has_draft_return_lines
+msgid "Has Draft Return Lines"
+msgstr "هل يحتوي على سطور رجيع مسودة"
+
+#. module: odex_benefit
+#: code:addons/odex_benefit/models/family_expense.py:0
+#, python-format
+msgid "This action is only available for return calculations."
+msgstr "هذا الإجراء متاح فقط لحسابات الرجيع."
+
+#. module: odex_benefit
+#: code:addons/odex_benefit/models/family_expense.py:0
+#, python-format
+msgid "No return lines in draft state to send to specialist."
+msgstr "لا توجد سطور رجيع في حالة المسودة لإرسالها إلى الأخصائي."
+
+#. module: odex_benefit
+#: code:addons/odex_benefit/models/family_expense.py:0
+#, python-format
+msgid ""
+"The following families do not have an assigned researcher:\n"
+"%s\n"
+"\n"
+"Please assign researchers to these families before sending."
+msgstr "الأسر التالية ليس لديها أخصائي:\n"
+"%s\n"
+"\n"
+"يرجى إسناد أخصائيين إلى هذه الأسر قبل الإرسال."
+
+#. module: odex_benefit
+#: model:ir.model.fields,field_description:odex_benefit.field_service_request__researcher_opinion
+msgid "Specialist Opinion"
+msgstr "رأي الأخصائي"
+
+#. module: odex_benefit
+#: code:addons/odex_benefit/models/service_request.py:0
+#, python-format
+msgid "Please write the specialist opinion before completing the action."
+msgstr "يرجى كتابة رأي الأخصائي قبل إكمال الإجراء."
+
+#. module: odex_benefit
+#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form
+msgid "Send to Researchers"
+msgstr "إرسال إلى الأخصائيين"
+
+#. module: odex_benefit
+#: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_form
+msgid "Researcher Opinion"
+msgstr "رأي الأخصائي"
+
+#. module: odex_benefit
+#: code:addons/odex_benefit/wizards/reason_for_return_wizard.py:0
+#, python-format
+msgid ""
+"State Changed: %s → Calculated
Returned By: "
+"%s
Reason: %s"
+msgstr "تم تغيير الحالة: %s → تم الحساب
تم الإرجاع بواسطة: "
+"%s
السبب: %s"
+
+
+
diff --git a/odex25_benefit/odex_benefit/models/family_expense.py b/odex25_benefit/odex_benefit/models/family_expense.py
index 076d43b01..e2431ade1 100644
--- a/odex25_benefit/odex_benefit/models/family_expense.py
+++ b/odex25_benefit/odex_benefit/models/family_expense.py
@@ -98,6 +98,17 @@ class ConfirmBenefitExpense(models.Model):
line_domain_ids = fields.Many2many(comodel_name='benefit.expense.line', compute='_compute_domain_ids',
string="Return Line Domain",
)
+ has_draft_return_lines = fields.Boolean(string="Has Draft Return Lines",
+ compute='_compute_has_draft_return_lines', )
+
+ @api.depends('return_expense_line_ids')
+ def _compute_has_draft_return_lines(self):
+ for rec in self:
+ if rec.return_expense_line_ids:
+ draft_lines = rec.return_expense_line_ids.filtered(lambda l: l.state == 'draft')
+ rec.has_draft_return_lines = bool(draft_lines)
+ else:
+ rec.has_draft_return_lines = False
@api.depends('payment_order_id', 'payment_order_id.state', 'move_id', 'move_id.state')
def _compute_payment_move_state(self):
@@ -310,10 +321,9 @@ class ConfirmBenefitExpense(models.Model):
rec.family_monthly_othaime = sum(lines.mapped('family_monthly_othaime'))
rec.family_monthly_total = rec.family_monthly_income + rec.family_monthly_meals + rec.family_monthly_clotting
- expense_lines = lines.filtered(lambda l: not l.meal_card)
othaim_lines = lines.filtered('meal_card')
- rec.family_count_expense = len(expense_lines.mapped('family_id'))
- rec.member_count_expense = sum(expense_lines.mapped('benefit_member_count'))
+ rec.family_count_expense = len(lines.mapped('family_id'))
+ rec.member_count_expense = sum(lines.mapped('benefit_member_count'))
rec.family_count_othaim = len(othaim_lines.mapped('family_id'))
rec.member_count_othaim = sum(othaim_lines.mapped('benefit_member_count'))
@@ -332,6 +342,35 @@ class ConfirmBenefitExpense(models.Model):
self.sudo().action_accounting_transfer()
self.sudo().state = 'accounting_approve'
+ def action_send_to_researcher(self):
+ for rec in self:
+ if not rec.is_return_calculation:
+ raise UserError(_("This action is only available for return calculations."))
+
+ return_lines = rec.return_expense_line_ids.filtered(lambda l: l.state == 'draft')
+
+ if not return_lines:
+ raise UserError(_("No return lines in draft state to send to specialist."))
+ lines_without_researcher = self.env['benefit.expense.line']
+
+ for line in return_lines:
+ family = line.family_id
+ researcher = family.researcher_id if hasattr(family, 'researcher_id') else False
+
+ if not researcher:
+ lines_without_researcher |= line
+ continue
+ line.write({
+ 'researcher_id': researcher.id,
+ 'state': 'waiting_processing'
+ })
+ if lines_without_researcher:
+ families_without_specialist = lines_without_researcher.mapped('family_id.name')
+ raise UserError(_(
+ "The following families do not have an assigned researcher:\n%s\n\n"
+ "Please assign researchers to these families before sending."
+ ) % ", ".join(families_without_specialist))
+
def action_cancel(self):
self.state = 'cancel'
diff --git a/odex25_benefit/odex_benefit/models/family_expense_line.py b/odex25_benefit/odex_benefit/models/family_expense_line.py
index dd4216d98..e7254e2de 100644
--- a/odex25_benefit/odex_benefit/models/family_expense_line.py
+++ b/odex25_benefit/odex_benefit/models/family_expense_line.py
@@ -34,7 +34,7 @@ class BenefitExpenseLine(models.Model):
('waiting_processing', 'Waiting Processing'),
('processing_done', 'Processing Done'),
], string="Status", default='draft', tracking=True)
- assigned_supervisor_id = fields.Many2one('hr.employee', string='Assigned Supervisor', tracking=True, copy=False)
+ researcher_id = fields.Many2one("committees.line", string="Researcher", tracking=True, copy=False)
@api.depends('family_monthly_income', 'family_monthly_clotting', 'family_monthly_meals')
def _compute_total_family_expenses(self):
@@ -55,16 +55,6 @@ class BenefitExpenseLine(models.Model):
}
}
- def action_assign_supervisor(self):
- self.ensure_one()
- return {
- 'name': _('Assign to Supervisor'),
- 'type': 'ir.actions.act_window',
- 'res_model': 'assign.supervisor.wizard',
- 'view_mode': 'form',
- 'target': 'new',
- }
-
def action_process_return(self):
self.ensure_one()
if self.state != 'waiting_processing':
diff --git a/odex25_benefit/odex_benefit/models/seasonal_service.py b/odex25_benefit/odex_benefit/models/seasonal_service.py
index c5be0c2b1..f36fdd84b 100644
--- a/odex25_benefit/odex_benefit/models/seasonal_service.py
+++ b/odex25_benefit/odex_benefit/models/seasonal_service.py
@@ -384,11 +384,14 @@ class SeasonalService(models.Model):
rec.state = 'draft'
def action_reset_to_calculated(self):
- for rec in self:
- rec.service_requests_ids.write({'state': 'draft'})
- rec.payment_order_id.unlink()
- rec.vendor_bill.unlink()
- rec.state = 'calculated'
+ self.ensure_one()
+ return {
+ 'name': _('Reason for Return'),
+ 'type': 'ir.actions.act_window',
+ 'res_model': 'reason.for.return.wizard',
+ 'view_mode': 'form',
+ 'target': 'new',
+ }
def action_open_related_move_records(self):
return {
diff --git a/odex25_benefit/odex_benefit/models/service_request.py b/odex25_benefit/odex_benefit/models/service_request.py
index 34e06c23e..1d21218b8 100644
--- a/odex25_benefit/odex_benefit/models/service_request.py
+++ b/odex25_benefit/odex_benefit/models/service_request.py
@@ -207,6 +207,7 @@ class ServiceRequest(models.Model):
agree_terms = fields.Boolean(string="I agree to the Terms and Conditions", default=False, )
related_information_html = fields.Html(string="Related Information",
compute='_compute_related_information_html', store=True, )
+ researcher_opinion = fields.Html(string='Specialist Opinion',tracking=True)
@api.depends('service_cat', 'family_id', 'member_id', 'benefit_type')
def _compute_related_information_html(self):
@@ -549,6 +550,10 @@ 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():
+ raise ValidationError(
+ _('Please write the specialist opinion before completing the action.')
+ )
if not rec.requested_service_amount or rec.requested_service_amount <= 0:
raise UserError(_("Please enter a valid service amount."))
diff --git a/odex25_benefit/odex_benefit/security/ir.model.access.csv b/odex25_benefit/odex_benefit/security/ir.model.access.csv
index e74391af9..8aae1687f 100644
--- a/odex25_benefit/odex_benefit/security/ir.model.access.csv
+++ b/odex25_benefit/odex_benefit/security/ir.model.access.csv
@@ -168,8 +168,7 @@ access_grant_benefit_account_move_line,access_grant_benefit_account_move_line,mo
access_grant_benefit_account_move,access_grant_benefit_account_move,model_account_move,odex_benefit.group_benefit_info,1,0,0,0
access_expense_line_family_services_manager,access_expense_line_family_services_manager,model_benefit_expense_line,odex_benefit.group_family_services_manager,1,1,1,1
access_expense_line_benefit_manager,access_expense_line_benefit_manager,model_benefit_expense_line,odex_benefit.group_benefit_manager,1,1,1,1
-access_expense_researcher,access_expense_researcher,model_benefit_expense_line,odex_benefit.group_benefit_info,1,0,0,0
+access_expense_researcher,access_expense_researcher,model_benefit_expense_line,odex_benefit.group_benefit_info,1,1,0,0
access_family_bank_report_wizard,access_family_bank_report_wizard,model_family_bank_report_wizard,base.group_user,1,1,1,1
access_return_reason,access_return_reason,model_return_reason,base.group_user,1,1,1,1
-access_return_reason_wizard,access_return_reason_wizard,model_return_reason_wizard,base.group_user,1,1,1,1
-access_assign_supervisor_wizard,access_assign_supervisor_wizard,model_assign_supervisor_wizard,base.group_user,1,1,1,1
\ No newline at end of file
+access_return_reason_wizard,access_return_reason_wizard,model_return_reason_wizard,base.group_user,1,1,1,1
\ No newline at end of file
diff --git a/odex25_benefit/odex_benefit/security/security_view.xml b/odex25_benefit/odex_benefit/security/security_view.xml
index 8a816610c..14dda0ae2 100644
--- a/odex25_benefit/odex_benefit/security/security_view.xml
+++ b/odex25_benefit/odex_benefit/security/security_view.xml
@@ -350,5 +350,31 @@
+
+
+ Show Bank Return Line Assigned To Researcher
+
+ ['|',
+ ('family_id.assigned_researcher_id.employee_id','in', user.employee_id.ids),
+ ('family_id.researcher_id.employee_id', 'in', user.employee_id.ids)]
+
+
+
+
+
+ Show All Bank Return Line
+
+ [(1, '=', 1)]
+
+
+
+
+
+ Show Bank Return Line of Own Branch
+
+ [('branch_id.branch.manager_id', '=', user.employee_id.id)]
+
+
+
diff --git a/odex25_benefit/odex_benefit/views/actions_and_menus.xml b/odex25_benefit/odex_benefit/views/actions_and_menus.xml
index 754ea6f6d..c1017570e 100644
--- a/odex25_benefit/odex_benefit/views/actions_and_menus.xml
+++ b/odex25_benefit/odex_benefit/views/actions_and_menus.xml
@@ -1077,7 +1077,7 @@
+ action="action_bank_return_benefit_expense" sequence="15" groups="odex_benefit.group_benefit_researcher,odex_benefit.group_family_services_manager,odex_benefit.group_benefit_manager"/>