fix(jobs): make "In Progress" workflow milestone fire reliably

Two coupled fixes so the workflow bar shows "In Progress" when work
is actually underway, even on recipes without kind tagging:

  B. Auto-promote fp.job.state on first step start.
     fp.job.step.write hook detects step transitions to in_progress
     and promotes parent job state from 'confirmed' → 'in_progress'.
     Without this, fp.job.state never reached 'in_progress' anywhere
     in the codebase, so the trigger_on_job_state='in_progress'
     path was dead code.

  C. Smarter trigger_first_step_started for untagged recipes.
     For tagged recipes (any step has kind in wet/bake/mask/rack),
     keep the strict kind-based check. For untagged recipes (all
     steps kind='other' or similar), fall back to "any step in
     in_progress/paused/done" so the milestone fires regardless of
     recipe authoring quality.

Verified end-to-end on entech with untagged steps:
  - confirmed → in_progress when first step starts
  - workflow bar tracks at in_progress through the work
  - workflow bar advances to done when all steps done/skipped

Recipe authoring still encouraged for full Received / Inspected
intermediate states (those keep their default_kind triggers).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-12 00:27:05 -04:00
parent 89dd77aff2
commit 8d082cd9cc
3 changed files with 33 additions and 11 deletions

View File

@@ -3,7 +3,7 @@
# License OPL-1 (Odoo Proprietary License v1.0)
{
'name': 'Fusion Plating — Native Jobs',
'version': '19.0.8.20.3',
'version': '19.0.8.20.4',
'category': 'Manufacturing/Plating',
'summary': 'Native plating job model — replaces mrp.production / mrp.workorder bridge.',
'author': 'Nexa Systems Inc.',

View File

@@ -174,6 +174,18 @@ class FpJobStep(models.Model):
'(state=%s) by %s.'
)) % (step.name, old_name, new_name, step.state,
self.env.user.name))
# Auto-promote parent job: confirmed → in_progress on first
# step start. Without this, fp.job.state never reaches
# 'in_progress' anywhere in the codebase, so the In Progress
# workflow milestone (trigger_on_job_state='in_progress')
# never fires.
if vals.get('state') == 'in_progress':
jobs_to_promote = self.mapped('job_id').filtered(
lambda j: j.state == 'confirmed'
)
if jobs_to_promote:
jobs_to_promote.write({'state': 'in_progress'})
return result
@api.model

View File

@@ -227,18 +227,28 @@ class FpJobWorkflowState(models.Model):
actual = order.get(job.state, -1)
return required >= 0 and actual >= required
# Special trigger: first wet step started
# Special trigger: first wet step started.
# For tagged recipes (any step has kind in wet/bake/mask/rack),
# use strict kind-based check. For untagged recipes (all steps
# are kind='other'), fall back to "any step started" so the
# milestone fires regardless of recipe authoring quality.
if self.trigger_first_step_started:
wet_kinds = ('wet', 'bake', 'mask', 'rack')
production_started = any(
s.state in ('in_progress', 'paused', 'done')
and (s.kind in wet_kinds)
for s in steps
)
if not production_started:
return False
# Production milestone — not blocked by quality hold here
return True
has_kind_tagging = any(s.kind in wet_kinds for s in steps)
if has_kind_tagging:
production_started = any(
s.state in ('in_progress', 'paused', 'done')
and (s.kind in wet_kinds)
for s in steps
)
else:
# Untagged recipe — any started step counts as
# "production has started".
production_started = any(
s.state in ('in_progress', 'paused', 'done')
for s in steps
)
return production_started
# Standard trigger: ALL recipe steps matching the trigger
# (default_kind in our list OR per-node override pointing at