feat(reports): MO-bound WO sticker + polished professional layout
User reported two issues with the sticker:
1. "Print → WO Box Sticker" didn't appear on the MO form
(WH/MO/00067). The operator workflow lives on the MO form, not
the WO — binding only to mrp.workorder meant they couldn't see
the option. Now bound to BOTH:
* mrp.workorder (per-WO sticker)
* mrp.production (per-MO sticker — prints the MO friendly
name after "WO #" so it reads naturally in shop-floor
vocabulary)
Internal refactor: factored the layout into a shared inner
template report_fp_wo_sticker_inner; the two outer templates
normalise their input to the same _order_id / _scan_id / _mo
variables and t-call the inner.
2. Design polish. The previous layout was a plain label/value
table that looked rough. Redesigned with:
* Proper sticker chrome: 0.5mm black border, 1.5mm rounded
corners, edge padding.
* Header row with bottom border rule separating logo+WO-# on
the left from QR+caption on the right.
* Grid rows now alternate white / #f4f5f7 zebra-striping with
a right-aligned vertical rule between label and value.
* ALL-CAPS, letter-spaced, gray-333 labels at 7.5pt; values
at 8.5pt with strong (9.5pt, 700) emphasis on the key data
(PO, Part Number, Qty) so it reads at a glance from across
the warehouse.
* Helvetica Neue font stack.
* "SCAN TO OPEN" caption under the QR.
Scan endpoint updated: /fp/wo/<id> now tries mrp.production first
(operator home form) then falls back to mrp.workorder. Numeric
collisions between the two id spaces are possible; MO wins because
the MO view carries the full context.
fusion_plating_reports → 19.0.7.1.0
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,19 +20,27 @@ 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 WO sticker to the work-order form.
|
||||
"""Redirect a scanned sticker to the right backend form.
|
||||
|
||||
Uses Odoo 17+/19's action-URL format so the backend opens
|
||||
directly on the WO's form view. Falls back to a generic
|
||||
not-found URL if the id doesn't resolve.
|
||||
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.
|
||||
"""
|
||||
wo = request.env['mrp.workorder'].sudo().browse(wo_id).exists()
|
||||
if not wo:
|
||||
# Land on the list of all WOs so staff can search manually.
|
||||
return request.redirect('/odoo/manufacturing/work-orders')
|
||||
# /odoo/action-<xmlid>/<id> opens the record's form view.
|
||||
# Using the vanilla MRP action here so it works regardless of
|
||||
# whether the user has Plating-specific menus.
|
||||
return request.redirect(
|
||||
'/odoo/action-mrp.action_mrp_workorder/%d' % wo.id
|
||||
)
|
||||
MO = request.env['mrp.production'].sudo()
|
||||
WO = request.env['mrp.workorder'].sudo()
|
||||
|
||||
mo = MO.browse(wo_id).exists()
|
||||
if mo:
|
||||
return request.redirect(
|
||||
'/odoo/action-mrp.mrp_production_action/%d' % mo.id
|
||||
)
|
||||
|
||||
wo = WO.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.
|
||||
return request.redirect('/odoo/manufacturing/work-orders')
|
||||
|
||||
Reference in New Issue
Block a user