diff --git a/report_py3o/models/ir_actions_report.py b/report_py3o/models/ir_actions_report.py index ccb067e9a4..500247b138 100644 --- a/report_py3o/models/ir_actions_report.py +++ b/report_py3o/models/ir_actions_report.py @@ -2,6 +2,8 @@ # Copyright 2018 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging +from collections import OrderedDict +from io import BytesIO from odoo import _, api, fields, models from odoo.exceptions import ValidationError @@ -171,6 +173,36 @@ def _render_py3o(self, report_ref, res_ids, data=None): .create_report(res_ids, data) ) + def _pre_render_qweb_pdf(self, report_ref, res_ids=None, data=None): + report = self._get_report(report_ref) + if report.report_type != "py3o": + return super()._pre_render_qweb_pdf( + report_ref, + res_ids=res_ids, + data=data, + ) + + if isinstance(res_ids, int): + res_ids = [res_ids] + + collected_streams = OrderedDict() + for res_id in res_ids or []: + content, report_type = self._render(report_ref, [res_id], data=data) + if report_type != "pdf": + raise ValidationError( + _( + "Py3O report '%(report)s' must generate PDF output for " + "invoice sending. Current output format: %(format)s" + ) + % {"report": report.display_name, "format": report_type} + ) + collected_streams[res_id] = { + "stream": BytesIO(content), + "attachment": None, + } + + return collected_streams, "pdf" + def gen_report_download_filename(self, res_ids, data): """Override this function to change the name of the downloaded report""" self.ensure_one() diff --git a/report_py3o/tests/test_report_py3o.py b/report_py3o/tests/test_report_py3o.py index 713fb25935..043500f58f 100644 --- a/report_py3o/tests/test_report_py3o.py +++ b/report_py3o/tests/test_report_py3o.py @@ -266,3 +266,34 @@ def test_py3o_report_availability(self): self.assertFalse(self.report.msg_py3o_report_not_available) res = self.report._render(self.report.id, self.env.user.ids) self.assertTrue(res) + + def test_pre_render_qweb_pdf_py3o_streams(self): + with mock.patch.object( + self.report.__class__, + "_render", + return_value=(b"pdf-content", "pdf"), + ) as mocked_render: + streams, report_type = self.report._pre_render_qweb_pdf( + self.report.report_name, + res_ids=self.env.user.ids, + ) + + self.assertEqual(report_type, "pdf") + self.assertEqual(set(streams.keys()), set(self.env.user.ids)) + for stream_data in streams.values(): + self.assertEqual(stream_data["stream"].getvalue(), b"pdf-content") + stream_data["stream"].close() + + self.assertEqual(mocked_render.call_count, len(self.env.user.ids)) + + def test_pre_render_qweb_pdf_py3o_non_pdf(self): + with mock.patch.object( + self.report.__class__, + "_render", + return_value=(b"odt-content", "odt"), + ): + with self.assertRaises(ValidationError): + self.report._pre_render_qweb_pdf( + self.report.report_name, + res_ids=[self.env.user.id], + )