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