fix(shopfloor,reports): make QR scan actually navigate after decode
Two bugs were colluding to make iPhone scans look like "nothing
happens":
1. The in-app scanner was calling action.doAction({res_model: 'fp.job',
res_id: <decoded-id>}). Old physical stickers (still on every box)
encode /fp/wo/<mrp.production.id> — that id space doesn't match
fp.job, so the form opened on a non-existent record and silently
showed nothing. New /fp/job/<id> stickers happened to work because
the IDs lined up by coincidence.
2. The /fp/wo/<id> controller redirected to mrp.production / mrp.workorder
forms, both of which still exist as legacy records but aren't the
canonical source of truth post-migration.
Fix:
- qr_scanner._handleCode now navigates via window.location.href instead
of action.doAction. It hands /fp/job/<n> and /fp/wo/<n> URLs straight
to the existing server-side controllers, which know how to resolve
the right record. Bare numeric ids pasted manually -> /fp/job/<n>.
Anything else surfaces the decoded text as an error so the operator
can see decode worked but the value isn't a sticker.
- Modal now shows "Detected: <value>" the moment a code is decoded
(before navigation), so even on slow phones the operator sees
immediate feedback that the camera read the QR.
- wo_scan.py now resolves in this order:
1. fp.job by legacy_mrp_production_id (migration-aware — old
stickers route to the new model)
2. mrp.production direct browse
3. mrp.workorder direct browse
4. fall back to /odoo/plating-jobs (or work-orders list)
Versions: shopfloor 19.0.17.0.0 -> 19.0.18.0.0,
reports 19.0.7.15.0 -> 19.0.7.16.0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,25 +22,42 @@ class FpWoScanController(http.Controller):
|
||||
def wo_scan_redirect(self, wo_id, **kwargs):
|
||||
"""Redirect a scanned sticker to the right backend form.
|
||||
|
||||
Stickers are printed from two sources — mrp.workorder (WO) and
|
||||
mrp.production (MO) — and both embed their own numeric id in
|
||||
the QR. Try the MO table first (operators live on the MO
|
||||
form — customer, SO, all WOs visible) and fall back to WO.
|
||||
Resolution order:
|
||||
1. fp.job mapped from this MO id via legacy_mrp_production_id
|
||||
(post-migration: physical stickers still encode the old MO
|
||||
id, but the canonical record is now an fp.job)
|
||||
2. mrp.production with this id (pre-migration callers, or if
|
||||
the legacy mapping wasn't run)
|
||||
3. mrp.workorder with this id (older stickers that encoded
|
||||
the WO id rather than the MO id)
|
||||
4. fall back to the jobs list so staff can search manually.
|
||||
"""
|
||||
MO = request.env['mrp.production'].sudo()
|
||||
WO = request.env['mrp.workorder'].sudo()
|
||||
env = request.env
|
||||
|
||||
mo = MO.browse(wo_id).exists()
|
||||
# 1) New native model — preferred when migration has run.
|
||||
if 'fp.job' in env and 'legacy_mrp_production_id' in env['fp.job']._fields:
|
||||
job = env['fp.job'].sudo().search(
|
||||
[('legacy_mrp_production_id', '=', wo_id)], limit=1)
|
||||
if job:
|
||||
return request.redirect(
|
||||
'/odoo/action-fusion_plating.action_fp_job/%d' % job.id
|
||||
)
|
||||
|
||||
# 2) Legacy MO form (pre-migration or non-migrated records).
|
||||
mo = env['mrp.production'].sudo().browse(wo_id).exists()
|
||||
if mo:
|
||||
return request.redirect(
|
||||
'/odoo/action-mrp.mrp_production_action/%d' % mo.id
|
||||
)
|
||||
|
||||
wo = WO.browse(wo_id).exists()
|
||||
# 3) Legacy WO form.
|
||||
wo = env['mrp.workorder'].sudo().browse(wo_id).exists()
|
||||
if wo:
|
||||
return request.redirect(
|
||||
'/odoo/action-mrp.action_mrp_workorder/%d' % wo.id
|
||||
)
|
||||
|
||||
# Neither resolved — land on the WO list so staff can search manually.
|
||||
# 4) Fall back: native jobs list if it exists, otherwise WO list.
|
||||
if 'fp.job' in env:
|
||||
return request.redirect('/odoo/plating-jobs')
|
||||
return request.redirect('/odoo/manufacturing/work-orders')
|
||||
|
||||
Reference in New Issue
Block a user