From 9fe7855fc398f00583c7a0e1cc06379eeae473c3 Mon Sep 17 00:00:00 2001 From: gsinghpal Date: Sat, 25 Apr 2026 13:30:40 -0400 Subject: [PATCH] fix(shopfloor,reports): scanner status line + sticker rev cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Re-detect BarcodeDetector / window.jsQR at every modal open instead of only at component setup. Avoids the trap where a stale cached bundle reports "no decoder" even after a redeploy. - Add a one-line status indicator at the top of the scan modal showing exactly which decoder is active ("Decoder: native" / "Decoder: jsqr" / "Decoder: none — paste URL below"). Lets the operator see at a glance whether scanning is even possible without round-tripping through Safari Web Inspector. - Sticker: strip a leading "Rev " (case-insensitive) from fp.part.catalog.revision before printing so values like "Rev 1" don't render as "Rev Rev 1". Versions: shopfloor 19.0.18 -> 19.0.19, reports 19.0.7.16 -> 19.0.7.17. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../fusion_plating_reports/__manifest__.py | 2 +- .../report/report_fp_wo_sticker.xml | 11 +++++- .../fusion_plating_shopfloor/__manifest__.py | 2 +- .../shopfloor_controller.cpython-312.pyc | Bin 26605 -> 0 bytes .../static/src/js/qr_scanner.js | 37 ++++++++++++++---- .../static/src/scss/qr_scanner.scss | 10 ++++- .../static/src/xml/qr_scanner.xml | 4 ++ 7 files changed, 55 insertions(+), 11 deletions(-) delete mode 100644 fusion_plating/fusion_plating_shopfloor/controllers/__pycache__/shopfloor_controller.cpython-312.pyc diff --git a/fusion_plating/fusion_plating_reports/__manifest__.py b/fusion_plating/fusion_plating_reports/__manifest__.py index a0da068d..084e21f7 100644 --- a/fusion_plating/fusion_plating_reports/__manifest__.py +++ b/fusion_plating/fusion_plating_reports/__manifest__.py @@ -3,7 +3,7 @@ # License OPL-1 (Odoo Proprietary License v1.0) { 'name': 'Fusion Plating — Reports', - 'version': '19.0.7.16.0', + 'version': '19.0.7.17.0', 'category': 'Manufacturing/Plating', 'summary': 'PDF reports for Fusion Plating: quote, SO, WO, packing, BoL, CoC, invoice, receipt, quality + compliance.', 'depends': [ diff --git a/fusion_plating/fusion_plating_reports/report/report_fp_wo_sticker.xml b/fusion_plating/fusion_plating_reports/report/report_fp_wo_sticker.xml index 3812a0f8..706b8962 100644 --- a/fusion_plating/fusion_plating_reports/report/report_fp_wo_sticker.xml +++ b/fusion_plating/fusion_plating_reports/report/report_fp_wo_sticker.xml @@ -306,8 +306,17 @@ + + + + + - Rev + Rev diff --git a/fusion_plating/fusion_plating_shopfloor/__manifest__.py b/fusion_plating/fusion_plating_shopfloor/__manifest__.py index a43f57e4..9d15dd99 100644 --- a/fusion_plating/fusion_plating_shopfloor/__manifest__.py +++ b/fusion_plating/fusion_plating_shopfloor/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Fusion Plating — Shop Floor', - 'version': '19.0.18.0.0', + 'version': '19.0.19.0.0', 'category': 'Manufacturing/Plating', 'summary': 'Shop-floor tablet stations, QR scanning, bake window enforcer, ' 'first-piece inspection gates.', diff --git a/fusion_plating/fusion_plating_shopfloor/controllers/__pycache__/shopfloor_controller.cpython-312.pyc b/fusion_plating/fusion_plating_shopfloor/controllers/__pycache__/shopfloor_controller.cpython-312.pyc deleted file mode 100644 index 85f97b3eadc5eb297ebef8144c98d8cbf46e3f3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26605 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 - // when false we fall through to the manual paste UI only. - canScan: hasNative || hasJsQR, - decoder: hasNative ? "native" : (hasJsQR ? "jsqr" : "none"), + // canScan / decoder are recomputed in open() — don't trust + // setup-time values because vendored libs may attach to + // window asynchronously after the bundle finishes parsing. + canScan: false, + decoder: "none", + statusLine: "", // visible diagnostic shown in modal }); this.stream = null; this.decodeLoopActive = false; @@ -68,9 +67,33 @@ export class QrScanner extends Component { onWillUnmount(() => this._stopCamera()); } + /** + * Check what decoder is available right now and update state. Run + * at every open() — not just setup() — because a stale bundle in + * the browser cache can flip results between page loads. + */ + _detectCapabilities() { + const hasNative = typeof BarcodeDetector !== "undefined"; + const hasJsQR = typeof window !== "undefined" && typeof window.jsQR === "function"; + this.state.canScan = hasNative || hasJsQR; + this.state.decoder = hasNative ? "native" : (hasJsQR ? "jsqr" : "none"); + // Build a one-line status the user can read in the modal so + // it's obvious whether the decoder loaded. Helps diagnose + // "nothing happens" reports without round-tripping through + // Safari Web Inspector. + this.state.statusLine = ( + "Decoder: " + this.state.decoder + + (hasNative ? " (native)" : "") + + (!hasNative && hasJsQR ? " (jsQR)" : "") + + (!this.state.canScan ? " — paste URL below" : "") + ); + } + async open() { + this._detectCapabilities(); this.state.open = true; this.state.error = null; + this.state.detected = ""; await this._startCamera(); } diff --git a/fusion_plating/fusion_plating_shopfloor/static/src/scss/qr_scanner.scss b/fusion_plating/fusion_plating_shopfloor/static/src/scss/qr_scanner.scss index 3f111a8a..fd42bfb8 100644 --- a/fusion_plating/fusion_plating_shopfloor/static/src/scss/qr_scanner.scss +++ b/fusion_plating/fusion_plating_shopfloor/static/src/scss/qr_scanner.scss @@ -66,7 +66,8 @@ .o_fp_qr_error, .o_fp_qr_warn, -.o_fp_qr_detected { +.o_fp_qr_detected, +.o_fp_qr_status { padding: $fp-space-2 $fp-space-3; border-radius: $fp-radius-sm; background: $fp-card-soft; @@ -75,6 +76,13 @@ word-break: break-all; } +.o_fp_qr_status { + border-left: 3px solid $fp-accent; + color: $fp-ink; + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; + font-size: 11px; +} + .o_fp_qr_error { border-left: 3px solid $fp-bad; } diff --git a/fusion_plating/fusion_plating_shopfloor/static/src/xml/qr_scanner.xml b/fusion_plating/fusion_plating_shopfloor/static/src/xml/qr_scanner.xml index 5a34c7e1..6ce24767 100644 --- a/fusion_plating/fusion_plating_shopfloor/static/src/xml/qr_scanner.xml +++ b/fusion_plating/fusion_plating_shopfloor/static/src/xml/qr_scanner.xml @@ -25,6 +25,10 @@
+
+ + +
Live decoding isn't supported in this browser.