diff --git a/account_email_to_pdf/__init__.py b/account_email_to_pdf/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/account_email_to_pdf/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/account_email_to_pdf/__manifest__.py b/account_email_to_pdf/__manifest__.py new file mode 100644 index 0000000..f5c4d75 --- /dev/null +++ b/account_email_to_pdf/__manifest__.py @@ -0,0 +1,23 @@ +{ + 'name': 'Account Email to PDF', + 'version': '18.0.1.0.0', + 'category': 'Accounting', + 'summary': 'Convert email messages to PDF attachments for vendor bills', + 'description': """ +Account Email to PDF +=================== +This module converts email messages without attachments into PDF attachments +when processing incoming emails for vendor bills. + +Instead of rejecting emails without attachments, the system will create a PDF +from the email content and attach it to the message, allowing the vendor bill +creation process to continue. + """, + 'author': 'Bemade', + 'website': 'https://bemade.org', + 'depends': ['account'], + 'data': [], + 'installable': True, + 'auto_install': False, + 'license': 'LGPL-3', +} diff --git a/account_email_to_pdf/models/__init__.py b/account_email_to_pdf/models/__init__.py new file mode 100644 index 0000000..9c0a421 --- /dev/null +++ b/account_email_to_pdf/models/__init__.py @@ -0,0 +1 @@ +from . import account_move diff --git a/account_email_to_pdf/models/account_move.py b/account_email_to_pdf/models/account_move.py new file mode 100644 index 0000000..e9eb647 --- /dev/null +++ b/account_email_to_pdf/models/account_move.py @@ -0,0 +1,87 @@ +import base64 +import logging +from datetime import datetime +from email.utils import formatdate +from html import escape + +from odoo import models, fields +from odoo.tools.pdf import html_to_pdf + +_logger = logging.getLogger(__name__) + + +class AccountMove(models.Model): + _inherit = 'account.move' + + def _check_and_decode_attachment(self, attachments): + """Override to convert email message to PDF if no attachments are present.""" + if not attachments or self.env.context.get('no_new_invoice'): + # Original code would return False here, causing email rejection + # Instead, we'll create a PDF from the email message + message_dict = self.env.context.get('message_dict', {}) + if message_dict: + try: + # 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]) + except Exception as e: + _logger.exception("Error creating PDF from email: %s", e) + + # If we couldn't create a PDF, fall back to original behavior + return False + + # If there are attachments, proceed with the original method + return super()._check_and_decode_attachment(attachments) + + def _create_pdf_from_email(self, message_dict): + """Create a PDF attachment from an email message.""" + # Extract email details + email_from = message_dict.get('email_from', 'Unknown Sender') + email_date = message_dict.get('date', datetime.now()) + subject = message_dict.get('subject', 'No Subject') + body = message_dict.get('body', '') + + # Format the date if it's a datetime object + if isinstance(email_date, datetime): + email_date = email_date.strftime('%Y-%m-%d %H:%M:%S') + + # Create HTML content for the PDF + html_content = f""" + +
+ + + +