From 7ad7481195939cd979914c183f61cf8f2ffb26c5 Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Sun, 19 Apr 2026 07:29:28 -0400 Subject: [PATCH] fix(bol): bigger title, shipper info, uniform headers, cargo qty, taller signatures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five fixes applied to the Bill of Lading and (where relevant) all report templates: 1. **Bigger title + BoL #** — portrait now uses h2 24pt (was h4 16pt), landscape h2 26pt; BoL # ticker is 13/14pt instead of body size. 2. **Shipper info missing** — root cause: `_fp_build_delivery_vals` was creating deliveries without `company_id`, so the BoL's `` rendered empty. Two fixes: - Hook now sets `company_id = mo.company_id.id or env.company.id`. - Template falls back defensively to `env.company` when `doc.company_id` is empty (covers any legacy delivery that somehow slips through without it). - Backfilled 14 existing deliveries via SQL on entech. 3. **Uniform header backgrounds** — replaced mixed `info-header` (gray) + default-th (brand black) headers with a single `fp-header-primary` (brand black) across all sub-tables for a consistent look. 4. **Cargo description alignment + missing column** — added a QTY column (matches landscape variant), pulled from the linked MO via job_ref → mrp.production.product_qty. Added `.fp-cell-mid` utility class with `vertical-align: middle !important;` and applied it to every cargo + info cell so values sit centred instead of jammed against the top border. 5. **Signature box too short** — bumped `.sig-box` from 70 → 110 px (portrait) / 130 px (landscape), `.sig-line` from 28 → 60/70 px, added flex layout so the label sits at the bottom and signers have a real space to write in. Lives in the shared `report_base_styles.xml` so EVERY FP template benefits, not just the BoL. Verified: BoL portrait renders cleanly at 140 KB with full shipper block + uniform headers + middle-aligned cargo cells. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../fusion_plating_bridge_mrp/__manifest__.py | 2 +- .../models/mrp_production.py | 1 + .../fusion_plating_reports/__manifest__.py | 2 +- .../report/report_base_styles.xml | 10 +- .../report/report_fp_bol.xml | 93 +++++++++++-------- fusion_plating/scripts/fp_bol_inspect.py | 15 +++ fusion_plating/scripts/fp_company_check.py | 19 ++++ fusion_plating/scripts/fp_dlv_check.py | 7 ++ 8 files changed, 102 insertions(+), 47 deletions(-) create mode 100644 fusion_plating/scripts/fp_bol_inspect.py create mode 100644 fusion_plating/scripts/fp_company_check.py create mode 100644 fusion_plating/scripts/fp_dlv_check.py diff --git a/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py b/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py index 801e9ca1..52715b5f 100644 --- a/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py +++ b/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Fusion Plating — MRP Bridge", - 'version': '19.0.6.0.0', + 'version': '19.0.6.1.0', 'category': 'Manufacturing/Plating', 'summary': 'Bridge Fusion Plating facilities, baths and tanks to Odoo MRP work orders.', 'description': """ diff --git a/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py b/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py index da53329f..da07c4ca 100644 --- a/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py +++ b/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py @@ -674,6 +674,7 @@ class MrpProduction(models.Model): ], order='id', limit=1) return { + 'company_id': mo.company_id.id or self.env.company.id, 'partner_id': job.partner_id.id, 'job_ref': job.name, 'source_facility_id': ( diff --git a/fusion_plating/fusion_plating_reports/__manifest__.py b/fusion_plating/fusion_plating_reports/__manifest__.py index 31cc9603..fdaadf7a 100644 --- a/fusion_plating/fusion_plating_reports/__manifest__.py +++ b/fusion_plating/fusion_plating_reports/__manifest__.py @@ -3,7 +3,7 @@ # License OPL-1 (Odoo Proprietary License v1.0) { 'name': 'Fusion Plating — Reports', - 'version': '19.0.4.1.0', + 'version': '19.0.4.2.0', 'category': 'Manufacturing/Plating', 'summary': 'PDF reports for Fusion Plating: quote, SO, WO, packing, BoL, CoC, invoice, receipt, quality + compliance.', 'depends': [ diff --git a/fusion_plating/fusion_plating_reports/report/report_base_styles.xml b/fusion_plating/fusion_plating_reports/report/report_base_styles.xml index 5392a780..84eb82e5 100644 --- a/fusion_plating/fusion_plating_reports/report/report_base_styles.xml +++ b/fusion_plating/fusion_plating_reports/report/report_base_styles.xml @@ -46,9 +46,10 @@ .fp-report .status-ok { color: #2e7d32; font-weight: bold; } .fp-report .status-warning { color: #f57f17; font-weight: bold; } .fp-report .status-fail { color: #c62828; font-weight: bold; } - .fp-report .sig-box { border: 1px solid #000; padding: 12px; min-height: 70px; } - .fp-report .sig-line { border-bottom: 1px solid #000; min-height: 28px; } + .fp-report .sig-box { border: 1px solid #000; padding: 14px 12px 8px 12px; min-height: 110px; display: flex; flex-direction: column; justify-content: flex-end; } + .fp-report .sig-line { border-bottom: 1px solid #000; min-height: 60px; } .fp-report .small-muted { font-size: 8pt; color: #666; } + .fp-report .fp-cell-mid { vertical-align: middle !important; } @@ -82,9 +83,10 @@ .fp-landscape .status-ok { color: #2e7d32; font-weight: bold; } .fp-landscape .status-warning { color: #f57f17; font-weight: bold; } .fp-landscape .status-fail { color: #c62828; font-weight: bold; } - .fp-landscape .sig-box { border: 1px solid #000; padding: 12px; min-height: 70px; } - .fp-landscape .sig-line { border-bottom: 1px solid #000; min-height: 28px; } + .fp-landscape .sig-box { border: 1px solid #000; padding: 14px 12px 8px 12px; min-height: 130px; display: flex; flex-direction: column; justify-content: flex-end; } + .fp-landscape .sig-line { border-bottom: 1px solid #000; min-height: 70px; } .fp-landscape .small-muted { font-size: 9pt; color: #666; } + .fp-landscape .fp-cell-mid { vertical-align: middle !important; } diff --git a/fusion_plating/fusion_plating_reports/report/report_fp_bol.xml b/fusion_plating/fusion_plating_reports/report/report_fp_bol.xml index 3e36e3fc..8a3bd819 100644 --- a/fusion_plating/fusion_plating_reports/report/report_fp_bol.xml +++ b/fusion_plating/fusion_plating_reports/report/report_fp_bol.xml @@ -19,10 +19,14 @@
-

+ + + +

BILL OF LADING -

-
+

+
BoL #:
@@ -30,21 +34,21 @@ - - + + - - - - - + + + - - + -
SHIPPERCONSIGNEESHIPPERCONSIGNEE
-
+
+

-
+
SHIP DATEDRIVERVEHICLESHIP DATEDRIVERVEHICLE
+ - + @@ -97,14 +101,14 @@ - - + + - - + @@ -112,30 +116,35 @@
JOB REFERENCEDANGEROUS GOODS (TDG)JOB REFERENCEDANGEROUS GOODS (TDG)
+ TDG REQUIRED No TDG
- + - + - - - - + + + + + - - + - - + + @@ -147,17 +156,17 @@
CARGO DESCRIPTIONCARGO DESCRIPTION
PACKAGESDESCRIPTION OF GOODSWEIGHTCLASSPACKAGESDESCRIPTION OF GOODSQTYWEIGHTCLASS
1 + 1 Plated parts — Job
+ + + + TDG NON-HAZ
- - + + - - @@ -212,8 +221,10 @@
-

BILL OF LADING

-
+ + +

BILL OF LADING

+
BoL #:
@@ -221,21 +232,21 @@
CoC ATTACHEDPACKING LISTCoC ATTACHEDPACKING LIST
+ ✓ Attached + ✓ Attached
- - + + - -
SHIPPERCONSIGNEESHIPPERCONSIGNEE
-
+
+

-
+
SHIPPER<.*?(.*?)
', out, re.S) +if m: + print('--- SHIPPER/CONSIGNEE table body ---') + print(m.group(1)[:2500]) +else: + print('SHIPPER section not found, dumping first 2000 chars:') + print(out[:2000]) diff --git a/fusion_plating/scripts/fp_company_check.py b/fusion_plating/scripts/fp_company_check.py new file mode 100644 index 00000000..6a823c23 --- /dev/null +++ b/fusion_plating/scripts/fp_company_check.py @@ -0,0 +1,19 @@ +env = env # noqa +co = env['res.company'].search([], limit=1) +p = co.partner_id +print('company:', co.name) +print(' partner_id:', p.id, p.name) +print(' street:', repr(p.street)) +print(' street2:', repr(p.street2)) +print(' city:', repr(p.city), 'zip:', repr(p.zip)) +print(' state:', p.state_id.name if p.state_id else None) +print(' country:', p.country_id.name if p.country_id else None) +print(' phone:', repr(p.phone), 'email:', repr(p.email)) +print() +# Also check if delivery has a source_facility_id with address +dlv = env['fusion.plating.delivery'].search([], order='id desc', limit=1) +if dlv.source_facility_id: + f = dlv.source_facility_id + print('facility:', f.name) + print(' address:', getattr(f, 'address', None) or getattr(f, 'street', None) or '(no address field)') + print(' fields:', [k for k in f._fields if 'addr' in k or 'street' in k or 'city' in k]) diff --git a/fusion_plating/scripts/fp_dlv_check.py b/fusion_plating/scripts/fp_dlv_check.py new file mode 100644 index 00000000..78a39ceb --- /dev/null +++ b/fusion_plating/scripts/fp_dlv_check.py @@ -0,0 +1,7 @@ +env = env # noqa +dlv = env['fusion.plating.delivery'].search([], order='id desc', limit=1) +print('delivery:', dlv.name) +print(' company_id:', dlv.company_id, '/', dlv.company_id.name if dlv.company_id else None) +print(' source_facility_id:', dlv.source_facility_id, '/', dlv.source_facility_id.name if dlv.source_facility_id else None) +print(' has company_id field?', 'company_id' in dlv._fields) +print(' field def:', dlv._fields.get('company_id'))