From 82e17cff03f6ff9a98b01839f8e7b48486ad780f Mon Sep 17 00:00:00 2001 From: "Abdelouahab (abla)" Date: Fri, 20 Jan 2023 15:21:23 +0000 Subject: [PATCH] [FIX] account: print image in pdf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To Reproduce ============ - create a vendor bill and add an image as attachment - print Original Bill -> the generated pdf can't be loaded Problem ======= when trying to add an image attachment to pdf report, the image needs a special process. Solution ======== add the image processing when printing pdf fix inspired from 15 [commit](https://github.com/odoo/odoo/commit/b82a6cdea21a66588ddcafcdfb5026ec22546745) opw-3127535 closes odoo/odoo#112596 X-original-commit: 41c79f66cfb5cdb558110d32842198157932397e Signed-off-by: William André (wan) --- addons/account/models/ir_actions_report.py | 5 ++--- odoo/tools/pdf.py | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/addons/account/models/ir_actions_report.py b/addons/account/models/ir_actions_report.py index 4e5e41fd4bb..78d5ab3616f 100644 --- a/addons/account/models/ir_actions_report.py +++ b/addons/account/models/ir_actions_report.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -import io import textwrap from collections import OrderedDict from PyPDF2.utils import PdfStreamError @@ -29,8 +28,8 @@ class IrActionsReport(models.Model): for invoice in invoices: attachment = invoice.message_main_attachment_id if attachment: - stream = io.BytesIO(attachment.raw) - if attachment.mimetype == 'application/pdf': + stream = pdf.to_pdf_stream(attachment) + if stream: record = self.env[attachment.res_model].browse(attachment.res_id) try: stream = pdf.add_banner(stream, record.name, logo=True) diff --git a/odoo/tools/pdf.py b/odoo/tools/pdf.py index de471d87008..46fee2c6ed0 100644 --- a/odoo/tools/pdf.py +++ b/odoo/tools/pdf.py @@ -9,7 +9,7 @@ from logging import getLogger from PyPDF2 import PdfFileWriter, PdfFileReader from PyPDF2.generic import DictionaryObject, NameObject, ArrayObject, DecodedStreamObject, NumberObject, createStringObject, ByteStringObject from zlib import compress, decompress -from PIL import Image +from PIL import Image, PdfImagePlugin from reportlab.lib import colors from reportlab.lib.units import cm from reportlab.lib.utils import ImageReader @@ -28,6 +28,9 @@ REGEX_SUBTYPE_UNFORMATED = re.compile(r'^\w+/[\w-]+$') REGEX_SUBTYPE_FORMATED = re.compile(r'^/\w+#2F[\w-]+$') +# Disable linter warning: this import is needed to make sure a PDF stream can be saved in Image. +PdfImagePlugin.__name__ + # make sure values are unwrapped by calling the specialized __getitem__ def _unwrapping_get(self, key, default=None): try: @@ -84,6 +87,18 @@ def rotate_pdf(pdf): return _buffer.getvalue() +def to_pdf_stream(attachment) -> io.BytesIO: + """Get the byte stream of the attachment as a PDF.""" + stream = io.BytesIO(attachment.raw) + if attachment.mimetype == 'application/pdf': + return stream + elif attachment.mimetype.startswith('image'): + output_stream = io.BytesIO() + Image.open(stream).convert("RGB").save(output_stream, format="pdf") + return output_stream + _logger.warning("mimetype (%s) not recognized for %s", attachment.mimetype, attachment) + + def add_banner(pdf_stream, text=None, logo=False, thickness=2 * cm): """ Add a banner on a PDF in the upper right corner, with Odoo's logo (optionally).