further fixes and tests for email_to_pdf
This commit is contained in:
parent
f3259fd6a1
commit
ad2bc057a2
4 changed files with 119 additions and 10 deletions
|
|
@ -28,8 +28,19 @@ class AccountMove(models.Model):
|
|||
# Create a PDF from the email content
|
||||
pdf_attachment = self._create_pdf_from_email(message_dict)
|
||||
if pdf_attachment:
|
||||
# Add the PDF to the attachments list
|
||||
return super()._check_and_decode_attachment([pdf_attachment])
|
||||
_logger.info(
|
||||
"Successfully created PDF attachment, proceeding with invoice creation"
|
||||
)
|
||||
# We need to return the result of _extend_with_attachments directly
|
||||
# as that's what the original method would return
|
||||
# Convert the list to a recordset before passing to _extend_with_attachments
|
||||
attachment_recordset = self.env["ir.attachment"].browse(
|
||||
[pdf_attachment.id]
|
||||
)
|
||||
return self._extend_with_attachments(
|
||||
attachment_recordset,
|
||||
new=bool(self._context.get("from_alias")),
|
||||
)
|
||||
except Exception as e:
|
||||
_logger.exception("Error creating PDF from email: %s", e)
|
||||
|
||||
|
|
@ -110,7 +121,14 @@ class AccountMove(models.Model):
|
|||
_logger.error("Failed to remove temporary files")
|
||||
|
||||
def _create_pdf_from_email(self, message_dict):
|
||||
"""Create a PDF attachment from an email message."""
|
||||
"""Create a PDF attachment from an email message.
|
||||
|
||||
Args:
|
||||
message_dict (dict): Email message dictionary
|
||||
|
||||
Returns:
|
||||
ir.attachment: The created attachment record or False if failed
|
||||
"""
|
||||
# Extract email details
|
||||
email_from = message_dict.get("email_from", "Unknown Sender")
|
||||
email_date = message_dict.get("date", datetime.now())
|
||||
|
|
@ -151,13 +169,16 @@ class AccountMove(models.Model):
|
|||
if not pdf_content:
|
||||
return False
|
||||
|
||||
# Create attachment tuple (filename, content, mime_type)
|
||||
# Create a proper ir.attachment record
|
||||
filename = f"Email_{subject.replace(' ', '_')[:30]}.pdf"
|
||||
attachment = (
|
||||
filename,
|
||||
base64.b64encode(pdf_content).decode("utf-8"),
|
||||
"application/pdf",
|
||||
)
|
||||
attachment_vals = {
|
||||
"name": filename,
|
||||
"datas": base64.b64encode(pdf_content),
|
||||
"mimetype": "application/pdf",
|
||||
"res_model": "mail.message",
|
||||
"res_id": message_dict.get("id", 0),
|
||||
}
|
||||
|
||||
attachment = self.env["ir.attachment"].create(attachment_vals)
|
||||
_logger.info("Created PDF attachment from email: %s", filename)
|
||||
return attachment
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
from . import test_email_to_pdf
|
||||
from . import test_email_integration
|
||||
|
|
|
|||
88
account_email_to_pdf/tests/test_email_integration.py
Normal file
88
account_email_to_pdf/tests/test_email_integration.py
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import base64
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.tools.misc import find_in_path
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
class TestEmailProcessing(TransactionCase):
|
||||
"""Integration tests for email processing with PDF generation."""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
# Check if wkhtmltopdf is available
|
||||
cls.wkhtmltopdf_available = bool(find_in_path("wkhtmltopdf"))
|
||||
|
||||
# Get the model class to access the methods
|
||||
cls.account_move = cls.env["account.move"]
|
||||
|
||||
def test_create_pdf_from_email(self):
|
||||
"""Test that an email without attachments can be converted to PDF.
|
||||
|
||||
This test directly verifies that the _create_pdf_from_email method
|
||||
correctly generates a PDF attachment from an email message without
|
||||
attachments, allowing the invoice creation process to continue.
|
||||
"""
|
||||
if not self.wkhtmltopdf_available:
|
||||
self.skipTest("wkhtmltopdf not available")
|
||||
|
||||
# Create a sample email message dictionary (similar to what would be parsed from an email)
|
||||
message_dict = {
|
||||
"subject": "Test Invoice",
|
||||
"from": "test@example.com",
|
||||
"to": "invoices@example.com",
|
||||
"body": "<html><body><h1>Invoice Test</h1><p>This is a test invoice.</p></body></html>",
|
||||
"attachments": [], # No attachments
|
||||
"message_id": "<test123@example.com>",
|
||||
}
|
||||
|
||||
# Call the method directly to create a PDF from the email
|
||||
attachment = self.account_move._create_pdf_from_email(message_dict)
|
||||
|
||||
# Verify that an attachment was created
|
||||
self.assertTrue(attachment, "An attachment should have been created")
|
||||
# The actual name format is 'Email_' + subject + '.pdf' with spaces replaced by underscores
|
||||
self.assertEqual(
|
||||
attachment.name,
|
||||
"Email_Test_Invoice.pdf",
|
||||
"Attachment name should match expected format",
|
||||
)
|
||||
self.assertEqual(
|
||||
attachment.mimetype, "application/pdf", "Attachment should be a PDF"
|
||||
)
|
||||
|
||||
# Verify the content of the PDF attachment
|
||||
pdf_data = base64.b64decode(attachment.datas)
|
||||
self.assertTrue(pdf_data.startswith(b"%PDF-"), "Content should be a valid PDF")
|
||||
self.assertTrue(len(pdf_data) > 100, "PDF should have a reasonable size")
|
||||
|
||||
def test_check_and_decode_attachment_with_empty_attachments(self):
|
||||
"""Test that _check_and_decode_attachment doesn't reject emails with no attachments."""
|
||||
if not self.wkhtmltopdf_available:
|
||||
self.skipTest("wkhtmltopdf not available")
|
||||
|
||||
# Set up a context with a message_dict to simulate email processing
|
||||
message_dict = {
|
||||
"subject": "Test Invoice",
|
||||
"from": "test@example.com",
|
||||
"to": "invoices@example.com",
|
||||
"body": "<html><body><h1>Invoice Test</h1><p>This is a test invoice.</p></body></html>",
|
||||
"attachments": [], # No attachments
|
||||
"message_id": "<test123@example.com>",
|
||||
}
|
||||
|
||||
# Call the method with an empty attachments list
|
||||
# We need to pass the message_dict in the context so _create_pdf_from_email can access it
|
||||
result = self.account_move.with_context(
|
||||
message_dict=message_dict
|
||||
)._check_and_decode_attachment([])
|
||||
|
||||
# Verify that the result is not False (which would mean email rejection)
|
||||
self.assertNotEqual(
|
||||
result,
|
||||
False,
|
||||
"Should not reject the email when no attachments are provided",
|
||||
)
|
||||
|
||||
# Verify that the result contains attachment data
|
||||
self.assertTrue(result, "Should return attachment data")
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import base64
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.tools.misc import find_in_path
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue