changes
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
# Part of the Fusion Plating product family.
|
||||
|
||||
"""19.0.12.5.0 — Backfill default_kind on existing recipe nodes.
|
||||
|
||||
The Page-2 audit (2026-04-28) showed that pre-Sub-12a recipe nodes
|
||||
have NULL `default_kind` because the field was added later. The
|
||||
recipe-side soft-gates (Sub 8 racking, Policy B contract review) fall
|
||||
back to name-matching when the kind is missing, which means a
|
||||
renamed step ("Hang on Bar" instead of "Racking") silently bypasses
|
||||
the gate.
|
||||
|
||||
This migration walks `fusion.plating.process.node` rows with NULL
|
||||
default_kind, resolves a sensible kind via the central
|
||||
`fp_resolve_step_kind()` helper, and sets it.
|
||||
|
||||
It also walks `fp.job.step` rows whose `kind` is the legacy 'other'
|
||||
placeholder and re-derives `kind` from `recipe_node_id.default_kind`
|
||||
(after the node-side backfill above sets it). Non-other kinds are
|
||||
left alone — operator may have set them deliberately.
|
||||
|
||||
Idempotent.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from odoo.api import Environment
|
||||
|
||||
from odoo.addons.fusion_plating import fp_resolve_step_kind
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Same mapping as in fp_job.py — keep them in sync.
|
||||
_NODE_KIND_TO_STEP_KIND = {
|
||||
'cleaning': 'wet',
|
||||
'etch': 'wet',
|
||||
'rinse': 'wet',
|
||||
'plate': 'wet',
|
||||
'dry': 'wet',
|
||||
'wbf_test': 'wet',
|
||||
'bake': 'bake',
|
||||
'mask': 'mask',
|
||||
'demask': 'mask',
|
||||
'racking': 'rack',
|
||||
'derack': 'rack',
|
||||
'inspect': 'inspect',
|
||||
'final_inspect': 'inspect',
|
||||
'contract_review': 'other',
|
||||
'gating': 'other',
|
||||
'ship': 'other',
|
||||
}
|
||||
|
||||
|
||||
def migrate(cr, version):
|
||||
env = Environment(cr, 1, {})
|
||||
|
||||
# ---- 1. Backfill default_kind on recipe nodes -----------------------
|
||||
Node = env['fusion.plating.process.node']
|
||||
blank = Node.search([
|
||||
('default_kind', '=', False),
|
||||
('node_type', 'in', ('operation', 'step')),
|
||||
])
|
||||
fixed = 0
|
||||
for n in blank:
|
||||
kind = fp_resolve_step_kind(n.name)
|
||||
if kind:
|
||||
n.default_kind = kind
|
||||
fixed += 1
|
||||
_logger.info(
|
||||
'19.0.12.5.0: backfilled default_kind on %s/%s recipe nodes via '
|
||||
'fp_resolve_step_kind.', fixed, len(blank),
|
||||
)
|
||||
|
||||
# ---- 2. Re-derive fp.job.step.kind from recipe node default_kind ----
|
||||
Step = env['fp.job.step']
|
||||
other_steps = Step.search([
|
||||
('kind', '=', 'other'),
|
||||
('recipe_node_id', '!=', False),
|
||||
('state', 'not in', ('done', 'cancelled')),
|
||||
])
|
||||
rederived = 0
|
||||
for s in other_steps:
|
||||
node_kind = (
|
||||
s.recipe_node_id.default_kind
|
||||
if 'default_kind' in s.recipe_node_id._fields else None
|
||||
)
|
||||
new_kind = _NODE_KIND_TO_STEP_KIND.get(node_kind) if node_kind else None
|
||||
if new_kind and new_kind != 'other':
|
||||
s.kind = new_kind
|
||||
rederived += 1
|
||||
_logger.info(
|
||||
'19.0.12.5.0: re-derived kind on %s/%s in-flight job steps from '
|
||||
'recipe node default_kind.', rederived, len(other_steps),
|
||||
)
|
||||
Reference in New Issue
Block a user