From 4abc7df7b22dbad43b309c2adc65d9d87613e7a5 Mon Sep 17 00:00:00 2001
From: "Solan Delvenne (sode)" <sode@odoo.com>
Date: Tue, 29 Nov 2022 15:14:28 +0000
Subject: [PATCH] [FIX] snailmail: overwrite margins in letters

In order to pass the validation of the snailmail provider, the margins
are required to have nothing but white pixels. To avoid letters being
stuck until their layout is fixed, we fill the margins with white.

closes odoo/odoo#106791

Signed-off-by: Florian Daloze (fda) <fda@odoo.com>
---
 addons/snailmail/models/snailmail_letter.py | 49 ++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/addons/snailmail/models/snailmail_letter.py b/addons/snailmail/models/snailmail_letter.py
index 5413b5829158..bb05177535de 100644
--- a/addons/snailmail/models/snailmail_letter.py
+++ b/addons/snailmail/models/snailmail_letter.py
@@ -4,7 +4,7 @@ import re
 import base64
 import io
 
-from PyPDF2 import PdfFileReader, PdfFileMerger
+from PyPDF2 import PdfFileReader, PdfFileMerger, PdfFileWriter
 from reportlab.platypus import Frame, Paragraph, KeepInFrame
 from reportlab.lib.units import mm
 from reportlab.lib.pagesizes import A4
@@ -133,6 +133,7 @@ class SnailmailLetter(models.Model):
             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, lang='en_US').render_qweb_pdf(self.res_id)
+            pdf_bin = self._overwrite_margins(pdf_bin)
             if self.cover:
                 pdf_bin = self._append_cover_page(pdf_bin)
             attachment = self.env['ir.attachment'].create({
@@ -441,3 +442,49 @@ class SnailmailLetter(models.Model):
         out_buff = io.BytesIO()
         merger.write(out_buff)
         return out_buff.getvalue()
+
+    def _overwrite_margins(self, invoice_bin: bytes):
+        """
+        Fill the margins with white for validation purposes.
+        """
+        pdf_buf = io.BytesIO()
+        canvas = Canvas(pdf_buf, pagesize=A4)
+        canvas.setFillColorRGB(255, 255, 255)
+        page_width = A4[0]
+        page_height = A4[1]
+
+        # Horizontal Margin
+        hmargin_width = page_width
+        hmargin_height = 5 * mm
+
+        # Vertical Margin
+        vmargin_width = 5 * mm
+        vmargin_height = page_height
+
+        # Bottom left square
+        sq_width = 15 * mm
+
+        # Draw the horizontal margins
+        canvas.rect(0, 0, hmargin_width, hmargin_height, stroke=0, fill=1)
+        canvas.rect(0, page_height, hmargin_width, -hmargin_height, stroke=0, fill=1)
+
+        # Draw the vertical margins
+        canvas.rect(0, 0, vmargin_width, vmargin_height, stroke=0, fill=1)
+        canvas.rect(page_width, 0, -vmargin_width, vmargin_height, stroke=0, fill=1)
+
+        # Draw the bottom left white square
+        canvas.rect(0, 0, sq_width, sq_width, stroke=0, fill=1)
+        canvas.save()
+        pdf_buf.seek(0)
+
+        new_pdf = PdfFileReader(pdf_buf)
+        curr_pdf = PdfFileReader(io.BytesIO(invoice_bin))
+        out = PdfFileWriter()
+        for page in curr_pdf.pages:
+            page.mergePage(new_pdf.getPage(0))
+            out.addPage(page)
+        out_stream = io.BytesIO()
+        out.write(out_stream)
+        out_bin = out_stream.getvalue()
+        out_stream.close()
+        return out_bin
-- 
GitLab