From 72383aa2008c4b27963097644c6f075a79058814 Mon Sep 17 00:00:00 2001 From: Kristof Bernaert Date: Mon, 26 Jan 2026 01:55:16 +0100 Subject: [PATCH] Fix allow_mail_archived_partner causing system notifications to send emails --- .../models/mail_compose_message.py | 92 +++++++++++++------ .../models/res_partner.py | 43 ++++----- 2 files changed, 81 insertions(+), 54 deletions(-) diff --git a/allow_mail_archived_partner/models/mail_compose_message.py b/allow_mail_archived_partner/models/mail_compose_message.py index 90ff3ce..99a6d7e 100755 --- a/allow_mail_archived_partner/models/mail_compose_message.py +++ b/allow_mail_archived_partner/models/mail_compose_message.py @@ -10,46 +10,70 @@ class MailComposeMessage(models.TransientModel): @api.model def default_get(self, fields): """ - Pre-fill the email wizard with archived partner's email. - This makes the archived partner appear in the "To" field. + DEBUG VERSION - Trace everything """ + _logger.info("=== MAIL.COMPOSE.MESSAGE DEFAULT_GET START ===") + _logger.info(f"Context: {dict(self.env.context)}") + _logger.info(f"Fields requested: {fields}") + res = super().default_get(fields) + _logger.info(f"Super result partner_ids: {res.get('partner_ids')}") model = self.env.context.get("active_model") res_id = self.env.context.get("active_id") + _logger.info(f"Active model: {model}, Active ID: {res_id}") - # For invoices if model == "account.move" and res_id: + _logger.info(f"Processing invoice {res_id}") + + # Test 1: Without context + invoice_normal = self.env["account.move"].browse(res_id) + _logger.info(f"Normal browse - Partner: {invoice_normal.partner_id.id if invoice_normal.partner_id else 'None'}") + _logger.info(f"Normal browse - Partner active: {invoice_normal.partner_id.active if invoice_normal.partner_id else 'N/A'}") + + # Test 2: With context + invoice_with_context = self.env["account.move"].with_context( + active_test=False + ).browse(res_id) + _logger.info(f"With context - Partner: {invoice_with_context.partner_id.id if invoice_with_context.partner_id else 'None'}") + + # Test 3: Direct partner search + if invoice_normal.partner_id: + partner = self.env["res.partner"].with_context( + active_test=False + ).search([('id', '=', invoice_normal.partner_id.id)]) + _logger.info(f"Direct partner search found: {len(partner)} partners") + + # Now do the actual logic invoice = self.env["account.move"].with_context( - active_test=False # CRITICAL: Find archived partner + active_test=False ).browse(res_id) - if invoice.exists() and invoice.partner_id: - res["partner_ids"] = [(6, 0, [invoice.partner_id.id])] - _logger.debug(f"Pre-filled archived partner {invoice.partner_id.name} for invoice") - - # For sales orders - elif model == "sale.order" and res_id: - order = self.env["sale.order"].with_context( - active_test=False # CRITICAL: Find archived partner - ).browse(res_id) - - if order.exists() and order.partner_id: - res["partner_ids"] = [(6, 0, [order.partner_id.id])] - _logger.debug(f"Pre-filled archived partner {order.partner_id.name} for sales order") + if invoice.exists(): + _logger.info(f"Invoice exists: {invoice.exists()}") + _logger.info(f"Invoice partner: {invoice.partner_id.id if invoice.partner_id else 'None'}") + _logger.info(f"Invoice partner email: {invoice.partner_id.email if invoice.partner_id else 'None'}") + + if invoice.partner_id: + res["partner_ids"] = [(6, 0, [invoice.partner_id.id])] + _logger.info(f"SET partner_ids to: {res['partner_ids']}") + _logger.info("=== MAIL.COMPOSE.MESSAGE DEFAULT_GET END ===") return res def _prepare_mail_values(self, res_ids): """ - Set context to allow archived partners during email sending. - This ensures the email can actually be sent to archived partners. + Debug this too """ + _logger.info("=== _prepare_mail_values START ===") + _logger.info(f"Context before: {dict(self.env.context)}") + model = self.env.context.get("active_model") or self.model + _logger.info(f"Model: {model}, res_ids: {res_ids}") if model in ["sale.order", "account.move"]: - _logger.debug(f"Setting context for {model} to allow archived partners") - return super( + _logger.info(f"Setting context for {model} to allow archived partners") + result = super( MailComposeMessage, self.with_context( active_test=False, @@ -57,26 +81,40 @@ class MailComposeMessage(models.TransientModel): mail_notify_force=True, ) )._prepare_mail_values(res_ids) + _logger.info(f"Context after: {dict(self.env.context)}") + _logger.info("=== _prepare_mail_values END ===") + return result - return super()._prepare_mail_values(res_ids) + result = super()._prepare_mail_values(res_ids) + _logger.info("=== _prepare_mail_values END ===") + return result def _prepare_recipient_values(self, partner): """ - Handle archived partners when context allows. - This ensures archived partner data is properly formatted for email. + Debug recipient values """ + _logger.info(f"=== _prepare_recipient_values ===") + _logger.info(f"Partner: {partner.id if partner else 'None'}") + _logger.info(f"Partner active: {partner.active if partner else 'N/A'}") + _logger.info(f"Context include_archived: {self.env.context.get('include_archived_partners')}") + _logger.info(f"Context mail_notify_force: {self.env.context.get('mail_notify_force')}") + include_archived = ( self.env.context.get("include_archived_partners") or self.env.context.get("mail_notify_force") ) if include_archived and partner and not partner.active: - _logger.debug(f"Including archived partner {partner.name} in email") - return { + _logger.info(f"Including archived partner {partner.name}") + result = { "partner_id": partner.id, "email": partner.email, "name": partner.name, "lang": partner.lang or self.env.context.get("lang") or "en_US", } + _logger.info(f"Returning: {result}") + return result - return super()._prepare_recipient_values(partner) \ No newline at end of file + parent_result = super()._prepare_recipient_values(partner) + _logger.info(f"Parent returning: {parent_result}") + return parent_result \ No newline at end of file diff --git a/allow_mail_archived_partner/models/res_partner.py b/allow_mail_archived_partner/models/res_partner.py index e6484b8..10feae1 100755 --- a/allow_mail_archived_partner/models/res_partner.py +++ b/allow_mail_archived_partner/models/res_partner.py @@ -8,41 +8,30 @@ class ResPartner(models.Model): _inherit = "res.partner" @api.model - def _search( - self, - args, - offset=0, - limit=None, - order=None, - count=False, - access_rights_uid=None - ): + def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None): """ - Only include archived partners when the caller explicitly opts in via: - context['include_archived_partners'] = True - - Never key off fragile string matches like 'mail'/'notify'/'message'. + DEBUG search method """ - if self.env.context.get("include_archived_partners"): - # Remove explicit active=True filters only (do not touch other domains) + _logger.info("=== RES.PARTNER _search ===") + _logger.info(f"Search args before: {args}") + _logger.info(f"Context include_archived: {self.env.context.get('include_archived_partners')}") + _logger.info(f"Context active_test: {self.env.context.get('active_test')}") + _logger.info(f"Context mail_notify_force: {self.env.context.get('mail_notify_force')}") + + if self.env.context.get("include_archived_partners") or self.env.context.get("mail_notify_force"): + _logger.info("Context flags found - removing active filters") + # Remove active filters args = [ arg for arg in args if not ( isinstance(arg, (list, tuple)) and len(arg) == 3 and arg[0] == "active" - and arg[1] == "=" - and arg[2] is True ) ] - # Also ensure active_test is off so ORM won't auto-filter archived partners self = self.with_context(active_test=False) - - return super()._search( - args, - offset=offset, - limit=limit, - order=order, - count=count, - access_rights_uid=access_rights_uid - ) + _logger.info(f"Search args after: {args}") + + result = super()._search(args, offset, limit, order, count, access_rights_uid) + _logger.info(f"Search result: {result[:10] if not count else 'count='+str(result)}") + return result \ No newline at end of file