feat(reports): packing slip in Print menu of SO, Work Order, Receiving
Generalize the delivery packing slip template to be model-agnostic (branches on doc._name to resolve the sale order + ship-to for sale.order / fp.job / fp.receiving / fusion.plating.delivery) and add three report actions bound to sale.order, fp.job and fp.receiving so the packing slip appears in each one's Print menu (delivery already had it). Uses _scheduled / _notes so it never AttributeErrors on models without scheduled_date / notes. Declare the fusion_plating_receiving dep on reports (already transitive via logistics) for the fp.receiving binding. Verified on entech: real content for SO-30102, WO-30102, RCV-30103; all four Print-menu bindings live. Co-Authored-By: Claude Opus 4.8 (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.11.34.0',
|
||||
'version': '19.0.11.36.0',
|
||||
'category': 'Manufacturing/Plating',
|
||||
'summary': 'PDF reports for Fusion Plating: quote, SO, WO, packing, BoL, CoC, invoice, receipt, quality + compliance.',
|
||||
'depends': [
|
||||
@@ -25,6 +25,11 @@
|
||||
# creates a cycle. Our only fp.job touchpoint is wo_scan.py which
|
||||
# uses runtime env.get('fp.job') — safe without the manifest dep.
|
||||
'fusion_plating_logistics',
|
||||
# Needed for the packing-slip Print binding on fp.receiving
|
||||
# (binding_model_id ref). Already a transitive dep via logistics;
|
||||
# declared explicitly so the ref is robust. No cycle — receiving
|
||||
# does not depend on reports.
|
||||
'fusion_plating_receiving',
|
||||
],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
|
||||
@@ -549,18 +549,36 @@
|
||||
<t t-call="fusion_plating_reports.fp_portrait_styles"/>
|
||||
<t t-call="fusion_plating_reports.fp_packing_slip_styles"/>
|
||||
|
||||
<!-- Resolve SO + lines from the delivery's job_ref
|
||||
(mirrors the BoL report's resolution). -->
|
||||
<t t-set="_job" t-value="env['fp.job'].sudo().search([('name', '=', doc.job_ref)], limit=1) if doc.job_ref else env['fp.job']"/>
|
||||
<t t-set="_so" t-value="_job.sale_order_id if _job else False"/>
|
||||
<!-- Model-agnostic resolution. This ONE template backs
|
||||
four report actions (sale.order, fp.job,
|
||||
fp.receiving, fusion.plating.delivery) so the
|
||||
packing slip prints from any of those screens.
|
||||
Resolve the sale order + ship-to per doc type, then
|
||||
render a common layout from the SO lines. (Template
|
||||
id kept as "...delivery..." for back-compat with the
|
||||
action + Python that reference it.) -->
|
||||
<t t-set="m" t-value="doc._name"/>
|
||||
<t t-set="_so" t-value="False"/>
|
||||
<t t-if="m == 'sale.order'">
|
||||
<t t-set="_so" t-value="doc"/>
|
||||
</t>
|
||||
<t t-elif="m == 'fp.job' or m == 'fp.receiving'">
|
||||
<t t-set="_so" t-value="doc.sale_order_id"/>
|
||||
</t>
|
||||
<t t-elif="m == 'fusion.plating.delivery'">
|
||||
<t t-set="_dlv_job" t-value="env['fp.job'].sudo().search([('name', '=', doc.job_ref)], limit=1) if doc.job_ref else env['fp.job']"/>
|
||||
<t t-set="_so" t-value="_dlv_job.sale_order_id if _dlv_job else False"/>
|
||||
</t>
|
||||
<t t-set="_lines" t-value="_so.order_line.filtered(lambda l: l.product_id and not l.display_type and l.product_uom_qty > 0) if _so else False"/>
|
||||
|
||||
<t t-set="bill_partner" t-value="(_so.partner_invoice_id if _so and _so.partner_invoice_id else (doc.partner_id.commercial_partner_id or doc.partner_id))"/>
|
||||
<t t-set="ship_partner" t-value="doc.delivery_address_id or doc.partner_id"/>
|
||||
<t t-set="has_carrier" t-value="'x_fc_carrier_id' in doc._fields and doc.x_fc_carrier_id"/>
|
||||
<t t-set="ship_partner" t-value="(doc.delivery_address_id or doc.partner_id) if m == 'fusion.plating.delivery' else ((_so.partner_shipping_id or _so.partner_id) if _so else doc.partner_id)"/>
|
||||
<t t-set="bill_partner" t-value="(_so.partner_invoice_id if _so and _so.partner_invoice_id else (ship_partner.commercial_partner_id or ship_partner))"/>
|
||||
<t t-set="has_carrier" t-value="m == 'fusion.plating.delivery' and 'x_fc_carrier_id' in doc._fields and doc.x_fc_carrier_id"/>
|
||||
<t t-set="ship_via" t-value="(doc.x_fc_carrier_id.name if has_carrier else (_so.x_fc_ship_via if _so and 'x_fc_ship_via' in _so._fields and _so.x_fc_ship_via else 'CUSTOMER PICKUP'))"/>
|
||||
<t t-set="tracking_text" t-value="'Ready for pick up' if not has_carrier else '—'"/>
|
||||
<t t-set="po_number" t-value="(_so.client_order_ref if _so and _so.client_order_ref else '')"/>
|
||||
<t t-set="_scheduled" t-value="doc.scheduled_date if m == 'fusion.plating.delivery' else (doc.commitment_date if m == 'sale.order' else (_so.commitment_date if _so else False))"/>
|
||||
<t t-set="_notes" t-value="doc.notes if m == 'fusion.plating.delivery' else (doc.note if m == 'sale.order' else False)"/>
|
||||
|
||||
<t t-set="so_name_raw" t-value="_so.name if _so else (doc.name or '')"/>
|
||||
<t t-set="ps_number" t-value="so_name_raw.rsplit('-', 1)[-1] if '-' in so_name_raw else so_name_raw"/>
|
||||
@@ -622,8 +640,8 @@
|
||||
<tr>
|
||||
<td><span t-esc="ship_via"/></td>
|
||||
<td>
|
||||
<t t-if="doc.scheduled_date">
|
||||
<span t-field="doc.scheduled_date" t-options="{'widget': 'date'}"/>
|
||||
<t t-if="_scheduled">
|
||||
<span t-out="_scheduled" t-options="{'widget': 'date'}"/>
|
||||
</t>
|
||||
<t t-else="">—</t>
|
||||
</td>
|
||||
@@ -639,15 +657,15 @@
|
||||
</t>
|
||||
<t t-else="">
|
||||
<p style="margin-top: 10px; color: #555;">
|
||||
No order lines are linked to this delivery
|
||||
(job <span t-esc="doc.job_ref or doc.name"/>).
|
||||
No order lines found for this document
|
||||
(<span t-esc="doc.name or ''"/>).
|
||||
</p>
|
||||
</t>
|
||||
|
||||
<t t-if="doc.notes">
|
||||
<t t-if="_notes">
|
||||
<div style="margin-top: 10px;">
|
||||
<strong>Notes:</strong>
|
||||
<div t-field="doc.notes"/>
|
||||
<div t-out="_notes"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -671,4 +689,43 @@
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_portrait"/>
|
||||
</record>
|
||||
|
||||
<!-- Same packing slip, exposed in the Print menu of the Sale Order,
|
||||
Work Order (fp.job) and Receiving/Shipping (fp.receiving) screens.
|
||||
All reuse the model-agnostic template above. -->
|
||||
<record id="action_report_fp_packing_slip_so_portrait" model="ir.actions.report">
|
||||
<field name="name">Packing Slip</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_fp_packing_slip_delivery_portrait</field>
|
||||
<field name="report_file">fusion_plating_reports.report_fp_packing_slip_delivery_portrait</field>
|
||||
<field name="print_report_name">'Packing Slip - %s' % (object.name or '')</field>
|
||||
<field name="binding_model_id" ref="sale.model_sale_order"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_portrait"/>
|
||||
</record>
|
||||
|
||||
<record id="action_report_fp_packing_slip_job_portrait" model="ir.actions.report">
|
||||
<field name="name">Packing Slip</field>
|
||||
<field name="model">fp.job</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_fp_packing_slip_delivery_portrait</field>
|
||||
<field name="report_file">fusion_plating_reports.report_fp_packing_slip_delivery_portrait</field>
|
||||
<field name="print_report_name">'Packing Slip - %s' % (object.name or '')</field>
|
||||
<field name="binding_model_id" ref="fusion_plating.model_fp_job"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_portrait"/>
|
||||
</record>
|
||||
|
||||
<record id="action_report_fp_packing_slip_receiving_portrait" model="ir.actions.report">
|
||||
<field name="name">Packing Slip</field>
|
||||
<field name="model">fp.receiving</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">fusion_plating_reports.report_fp_packing_slip_delivery_portrait</field>
|
||||
<field name="report_file">fusion_plating_reports.report_fp_packing_slip_delivery_portrait</field>
|
||||
<field name="print_report_name">'Packing Slip - %s' % (object.name or '')</field>
|
||||
<field name="binding_model_id" ref="fusion_plating_receiving.model_fp_receiving"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_fp_a4_portrait"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user