fix(jobs): Finish & Next bulk-moves all parts, no more "click N times"

User feedback: operators with small parts (e.g. valve bodies) batch
them through the whole recipe. The previous behavior — Finish & Next
raising "use Complete 1 → Next or Move..." when qty>1 — forced N
clicks for a workflow that's naturally one click.

Change: _fp_record_one_piece_auto_move now ALWAYS bulk-moves
qty_at_step parts to the next step in one move record, regardless of
whether the qty is seed-only (first / paperwork step) or real (parked
from an upstream move). Audit trail is preserved (one move row per
finish), operator gets one click.

Three buttons now map cleanly to the three workflows:
  - Finish & Next: bulk all parts forward, finish, auto-start next
  - Complete 1 -> Next: streaming flow, move 1 part, stay open
  - Move...: explicit qty + destination wizard for partial batches

Verified end-to-end on entech: seed qty=6 + real-incoming qty=6 both
move forward in a single click each.

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

View File

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

View File

@@ -1135,37 +1135,21 @@ class FpJobStep(models.Model):
).sorted('sequence')[:1] ).sorted('sequence')[:1]
if not next_step: if not next_step:
return False return False
# Seed-only qty: no real incoming moves backing it. Paperwork # Bulk-move all parts in one shot. Covers three use cases:
# step or first-step seed — bulk-move all parts in one shot. # - seed-only qty (paperwork / first step): creates the
has_real_incoming = bool( # first explicit move record for the batch
self.incoming_move_ids.filtered( # - real incoming, qty == 1 (streaming flow last part):
lambda m: m.from_step_id != self # same as Complete 1 → Next's tail call
) # - real incoming, qty > 1 (batched flow): one click moves
) # everything forward — operators with small parts don't
if not has_real_incoming: # have to click Complete 1 → Next repeatedly
self.env['fp.job.step.move'].create({ # Complete 1 → Next is still available for one-by-one flow.
'job_id': self.job_id.id,
'from_step_id': self.id,
'to_step_id': next_step.id,
'transfer_type': 'step',
'qty_moved': qty,
'moved_by_user_id': self.env.user.id,
})
return True
if qty > 1:
raise UserError(_(
"Step '%s' still has %d parts here — use the row's "
"'Complete 1 → Next' button (for one-by-one flow) "
"or the 'Move…' wizard (for batched flow) to drain "
"the step before finishing."
) % (self.name, qty))
# qty == 1 + real incoming → record single move.
self.env['fp.job.step.move'].create({ self.env['fp.job.step.move'].create({
'job_id': self.job_id.id, 'job_id': self.job_id.id,
'from_step_id': self.id, 'from_step_id': self.id,
'to_step_id': next_step.id, 'to_step_id': next_step.id,
'transfer_type': 'step', 'transfer_type': 'step',
'qty_moved': 1, 'qty_moved': qty,
'moved_by_user_id': self.env.user.id, 'moved_by_user_id': self.env.user.id,
}) })
return True return True