diff --git a/fusion_plating/fusion_plating/__manifest__.py b/fusion_plating/fusion_plating/__manifest__.py
index 528320b8..73807f6e 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.6',
+ 'version': '19.0.18.15.7',
'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 9068bcc4..b81ddbc2 100644
--- a/fusion_plating/fusion_plating/models/fp_job.py
+++ b/fusion_plating/fusion_plating/models/fp_job.py
@@ -289,6 +289,37 @@ class FpJob(models.Model):
'job form to know it\'s rush.',
)
+ # ---- Scheduling targets mirrored from sale.order -----------------
+ # These are kept separate from the operational date_planned_start /
+ # date_deadline fields (which may be tweaked by scheduling logic) —
+ # this preserves the ORIGINAL customer-facing dates entered on the SO.
+ x_fc_internal_deadline = fields.Date(
+ string='Internal Deadline',
+ tracking=True,
+ help='Shop\'s internal target finish date, copied from sale.order. '
+ 'Buffer ahead of the customer-facing deadline.',
+ )
+ x_fc_planned_start_date = fields.Date(
+ string='Planned Start (SO)',
+ tracking=True,
+ help='Customer-quoted planned start date copied from sale.order. '
+ 'Different from date_planned_start (which scheduling logic '
+ 'may adjust based on shop capacity).',
+ )
+
+ # ---- Operational notes mirrored from sale.order ------------------
+ x_fc_internal_note = fields.Text(
+ string='Internal Note',
+ tracking=True,
+ help='Shop-internal notes from the order. Not shown to customer.',
+ )
+ x_fc_external_note = fields.Text(
+ string='External Note',
+ tracking=True,
+ help='Customer-facing notes copied from the sale order. Printed '
+ 'on traveller / BoL / cert.',
+ )
+
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 4d629a5e..ddc9633b 100644
--- a/fusion_plating/fusion_plating/views/fp_job_views.xml
+++ b/fusion_plating/fusion_plating/views/fp_job_views.xml
@@ -41,6 +41,12 @@
+
+
+
+
+
+
diff --git a/fusion_plating/fusion_plating_configurator/__manifest__.py b/fusion_plating/fusion_plating_configurator/__manifest__.py
index f210ad14..67aa5e18 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.10.0',
+ 'version': '19.0.18.10.1',
'category': 'Manufacturing/Plating',
'summary': 'Quotation configurator with part catalog, coating configs, and formula-based pricing engine.',
'description': """
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 0c6524da..f272fb10 100644
--- a/fusion_plating/fusion_plating_configurator/models/sale_order_line.py
+++ b/fusion_plating/fusion_plating_configurator/models/sale_order_line.py
@@ -659,3 +659,28 @@ class SaleOrderLine(models.Model):
readonly=True,
store=True,
)
+
+ x_fc_internal_deadline = fields.Date(
+ related='order_id.x_fc_internal_deadline',
+ string='Internal Deadline',
+ readonly=True,
+ store=True,
+ )
+ x_fc_planned_start_date = fields.Date(
+ related='order_id.x_fc_planned_start_date',
+ string='Planned Start',
+ readonly=True,
+ store=True,
+ )
+ x_fc_internal_note = fields.Text(
+ related='order_id.x_fc_internal_note',
+ string='Internal Note',
+ readonly=True,
+ store=True,
+ )
+ x_fc_external_note = fields.Text(
+ related='order_id.x_fc_external_note',
+ string='External Note',
+ readonly=True,
+ store=True,
+ )
diff --git a/fusion_plating/fusion_plating_jobs/__manifest__.py b/fusion_plating/fusion_plating_jobs/__manifest__.py
index 9f964b22..0d7b7ab1 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.2',
+ 'version': '19.0.8.21.3',
'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 4c04c59b..b249192c 100644
--- a/fusion_plating/fusion_plating_jobs/models/sale_order.py
+++ b/fusion_plating/fusion_plating_jobs/models/sale_order.py
@@ -332,6 +332,22 @@ class SaleOrder(models.Model):
if 'x_fc_rush_order' in self._fields:
vals['x_fc_rush_order'] = bool(self.x_fc_rush_order)
+ # Scheduling targets — mirror the SO's customer-facing dates.
+ if 'x_fc_internal_deadline' in self._fields \
+ and self.x_fc_internal_deadline:
+ vals['x_fc_internal_deadline'] = self.x_fc_internal_deadline
+ if 'x_fc_planned_start_date' in self._fields \
+ and self.x_fc_planned_start_date:
+ vals['x_fc_planned_start_date'] = self.x_fc_planned_start_date
+
+ # Operational notes — mirror so the shop has them on the WO.
+ if 'x_fc_internal_note' in self._fields \
+ and self.x_fc_internal_note:
+ vals['x_fc_internal_note'] = self.x_fc_internal_note
+ if 'x_fc_external_note' in self._fields \
+ and self.x_fc_external_note:
+ vals['x_fc_external_note'] = self.x_fc_external_note
+
# 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