fix(coc): single-page layout — custom paperformat + strip Odoo wrappers
The CoC was rendering on 2 pages with ~35mm of dead whitespace at the
top. Three compounding causes:
1. Default Odoo paperformat reserves header_spacing=35mm (where the
standard letterhead would sit when using web.external_layout). Our
CoC has its own full-bleed header so that reservation was pure
empty space.
→ New paperformat_fp_coc with header_spacing=0, 8mm all-around
margins, attached to both report_coc_en and report_coc_fr actions.
2. The `<div class="article o_report_layout_boxed">` and nested
`<div class="page">` wrappers inherited Odoo's CSS which applies
`page-break-after: always` on `.page` and additional padding on
`.article`.
→ Dropped both wrappers — template now renders body directly
inside html_container.
3. Inline style block didn't override Odoo's body/main padding.
→ Aggressive !important reset at the top of the style block on
html, body, main, .article, .page, and the hidden header/footer
classes. Also shrunk all paddings by ~30% and bumped base font
to 9pt to guarantee single-page fit.
Verified: PDF is now 1 page, content starts at the top (title flush
with top margin), accreditation logos + customer logo + signature all
render correctly within the single page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,24 @@
|
||||
<field name="dpi">90</field>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- CoC paper format — zero header/footer band so the title -->
|
||||
<!-- starts at the top of the page, not 35mm down. -->
|
||||
<!-- ============================================================= -->
|
||||
<record id="paperformat_fp_coc" model="report.paperformat">
|
||||
<field name="name">Fusion Plating CoC</field>
|
||||
<field name="default" eval="False"/>
|
||||
<field name="format">A4</field>
|
||||
<field name="orientation">Portrait</field>
|
||||
<field name="margin_top">8</field>
|
||||
<field name="margin_bottom">8</field>
|
||||
<field name="margin_left">8</field>
|
||||
<field name="margin_right">8</field>
|
||||
<field name="header_line" eval="False"/>
|
||||
<field name="header_spacing">0</field>
|
||||
<field name="dpi">90</field>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- 1. Certificate of Conformance (Portal Job) — Landscape -->
|
||||
<!-- ============================================================= -->
|
||||
@@ -62,6 +80,7 @@
|
||||
<field name="print_report_name">'CoC EN - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_certificates.model_fp_certificate"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_coc"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
@@ -76,6 +95,7 @@
|
||||
<field name="print_report_name">'CoC FR - %s' % object.name</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_certificates.model_fp_certificate"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_coc"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
|
||||
@@ -33,29 +33,42 @@
|
||||
<t t-set="signer_name" t-value="doc.certified_by_id.name or (company.x_fc_owner_user_id.name if company.x_fc_owner_user_id else '')"/>
|
||||
|
||||
<style>
|
||||
@page { margin: 12mm 10mm; }
|
||||
body, .o_report_layout_boxed { margin: 0 !important; padding: 0 !important; }
|
||||
.fp-coc { font-family: Arial, sans-serif; font-size: 10pt; color: #000; padding: 0; }
|
||||
.fp-coc h1 { text-align: center; font-size: 22pt; margin: 0 0 10px 0; font-weight: bold; }
|
||||
.fp-coc hr.heavy { border: 0; border-top: 2px solid #000; margin: 6px 0; }
|
||||
/* Kill all Odoo-inherited body/main/page spacing */
|
||||
html, body { margin: 0 !important; padding: 0 !important; }
|
||||
main, .article, .page, .o_report_layout_boxed {
|
||||
margin: 0 !important; padding: 0 !important;
|
||||
page-break-after: auto !important;
|
||||
min-height: 0 !important;
|
||||
}
|
||||
header.o_company_header, footer.o_company_footer { display: none !important; }
|
||||
|
||||
.fp-coc { font-family: Arial, sans-serif; font-size: 9pt; color: #000;
|
||||
margin: 0; padding: 0; }
|
||||
.fp-coc h1 { text-align: center; font-size: 20pt; margin: 0 0 6px 0;
|
||||
font-weight: bold; page-break-before: avoid; }
|
||||
.fp-coc hr.heavy { border: 0; border-top: 2px solid #000; margin: 4px 0; }
|
||||
.fp-coc table { width: 100%; border-collapse: collapse; }
|
||||
.fp-coc table.bordered, .fp-coc table.bordered th, .fp-coc table.bordered td { border: 1px solid #000; }
|
||||
.fp-coc th { background-color: #ededed; font-weight: bold; padding: 6px 8px; font-size: 9pt; text-align: center; }
|
||||
.fp-coc td { padding: 6px 8px; vertical-align: top; font-size: 9pt; }
|
||||
.fp-coc table.bordered,
|
||||
.fp-coc table.bordered th,
|
||||
.fp-coc table.bordered td { border: 1px solid #000; }
|
||||
.fp-coc th { background-color: #ededed; font-weight: bold;
|
||||
padding: 4px 6px; font-size: 8.5pt; text-align: center; }
|
||||
.fp-coc td { padding: 4px 6px; vertical-align: top; font-size: 8.5pt; }
|
||||
.fp-coc .text-center { text-align: center; }
|
||||
.fp-coc .text-end { text-align: right; }
|
||||
.fp-coc .hdr-company { font-size: 9pt; line-height: 1.4; }
|
||||
.fp-coc .hdr-company strong { font-size: 11pt; }
|
||||
.fp-coc .cert-statement-box { border: 1px solid #000; padding: 12px; font-size: 9pt; }
|
||||
.fp-coc .cert-statement-box h4 { margin: 0 0 6px 0; font-size: 10pt; font-weight: bold; }
|
||||
.fp-coc .signature-img { max-height: 2.5cm; max-width: 8cm; }
|
||||
.fp-coc .accreditations { text-align: center; vertical-align: middle; }
|
||||
.fp-coc .accreditations img { max-height: 2.2cm; margin: 0 4px; vertical-align: middle; }
|
||||
.fp-coc .logo-box { text-align: right; vertical-align: middle; }
|
||||
.fp-coc .logo-box img { max-height: 2.5cm; max-width: 4cm; }
|
||||
.fp-coc .customer-logo { max-height: 2cm; max-width: 3.5cm; }
|
||||
.fp-coc .fp-footer-brand { font-size: 8pt; color: #666; text-align: center; margin-top: 14px; }
|
||||
.fp-coc .small-label { font-size: 8pt; opacity: 0.7; }
|
||||
.fp-coc .hdr-company { font-size: 8pt; line-height: 1.35; padding: 4px; }
|
||||
.fp-coc .hdr-company strong { font-size: 10pt; }
|
||||
.fp-coc .cert-statement-box { border: 1px solid #000; padding: 8px; font-size: 8pt; }
|
||||
.fp-coc .cert-statement-box h4 { margin: 0 0 4px 0; font-size: 9pt; font-weight: bold; }
|
||||
.fp-coc .signature-img { max-height: 1.8cm; max-width: 6.5cm; }
|
||||
.fp-coc .accreditations { text-align: center; vertical-align: middle; padding: 4px; }
|
||||
.fp-coc .accreditations img { max-height: 1.8cm; margin: 0 3px; vertical-align: middle; }
|
||||
.fp-coc .logo-box { text-align: right; vertical-align: middle; padding: 4px; }
|
||||
.fp-coc .logo-box img { max-height: 2cm; max-width: 3.5cm; }
|
||||
.fp-coc .customer-logo-box img { max-height: 1.6cm; max-width: 3cm; }
|
||||
.fp-coc .fp-footer-brand { font-size: 7.5pt; color: #666; text-align: center;
|
||||
margin-top: 8px; }
|
||||
.fp-coc .small-label { font-size: 7.5pt; opacity: 0.7; }
|
||||
</style>
|
||||
|
||||
<div class="fp-coc">
|
||||
@@ -318,19 +331,16 @@
|
||||
</template>
|
||||
|
||||
<!-- ================================================================== -->
|
||||
<!-- English CoC — uses html_container directly (no basic_layout -->
|
||||
<!-- wrapper) so the full page is ours to style, like the competitor -->
|
||||
<!-- English CoC — renders directly in html_container with NO wrapper -->
|
||||
<!-- templates, so Odoo's `.article` and `.page` styles (which force -->
|
||||
<!-- page-break-after + reserved header padding) don't apply. -->
|
||||
<!-- ================================================================== -->
|
||||
<template id="report_coc_en">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-set="company" t-value="(doc.portal_job_id.company_id if doc.portal_job_id else False) or (doc.sale_order_id.company_id if doc.sale_order_id else False) or env.company"/>
|
||||
<t t-set="LANG" t-value="'en'"/>
|
||||
<div class="article o_report_layout_boxed">
|
||||
<div class="page">
|
||||
<t t-call="fusion_plating_reports.coc_body"/>
|
||||
</div>
|
||||
</div>
|
||||
<t t-call="fusion_plating_reports.coc_body"/>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
@@ -343,11 +353,7 @@
|
||||
<t t-foreach="docs" t-as="doc">
|
||||
<t t-set="company" t-value="(doc.portal_job_id.company_id if doc.portal_job_id else False) or (doc.sale_order_id.company_id if doc.sale_order_id else False) or env.company"/>
|
||||
<t t-set="LANG" t-value="'fr'"/>
|
||||
<div class="article o_report_layout_boxed">
|
||||
<div class="page">
|
||||
<t t-call="fusion_plating_reports.coc_body"/>
|
||||
</div>
|
||||
</div>
|
||||
<t t-call="fusion_plating_reports.coc_body"/>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user