From 44a3ae0f4f29be0b5547d3ac88185590f2d2c98c Mon Sep 17 00:00:00 2001 From: "Solan Delvenne (sode)" <sode@odoo.com> Date: Tue, 20 Sep 2022 10:52:19 +0000 Subject: [PATCH] [FIX] snailmail: mandatory cover page + handle cover page generation Pingen's v2 API does not offer an endpoint to generate a Cover Page automatically with an API call anymore, thus the need to generate it and append it to the invoice from the client-side beforehand. Also make the Cover Page option mandatory due to the invoice being near impossible to format for Pingen's validation needs. (Odoo 13 Only) closes odoo/odoo#103385 Signed-off-by: Louis Baudoux (lba) <lba@odoo.com> --- addons/snailmail/models/snailmail_letter.py | 48 +++++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/addons/snailmail/models/snailmail_letter.py b/addons/snailmail/models/snailmail_letter.py index 3152db0a0252..12f872629d52 100644 --- a/addons/snailmail/models/snailmail_letter.py +++ b/addons/snailmail/models/snailmail_letter.py @@ -2,9 +2,16 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. import re import base64 -import datetime +import io -from odoo import fields, models, api, _, tools +from PyPDF2 import PdfFileReader, PdfFileMerger +from reportlab.platypus import Frame, Paragraph, KeepInFrame +from reportlab.lib.units import mm +from reportlab.lib.pagesizes import A4 +from reportlab.lib.styles import getSampleStyleSheet +from reportlab.pdfgen.canvas import Canvas + +from odoo import fields, models, api, _ from odoo.addons.iap import jsonrpc from odoo.exceptions import UserError, AccessError from odoo.tools.safe_eval import safe_eval @@ -120,7 +127,11 @@ class SnailmailLetter(models.Model): else: report_name = 'Document' filename = "%s.%s" % (report_name, "pdf") - pdf_bin, _ = report.with_context(snailmail_layout=not self.cover).render_qweb_pdf(self.res_id) + if not self.cover: + raise UserError(_("Snailmails without covers are no longer supported in Odoo 13.\nPlease enable the 'Add a Cover Page' option in your Invoicing settings or upgrade your Odoo.")) + pdf_bin, unused_filetype = report.with_context(snailmail_layout=not self.cover).render_qweb_pdf(self.res_id) + if self.cover: + pdf_bin = self._append_cover_page(pdf_bin) attachment = self.env['ir.attachment'].create({ 'name': filename, 'datas': base64.b64encode(pdf_bin), @@ -183,7 +194,6 @@ class SnailmailLetter(models.Model): dbuuid = self.env['ir.config_parameter'].sudo().get_param('database.uuid') documents = [] - batch = len(self) > 1 for letter in self: document = { # generic informations to send @@ -398,3 +408,33 @@ class SnailmailLetter(models.Model): } failures_infos.append(info) return failures_infos + + def _append_cover_page(self, invoice_bin: bytes): + address = self.partner_id.contact_address.replace('\n', '<br/>') + address_x = 118 * mm + address_y = 60 * mm + frame_width = 85.5 * mm + frame_height = 25.5 * mm + + cover_buf = io.BytesIO() + canvas = Canvas(cover_buf, pagesize=A4) + styles = getSampleStyleSheet() + + frame = Frame(address_x, A4[1] - address_y - frame_height, frame_width, frame_height) + story = [Paragraph(address, styles['Normal'])] + address_inframe = KeepInFrame(0, 0, story) + frame.addFromList([address_inframe], canvas) + canvas.save() + cover_buf.seek(0) + + invoice = PdfFileReader(io.BytesIO(invoice_bin)) + cover_bin = io.BytesIO(cover_buf.getvalue()) + cover_file = PdfFileReader(cover_bin) + merger = PdfFileMerger() + + merger.append(cover_file, import_bookmarks=False) + merger.append(invoice, import_bookmarks=False) + + out_buff = io.BytesIO() + merger.write(out_buff) + return out_buff.getvalue() -- GitLab