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:
@@ -573,6 +573,14 @@ class FpDirectOrderLine(models.Model):
|
||||
help='Free-text bake instructions. Empty = bake steps are opted out. '
|
||||
'Non-empty = bake step instructions on the operator tablet.',
|
||||
)
|
||||
masking_attachment_ids = fields.Many2many(
|
||||
'ir.attachment',
|
||||
'fp_direct_order_line_masking_att_rel', 'line_id', 'attachment_id',
|
||||
string='Masking Reference(s)',
|
||||
help='Image(s)/PDF(s) of what to mask. Carried to the SO line and '
|
||||
'shown to the operator on the job\'s masking step. Only relevant '
|
||||
'when Masking is enabled.',
|
||||
)
|
||||
|
||||
# ---- Computes ----
|
||||
@api.depends('quantity', 'unit_price')
|
||||
@@ -766,6 +774,29 @@ class FpDirectOrderLine(models.Model):
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
def action_upload_masking_ref(self):
|
||||
"""Attach a masking reference (image/PDF) to this line.
|
||||
|
||||
Called by the Express 'MASK REF' button — once per file (multi-select
|
||||
loops in JS), via context keys fp_masking_file + fp_masking_filename.
|
||||
Stored on the line's masking_attachment_ids; carried to the SO line
|
||||
and the job's masking step at order confirm.
|
||||
"""
|
||||
self.ensure_one()
|
||||
from odoo.exceptions import UserError
|
||||
file_data = self.env.context.get('fp_masking_file')
|
||||
filename = self.env.context.get('fp_masking_filename', 'masking-ref')
|
||||
if not file_data:
|
||||
raise UserError(_('No file data received.'))
|
||||
att = self.env['ir.attachment'].sudo().create({
|
||||
'name': filename,
|
||||
'datas': file_data,
|
||||
'res_model': 'fp.direct.order.line',
|
||||
'res_id': self.id,
|
||||
})
|
||||
self.write({'masking_attachment_ids': [(4, att.id)]})
|
||||
return True
|
||||
|
||||
def action_upload_drawing(self):
|
||||
"""Attach a file (via context) to the line's part as a drawing.
|
||||
|
||||
|
||||
@@ -956,6 +956,7 @@ class FpDirectOrderWizard(models.Model):
|
||||
'x_fc_customer_line_ref': line.customer_line_ref or False,
|
||||
'x_fc_masking_enabled': line.masking_enabled,
|
||||
'x_fc_bake_instructions': line.bake_instructions or False,
|
||||
'x_fc_masking_attachment_ids': [(6, 0, line.masking_attachment_ids.ids)],
|
||||
# Sub 9 — explicit tax override from the wizard line.
|
||||
# When blank, Odoo will compute taxes from the product
|
||||
# defaults at SO-line save time (the standard behaviour).
|
||||
|
||||
Reference in New Issue
Block a user