From 0a09f8bfe7a980c156dabebb626fda0d9a623692 Mon Sep 17 00:00:00 2001 From: emjay0921 Date: Wed, 5 Aug 2026 20:03:27 +0800 Subject: [PATCH 1/6] fix(spp_drims): make the waybill render and say what is on the vehicle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rendered the waybill and read the result rather than the template. It came out two pages, with every column stacked and the signature row pushed onto page 2; the TO box empty; "Total Items" reading 1 for a 200-unit consignment; the picking's internal note printed; the quantity column showing demand rather than what was picked; and no barcode. Lay it out with tables instead of Bootstrap's grid. Reports are rendered by wkhtmltopdf 0.12.6, a WebKit build with no flexbox, so row/col-* and card collapse and each column becomes a row. A test fails if any of those classes reappear, because the damage is invisible in the browser preview and only shows in the PDF. Fill the TO box from location_dest_id. partner_id is blank on a dispatch — relief goods go to a location, not a customer — which is why the box was empty. Print an address only when a street is recorded, since the contact widget on a bare partner renders its name wrapped in dashes. Show Shipped alongside Demand. A waybill accompanies the goods, so it has to state what is actually on the vehicle; demand stays for reconciliation at the receiving end. Drop the "Total Items" footer, which counted move lines, and the note, which is internal. Always print the Vehicle and Driver rows so there is somewhere to write, and print whichever of Request or Donation matches the transaction type. Add the transaction type, distribution area, estimated beneficiaries and distribution type. The barcode needed two fixes and neither was in the template. reportlab 4.1 defaults renderPMBackend to rlPyCairo, which the image does not install, so /report/barcode/ answered HTTP 500 for every URL form — every barcode and QR code in every Odoo report, not just this one. Odoo's own requirements only pin a backend for win32, assuming the Debian package covers Linux. Adding rlPyCairo fixes the route. The image still did not appear, because an with a relative URL needs wkhtmltopdf to fetch it from inside the rendering process, where web.base.url points at an external host and port that cannot be reached; embedding it as a data URI removes that dependency, verified by rendering with web.base.url deliberately pointed at a dead port. A failure to build the barcode is logged and skipped rather than raised, so it cannot stop a waybill printing. Also expose stock.move's drims_request_line_id and drims_donation_line_id, which appeared in no view, so it is possible to see which request or donation line a move fulfils. Read-only, since reassigning one by hand would misattribute dispatched and delivered quantities. Kept in its own file: the picking form's Operations list is defined inline in stock.view_picking_form and cannot be extended from a separate view. Note the ticket lists a third linkage field, drims_allocation_id, which does not exist on the model. OP#1151 --- docker/requirements.txt | 11 + spp_drims/__manifest__.py | 1 + spp_drims/models/stock_picking.py | 41 ++ spp_drims/report/waybill_template.xml | 544 ++++++++++++++++--------- spp_drims/tests/__init__.py | 1 + spp_drims/tests/test_waybill_report.py | 249 +++++++++++ spp_drims/views/stock_move_views.xml | 81 ++++ 7 files changed, 745 insertions(+), 183 deletions(-) create mode 100644 spp_drims/tests/test_waybill_report.py create mode 100644 spp_drims/views/stock_move_views.xml diff --git a/docker/requirements.txt b/docker/requirements.txt index e57229741..a3ec6fbb8 100644 --- a/docker/requirements.txt +++ b/docker/requirements.txt @@ -19,6 +19,17 @@ git-aggregator==4.0 # PDF processing (reportlab uses these) pdfminer.six +# renderPM backend for reportlab 4.x, which every barcode and QR code in every +# Odoo report goes through: /report/barcode/ -> ir.actions.report.barcode() -> +# Drawing.asString('png') -> renderPM. reportlab 4.1 defaults +# rl_config.renderPMBackend to 'rlPyCairo', and without it that route answers +# HTTP 500 with "cannot import desired renderPM backend rlPyCairo" (OP#1151). +# Odoo's own requirements only pin a backend for win32, assuming the Debian +# python3-renderpm package covers Linux — this image does not install it. +# Builds fine here: the builder stage already has libcairo2-dev and the runtime +# image ships libcairo2. +rlPyCairo + # ----------------------------------------------------------------------------- # OpenSPP Specific (not in module manifests but required) # ----------------------------------------------------------------------------- diff --git a/spp_drims/__manifest__.py b/spp_drims/__manifest__.py index 5cd7472c7..59613a944 100644 --- a/spp_drims/__manifest__.py +++ b/spp_drims/__manifest__.py @@ -67,6 +67,7 @@ "views/request_template_views.xml", "views/return_views.xml", "views/stock_picking_views.xml", + "views/stock_move_views.xml", "views/stock_warehouse_views.xml", "views/stock_quant_views.xml", "views/stock_lot_views.xml", diff --git a/spp_drims/models/stock_picking.py b/spp_drims/models/stock_picking.py index 703c4403f..2e4088f22 100644 --- a/spp_drims/models/stock_picking.py +++ b/spp_drims/models/stock_picking.py @@ -1,4 +1,5 @@ # Part of OpenSPP. See LICENSE file for full copyright and licensing details. +import base64 import json import logging @@ -165,6 +166,46 @@ def action_open_gis_map(self): """Open the unified DRIMS Operations Map.""" return self.env.ref("spp_drims.action_drims_operations_map").read()[0] + def _get_waybill_barcode_data_uri(self, width=300, height=50): + """Return the waybill number as an embedded Code128 ``data:`` URI (OP#1151). + + The waybill template used to point an ```` at ``/report/barcode/``. + That makes the barcode depend on wkhtmltopdf being able to fetch a URL + from inside the rendering process, so it silently vanished whenever + ``web.base.url`` was not reachable there — which is the normal state of a + containerised deployment where Odoo listens on 8069 internally but + ``web.base.url`` holds an external host and port. Embedding the image + removes the network round trip, so the barcode renders the same in dev, + CI and production. + + Requires reportlab's renderPM backend (``rlPyCairo``) to be installed; + see ``docker/requirements.txt``. Returns ``False`` rather than raising if + the barcode cannot be produced, since a missing barcode must not stop a + waybill printing. + + Returns: + str | bool: ``data:image/png;base64,...`` or ``False``. + """ + self.ensure_one() + if not self.waybill_number: + return False + try: + png = self.env["ir.actions.report"].barcode( + "Code128", + self.waybill_number, + width=width, + height=height, + humanreadable=0, + ) + except Exception: # noqa: BLE001 - never let a barcode break the document + _logger.warning( + "Could not render the Code128 barcode for waybill %s; printing without it. Is rlPyCairo installed?", + self.waybill_number, + exc_info=True, + ) + return False + return "data:image/png;base64," + base64.b64encode(png).decode() + def action_confirm_departure(self): """Confirm dispatch departure.""" for rec in self: diff --git a/spp_drims/report/waybill_template.xml b/spp_drims/report/waybill_template.xml index f7b524fb8..f37b57fcb 100644 --- a/spp_drims/report/waybill_template.xml +++ b/spp_drims/report/waybill_template.xml @@ -14,158 +14,355 @@ report - +