finally got the right method override (I hope) for email to pdf

This commit is contained in:
Marc Durepos 2025-03-27 17:16:26 -04:00
parent bfbc5d6491
commit 640326629a
2 changed files with 32 additions and 43 deletions

View file

@ -8,7 +8,7 @@ from datetime import datetime
from html import escape from html import escape
import re import re
from odoo import models, fields from odoo import models, api
from odoo.tools.misc import find_in_path from odoo.tools.misc import find_in_path
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -17,25 +17,23 @@ _logger = logging.getLogger(__name__)
class AccountMove(models.Model): class AccountMove(models.Model):
_inherit = "account.move" _inherit = "account.move"
def message_new(self, msg_dict, custom_values={}): @api.model
"""Override to create a PDF attachment from the email content before processing. def _routing_check_route(self, message, message_dict, route, raise_exception=True):
This ensures that emails without attachments can still be processed and converted to invoices. """Override to create a PDF attachment from the email content before checking the route.
The standard Odoo behavior bounces emails without attachments, but we want to
process them by generating a PDF from the email content.
""" """
# Get existing attachments in the email if route[0] == "account.move" and (
attachments = msg_dict.get("attachments", []) len(message_dict.get("attachments", [])) < 1
or message_dict["attachments"][0][0].lower().endswith(".eml")
# Check if there are attachments that are not the .eml of the message itself ):
regex = re.compile(r"^.*\.eml$", re.IGNORECASE)
if len(attachments) > 1 or (len(attachments) == 1 and not regex.match(attachments[0][0])):
return super().message_new(msg_dict, custom_values=custom_values)
try: try:
# Create a PDF from the email content # Create a PDF from the email content
pdf_attachment = self._create_pdf_from_email(msg_dict) pdf_attachment = self._create_pdf_from_email(message_dict)
if pdf_attachment: if pdf_attachment:
# Add the PDF to the message's attachments # Add the PDF to the message's attachments
if not msg_dict.get("attachments"): if not message_dict.get("attachments"):
msg_dict["attachments"] = [] message_dict["attachments"] = []
# Convert the attachment to the format expected by mail_thread # Convert the attachment to the format expected by mail_thread
# Format: (name, base64_data, info_dict) # Format: (name, base64_data, info_dict)
@ -44,10 +42,15 @@ class AccountMove(models.Model):
pdf_attachment["datas"], pdf_attachment["datas"],
{"mimetype": "application/pdf"}, {"mimetype": "application/pdf"},
) )
attachments.append(attachment_data) message_dict["attachments"].append(attachment_data)
except Exception as e: except Exception as e:
_logger.exception("Error creating PDF from email: %s", e) _logger.exception(
return super().message_new(msg_dict, custom_values=custom_values) "Error creating PDF from email in _routing_check_route: %s", e
)
return super()._routing_check_route(
message, message_dict, route, raise_exception=raise_exception
)
@classmethod @classmethod
def _html_to_pdf(cls, html_content): def _html_to_pdf(cls, html_content):

View file

@ -1,9 +1,7 @@
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase
from odoo.tools.misc import find_in_path from odoo.tools.misc import find_in_path
import logging
from datetime import datetime from datetime import datetime
_logger = logging.getLogger(__name__)
class TestHtmlToPdf(TransactionCase): class TestHtmlToPdf(TransactionCase):
@ -173,18 +171,6 @@ Content-Transfer-Encoding: 7bit
messages = invoice.message_ids messages = invoice.message_ids
self.assertEqual(len(messages), 1, "The account move should have one message") self.assertEqual(len(messages), 1, "The account move should have one message")
# Debug message attachments
_logger.info("Message ID: %s", messages.id)
_logger.info("Message attachments: %s", messages.attachment_ids)
_logger.info("Message attachment count: %s", len(messages.attachment_ids))
# Debug all attachments in the system
all_attachments = self.env["ir.attachment"].search(
[("res_model", "=", "mail.message"), ("res_id", "=", messages.id)]
)
_logger.info("All attachments for this message: %s", all_attachments)
_logger.info("All attachment count: %s", len(all_attachments))
attachment = messages.attachment_ids attachment = messages.attachment_ids
self.assertTrue(attachment, "The message should have an attachment") self.assertTrue(attachment, "The message should have an attachment")