diff --git a/fusion_plating/fusion_plating/__manifest__.py b/fusion_plating/fusion_plating/__manifest__.py
index c5e47887..528320b8 100644
--- a/fusion_plating/fusion_plating/__manifest__.py
+++ b/fusion_plating/fusion_plating/__manifest__.py
@@ -5,7 +5,7 @@
{
'name': 'Fusion Plating',
- 'version': '19.0.18.15.5',
+ 'version': '19.0.18.15.6',
'category': 'Manufacturing/Plating',
'summary': 'Core plating / metal finishing ERP: facilities, processes, tanks, baths, jobs, operators.',
'description': """
diff --git a/fusion_plating/fusion_plating/models/fp_job.py b/fusion_plating/fusion_plating/models/fp_job.py
index c918a611..9068bcc4 100644
--- a/fusion_plating/fusion_plating/models/fp_job.py
+++ b/fusion_plating/fusion_plating/models/fp_job.py
@@ -262,6 +262,33 @@ class FpJob(models.Model):
# Header counters mirror the paper traveller's "Qty Rec." / "VIS INSP."
# / "Rework" columns (screens 16-18). Sub 12c's traveller report pulls
# these into the printed header.
+ # ---- Customer references mirrored from sale.order ----------------
+ # Populated on SO confirm by _fp_auto_create_job. Without these
+ # mirrors, certs / deliveries / chatter would have to round-trip
+ # through job.sale_order_id.x_fc_* to find the customer's references,
+ # and offline-printed paperwork on the shop floor wouldn't show them.
+ x_fc_customer_job_number = fields.Char(
+ string='Customer Job #',
+ tracking=True,
+ help='Customer\'s own job/lot reference. Copied from the '
+ 'sale order when the job is auto-created on SO confirm; '
+ 'printed on the cert, traveller, and BoL.',
+ )
+ x_fc_po_number = fields.Char(
+ string='Customer PO #',
+ tracking=True,
+ help='Customer purchase order number. Mirrored from sale.order '
+ 'so the shop floor and printed paperwork have it without '
+ 'a round-trip to the SO.',
+ )
+ x_fc_rush_order = fields.Boolean(
+ string='Rush Order',
+ tracking=True,
+ help='High-priority flag mirrored from sale.order. Operators see '
+ 'this on the queue / tablet at-a-glance — saves lifting the '
+ 'job form to know it\'s rush.',
+ )
+
qty_received = fields.Integer(
string='Qty Received',
help='Paper traveller "Qty Rec." column.',
diff --git a/fusion_plating/fusion_plating/views/fp_job_views.xml b/fusion_plating/fusion_plating/views/fp_job_views.xml
index aa5c6f56..4d629a5e 100644
--- a/fusion_plating/fusion_plating/views/fp_job_views.xml
+++ b/fusion_plating/fusion_plating/views/fp_job_views.xml
@@ -37,6 +37,11 @@
+
+
+
+
+
diff --git a/fusion_plating/fusion_plating_configurator/__manifest__.py b/fusion_plating/fusion_plating_configurator/__manifest__.py
index 96e5a83f..f210ad14 100644
--- a/fusion_plating/fusion_plating_configurator/__manifest__.py
+++ b/fusion_plating/fusion_plating_configurator/__manifest__.py
@@ -5,7 +5,7 @@
{
'name': 'Fusion Plating — Configurator',
- 'version': '19.0.18.12.9',
+ 'version': '19.0.18.10.0',
'category': 'Manufacturing/Plating',
'summary': 'Quotation configurator with part catalog, coating configs, and formula-based pricing engine.',
'description': """
@@ -59,7 +59,6 @@ Provides:
'wizard/fp_add_from_quote_wizard_views.xml',
'wizard/fp_quote_promote_wizard_views.xml',
'wizard/fp_part_catalog_import_wizard_views.xml',
- 'wizard/fp_part_revision_bump_wizard_views.xml',
'wizard/fp_serial_bulk_add_wizard_views.xml',
'views/fp_configurator_menu.xml',
'data/fp_sale_description_template_data.xml',
diff --git a/fusion_plating/fusion_plating_configurator/models/sale_order_line.py b/fusion_plating/fusion_plating_configurator/models/sale_order_line.py
index 984c67b9..0c6524da 100644
--- a/fusion_plating/fusion_plating_configurator/models/sale_order_line.py
+++ b/fusion_plating/fusion_plating_configurator/models/sale_order_line.py
@@ -641,3 +641,21 @@ class SaleOrderLine(models.Model):
'n': n,
'qty': int(line.product_uom_qty),
})
+
+
+ # ---- Customer references mirrored from parent sale.order ----------
+ # Related (not stored) — display-only on the line list so shipping /
+ # invoicing operators see the customer's job/PO ref per-line without
+ # navigating up to the order header.
+ x_fc_customer_job_number = fields.Char(
+ related='order_id.x_fc_customer_job_number',
+ string='Customer Job #',
+ readonly=True,
+ store=True,
+ )
+ x_fc_po_number = fields.Char(
+ related='order_id.x_fc_po_number',
+ string='Customer PO #',
+ readonly=True,
+ store=True,
+ )
diff --git a/fusion_plating/fusion_plating_jobs/__manifest__.py b/fusion_plating/fusion_plating_jobs/__manifest__.py
index 883dd096..9f964b22 100644
--- a/fusion_plating/fusion_plating_jobs/__manifest__.py
+++ b/fusion_plating/fusion_plating_jobs/__manifest__.py
@@ -3,7 +3,7 @@
# License OPL-1 (Odoo Proprietary License v1.0)
{
'name': 'Fusion Plating — Native Jobs',
- 'version': '19.0.8.21.1',
+ 'version': '19.0.8.21.2',
'category': 'Manufacturing/Plating',
'summary': 'Native plating job model — replaces mrp.production / mrp.workorder bridge.',
'author': 'Nexa Systems Inc.',
diff --git a/fusion_plating/fusion_plating_jobs/models/sale_order.py b/fusion_plating/fusion_plating_jobs/models/sale_order.py
index 16b476a5..4c04c59b 100644
--- a/fusion_plating/fusion_plating_jobs/models/sale_order.py
+++ b/fusion_plating/fusion_plating_jobs/models/sale_order.py
@@ -322,6 +322,16 @@ class SaleOrder(models.Model):
if recipe:
vals['recipe_id'] = recipe.id
+ # Customer references — mirror onto the job so the shop floor
+ # has them without round-tripping to the SO.
+ if 'x_fc_customer_job_number' in self._fields \
+ and self.x_fc_customer_job_number:
+ vals['x_fc_customer_job_number'] = self.x_fc_customer_job_number
+ if 'x_fc_po_number' in self._fields and self.x_fc_po_number:
+ vals['x_fc_po_number'] = self.x_fc_po_number
+ if 'x_fc_rush_order' in self._fields:
+ vals['x_fc_rush_order'] = bool(self.x_fc_rush_order)
+
# Customer spec / facility / manager — copy from SO if present
if 'x_fc_customer_spec_id' in self._fields and self.x_fc_customer_spec_id:
vals['customer_spec_id'] = self.x_fc_customer_spec_id.id