From cd755cbc431577e0b32f7536c105b8acf76df295 Mon Sep 17 00:00:00 2001 From: Kristof Bernaert Date: Mon, 26 Jan 2026 02:09:50 +0100 Subject: [PATCH] Fix allow_mail_archived_partner causing system notifications to send emails --- .../models/account_move_send.py | 45 ++++++-- .../models/mail_compose_message.py | 104 ++++++------------ 2 files changed, 72 insertions(+), 77 deletions(-) diff --git a/allow_mail_archived_partner/models/account_move_send.py b/allow_mail_archived_partner/models/account_move_send.py index 07de6e4..00bb2ad 100755 --- a/allow_mail_archived_partner/models/account_move_send.py +++ b/allow_mail_archived_partner/models/account_move_send.py @@ -1,4 +1,6 @@ -# account_move_send.py +import logging +_logger = logging.getLogger(__name__) + from odoo import models, api @@ -8,24 +10,51 @@ class AccountInvoiceSend(models.TransientModel): @api.model def default_get(self, fields): """ - Pre-fill invoice email wizard with archived partner. + Force inclusion of archived partners for invoice email wizard """ + _logger.info("=== ACCOUNT.INVOICE.SEND DEFAULT_GET ===") + _logger.info(f"Fields: {fields}") + _logger.info(f"Context: {self.env.context}") + + # Get the default result first res = super().default_get(fields) + _logger.info(f"Super result partner_ids: {res.get('partner_ids')}") active_ids = self.env.context.get('active_ids', []) + _logger.info(f"Active IDs: {active_ids}") if active_ids: - # Find invoices WITH archived partners - invoices = self.env['account.move'].with_context( + # Find invoices WITH archived partners allowed + moves = self.env['account.move'].with_context( active_test=False ).browse(active_ids) partner_ids = [] - for inv in invoices: - if inv.partner_id: - partner_ids.append(inv.partner_id.id) + for move in moves: + if move.partner_id: + partner_ids.append(move.partner_id.id) + _logger.info(f"Found partner {move.partner_id.id} (active={move.partner_id.active}) for invoice {move.id}") if partner_ids: res['partner_ids'] = [(6, 0, partner_ids)] + _logger.info(f"SET partner_ids: {res['partner_ids']}") + else: + _logger.info("No partners found for invoices") - return res \ No newline at end of file + return res + + def _get_composer_values(self, res_ids, template): + """ + Pass context to allow archived partners in email composition + """ + _logger.info("=== ACCOUNT.INVOICE.SEND _get_composer_values ===") + _logger.info(f"Passing context to allow archived partners") + + return super( + AccountInvoiceSend, + self.with_context( + active_test=False, + include_archived_partners=True, + mail_notify_force=True, + ) + )._get_composer_values(res_ids, template) \ No newline at end of file diff --git a/allow_mail_archived_partner/models/mail_compose_message.py b/allow_mail_archived_partner/models/mail_compose_message.py index 99a6d7e..1468970 100755 --- a/allow_mail_archived_partner/models/mail_compose_message.py +++ b/allow_mail_archived_partner/models/mail_compose_message.py @@ -10,111 +10,77 @@ class MailComposeMessage(models.TransientModel): @api.model def default_get(self, fields): """ - DEBUG VERSION - Trace everything + Pre-fill email wizard with archived partners for sales orders. + For invoices, this is handled by account.invoice.send. """ - _logger.info("=== MAIL.COMPOSE.MESSAGE DEFAULT_GET START ===") - _logger.info(f"Context: {dict(self.env.context)}") - _logger.info(f"Fields requested: {fields}") + _logger.debug("=== MAIL.COMPOSE.MESSAGE DEFAULT_GET ===") 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}") - if model == "account.move" and res_id: - _logger.info(f"Processing invoice {res_id}") + # Only handle sales orders here - invoices use account.invoice.send + if model == "sale.order" and res_id: + _logger.debug(f"Processing sales order {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( + # Find order with archived partners allowed + order = self.env["sale.order"].with_context( active_test=False ).browse(res_id) - 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']}") + 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.id} for sales order") - _logger.info("=== MAIL.COMPOSE.MESSAGE DEFAULT_GET END ===") return res def _prepare_mail_values(self, res_ids): """ - Debug this too + Set context flags for manual email sends. + This ensures archived partners are allowed during email sending. """ - _logger.info("=== _prepare_mail_values START ===") - _logger.info(f"Context before: {dict(self.env.context)}") + _logger.debug("=== _prepare_mail_values ===") model = self.env.context.get("active_model") or self.model - _logger.info(f"Model: {model}, res_ids: {res_ids}") + # Only for sales orders and account moves (invoices) + # Note: account.invoice.send should handle invoices, but keep this as fallback if model in ["sale.order", "account.move"]: - _logger.info(f"Setting context for {model} to allow archived partners") - result = super( + _logger.debug(f"Setting context for {model} to allow archived partners") + return super( MailComposeMessage, self.with_context( - active_test=False, - include_archived_partners=True, - mail_notify_force=True, + active_test=False, # Allow finding archived partners + include_archived_partners=True, # Tell other methods + mail_notify_force=True, # Mark as explicit user action ) )._prepare_mail_values(res_ids) - _logger.info(f"Context after: {dict(self.env.context)}") - _logger.info("=== _prepare_mail_values END ===") - return result - result = super()._prepare_mail_values(res_ids) - _logger.info("=== _prepare_mail_values END ===") - return result + return super()._prepare_mail_values(res_ids) def _prepare_recipient_values(self, partner): """ - Debug recipient values + Handle archived partners for manual email sends. + This is called for each recipient when building the email. """ - _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 = ( + # Check if we're in a manual send context + is_manual_send = ( self.env.context.get("include_archived_partners") or - self.env.context.get("mail_notify_force") + self.env.context.get("mail_notify_force") or + self.env.context.get("force_email") or # From invoice wizard + self.env.context.get("mark_invoice_as_sent") # From invoice wizard ) - if include_archived and partner and not partner.active: - _logger.info(f"Including archived partner {partner.name}") - result = { + # If it's a manual send and partner is archived, include them + if is_manual_send and partner and not partner.active: + _logger.debug(f"Including archived partner {partner.name} in email") + return { "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 - parent_result = super()._prepare_recipient_values(partner) - _logger.info(f"Parent returning: {parent_result}") - return parent_result \ No newline at end of file + # Default behavior for active partners or non-manual sends + return super()._prepare_recipient_values(partner) \ No newline at end of file