Files
Odoo-Modules/fusion_plating/fusion_plating_reports/controllers/wo_scan.py
gsinghpal b93633d728 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>
2026-04-25 13:14:06 -04:00

64 lines
2.5 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)
# Part of the Fusion Plating product family.
#
# /fp/wo/<id> — scan-redirect endpoint.
#
# The WO box sticker embeds a QR code that encodes this URL. When
# warehouse staff scan the sticker with their phone / tablet /
# handheld scanner, the device opens the URL; this controller then
# redirects them to the work-order form inside Odoo's backend.
# Logged-out users land on the standard Odoo login page and bounce
# back after authenticating (Odoo's redirect handles the round-trip).
from odoo import http
from odoo.http import request
class FpWoScanController(http.Controller):
@http.route('/fp/wo/<int:wo_id>', type='http', auth='user', website=False)
def wo_scan_redirect(self, wo_id, **kwargs):
"""Redirect a scanned sticker to the right backend form.
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.
"""
env = request.env
# 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
)
# 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
)
# 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')