changes
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
{
|
||||
'name': 'Fusion Plating — Reports',
|
||||
'version': '19.0.11.1.0',
|
||||
'version': '19.0.11.14.0',
|
||||
'category': 'Manufacturing/Plating',
|
||||
'summary': 'PDF reports for Fusion Plating: quote, SO, WO, packing, BoL, CoC, invoice, receipt, quality + compliance.',
|
||||
'depends': [
|
||||
|
||||
@@ -307,6 +307,9 @@
|
||||
<field name="header_line" eval="False"/>
|
||||
<field name="header_spacing">0</field>
|
||||
<field name="disable_shrinking" eval="True"/>
|
||||
<!-- dpi=300 is the calibrated value for this paperformat; the
|
||||
sticker inner's px-based geometry is tuned against it. Do
|
||||
NOT bump (see CLAUDE.md rule 14 — 600 broke layout). -->
|
||||
<field name="dpi">300</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -6,14 +6,17 @@
|
||||
|
||||
Shared CSS for all Fusion Plating reports (portrait + landscape).
|
||||
|
||||
The primary colour is driven by the active company's
|
||||
res.company.primary_color field (Settings → Company → Report Layout),
|
||||
falling back to #1d1f1e when the company has no brand colour set.
|
||||
Section-header band: #c1c1c1 (neutral grey) with #4e4e4e text
|
||||
Document titles (h2/h4): #4e4e4e
|
||||
Hardcoded — used to follow `res.company.primary_color` but the
|
||||
client wanted a uniform neutral palette across every FP report
|
||||
regardless of company branding. `fp_primary` is kept in scope for
|
||||
any per-report template that still wants the company colour.
|
||||
|
||||
To keep section-header markup concise in individual report files,
|
||||
a utility class `.fp-header-primary` is exposed — apply that class
|
||||
to any `<th>` or `<td>` that should render as a primary-coloured
|
||||
section banner (e.g. CARGO DESCRIPTION, PAYMENT DETAILS).
|
||||
to any `<th>` or `<td>` that should render as a section banner
|
||||
(e.g. CARGO DESCRIPTION, PAYMENT DETAILS).
|
||||
-->
|
||||
<odoo>
|
||||
<!-- ============================================================= -->
|
||||
@@ -24,10 +27,28 @@
|
||||
<t t-set="fp_primary" t-value="(_fp_company.primary_color if _fp_company else False) or '#1d1f1e'"/>
|
||||
<style>
|
||||
.fp-report { font-family: Arial, sans-serif; font-size: 10pt; color: #000; }
|
||||
.fp-report table { width: 100%; border-collapse: collapse; margin-bottom: 10px; }
|
||||
.fp-report table.bordered, .fp-report table.bordered th, .fp-report table.bordered td { border: 1px solid #000; }
|
||||
.fp-report th { background-color: <t t-out="fp_primary"/>; color: white; padding: 6px 8px; font-weight: bold; text-align: center; font-size: 9pt; }
|
||||
.fp-report td { padding: 6px 8px; vertical-align: top; font-size: 10pt; }
|
||||
.fp-report table { width: 100%; border-collapse: collapse; border-spacing: 0; margin-bottom: 10px; }
|
||||
/* Standard collapse + longhand borders + background-clip.
|
||||
Tried border-collapse:separate with single-side-per-cell
|
||||
(right+bottom on cell, top+left on table) to fix wkhtmltopdf's
|
||||
slightly-lighter-verticals quirk — but the `separate` model
|
||||
makes column widths drift between tables with different
|
||||
column counts, so tables stacked on the page no longer
|
||||
line up at the outer edges. Reverted. The collapse pattern
|
||||
gives correct alignment; the verticals may render a hair
|
||||
softer than horizontals on entech wkhtmltopdf but that's
|
||||
the less-bad trade-off vs misaligned tables. */
|
||||
.fp-report table.bordered { border: 0; border-collapse: collapse; border-spacing: 0; }
|
||||
.fp-report table.bordered th,
|
||||
.fp-report table.bordered td {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #000;
|
||||
background-clip: padding-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.fp-report th { background-color: #c1c1c1; color: #1d1f1e; padding: 6px 8px; font-weight: bold; text-align: center; font-size: 9pt; background-clip: padding-box; }
|
||||
.fp-report td { padding: 6px 8px; vertical-align: top; font-size: 10pt; background-clip: padding-box; }
|
||||
.fp-report .text-center { text-align: center; }
|
||||
.fp-report .text-end { text-align: right; }
|
||||
.fp-report .text-start { text-align: left; }
|
||||
@@ -35,20 +56,45 @@
|
||||
.fp-report .client-bg { background-color: #fff3e0; }
|
||||
.fp-report .section-row { background-color: #f0f0f0; font-weight: bold; }
|
||||
.fp-report .note-row { font-style: italic; color: #555; font-size: 9pt; }
|
||||
.fp-report h4 { color: <t t-out="fp_primary"/>; margin: 0 0 15px 0; font-size: 16pt; }
|
||||
.fp-report .totals-table { border: 1px solid #000; border-collapse: collapse; }
|
||||
.fp-report .totals-table td { border: 1px solid #000; padding: 6px 8px; }
|
||||
.fp-report h4 { color: #2e2e2e; margin: 0 0 15px 0; font-size: 20pt; }
|
||||
.fp-report .totals-table { border: 0; border-collapse: collapse; border-spacing: 0; }
|
||||
.fp-report .totals-table td {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #000;
|
||||
padding: 6px 8px;
|
||||
background-clip: padding-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.fp-report .info-header { background-color: #f5f5f5; color: #333; }
|
||||
.fp-report .adp-header { background-color: #e3f2fd; color: #333; }
|
||||
.fp-report .highlight-box { border: 2px solid <t t-out="fp_primary"/>; background-color: #eaf2f8; padding: 10px; margin: 10px 0; }
|
||||
.fp-report .fp-header-primary { background-color: <t t-out="fp_primary"/>; color: white; }
|
||||
.fp-report .highlight-box { border: 2px solid #c1c1c1; background-color: #f5f5f5; padding: 10px; margin: 10px 0; }
|
||||
.fp-report .fp-header-primary { background-color: #c1c1c1; color: #1d1f1e; }
|
||||
.fp-report .paid-stamp { color: #28a745; font-size: 36pt; font-weight: bold; border: 4px solid #28a745; padding: 10px 20px; transform: rotate(-8deg); display: inline-block; }
|
||||
.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-line { border-bottom: 1px solid #000; height: 60px; margin-bottom: 4px; }
|
||||
.fp-report .sig-table { width: 100%; border-collapse: collapse; margin-top: 16px; border: 1px solid #000; page-break-inside: avoid; break-inside: avoid; }
|
||||
.fp-report .sig-table .sig-cell { padding: 14px 12px 8px 12px; vertical-align: top; border: 1px solid #000; page-break-inside: avoid; break-inside: avoid; }
|
||||
.fp-report .sig-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
margin-top: 16px;
|
||||
border: 0;
|
||||
page-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
}
|
||||
.fp-report .sig-table .sig-cell {
|
||||
padding: 14px 12px 8px 12px;
|
||||
vertical-align: top;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #000;
|
||||
background-clip: padding-box;
|
||||
box-sizing: border-box;
|
||||
page-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
}
|
||||
.fp-report .small-muted { font-size: 8pt; color: #666; }
|
||||
.fp-report .fp-cell-mid { vertical-align: middle !important; }
|
||||
.fp-report .fp-keep-together { page-break-inside: avoid; break-inside: avoid; }
|
||||
@@ -65,9 +111,18 @@
|
||||
<t t-set="fp_primary" t-value="(_fp_company.primary_color if _fp_company else False) or '#1d1f1e'"/>
|
||||
<style>
|
||||
.fp-landscape { font-family: Arial, sans-serif; font-size: 10pt; color: #000; }
|
||||
.fp-landscape table { width: 100%; border-collapse: collapse; margin-bottom: 6px; }
|
||||
.fp-landscape table.bordered, .fp-landscape table.bordered th, .fp-landscape table.bordered td { border: 1px solid #000; }
|
||||
.fp-landscape th { background-color: <t t-out="fp_primary"/>; color: white; padding: 4px 8px; font-weight: bold; font-size: 9pt; }
|
||||
.fp-landscape table { width: 100%; border-collapse: collapse; border-spacing: 0; margin-bottom: 6px; }
|
||||
/* Standard collapse + longhand + background-clip — see comment in fp_portrait_styles. */
|
||||
.fp-landscape table.bordered { border: 0; border-collapse: collapse; border-spacing: 0; }
|
||||
.fp-landscape table.bordered th,
|
||||
.fp-landscape table.bordered td {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #000;
|
||||
background-clip: padding-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.fp-landscape th { background-color: #c1c1c1; color: #1d1f1e; padding: 4px 8px; font-weight: bold; font-size: 9pt; background-clip: padding-box; }
|
||||
.fp-landscape td { padding: 4px 8px; vertical-align: top; font-size: 9.5pt; }
|
||||
.fp-landscape .text-center { text-align: center; }
|
||||
.fp-landscape .text-end { text-align: right; }
|
||||
@@ -76,13 +131,13 @@
|
||||
.fp-landscape .client-bg { background-color: #fff3e0; }
|
||||
.fp-landscape .section-row { background-color: #f0f0f0; font-weight: bold; }
|
||||
.fp-landscape .note-row { font-style: italic; color: #555; }
|
||||
.fp-landscape h2 { color: <t t-out="fp_primary"/>; margin: 4px 0; font-size: 18pt; }
|
||||
.fp-landscape h2 { color: #2e2e2e; margin: 4px 0; font-size: 22pt; }
|
||||
.fp-landscape .info-table td { padding: 8px 12px; font-size: 11pt; }
|
||||
.fp-landscape .info-table th { background-color: #f5f5f5; color: #333; font-size: 10pt; padding: 6px 12px; }
|
||||
.fp-landscape .totals-table { border: 1px solid #000; }
|
||||
.fp-landscape .totals-table td { border: 1px solid #000; padding: 8px 12px; font-size: 11pt; }
|
||||
.fp-landscape .highlight-box { border: 2px solid <t t-out="fp_primary"/>; background-color: #eaf2f8; padding: 6px 10px; margin: 6px 0; font-size: 9pt; }
|
||||
.fp-landscape .fp-header-primary { background-color: <t t-out="fp_primary"/>; color: white; }
|
||||
.fp-landscape .highlight-box { border: 2px solid #c1c1c1; background-color: #f5f5f5; padding: 6px 10px; margin: 6px 0; font-size: 9pt; }
|
||||
.fp-landscape .fp-header-primary { background-color: #c1c1c1; color: #1d1f1e; }
|
||||
.fp-landscape .paid-stamp { color: #28a745; font-size: 42pt; font-weight: bold; border: 4px solid #28a745; padding: 10px 20px; transform: rotate(-8deg); display: inline-block; }
|
||||
.fp-landscape .status-ok { color: #2e7d32; font-weight: bold; }
|
||||
.fp-landscape .status-warning { color: #f57f17; font-weight: bold; }
|
||||
|
||||
@@ -26,15 +26,16 @@
|
||||
<!-- ================================================================== -->
|
||||
<template id="coc_body">
|
||||
<t t-set="is_fr" t-value="LANG == 'fr'"/>
|
||||
<t t-set="owner_sig" t-value="False"/>
|
||||
<t t-if="company.x_fc_owner_user_id">
|
||||
<t t-set="_emp" t-value="company.x_fc_owner_user_id.employee_ids[:1]"/>
|
||||
<t t-if="_emp and 'signature' in _emp._fields">
|
||||
<t t-set="owner_sig" t-value="_emp['signature']"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-set="signature_img" t-value="company.x_fc_coc_signature_override or owner_sig"/>
|
||||
<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 '')"/>
|
||||
<!-- Signer + signature resolution (2026-05-17): unified with the
|
||||
WO Detail certifier pattern. Signer = cert's certified_by
|
||||
user; falls back to the company owner. Signature image is
|
||||
that user's Plating Signature (x_fc_signature_image from
|
||||
Preferences → My Profile). The previous HR Employee
|
||||
signature lookup was retired in favour of this single
|
||||
source so all FP reports pull from the same field. -->
|
||||
<t t-set="signer_user" t-value="doc.certified_by_id or company.x_fc_owner_user_id or False"/>
|
||||
<t t-set="signature_img" t-value="(signer_user and 'x_fc_signature_image' in signer_user._fields and signer_user.x_fc_signature_image) or False"/>
|
||||
<t t-set="signer_name" t-value="(signer_user and signer_user.name) or ''"/>
|
||||
|
||||
<style>
|
||||
.fp-coc { font-family: Arial, sans-serif; font-size: 9pt; color: #000;
|
||||
|
||||
@@ -208,16 +208,13 @@
|
||||
|
||||
<hr class="heavy"/>
|
||||
|
||||
<!-- Sign-off block (re-uses owner_user_id signature pattern from coc_body) -->
|
||||
<t t-set="owner_sig" t-value="False"/>
|
||||
<t t-if="company.x_fc_owner_user_id">
|
||||
<t t-set="_emp" t-value="company.x_fc_owner_user_id.employee_ids[:1]"/>
|
||||
<t t-if="_emp and 'signature' in _emp._fields">
|
||||
<t t-set="owner_sig" t-value="_emp['signature']"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-set="signature_img" t-value="company.x_fc_coc_signature_override or owner_sig"/>
|
||||
<t t-set="signer_name" t-value="(doc.certified_by_id and doc.certified_by_id.name) or (company.x_fc_owner_user_id and company.x_fc_owner_user_id.name) or ''"/>
|
||||
<!-- Sign-off block — unified with WO Detail / CoC (2026-05-17).
|
||||
Signer = cert's certified_by user → falls back to company
|
||||
owner. Signature image = signer's Plating Signature
|
||||
(x_fc_signature_image from Preferences → My Profile). -->
|
||||
<t t-set="signer_user" t-value="doc.certified_by_id or company.x_fc_owner_user_id or False"/>
|
||||
<t t-set="signature_img" t-value="(signer_user and 'x_fc_signature_image' in signer_user._fields and signer_user.x_fc_signature_image) or False"/>
|
||||
<t t-set="signer_name" t-value="(signer_user and signer_user.name) or ''"/>
|
||||
|
||||
<!-- Sub 12c+ — cert statement: per-customer override → company default → hardcoded fallback -->
|
||||
<t t-set="_cust_stmt" t-value="('x_fc_cert_statement' in doc.partner_id._fields and doc.partner_id.x_fc_cert_statement) or False"/>
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
<div class="page">
|
||||
|
||||
<h4>
|
||||
<span t-if="doc.move_type == 'out_invoice' and doc.state == 'posted'">Invoice </span>
|
||||
<span t-elif="doc.move_type == 'out_invoice' and doc.state == 'draft'">Draft Invoice </span>
|
||||
<span t-elif="doc.move_type == 'out_refund'">Credit Note </span>
|
||||
<span t-elif="doc.move_type == 'in_invoice'">Vendor Bill </span>
|
||||
<span t-if="doc.move_type == 'out_invoice' and doc.state == 'posted'">Invoice # </span>
|
||||
<span t-elif="doc.move_type == 'out_invoice' and doc.state == 'draft'">Draft Invoice # </span>
|
||||
<span t-elif="doc.move_type == 'out_refund'">Credit Note # </span>
|
||||
<span t-elif="doc.move_type == 'in_invoice'">Vendor Bill # </span>
|
||||
<span t-field="doc.name"/>
|
||||
</h4>
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
<span t-field="doc.amount_tax" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="background-color: #eaf2f8;">
|
||||
<tr style="background-color: #c1c1c1;">
|
||||
<td><strong>Grand Total</strong></td>
|
||||
<td class="text-end"><strong>
|
||||
<span t-field="doc.amount_total" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/>
|
||||
@@ -205,10 +205,10 @@
|
||||
<div class="page">
|
||||
|
||||
<h2 style="text-align: left;">
|
||||
<span t-if="doc.move_type == 'out_invoice' and doc.state == 'posted'">Invoice </span>
|
||||
<span t-elif="doc.move_type == 'out_invoice' and doc.state == 'draft'">Draft Invoice </span>
|
||||
<span t-elif="doc.move_type == 'out_refund'">Credit Note </span>
|
||||
<span t-elif="doc.move_type == 'in_invoice'">Vendor Bill </span>
|
||||
<span t-if="doc.move_type == 'out_invoice' and doc.state == 'posted'">Invoice # </span>
|
||||
<span t-elif="doc.move_type == 'out_invoice' and doc.state == 'draft'">Draft Invoice # </span>
|
||||
<span t-elif="doc.move_type == 'out_refund'">Credit Note # </span>
|
||||
<span t-elif="doc.move_type == 'in_invoice'">Vendor Bill # </span>
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
@@ -341,7 +341,7 @@
|
||||
<span t-field="doc.amount_tax" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="background-color: #eaf2f8;">
|
||||
<tr style="background-color: #c1c1c1;">
|
||||
<td><strong>Grand Total</strong></td>
|
||||
<td class="text-end"><strong>
|
||||
<span t-field="doc.amount_total" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<div class="page">
|
||||
|
||||
<h4>
|
||||
Packing Slip —
|
||||
Packing Slip #
|
||||
<span t-field="doc.name"/>
|
||||
</h4>
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
<div class="page">
|
||||
|
||||
<h2 style="text-align: left;">
|
||||
Packing Slip —
|
||||
Packing Slip #
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
|
||||
<!-- Title -->
|
||||
<h4>
|
||||
<span t-if="doc.state in ['draft','sent']">Quotation </span>
|
||||
<span t-else="">Sales Order </span>
|
||||
<span t-if="doc.state in ['draft','sent']">Quotation # </span>
|
||||
<span t-else="">Sales Order # </span>
|
||||
<span t-field="doc.name"/>
|
||||
</h4>
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
<span t-field="doc.amount_tax" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="background-color: #eaf2f8;">
|
||||
<tr style="background-color: #c1c1c1;">
|
||||
<td><strong>Grand Total</strong></td>
|
||||
<td class="text-end"><strong>
|
||||
<span t-field="doc.amount_total" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/>
|
||||
@@ -282,8 +282,8 @@
|
||||
|
||||
<!-- Title -->
|
||||
<h2 style="text-align: left;">
|
||||
<span t-if="doc.state in ['draft','sent']">Quotation </span>
|
||||
<span t-else="">Sales Order </span>
|
||||
<span t-if="doc.state in ['draft','sent']">Quotation # </span>
|
||||
<span t-else="">Sales Order # </span>
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
@@ -492,7 +492,7 @@
|
||||
<span t-field="doc.amount_tax" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="background-color: #eaf2f8;">
|
||||
<tr style="background-color: #c1c1c1;">
|
||||
<td><strong>Grand Total</strong></td>
|
||||
<td class="text-end"><strong>
|
||||
<span t-field="doc.amount_total" t-options='{"widget": "monetary", "display_currency": doc.currency_id}'/>
|
||||
|
||||
@@ -95,17 +95,27 @@
|
||||
<!-- Notes content — outer can pre-set this (e.g. the Internal
|
||||
variant passes line.x_fc_internal_description). Otherwise
|
||||
falls back to line.name (customer-facing description per
|
||||
Sub 2 Q6), then to part.name. -->
|
||||
<t t-set="_notes_content" t-value="_notes_content
|
||||
or (_line and _line.name)
|
||||
or (_part and _part.name)
|
||||
or '-'"/>
|
||||
Sub 2 Q6), then to part.name. Strip en/em-dash, smart
|
||||
quotes, and ellipsis defensively for the wkhtmltopdf font
|
||||
path on entech — same treatment as thickness above, which
|
||||
otherwise turns "—" into the "â€"" mojibake. -->
|
||||
<t t-set="_notes_raw" t-value="_notes_content
|
||||
or (_line and _line.name)
|
||||
or (_part and _part.name)
|
||||
or '-'"/>
|
||||
<t t-set="_notes_content" t-value="_notes_raw
|
||||
.replace(u'—', '-').replace(u'–', '-')
|
||||
.replace(u'‘', "'").replace(u'’', "'")
|
||||
.replace(u'“', '"').replace(u'”', '"')
|
||||
.replace(u'…', '...')"/>
|
||||
<!-- Inline the QR as base64 data URI so wkhtmltopdf doesn't need
|
||||
to fetch /report/barcode/ over the network during rendering.
|
||||
600x600 source at 300dpi print = ~515ppi effective — high-def
|
||||
scan reliability for the 4x6" label. -->
|
||||
1000x1000 source — Odoo core caps barcode area at 1.2M pixels
|
||||
(`width * height > 1200000` raises "Barcode too large"), so we
|
||||
stay under that ceiling. 1000x1000 at the 31mm wrapper gives
|
||||
~821ppi effective — far above the 203dpi thermal printer. -->
|
||||
<t t-set="_qr_src" t-value="env['ir.actions.report'].barcode_data_uri(
|
||||
'QR', _scan_url, width=600, height=600)"/>
|
||||
'QR', _scan_url, width=1000, height=1000)"/>
|
||||
|
||||
<style>
|
||||
@page { margin: 0; size: 152mm 102mm; }
|
||||
@@ -173,7 +183,8 @@
|
||||
adds around the QR pattern. We render the image larger than
|
||||
the wrapper and offset so the wrapper clips that border out.
|
||||
Wrapper 365px = ~30.9mm at 300dpi (30% larger than the
|
||||
previous 280px). 600x600 source = high-def at print scale. ---- */
|
||||
previous 280px). 1000x1000 source = print-sharp at the
|
||||
paperformat DPI (under Odoo's 1.2M-pixel barcode cap). ---- */
|
||||
.fp-sticker-qr-wrap {
|
||||
width: 365px;
|
||||
height: 365px;
|
||||
@@ -237,7 +248,13 @@
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.fp-sticker-strong { font-weight: 700; }
|
||||
/* Values used to be bold via .fp-sticker-strong (PO/Part#/Qty).
|
||||
Per ops, only the field title and the WO# header should be
|
||||
bold; values stay regular weight. Font sizes unchanged from
|
||||
the original layout — bumping them broke wkhtmltopdf's row
|
||||
packing on entech, so we accept the same visual weight as
|
||||
before. -->
|
||||
.fp-sticker-strong { font-weight: 400; }
|
||||
.fp-sticker-muted { color: #555; font-size: 30pt; }
|
||||
/* Notes column on the right side of the body. */
|
||||
.fp-notes-label {
|
||||
@@ -327,7 +344,10 @@
|
||||
<tr>
|
||||
<td class="fp-sticker-label">Part #:</td>
|
||||
<td class="fp-sticker-value">
|
||||
<t t-if="_part">
|
||||
<t t-if="_multi_line">
|
||||
<span class="fp-sticker-strong">Multiple Line Items</span>
|
||||
</t>
|
||||
<t t-elif="_part">
|
||||
<span class="fp-sticker-strong"
|
||||
t-esc="_part.part_number"/>
|
||||
<t t-if="_part.revision">
|
||||
@@ -408,6 +428,11 @@
|
||||
<t t-set="_scan_path" t-value="False"/>
|
||||
<t t-set="_notes_content" t-value="False"/>
|
||||
<t t-set="_qty_total" t-value="False"/>
|
||||
<!-- _multi_line = True signals "this PO has multiple part lines";
|
||||
Part # prints "Multiple Line Items", line-specific fields
|
||||
(SN/Thickness/Notes) auto-resolve to "-" via _line=False, and
|
||||
Qty shows the SO-line sum (outer sets _qty + _qty_total=1). -->
|
||||
<t t-set="_multi_line" t-value="False"/>
|
||||
</template>
|
||||
|
||||
<!-- ========== Outer template — mrp.workorder entry ========== -->
|
||||
@@ -454,24 +479,50 @@
|
||||
<template id="report_fp_so_sticker">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="so">
|
||||
<t t-foreach="so.order_line.filtered(lambda l: l.x_fc_part_catalog_id)"
|
||||
t-as="line">
|
||||
<t t-set="_part_lines"
|
||||
t-value="so.order_line.filtered(lambda l: l.x_fc_part_catalog_id)"/>
|
||||
<t t-if="len(_part_lines) >= 2">
|
||||
<!-- Multi-line PO: one consolidated sticker.
|
||||
Part # prints "Multiple Line Items", Qty is the
|
||||
sum of all part-line qtys. Per-box loop disabled
|
||||
(_qty_total=1) — the consolidated label is the
|
||||
master-skid label, not per-physical-box. -->
|
||||
<t t-call="fusion_plating_reports.report_fp_wo_sticker_defaults"/>
|
||||
<t t-set="_order_id" t-value="so.name"/>
|
||||
<t t-set="_scan_id" t-value="line.id"/>
|
||||
<t t-set="_scan_id" t-value="_part_lines[:1].id"/>
|
||||
<t t-set="_scan_path" t-value="'/fp/so-line/'"/>
|
||||
<t t-set="_mo" t-value="False"/>
|
||||
<t t-set="_so" t-value="so"/>
|
||||
<t t-set="_line" t-value="line"/>
|
||||
<t t-set="_part" t-value="line.x_fc_part_catalog_id"/>
|
||||
<t t-set="_spec" t-value="line.x_fc_customer_spec_id"/>
|
||||
<t t-set="_due" t-value="line.x_fc_part_deadline or so.commitment_date or False"/>
|
||||
<t t-set="_qty" t-value="line.product_uom_qty"/>
|
||||
<t t-set="_qty_total" t-value="line.product_uom_qty"/>
|
||||
<t t-set="_line" t-value="False"/>
|
||||
<t t-set="_part" t-value="False"/>
|
||||
<t t-set="_spec" t-value="False"/>
|
||||
<t t-set="_due" t-value="so.commitment_date or False"/>
|
||||
<t t-set="_qty" t-value="sum(_part_lines.mapped('product_uom_qty'))"/>
|
||||
<t t-set="_qty_total" t-value="1"/>
|
||||
<t t-set="_partner_name" t-value="so.partner_id.name"/>
|
||||
<t t-set="_mo_ref" t-value="''"/>
|
||||
<t t-set="_multi_line" t-value="True"/>
|
||||
<t t-call="fusion_plating_reports.report_fp_wo_sticker_inner"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-foreach="_part_lines" t-as="line">
|
||||
<t t-call="fusion_plating_reports.report_fp_wo_sticker_defaults"/>
|
||||
<t t-set="_order_id" t-value="so.name"/>
|
||||
<t t-set="_scan_id" t-value="line.id"/>
|
||||
<t t-set="_scan_path" t-value="'/fp/so-line/'"/>
|
||||
<t t-set="_mo" t-value="False"/>
|
||||
<t t-set="_so" t-value="so"/>
|
||||
<t t-set="_line" t-value="line"/>
|
||||
<t t-set="_part" t-value="line.x_fc_part_catalog_id"/>
|
||||
<t t-set="_spec" t-value="line.x_fc_customer_spec_id"/>
|
||||
<t t-set="_due" t-value="line.x_fc_part_deadline or so.commitment_date or False"/>
|
||||
<t t-set="_qty" t-value="line.product_uom_qty"/>
|
||||
<t t-set="_qty_total" t-value="line.product_uom_qty"/>
|
||||
<t t-set="_partner_name" t-value="so.partner_id.name"/>
|
||||
<t t-set="_mo_ref" t-value="''"/>
|
||||
<t t-call="fusion_plating_reports.report_fp_wo_sticker_inner"/>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
@@ -484,27 +535,52 @@
|
||||
<template id="report_fp_so_sticker_internal">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="so">
|
||||
<t t-foreach="so.order_line.filtered(lambda l: l.x_fc_part_catalog_id)"
|
||||
t-as="line">
|
||||
<t t-set="_part_lines"
|
||||
t-value="so.order_line.filtered(lambda l: l.x_fc_part_catalog_id)"/>
|
||||
<t t-if="len(_part_lines) >= 2">
|
||||
<!-- Multi-line PO: one consolidated sticker.
|
||||
Notes column blanked ("-") because each line has
|
||||
its own internal description. -->
|
||||
<t t-call="fusion_plating_reports.report_fp_wo_sticker_defaults"/>
|
||||
<t t-set="_order_id" t-value="so.name"/>
|
||||
<t t-set="_scan_id" t-value="line.id"/>
|
||||
<t t-set="_scan_id" t-value="_part_lines[:1].id"/>
|
||||
<t t-set="_scan_path" t-value="'/fp/so-line/'"/>
|
||||
<t t-set="_mo" t-value="False"/>
|
||||
<t t-set="_so" t-value="so"/>
|
||||
<t t-set="_line" t-value="line"/>
|
||||
<t t-set="_part" t-value="line.x_fc_part_catalog_id"/>
|
||||
<t t-set="_spec" t-value="line.x_fc_customer_spec_id"/>
|
||||
<t t-set="_due" t-value="line.x_fc_part_deadline or so.commitment_date or False"/>
|
||||
<t t-set="_qty" t-value="line.product_uom_qty"/>
|
||||
<t t-set="_qty_total" t-value="line.product_uom_qty"/>
|
||||
<t t-set="_line" t-value="False"/>
|
||||
<t t-set="_part" t-value="False"/>
|
||||
<t t-set="_spec" t-value="False"/>
|
||||
<t t-set="_due" t-value="so.commitment_date or False"/>
|
||||
<t t-set="_qty" t-value="sum(_part_lines.mapped('product_uom_qty'))"/>
|
||||
<t t-set="_qty_total" t-value="1"/>
|
||||
<t t-set="_partner_name" t-value="so.partner_id.name"/>
|
||||
<t t-set="_mo_ref" t-value="''"/>
|
||||
<!-- Internal override: read x_fc_internal_description -->
|
||||
<t t-set="_notes_content" t-value="('x_fc_internal_description' in line._fields
|
||||
and line.x_fc_internal_description) or '-'"/>
|
||||
<t t-set="_multi_line" t-value="True"/>
|
||||
<t t-set="_notes_content" t-value="'-'"/>
|
||||
<t t-call="fusion_plating_reports.report_fp_wo_sticker_inner"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-foreach="_part_lines" t-as="line">
|
||||
<t t-call="fusion_plating_reports.report_fp_wo_sticker_defaults"/>
|
||||
<t t-set="_order_id" t-value="so.name"/>
|
||||
<t t-set="_scan_id" t-value="line.id"/>
|
||||
<t t-set="_scan_path" t-value="'/fp/so-line/'"/>
|
||||
<t t-set="_mo" t-value="False"/>
|
||||
<t t-set="_so" t-value="so"/>
|
||||
<t t-set="_line" t-value="line"/>
|
||||
<t t-set="_part" t-value="line.x_fc_part_catalog_id"/>
|
||||
<t t-set="_spec" t-value="line.x_fc_customer_spec_id"/>
|
||||
<t t-set="_due" t-value="line.x_fc_part_deadline or so.commitment_date or False"/>
|
||||
<t t-set="_qty" t-value="line.product_uom_qty"/>
|
||||
<t t-set="_qty_total" t-value="line.product_uom_qty"/>
|
||||
<t t-set="_partner_name" t-value="so.partner_id.name"/>
|
||||
<t t-set="_mo_ref" t-value="''"/>
|
||||
<!-- Internal override: read x_fc_internal_description -->
|
||||
<t t-set="_notes_content" t-value="('x_fc_internal_description' in line._fields
|
||||
and line.x_fc_internal_description) or '-'"/>
|
||||
<t t-call="fusion_plating_reports.report_fp_wo_sticker_inner"/>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<div class="page">
|
||||
|
||||
<h4>
|
||||
Work Order Traveller —
|
||||
Work Order Traveller #
|
||||
<span t-field="doc.name"/>
|
||||
</h4>
|
||||
|
||||
@@ -265,7 +265,7 @@
|
||||
<div class="page">
|
||||
|
||||
<h2 style="text-align: left;">
|
||||
Work Order Traveller —
|
||||
Work Order Traveller #
|
||||
<span t-field="doc.name"/>
|
||||
</h2>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user