feat(fusion_plating): Express masking reference images → mask step + workstation viewer

Order-entry shortcut: when masking is toggled ON for an Express order line,
an amber "MASK" button appears to attach reference image(s)/PDF(s). The files
ride the existing _fp_apply_express_overrides_to_job path onto the job's
masking step, so the operator sees exactly what to mask — no recipe edit or
custom prompt needed.

- configurator: masking_attachment_ids on the wizard line + SO line;
  action_upload_masking_ref; override branch writes refs onto mask steps;
  amber multi-file MASK button (express_action_btns) shown when masking is on.
- jobs: x_fc_masking_attachment_ids on fp.job.step (per-step) + computed
  rollup on fp.job; office "Masking Refs" form page (readonly preview).
- shopfloor: workspace step payload carries masking_refs (sudo'd attachment
  read, rule 13m); operator sees thumbnail/PDF tiles on the mask step that
  open in Odoo's full-screen FileViewer (zoom + swipe).

Verified end-to-end on entech: SO-line refs land on the mask step + job
rollup (WO-30091); payload mask_refs shape correct (is_image, /web/image).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-06-03 15:12:18 -04:00
parent b52b8758a1
commit 235c8fba39
16 changed files with 331 additions and 2 deletions

View File

@@ -68,6 +68,18 @@ class FpWorkspaceController(http.Controller):
override = job.override_ids.filtered(
lambda o, n=step.recipe_node_id: o.node_id.id == n.id
) if 'override_ids' in job._fields else env['fp.job.node.override']
# Masking reference image(s)/PDF(s) attached at Express order entry.
# sudo: low-priv operators can read fp.job.step but not always the
# linked ir.attachment (rule 13m). The files are safe to surface.
mask_atts = (step.sudo().x_fc_masking_attachment_ids
if 'x_fc_masking_attachment_ids' in step._fields
else env['ir.attachment'])
mask_refs = [{
'id': a.id,
'name': a.name or '',
'mimetype': a.mimetype or '',
'is_image': (a.mimetype or '').startswith('image/'),
} for a in mask_atts]
steps.append({
'id': step.id,
'sequence': step.sequence,
@@ -109,6 +121,7 @@ class FpWorkspaceController(http.Controller):
'quick_look_prompt_count': len(
getattr(step, 'quick_look_prompt_ids', step.browse())
),
'masking_refs': mask_refs,
})
# ---- Spec + attachments + chatter -------------------------------