fix(fusion_plating_jobs): first/seeded stage never auto-finished on drain
_fp_try_autofinish_on_drain guarded on _fp_has_real_incoming() — the WRONG direction. The first stage (e.g. Racking) is fed by the qty_at_step seed, not an incoming move, so it never auto-finished when all its parts were sent forward (operator sent everything out of Racking, step stayed in_progress at qty 0). Now guards on a real OUTGOING move (parts left), which covers the seeded first stage. Still best-effort + gated: button_finish runs the required-input / sign-off gates, so a step with an unrecorded required input (Racking's "Count the Parts") won't auto-finish — it stays in_progress for a manual finish after the input is recorded. Verified on entech. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -698,19 +698,29 @@ class FpJobStep(models.Model):
|
||||
operator to finish manually (the board will show it "running, 0
|
||||
here", which reads as "finish me").
|
||||
|
||||
Only fires for steps that had REAL incoming parts — never an
|
||||
untouched first-step seed. Returns True if the step finished.
|
||||
Fires for any step that actually moved parts OUT and drained to
|
||||
zero — INCLUDING the first/seeded stage (its qty comes from the
|
||||
qty_at_step seed, not a real incoming move). Returns True if the
|
||||
step finished.
|
||||
"""
|
||||
self.ensure_one()
|
||||
if self.state != 'in_progress':
|
||||
return False
|
||||
if not self._fp_has_real_incoming():
|
||||
return False
|
||||
# qty_at_step is a non-stored compute off the move rows — force a
|
||||
# re-read so we see the just-committed outgoing move.
|
||||
self.invalidate_recordset(['qty_at_step'])
|
||||
if self.qty_at_step != 0:
|
||||
return False
|
||||
# Guard: only auto-finish a step that genuinely moved parts OUT (a
|
||||
# real outgoing move, excluding self-loop measurement moves). The
|
||||
# earlier guard checked _fp_has_real_incoming() — the WRONG
|
||||
# direction: the first/seeded stage (e.g. Racking) is fed by the
|
||||
# qty_at_step seed, not an incoming move, so it never auto-finished
|
||||
# when all its parts were sent forward. Checking for a real
|
||||
# OUTGOING move covers the seeded first stage correctly.
|
||||
if not self.move_ids.filtered(
|
||||
lambda m: m.to_step_id != self and (m.qty_moved or 0) > 0):
|
||||
return False
|
||||
try:
|
||||
self.button_finish()
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user