feat(reports): split customer-facing line header into Part Number + Description columns
User request: on customer-facing PDFs the single "Part" column was
stacking part number + revision + description together. Split into
two distinct columns so customers see Part Number in its own field
and the Description column carries only the prose.
Macro split:
* customer_line_part_number — strong part number + "(Rev X)"
* customer_line_description — line.name + any populated line
metadata (serial, job#, thickness)
* customer_line_header (legacy) kept as a thin wrapper that
t-calls both macros stacked so older reports still render.
Reports updated — each gains a new first "PART NUMBER" column and
the old "PART" column renamed to "DESCRIPTION":
* report_fp_sale (both portrait variants)
* report_fp_invoice (both portrait variants)
* report_fp_packing_slip (both variants — delivery + MO-origin)
Column widths rebalanced per report. Section / note colspans bumped
to account for the extra column.
report_fp_bol left as-is — its "Description of Goods" td is a
freight-convention combined field, intentionally keeps the stacked
layout via the legacy customer_line_header macro.
fusion_plating_reports → 19.0.6.0.0
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
{
|
||||
'name': 'Fusion Plating — Reports',
|
||||
'version': '19.0.5.1.0',
|
||||
'version': '19.0.6.0.0',
|
||||
'category': 'Manufacturing/Plating',
|
||||
'summary': 'PDF reports for Fusion Plating: quote, SO, WO, packing, BoL, CoC, invoice, receipt, quality + compliance.',
|
||||
'depends': [
|
||||
|
||||
@@ -20,13 +20,34 @@
|
||||
<t t-call="fusion_plating_reports.customer_line_header"/>
|
||||
-->
|
||||
<odoo>
|
||||
|
||||
<!-- ==========================================================
|
||||
customer_line_header (legacy — kept for backward compat)
|
||||
|
||||
Prints part number + revision + description in ONE td.
|
||||
Reports written before the 2026-04-23 column split still
|
||||
call this macro. New reports should use the split macros
|
||||
below (customer_line_part_number + customer_line_description)
|
||||
which render into two separate <td> columns.
|
||||
========================================================== -->
|
||||
<template id="customer_line_header">
|
||||
<t t-call="fusion_plating_reports.customer_line_part_number"/>
|
||||
<br/>
|
||||
<t t-call="fusion_plating_reports.customer_line_description"/>
|
||||
</template>
|
||||
|
||||
<!-- ==========================================================
|
||||
customer_line_part_number — just the part number + rev
|
||||
Renders as a single-line "PN-1234 Rev A" block, intended
|
||||
for the "Part Number" td in customer-facing tables.
|
||||
========================================================== -->
|
||||
<template id="customer_line_part_number">
|
||||
<t t-if="line.x_fc_part_catalog_id">
|
||||
<strong>
|
||||
<span t-esc="line.x_fc_part_catalog_id.part_number"/>
|
||||
<!-- Sub 5 — prefer the revision snapshot captured on the line
|
||||
at save time; fall back to the catalog's current revision
|
||||
if no snapshot was frozen (old lines from before Sub 5). -->
|
||||
<!-- Prefer the Sub-5 revision snapshot captured on the
|
||||
line at save time; fall back to the catalog's
|
||||
current revision for older lines that predate it. -->
|
||||
<t t-set="_rev" t-value="(
|
||||
line.x_fc_revision_snapshot
|
||||
if 'x_fc_revision_snapshot' in line._fields
|
||||
@@ -36,11 +57,21 @@
|
||||
<span> (Rev <span t-esc="_rev"/>)</span>
|
||||
</t>
|
||||
</strong>
|
||||
<br/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<!-- Fee / freight / non-part line: no part number to show -->
|
||||
<span class="text-muted">—</span>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- ==========================================================
|
||||
customer_line_description — customer-facing description
|
||||
plus any populated line metadata (serial, job#, thickness).
|
||||
Intended for the "Description" td in customer-facing tables.
|
||||
========================================================== -->
|
||||
<template id="customer_line_description">
|
||||
<t t-if="line.x_fc_part_catalog_id">
|
||||
<span t-esc="line.name"/>
|
||||
<!-- Sub 5 — print serial / job# / thickness under the line
|
||||
description when populated. Each on its own row so blank
|
||||
fields disappear cleanly. -->
|
||||
<t t-if="'x_fc_serial_id' in line._fields and line.x_fc_serial_id">
|
||||
<br/>
|
||||
<small>Serial: <span t-esc="line.x_fc_serial_id.name"/></small>
|
||||
@@ -63,4 +94,5 @@
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -80,7 +80,8 @@
|
||||
<table class="bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-start" style="width: 52%;">PART</th>
|
||||
<th class="text-start" style="width: 20%;">PART NUMBER</th>
|
||||
<th class="text-start" style="width: 32%;">DESCRIPTION</th>
|
||||
<th style="width: 8%;">QTY</th>
|
||||
<th style="width: 8%;">UOM</th>
|
||||
<th style="width: 12%;">UNIT PRICE</th>
|
||||
@@ -91,15 +92,18 @@
|
||||
<tbody>
|
||||
<t t-foreach="doc.invoice_line_ids" t-as="line">
|
||||
<t t-if="line.display_type == 'line_section'">
|
||||
<tr class="section-row"><td colspan="6"><strong t-field="line.name"/></td></tr>
|
||||
<tr class="section-row"><td colspan="7"><strong t-field="line.name"/></td></tr>
|
||||
</t>
|
||||
<t t-elif="line.display_type == 'line_note'">
|
||||
<tr class="note-row"><td colspan="6"><span t-field="line.name"/></td></tr>
|
||||
<tr class="note-row"><td colspan="7"><span t-field="line.name"/></td></tr>
|
||||
</t>
|
||||
<t t-elif="not line.display_type or line.display_type == 'product'">
|
||||
<tr>
|
||||
<td>
|
||||
<t t-call="fusion_plating_reports.customer_line_header"/>
|
||||
<t t-call="fusion_plating_reports.customer_line_part_number"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-call="fusion_plating_reports.customer_line_description"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="int(line.quantity) if line.quantity == int(line.quantity) else line.quantity"/>
|
||||
@@ -262,11 +266,12 @@
|
||||
|
||||
<!-- Lines — hide discount column unless at least one line has a discount -->
|
||||
<t t-set="has_discount" t-value="any(l.discount for l in doc.invoice_line_ids)"/>
|
||||
<t t-set="col_count" t-value="7 if has_discount else 6"/>
|
||||
<t t-set="col_count" t-value="8 if has_discount else 7"/>
|
||||
<table class="bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-start" style="width: 42%;">PART</th>
|
||||
<th class="text-start" style="width: 18%;">PART NUMBER</th>
|
||||
<th class="text-start" style="width: 24%;">DESCRIPTION</th>
|
||||
<th style="width: 8%;">QTY</th>
|
||||
<th style="width: 8%;">UOM</th>
|
||||
<th style="width: 12%;">UNIT PRICE</th>
|
||||
@@ -286,7 +291,10 @@
|
||||
<t t-elif="not line.display_type or line.display_type == 'product'">
|
||||
<tr>
|
||||
<td>
|
||||
<t t-call="fusion_plating_reports.customer_line_header"/>
|
||||
<t t-call="fusion_plating_reports.customer_line_part_number"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-call="fusion_plating_reports.customer_line_description"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="int(line.quantity) if line.quantity == int(line.quantity) else line.quantity"/>
|
||||
|
||||
@@ -77,7 +77,8 @@
|
||||
<table class="bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-start" style="width: 56%;">PART</th>
|
||||
<th class="text-start" style="width: 22%;">PART NUMBER</th>
|
||||
<th class="text-start" style="width: 34%;">DESCRIPTION</th>
|
||||
<th style="width: 12%;">QTY</th>
|
||||
<th style="width: 10%;">UOM</th>
|
||||
<th style="width: 22%;">LOT / SERIAL</th>
|
||||
@@ -86,9 +87,12 @@
|
||||
<tbody>
|
||||
<t t-foreach="doc.move_ids_without_package" t-as="move">
|
||||
<tr>
|
||||
<t t-set="line" t-value="move.sale_line_id or move"/>
|
||||
<td>
|
||||
<t t-set="line" t-value="move.sale_line_id or move"/>
|
||||
<t t-call="fusion_plating_reports.customer_line_header"/>
|
||||
<t t-call="fusion_plating_reports.customer_line_part_number"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-call="fusion_plating_reports.customer_line_description"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="int(move.quantity) if move.quantity == int(move.quantity) else move.quantity"/>
|
||||
@@ -213,7 +217,8 @@
|
||||
<table class="bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-start" style="width: 44%;">PART</th>
|
||||
<th class="text-start" style="width: 18%;">PART NUMBER</th>
|
||||
<th class="text-start" style="width: 26%;">DESCRIPTION</th>
|
||||
<th style="width: 10%;">ORDERED</th>
|
||||
<th style="width: 10%;">DONE</th>
|
||||
<th style="width: 8%;">UOM</th>
|
||||
@@ -224,9 +229,12 @@
|
||||
<tbody>
|
||||
<t t-foreach="doc.move_ids_without_package" t-as="move">
|
||||
<tr>
|
||||
<t t-set="line" t-value="move.sale_line_id or move"/>
|
||||
<td>
|
||||
<t t-set="line" t-value="move.sale_line_id or move"/>
|
||||
<t t-call="fusion_plating_reports.customer_line_header"/>
|
||||
<t t-call="fusion_plating_reports.customer_line_part_number"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-call="fusion_plating_reports.customer_line_description"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="int(move.product_uom_qty) if move.product_uom_qty == int(move.product_uom_qty) else move.product_uom_qty"/>
|
||||
|
||||
@@ -137,7 +137,8 @@
|
||||
<table class="bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-start" style="width: 50%;">PART</th>
|
||||
<th class="text-start" style="width: 20%;">PART NUMBER</th>
|
||||
<th class="text-start" style="width: 30%;">DESCRIPTION</th>
|
||||
<th style="width: 8%;">QTY</th>
|
||||
<th style="width: 8%;">UOM</th>
|
||||
<th style="width: 12%;">UNIT PRICE</th>
|
||||
@@ -148,15 +149,18 @@
|
||||
<tbody>
|
||||
<t t-foreach="doc.order_line" t-as="line">
|
||||
<t t-if="line.display_type == 'line_section'">
|
||||
<tr class="section-row"><td colspan="6"><strong t-field="line.name"/></td></tr>
|
||||
<tr class="section-row"><td colspan="7"><strong t-field="line.name"/></td></tr>
|
||||
</t>
|
||||
<t t-elif="line.display_type == 'line_note'">
|
||||
<tr class="note-row"><td colspan="6"><span t-field="line.name"/></td></tr>
|
||||
<tr class="note-row"><td colspan="7"><span t-field="line.name"/></td></tr>
|
||||
</t>
|
||||
<t t-elif="not line.display_type or line.display_type == 'product'">
|
||||
<tr>
|
||||
<td>
|
||||
<t t-call="fusion_plating_reports.customer_line_header"/>
|
||||
<t t-call="fusion_plating_reports.customer_line_part_number"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-call="fusion_plating_reports.customer_line_description"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="int(line.product_uom_qty) if line.product_uom_qty == int(line.product_uom_qty) else line.product_uom_qty"/>
|
||||
@@ -403,11 +407,12 @@
|
||||
|
||||
<!-- Order lines — hide discount column unless at least one line has a discount -->
|
||||
<t t-set="has_discount" t-value="any(l.discount for l in doc.order_line)"/>
|
||||
<t t-set="col_count" t-value="7 if has_discount else 6"/>
|
||||
<t t-set="col_count" t-value="8 if has_discount else 7"/>
|
||||
<table class="bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-start" style="width: 42%;">PART</th>
|
||||
<th class="text-start" style="width: 18%;">PART NUMBER</th>
|
||||
<th class="text-start" style="width: 24%;">DESCRIPTION</th>
|
||||
<th style="width: 8%;">QTY</th>
|
||||
<th style="width: 8%;">UOM</th>
|
||||
<th style="width: 12%;">UNIT PRICE</th>
|
||||
@@ -427,7 +432,10 @@
|
||||
<t t-elif="not line.display_type or line.display_type == 'product'">
|
||||
<tr>
|
||||
<td>
|
||||
<t t-call="fusion_plating_reports.customer_line_header"/>
|
||||
<t t-call="fusion_plating_reports.customer_line_part_number"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-call="fusion_plating_reports.customer_line_description"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-esc="int(line.product_uom_qty) if line.product_uom_qty == int(line.product_uom_qty) else line.product_uom_qty"/>
|
||||
|
||||
Reference in New Issue
Block a user