From 775288bd0b4ce8e3d680ca1bbc24dbc36a644b7d Mon Sep 17 00:00:00 2001 From: Samir Ladoui Date: Sun, 4 Jan 2026 14:30:39 +0100 Subject: [PATCH 1/5] [FIX] odex_takaful: make super user env for printing receipts --- .../odex_takaful/controllers/report_api.py | 90 +++++++------------ 1 file changed, 33 insertions(+), 57 deletions(-) diff --git a/odex25_takaful/odex_takaful/controllers/report_api.py b/odex25_takaful/odex_takaful/controllers/report_api.py index 2ed6ba3f3..a8fe50d5c 100644 --- a/odex25_takaful/odex_takaful/controllers/report_api.py +++ b/odex25_takaful/odex_takaful/controllers/report_api.py @@ -1,69 +1,45 @@ import json -import logging + import werkzeug +import werkzeug.exceptions + from odoo import http from odoo.http import request +from odoo import api, SUPERUSER_ID -_logger = logging.getLogger(__name__) -class YourController(http.Controller): +class ReportController(http.Controller): @http.route([ '/sponsorship//', '/sponsorship///', - ], type='http', auth='public', website=True, csrf=False) + ], type='http', auth='public', website=True) def report_routes(self, reportname, docids=None, converter=None, **data): - try: - # 1. Setup Report and Context - report = request.env['ir.actions.report'].sudo()._get_report_from_name(reportname) - if not report: - return request.not_found() + env = api.Environment(request.cr, SUPERUSER_ID, {}) + report = request.env['ir.actions.report']._get_report_from_name(reportname) + context = dict(request.env.context) - context = dict(request.env.context) - - # FORCE RENDERING: This is crucial to bypass the "Attachment" check - # which is a common cause of 403 errors even with sudo() - context.update({'force_report_rendering': True}) - - if docids: - docids = [int(i) for i in docids.split(',')] - - if data.get('options'): - data.update(json.loads(data.pop('options'))) - - if data.get('context'): - data['context'] = json.loads(data['context']) - if data['context'].get('lang') and not data.get('force_context_lang'): - del data['context']['lang'] - context.update(data['context']) - - # 2. Rendering Logic with SUDO - # We use the updated context here - if converter == 'html': - html = report.with_context(context).sudo()._render_qweb_html(docids, data=data)[0] - return request.make_response(html) - - elif converter == 'pdf': - pdf = report.with_context(context).sudo()._render_qweb_pdf(docids, data=data)[0] - pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))] - return request.make_response(pdf, headers=pdfhttpheaders) - - elif converter == 'text': - text = report.with_context(context).sudo()._render_qweb_text(docids, data=data)[0] - texthttpheaders = [('Content-Type', 'text/plain'), ('Content-Length', len(text))] - return request.make_response(text, headers=texthttpheaders) - - else: - raise werkzeug.exceptions.HTTPException(description='Converter %s not implemented.' % converter) - - except Exception as e: - # 3. DEBUGGING BLOCK - # Crucial: Rollback the database transaction so we can send a response - request.env.cr.rollback() - - # Log the full stack trace to your Odoo terminal/logfile - _logger.exception("Error generating public report for %s", reportname) - - # Return the error message directly to the browser - error_msg = f"DEBUG ERROR: {str(e)}" - return request.make_response(error_msg, headers=[('Content-Type', 'text/plain')]) \ No newline at end of file + if docids: + docids = [int(i) for i in docids.split(',')] + if data.get('options'): + data.update(json.loads(data.pop('options'))) + if data.get('context'): + # Ignore 'lang' here, because the context in data is the one from the webclient *but* if + # the user explicitely wants to change the lang, this mechanism overwrites it. + data['context'] = json.loads(data['context']) + if data['context'].get('lang') and not data.get('force_context_lang'): + del data['context']['lang'] + context.update(data['context']) + if converter == 'html': + html = report.with_env(env).with_context(context)._render_qweb_html(docids, data=data)[0] + return request.make_response(html) + elif converter == 'pdf': + pdf = report.with_env(env).with_context(context)._render_qweb_pdf(docids) + pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))] + return request.make_response(pdf, headers=pdfhttpheaders) + elif converter == 'text': + text = report.with_env(env).with_context(context)._render_qweb_text(docids, data=data)[0] + texthttpheaders = [('Content-Type', 'text/plain'), ('Content-Length', len(text))] + return request.make_response(text, headers=texthttpheaders) + else: + raise werkzeug.exceptions.HTTPException(description='Converter %s not implemented.' % converter) From 9f5757d40a625159b92b6eb2ed93a2194f1e9b14 Mon Sep 17 00:00:00 2001 From: Samir Ladoui Date: Sun, 4 Jan 2026 15:31:43 +0100 Subject: [PATCH 2/5] [FIX] odex_takaful: select the first element from rendering pdf --- odex25_takaful/odex_takaful/controllers/report_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/odex25_takaful/odex_takaful/controllers/report_api.py b/odex25_takaful/odex_takaful/controllers/report_api.py index a8fe50d5c..d88796e3c 100644 --- a/odex25_takaful/odex_takaful/controllers/report_api.py +++ b/odex25_takaful/odex_takaful/controllers/report_api.py @@ -34,7 +34,7 @@ class ReportController(http.Controller): html = report.with_env(env).with_context(context)._render_qweb_html(docids, data=data)[0] return request.make_response(html) elif converter == 'pdf': - pdf = report.with_env(env).with_context(context)._render_qweb_pdf(docids) + pdf = report.with_env(env).with_context(context)._render_qweb_pdf(docids)[0] pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))] return request.make_response(pdf, headers=pdfhttpheaders) elif converter == 'text': From dbabb0e4c87a92b9457153e9f85c3d5c46cb082c Mon Sep 17 00:00:00 2001 From: maltayyar2 Date: Sun, 4 Jan 2026 20:55:54 +0300 Subject: [PATCH 3/5] [FIX] odex_takaful: automatic update Auto-generated commit based on local changes. --- .../models/donation_details_lines.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/odex25_takaful/odex_takaful/models/donation_details_lines.py b/odex25_takaful/odex_takaful/models/donation_details_lines.py index 7d332f16d..1fafb070a 100644 --- a/odex25_takaful/odex_takaful/models/donation_details_lines.py +++ b/odex25_takaful/odex_takaful/models/donation_details_lines.py @@ -721,7 +721,6 @@ class DonationsDetailsLines(models.Model): @api.depends('family_id','record_type') def _compute_family_domain_ids(self): for rec in self: - domain = [] if rec.record_type == 'donation': domain = [ '|', @@ -729,9 +728,11 @@ class DonationsDetailsLines(models.Model): '&', ('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended')] - family = self.env['grant.benefit'].sudo().search(domain) - - rec.family_domain_ids = [(6, 0, family.ids)] if family else False + family = self.env['grant.benefit'].sudo().search(domain) + rec.family_domain_ids = [(6, 0, family.ids)] if family else False + else: + # No family selection needed for sponsorships or other types + rec.family_domain_ids = False @api.depends('gender', 'record_type', @@ -839,8 +840,13 @@ class DonationsDetailsLines(models.Model): elif rec.record_type == 'donation' and rec.donation_mechanism == "with_conditions" and rec.family_id: domain = [("benefit_id", "=", rec.family_id.id)] - members = self.env['family.member'].sudo().search(domain) + else: + # No beneficiary selection needed (e.g., unconditional donations, waqf) + # Return empty recordset to avoid loading all records - fixes browser hang + rec.members_domain_ids = self.env['family.member'].sudo().browse() + continue + members = self.env['family.member'].sudo().search(domain) rec.members_domain_ids = members if members else self.env['family.member'].sudo().browse() From e27b0ad6276fe5bb411523a1bd78dfec80ad10d1 Mon Sep 17 00:00:00 2001 From: maltayyar2 Date: Sun, 4 Jan 2026 21:16:51 +0300 Subject: [PATCH 4/5] [FIX] odex_takaful: automatic update Auto-generated commit based on local changes. --- .../models/donation_details_lines.py | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/odex25_takaful/odex_takaful/models/donation_details_lines.py b/odex25_takaful/odex_takaful/models/donation_details_lines.py index 1fafb070a..fef0cef21 100644 --- a/odex25_takaful/odex_takaful/models/donation_details_lines.py +++ b/odex25_takaful/odex_takaful/models/donation_details_lines.py @@ -239,12 +239,27 @@ class DonationsDetailsLines(models.Model): @api.depends('sponsorship_duration' , 'product_template_id' , 'payment_month_count' , 'direct_debit') def _compute_get_age_range(self): for rec in self: + # ages field is only used for sponsorships (in _compute_members_domain_ids) + # Skip expensive computation for donations entirely + if rec.record_type != 'sponsorship': + rec.ages = 100 # Default value, not used for donations + continue + x = [] branch_id = rec.branch_custom_id.id - records = self.env['donations.details.lines'].search(['|' , ('state', '=', 'replace') , ('state', '=', 'waiting') ]) - filtered_records = records.filtered(lambda r: r.sponsorship_mechanism_id.branch_custom_id.id == branch_id) + if not branch_id: + rec.ages = 100 + continue + + # Optimized: Include branch filter in search domain instead of Python filtering + records = self.env['donations.details.lines'].search([ + '|', ('state', '=', 'replace'), ('state', '=', 'waiting'), + '|', + ('sponsorship_mechanism_id.branch_custom_id', '=', branch_id), + ('sponsorship_id.branch_custom_id', '=', branch_id) + ]) - for record in filtered_records: + for record in records: if record.sponsorship_duration == 'permanent' : x.append(1) elif record.sponsorship_duration != 'permanent' and record.payment_month_count < 6 and record.direct_debit : @@ -254,7 +269,6 @@ class DonationsDetailsLines(models.Model): elif record.sponsorship_duration != 'permanent' and record.payment_month_count < 6 : x.append(18) - if len(x) > 0 : lowest_value = min(x) if x else None else: From 234993283311a2502a4e45e118de7e69fe97d31c Mon Sep 17 00:00:00 2001 From: maltayyar2 Date: Mon, 5 Jan 2026 00:37:54 +0300 Subject: [PATCH 5/5] [I18N] odex_takaful: automatic update Auto-generated commit based on local changes. --- odex25_takaful/odex_takaful/i18n/ar_001.po | 74 ++++++++++++++++++- .../models/donation_details_lines.py | 7 +- .../models/takaful_sponorship_model.py | 3 +- .../wizards/account_payment_register.py | 1 - .../wizards/account_payment_register.xml | 51 +++++++++++-- .../wizards/donation_extension_wizard.py | 1 - 6 files changed, 122 insertions(+), 15 deletions(-) diff --git a/odex25_takaful/odex_takaful/i18n/ar_001.po b/odex25_takaful/odex_takaful/i18n/ar_001.po index b25686607..96835784e 100644 --- a/odex25_takaful/odex_takaful/i18n/ar_001.po +++ b/odex25_takaful/odex_takaful/i18n/ar_001.po @@ -7657,4 +7657,76 @@ msgstr "مساهمة مالية بالأمر %s" #: model:ir.model.fields.selection,name:odex_takaful.selection__takaful_sponsorship__state__paid #: model_terms:ir.ui.view,arch_db:odex_takaful.takaful_sponsorship_view_search msgid "Paid" -msgstr "تم الدفع" \ No newline at end of file +msgstr "تم الدفع" +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.view_account_payment_register_form +msgid "Donor Bank Account" +msgstr "حساب المتبرع" + + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.donation_extension_wizard +msgid "Months Amount" +msgstr "مبلغ الشهور" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.replace_benefit_wizard +msgid "Replacement Information" +msgstr "معلومات الاستبدال" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.replace_benefit_wizard +#: model_terms:ir.ui.view,arch_db:odex_takaful.orphan_replacement_wizard +msgid "Replacement Reason" +msgstr "سبب الاستبدال" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.add_benefit_wizard +msgid "Benefit Information" +msgstr "معلومات المستفيد" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.add_benefit_wizard +msgid "Add Benefit" +msgstr "إضافة مستفيد" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.replace_sponsor_wizard +msgid "Sponsor Information" +msgstr "معلومات المتبرع" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.replace_sponsor_wizard +msgid "Replace Sponsor" +msgstr "استبدال المتبرع" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.transfer_deduction_wizard_views +#: model_terms:ir.ui.view,arch_db:odex_takaful.benefit_month_payment_wiz_view +msgid "Print PDF" +msgstr "طباعة PDF" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.transfer_deduction_wizard_views +msgid "Print Excel" +msgstr "طباعة Excel" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.orphan_replacement_wizard +msgid "Replacement Wizard" +msgstr "معالج الاستبدال" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.esterdad_wizard +msgid "Esterdad Wizard" +msgstr "معالج الاسترداد" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.esterdad_wizard +msgid "Payment Details" +msgstr "تفاصيل الدفع" + +#. module: odex_takaful +#: model_terms:ir.ui.view,arch_db:odex_takaful.takaful_reports_wizards +msgid "Print The Report" +msgstr "طباعة التقرير" diff --git a/odex25_takaful/odex_takaful/models/donation_details_lines.py b/odex25_takaful/odex_takaful/models/donation_details_lines.py index fef0cef21..0a1c49d55 100644 --- a/odex25_takaful/odex_takaful/models/donation_details_lines.py +++ b/odex25_takaful/odex_takaful/models/donation_details_lines.py @@ -236,7 +236,7 @@ class DonationsDetailsLines(models.Model): # bank_transfer_attachment_file_name = fields.Char('Bank Transfer File Name', required=False) - @api.depends('sponsorship_duration' , 'product_template_id' , 'payment_month_count' , 'direct_debit') + @api.depends('sponsorship_duration', 'product_template_id', 'payment_month_count', 'direct_debit', 'record_type') def _compute_get_age_range(self): for rec in self: # ages field is only used for sponsorships (in _compute_members_domain_ids) @@ -735,7 +735,8 @@ class DonationsDetailsLines(models.Model): @api.depends('family_id','record_type') def _compute_family_domain_ids(self): for rec in self: - if rec.record_type == 'donation': + # Only fetch families for conditional donations where family_id field is used + if rec.record_type == 'donation' and rec.donation_mechanism == 'with_conditions': domain = [ '|', ('state', '=', 'second_approve'), @@ -745,7 +746,7 @@ class DonationsDetailsLines(models.Model): family = self.env['grant.benefit'].sudo().search(domain) rec.family_domain_ids = [(6, 0, family.ids)] if family else False else: - # No family selection needed for sponsorships or other types + # No family selection needed for sponsorships, unconditional donations, or other types rec.family_domain_ids = False @api.depends('gender', diff --git a/odex25_takaful/odex_takaful/models/takaful_sponorship_model.py b/odex25_takaful/odex_takaful/models/takaful_sponorship_model.py index 1c17b2cf0..0bb17e372 100644 --- a/odex25_takaful/odex_takaful/models/takaful_sponorship_model.py +++ b/odex25_takaful/odex_takaful/models/takaful_sponorship_model.py @@ -829,7 +829,6 @@ class TakafulSponsorship(models.Model): family_lines = sponsorship_lines.filtered(lambda l: l.family_id == family) bill_values = { 'takaful_sponsorship_id': sponsorship.id, - 'name': self.env['ir.sequence'].next_by_code('account.move.accrsp'), 'move_type': 'in_invoice', 'journal_id': benefit_journal_id, 'date': fields.Date.today(), @@ -1480,7 +1479,7 @@ class TakafulSponsorship(models.Model): current_invoice.sudo().write(invoice_values) invoice_id = current_invoice else: - invoice_values.update({'invoice_line_ids': invoice_line_vals, 'name': self.env['ir.sequence'].next_by_code('account.move.accrsp')}) + invoice_values.update({'invoice_line_ids': invoice_line_vals}) invoice_id = Invoice.create(invoice_values) for line in invoice_id.invoice_line_ids: diff --git a/odex25_takaful/odex_takaful/wizards/account_payment_register.py b/odex25_takaful/odex_takaful/wizards/account_payment_register.py index 18e7e675c..bc84844b2 100644 --- a/odex25_takaful/odex_takaful/wizards/account_payment_register.py +++ b/odex25_takaful/odex_takaful/wizards/account_payment_register.py @@ -135,7 +135,6 @@ class AccountRegisterPayment(models.TransientModel): bill_values = { 'takaful_sponsorship_id': sponsorship.id, - 'name': self.env['ir.sequence'].next_by_code('account.move.accrsp'), 'move_type': 'in_invoice', 'journal_id': benefit_journal_id, 'date': fields.Date.today(), diff --git a/odex25_takaful/odex_takaful/wizards/account_payment_register.xml b/odex25_takaful/odex_takaful/wizards/account_payment_register.xml index ad72cf3d8..507d73457 100644 --- a/odex25_takaful/odex_takaful/wizards/account_payment_register.xml +++ b/odex25_takaful/odex_takaful/wizards/account_payment_register.xml @@ -7,6 +7,39 @@ account.payment.register + + 1 + + + 2 + + + oe_center saudi_amount_field + font-size: 60px !important; height: 90px !important; font-weight: 800 !important; background-color: transparent; border: none !important; flex: 1 !important; min-width: 0 !important; text-align: center; font-family: 'SF Pro Display', 'Roboto', sans-serif; display: flex !important; flex-direction: row-reverse !important; justify-content: center !important; align-items: center !important; letter-spacing: -2px; + 0.00 + + + + @@ -35,12 +68,15 @@ context.get('sponsorship_payment') - - context.get('sponsorship_payment') + + + + + - + @@ -50,17 +86,18 @@ - + + + -