diff --git a/odex25_ensan/odex_benefit/__manifest__.py b/odex25_ensan/odex_benefit/__manifest__.py
index 0e5bf0f39..d4bc3829d 100644
--- a/odex25_ensan/odex_benefit/__manifest__.py
+++ b/odex25_ensan/odex_benefit/__manifest__.py
@@ -7,8 +7,8 @@
'website': 'http://exp-sa.com',
'license': 'GPL-3',
'author': 'Expert Ltd',
- 'depends': ['base','survey', 'takaful_core', 'website', 'account', 'report_xlsx', 'sale', 'product', 'stock', 'hr',
- 'purchase','web_google_maps','odex25_account_payment_fix','otp_sms_auth_custom'],
+ 'depends': ['base', 'survey', 'takaful_core', 'website', 'account', 'report_xlsx', 'sale', 'product', 'stock', 'hr',
+ 'purchase', 'web_google_maps', 'odex25_account_payment_fix', 'otp_sms_auth_custom'],
'data': [
'security/security_view.xml',
'security/ir.model.access.csv',
@@ -65,9 +65,11 @@
'wizards/visit_location_otp_wizard_view.xml',
'views/benefit_vehicle_model.xml',
'wizards/visit_location_refused_wizard_view.xml',
+ 'wizards/family_bank_report_wizard.xml',
'views/visit_survey.xml',
'views/actions_and_menus.xml',
-],
+ 'reports/family_bank_report.xml',
+ ],
'external_dependencies': {
'python': ['num2words'],
},
diff --git a/odex25_ensan/odex_benefit/i18n/ar_001.po b/odex25_ensan/odex_benefit/i18n/ar_001.po
index 64fcdd617..23de5f18a 100644
--- a/odex25_ensan/odex_benefit/i18n/ar_001.po
+++ b/odex25_ensan/odex_benefit/i18n/ar_001.po
@@ -15944,6 +15944,7 @@ msgstr "بإنتظار مساعد المدير العام"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__start_date
#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__start_date
+#: model:ir.model.fields,field_description:odex_benefit.field_family_bank_report_wizard__start_date
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__new_start
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__start
msgid "Start Date"
@@ -15953,6 +15954,7 @@ msgstr "تاريخ البداية"
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__end_date
#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__end_date
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__end
+#: model:ir.model.fields,field_description:odex_benefit.field_family_bank_report_wizard__end_date
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__new_end
msgid "End Date"
msgstr "تاريخ النهاية"
@@ -16556,3 +16558,50 @@ msgstr ""
"بعض الأسر المحددة ليست في حالة معتمدة أو تم إيقافها:\n"
"%s"
+#. module: odex_benefit
+#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__acc_holder_id_number
+msgid "Account Holder ID Number"
+msgstr "رقم هوية صاحب الحساب"
+
+#. module: odex_benefit
+#: code:addons/odex_benefit/models/benefit.py:0
+#, python-format
+msgid "Account Holder ID Number must contain exactly 10 digits."
+msgstr "يجب أن يحتوي رقم هوية صاحب الحساب على 10 أرقام بالضبط."
+
+#. module: odex_benefit
+#: model:ir.model,name:odex_benefit.model_report_odex_benefit_family_bank_report_xlsx
+msgid "Family Bank Report XLSX"
+msgstr "تقرير البنك للأسر XLSX"
+
+#. module: odex_benefit
+#: code:addons/odex_benefit/reports/family_bank_report.py:0
+#: model:ir.actions.act_window,name:odex_benefit.action_family_bank_report_wizard
+#: model:ir.model,name:odex_benefit.model_family_bank_report_wizard
+#: model:ir.ui.menu,name:odex_benefit.menu_family_bank_report_root
+#: model_terms:ir.ui.view,arch_db:odex_benefit.view_family_bank_report_wizard_form
+#, python-format
+msgid "Family Bank Report"
+msgstr "تقرير البنك للأسر"
+
+#. module: odex_benefit
+#: model:ir.actions.report,name:odex_benefit.action_family_bank_report_xlsx
+msgid "Family Bank Report (Excel)"
+msgstr "تقرير البنك للأسر (إكسل)"
+
+#. module: odex_benefit
+#: model:ir.model.fields,field_description:odex_benefit.field_family_bank_report_wizard__move_ids
+msgid "Monthly Expenses"
+msgstr "المصروفات الشهرية"
+
+#. module: odex_benefit
+#: code:addons/odex_benefit/wizards/family_bank_report_wizard.py:0
+#, python-format
+msgid "Please select at least one Monthly Expense."
+msgstr "يرجى اختيار مصروف شهري واحد على الأقل."
+
+#. module: odex_benefit
+#: code:addons/odex_benefit/wizards/family_bank_report_wizard.py:0
+#, python-format
+msgid "No debit lines with family information found."
+msgstr "لم يتم العثور على قيود تحتوي على معلومات الأسر."
\ No newline at end of file
diff --git a/odex25_ensan/odex_benefit/models/benefit.py b/odex25_ensan/odex_benefit/models/benefit.py
index e84758ed9..c2137f97f 100644
--- a/odex25_ensan/odex_benefit/models/benefit.py
+++ b/odex25_ensan/odex_benefit/models/benefit.py
@@ -70,6 +70,7 @@ class GrantBenefitProfile(models.Model):
family_bank = fields.Many2one('res.partner.bank')
acc_number = fields.Char('Account Number',copy=False)
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(
@@ -1033,6 +1034,14 @@ class GrantBenefitProfile(models.Model):
'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 = {
diff --git a/odex25_ensan/odex_benefit/reports/__init__.py b/odex25_ensan/odex_benefit/reports/__init__.py
index 52dc92d79..36787abff 100644
--- a/odex25_ensan/odex_benefit/reports/__init__.py
+++ b/odex25_ensan/odex_benefit/reports/__init__.py
@@ -1 +1,2 @@
-from . import benefit_report
\ No newline at end of file
+from . import benefit_report
+from . import family_bank_report
\ No newline at end of file
diff --git a/odex25_ensan/odex_benefit/reports/family_bank_report.py b/odex25_ensan/odex_benefit/reports/family_bank_report.py
new file mode 100644
index 000000000..7939d91fd
--- /dev/null
+++ b/odex25_ensan/odex_benefit/reports/family_bank_report.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+
+from odoo import api, fields, models, tools, _
+from odoo.exceptions import ValidationError, UserError
+from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
+
+
+class FamilyBankReportXlsx(models.AbstractModel):
+ _name = 'report.odex_benefit.family_bank_report_xlsx'
+ _description = 'Family Bank Report XLSX'
+ _inherit = 'report.report_xlsx.abstract'
+
+ @api.model
+ def generate_xlsx_report(self, workbook, data, objs):
+ sheet = workbook.add_worksheet(_('Family Bank Report'))
+ if self.env.user.lang != 'en_US':
+ sheet.right_to_left()
+
+ header_format = workbook.add_format({
+ 'bold': True,
+ 'align': 'center',
+ 'valign': 'vcenter',
+ 'bg_color': '#4472C4',
+ 'font_color': 'white',
+ 'border': 1,
+ 'text_wrap': True
+ })
+
+ subheader_format = workbook.add_format({
+ 'bold': True,
+ 'align': 'center',
+ 'valign': 'vcenter',
+ 'bg_color': '#D3D3D3',
+ 'border': 1,
+ 'font_size': 9
+ })
+
+ normal = workbook.add_format({
+ 'align': 'center',
+ 'valign': 'vcenter',
+ 'border': 1
+ })
+
+ bold = workbook.add_format({
+ 'bold': True,
+ 'align': 'center',
+ 'valign': 'vcenter',
+ 'border': 1
+ })
+
+ sheet.set_row(0, 30)
+ sheet.set_row(1, 25)
+ sheet.set_row(2, 25)
+
+ sheet.merge_range('A1:A2', 'Bank Name' + '\nاسم البنك', header_format)
+ sheet.merge_range('B1:B2', 'Account Number(24N)' + '\nرقم الحساب', header_format)
+ sheet.merge_range('C1:C2', 'Beneficiary Name' + '\nاسم المستفيد', header_format)
+ sheet.merge_range('D1:D2', 'Amount(15)' + '\nقيمة الحوالة', header_format)
+ sheet.merge_range('E1:E2', 'Civilian_Id(20)' + '\nرقم الهوية', header_format)
+ sheet.merge_range('F1:F2', 'Currency (3N)' + '\nالعملة', header_format)
+ sheet.merge_range('G1:G2', 'Beneficiaries Remarks (30)' + '\nملاحظات المستفيد', header_format)
+ sheet.merge_range('H1:H2', 'Payment Purpose' + '\nغرض الدفع', header_format)
+ sheet.merge_range('I1:I2', 'Beneficiary Email' + '\nالبريد الإلكتروني للمستفيد', header_format)
+
+ row = 3
+ total_amount = 0
+ for line in data['lines']:
+ sheet.write(row, 0, line['bank_name'], normal)
+ sheet.write(row, 1, line['account_number'], normal)
+ sheet.write(row, 2, line['beneficiary_name'], normal)
+ sheet.write_number(row, 3, line['transfer_amount'], normal)
+ sheet.write(row, 4, line['beneficiary_id'], normal)
+ sheet.write(row, 5, line['currency'], normal)
+ sheet.write(row, 6, line['family_code'], normal)
+ sheet.write(row, 7, line['purpose'], normal)
+ sheet.write(row, 8, line.get('beneficiary_email', ''), normal)
+ total_amount += line['transfer_amount']
+ row += 1
+
+
+ sheet.merge_range(row + 1, 0, row + 1, 2, "Total" + " / " + "الإجمالي", bold)
+ sheet.write_number(row + 1, 3, total_amount, bold)
+ sheet.write(row + 1, 4, "", bold)
+ sheet.write(row + 1, 5, "SAR", bold)
+
+ sheet.set_column('A:A', 25)
+ sheet.set_column('B:B', 25)
+ sheet.set_column('C:C', 30)
+ sheet.set_column('D:D', 15)
+ sheet.set_column('E:E', 20)
+ sheet.set_column('F:F', 12)
+ sheet.set_column('G:G', 25)
+ sheet.set_column('H:H', 20)
+ sheet.set_column('I:I', 30)
diff --git a/odex25_ensan/odex_benefit/reports/family_bank_report.xml b/odex25_ensan/odex_benefit/reports/family_bank_report.xml
new file mode 100644
index 000000000..7fbdf366a
--- /dev/null
+++ b/odex25_ensan/odex_benefit/reports/family_bank_report.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ family.bank.report.wizard
+ Family Bank Report (Excel)
+ xlsx
+ odex_benefit.family_bank_report_xlsx
+ odex_benefit.family_bank_report_xlsx
+
+
+
\ No newline at end of file
diff --git a/odex25_ensan/odex_benefit/security/ir.model.access.csv b/odex25_ensan/odex_benefit/security/ir.model.access.csv
index 17255f920..2f7af5c5b 100644
--- a/odex25_ensan/odex_benefit/security/ir.model.access.csv
+++ b/odex25_ensan/odex_benefit/security/ir.model.access.csv
@@ -166,4 +166,5 @@ access_survey_user_input_group_benefit_info,survey.user_input.group_benefit_info
access_survey_user_input_line_group_benefit_info,survey.user_input.line.group_benefit_info,survey.model_survey_user_input_line,odex_benefit.group_benefit_info,1,0,0,0
access_grant_benefit_account_move_line,access_grant_benefit_account_move_line,model_account_move_line,odex_benefit.group_benefit_info,1,0,0,0
access_grant_benefit_account_move,access_grant_benefit_account_move,model_account_move,odex_benefit.group_benefit_info,1,0,0,0
-access_benefit_expense_line,access_benefit_expense_line,model_benefit_expense_line,base.group_user,1,1,1,1
\ No newline at end of file
+access_benefit_expense_line,access_benefit_expense_line,model_benefit_expense_line,base.group_user,1,1,1,1
+access_family_bank_report_wizard,access_family_bank_report_wizard,model_family_bank_report_wizard,base.group_user,1,1,1,1
\ No newline at end of file
diff --git a/odex25_ensan/odex_benefit/views/actions_and_menus.xml b/odex25_ensan/odex_benefit/views/actions_and_menus.xml
index 6e8b5faf1..12d84a9ae 100644
--- a/odex25_ensan/odex_benefit/views/actions_and_menus.xml
+++ b/odex25_ensan/odex_benefit/views/actions_and_menus.xml
@@ -1039,6 +1039,11 @@
parent="education_main_menu" action="education_exam_type_action" sequence="9"/>
+
diff --git a/odex25_ensan/odex_benefit/views/benefit_view.xml b/odex25_ensan/odex_benefit/views/benefit_view.xml
index 13516281d..844c20ca7 100644
--- a/odex25_ensan/odex_benefit/views/benefit_view.xml
+++ b/odex25_ensan/odex_benefit/views/benefit_view.xml
@@ -1371,6 +1371,8 @@
groups="!odex_benefit.group_benefit_manager"/>
+
0 and l.benefit_family_id):
+ family = line.benefit_family_id
+ beneficiary_name = ''
+ beneficiary_id = ''
+ if family.is_family_member:
+ beneficiary_name = family.family_member_id.name
+ beneficiary_id = family.family_member_id.member_id_number
+ else:
+ beneficiary_name = family.acc_holder_name
+ beneficiary_id = family.acc_holder_id_number
+ lines_data.append({
+ 'bank_name': family.bank_id.name or '',
+ 'account_number': 'SA' + family.acc_number or '',
+ 'beneficiary_name': beneficiary_name,
+ 'transfer_amount': line.debit or 0.0,
+ 'beneficiary_id': beneficiary_id,
+ 'currency': 'SAR',
+ 'family_code': family.code or '',
+ 'purpose': 'Others',
+ })
+
+ if not lines_data:
+ raise UserError(_("No debit lines with family information found."))
+ datas = {
+ 'start_date': self.start_date,
+ 'end_date': self.end_date,
+ 'lines': lines_data,
+ }
+ return self.env.ref('odex_benefit.action_family_bank_report_xlsx').report_action(self, data=datas)
diff --git a/odex25_ensan/odex_benefit/wizards/family_bank_report_wizard.xml b/odex25_ensan/odex_benefit/wizards/family_bank_report_wizard.xml
new file mode 100644
index 000000000..8afb570b9
--- /dev/null
+++ b/odex25_ensan/odex_benefit/wizards/family_bank_report_wizard.xml
@@ -0,0 +1,42 @@
+
+
+
+
+ family.bank.report.wizard.form
+ family.bank.report.wizard
+
+
+
+
+
+
+ Family Bank Report
+ family.bank.report.wizard
+ form
+
+ new
+
+
+
+
\ No newline at end of file