feat(jobs): Phase 3 light refactors — parallel job/step links on dependent models

Adds x_fc_job_id / x_fc_step_id Many2ones via _inherit on:
- fusion.plating.batch (workorder_id stays for legacy MRP-bound batches)
- fusion.plating.quality.hold
- fp.certificate
- fp.thickness.reading
- fusion.plating.delivery (parallel to existing job_ref Char)
- fp.racking.inspection (parallel to existing production_id)

fp.job.action_confirm now also calls a best-effort racking-inspection
auto-create. The current fp.racking.inspection still has a required
production_id, so the helper skips cleanly when this job has no MO link
(pure-native mode). Phase 9 cutover flips the required FK to fp.job.

Strategy: parallel coexistence — bridge_mrp's existing fields stay
populated; this adds NEW fields populated by the native flow. Phase 9
cutover stops populating the old fields.

Adds fusion_plating_batch + fusion_plating_receiving to jobs module
depends.

Note: spec referenced fp.batch / fp.quality.hold; the actual models
in this codebase are fusion.plating.batch / fusion.plating.quality.hold
— used the real model names.

Manifest 19.0.1.5.0 → 19.0.1.6.0. 29 jobs tests pass.

Part of: native job model migration (spec 2026-04-25)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-24 23:34:05 -04:00
parent dd88afdf53
commit b359be3745
10 changed files with 265 additions and 4 deletions

View File

@@ -11,3 +11,11 @@ from . import fp_portal_job
from . import account_move
from . import res_config_settings
from . import sale_order
# Phase 3 — parallel job/step links on dependent modules' models.
from . import fp_batch
from . import fp_quality_hold
from . import fp_certificate
from . import fp_thickness_reading
from . import fp_delivery
from . import fp_racking_inspection

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
#
# Phase 3 — parallel job/step links on fusion.plating.batch.
# The legacy workorder_id link to mrp.workorder stays in place.
from odoo import fields, models
class FusionPlatingBatch(models.Model):
_inherit = 'fusion.plating.batch'
x_fc_step_id = fields.Many2one(
'fp.job.step',
string='Plating Step',
index=True,
help='Native fp.job.step link. Coexists with the legacy '
'workorder_id link to mrp.workorder.',
)
x_fc_job_id = fields.Many2one(
'fp.job',
related='x_fc_step_id.job_id',
store=True,
string='Plating Job',
)

View File

@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
#
# Phase 3 — parallel job link on fp.certificate.
# Coexists with bridge_mrp's production_id link.
from odoo import fields, models
class FpCertificate(models.Model):
_inherit = 'fp.certificate'
x_fc_job_id = fields.Many2one(
'fp.job',
string='Plating Job',
index=True,
help="Native fp.job link. Coexists with bridge_mrp's production_id.",
)

View File

@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
#
# Phase 3 — parallel job link on fusion.plating.delivery.
# Coexists with the legacy job_ref Char.
from odoo import fields, models
class FusionPlatingDelivery(models.Model):
_inherit = 'fusion.plating.delivery'
x_fc_job_id = fields.Many2one(
'fp.job',
string='Plating Job',
index=True,
help='Native fp.job link. Coexists with the legacy job_ref Char.',
)

View File

@@ -259,8 +259,49 @@ class FpJob(models.Model):
for job in self:
job._fp_create_portal_job()
job._fp_create_qc_check_if_needed()
job._fp_create_racking_inspection()
return result
def _fp_create_racking_inspection(self):
"""Auto-create a draft racking inspection on job confirm.
Mirrors bridge_mrp's behaviour for MO confirm. Best-effort: the
legacy fp.racking.inspection model still requires a production_id
(mrp.production), so we can only create one when this job is
bound to an MO via bridge_mrp. Otherwise we skip cleanly — Phase
9 will flip the required-FK to fp.job.
"""
self.ensure_one()
if 'fp.racking.inspection' not in self.env:
return
Inspection = self.env['fp.racking.inspection'].sudo()
# The model still requires production_id today. If the job has
# no MO link (which it won't in pure-native mode), skip rather
# than crash. The link exists when fusion_plating_bridge_mrp is
# installed and a production was created in parallel.
production = False
if 'production_id' in self._fields and self.production_id:
production = self.production_id
elif 'mrp_production_id' in self._fields and getattr(
self, 'mrp_production_id', False):
production = self.mrp_production_id
if not production:
_logger.debug(
"Job %s: no MO link — skipping racking-inspection auto-create "
"(required production_id not yet on fp.job).", self.name,
)
return
try:
vals = {'production_id': production.id}
if 'x_fc_job_id' in Inspection._fields:
vals['x_fc_job_id'] = self.id
Inspection.create(vals)
except Exception as e:
_logger.warning(
"Job %s: failed to auto-create racking inspection: %s",
self.name, e,
)
def _fp_create_portal_job(self):
"""Create the fusion.plating.portal.job mirror record."""
self.ensure_one()

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
#
# Phase 3 — parallel job/step links on fusion.plating.quality.hold.
# Coexists with bridge_mrp's existing production_id link.
from odoo import fields, models
class FusionPlatingQualityHold(models.Model):
_inherit = 'fusion.plating.quality.hold'
x_fc_job_id = fields.Many2one(
'fp.job',
string='Plating Job',
index=True,
help="Native fp.job link. Coexists with bridge_mrp's production_id "
"link.",
)
x_fc_step_id = fields.Many2one(
'fp.job.step',
string='Plating Step',
index=True,
)

View File

@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
#
# Phase 3 — parallel job link on fp.racking.inspection.
# Coexists with the legacy production_id (mrp.production) link.
from odoo import fields, models
class FpRackingInspection(models.Model):
_inherit = 'fp.racking.inspection'
x_fc_job_id = fields.Many2one(
'fp.job',
string='Plating Job',
index=True,
help='Native fp.job link. Coexists with the legacy production_id.',
)

View File

@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
#
# Phase 3 — parallel job/step links on fp.thickness.reading.
from odoo import fields, models
class FpThicknessReading(models.Model):
_inherit = 'fp.thickness.reading'
x_fc_job_id = fields.Many2one(
'fp.job',
string='Plating Job',
index=True,
)
x_fc_step_id = fields.Many2one(
'fp.job.step',
string='Plating Step',
index=True,
)