feat(fp.job.step): wrap button_finish with gate + advance (Task 4)

Pre-super: when finishing the last open step on an in_progress job,
run the bake/qty/QC gates from button_mark_done so failures surface
as UserError on the click (per spec D12). Without this the
auto-advance would silently fail with no error path.

Post-super: trigger _fp_check_advance_post_shop so the state
auto-advances cleanly (in_progress → awaiting_cert / awaiting_ship).

Added _fp_check_finish_gates helper on fp.job and a
fp_check_gates_only context flag honored by button_mark_done so the
gate logic is single-sourced (DRY).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-25 09:22:33 -04:00
parent 5173554281
commit 72f0f182a6
2 changed files with 57 additions and 0 deletions

View File

@@ -1311,8 +1311,36 @@ class FpJobStep(models.Model):
self._fp_check_contract_review_complete()
self._fp_check_receiving_gate()
# ----- Post-shop gate (spec 2026-05-25 D12) ---------------------
# When finishing the LAST open step on an in_progress job, run
# the bake/qty/QC gates that used to live in button_mark_done.
# Failure raises UserError on THIS click — operator fixes
# (qty, bake, QC) and retries the finish. Without this the
# auto-advance helper would silently fail with no error path.
for step in self:
if step.state not in ('in_progress', 'paused', 'ready'):
continue
job = step.job_id
if not job or job.state != 'in_progress':
continue
# Would this finish leave every step terminal?
siblings_open = job.step_ids.filtered(
lambda s: s.id != step.id
and s.state not in ('done', 'skipped', 'cancelled')
)
if siblings_open:
continue # not the last open step — skip the gates
job._fp_check_finish_gates()
result = super().button_finish()
# ----- Post-shop auto-advance (spec 2026-05-25) -----------------
# After super().button_finish flips step state to done, ask the
# job to check whether ALL steps are now terminal. If so the
# helper auto-advances state to awaiting_cert / awaiting_ship.
for job in self.mapped('job_id'):
job._fp_check_advance_post_shop()
# ----- Post-finish side effects --------------------------------
BW = self.env['fusion.plating.bake.window']
Bath = self.env['fusion.plating.bath']