feat(configurator): B5+B6 - SO line carry-through + part-default write-back on confirm
This commit is contained in:
@@ -716,6 +716,12 @@ class FpDirectOrderWizard(models.Model):
|
|||||||
'x_fc_serial_id': line.serial_id.id or False,
|
'x_fc_serial_id': line.serial_id.id or False,
|
||||||
'x_fc_job_number': line.job_number or False,
|
'x_fc_job_number': line.job_number or False,
|
||||||
'x_fc_thickness_range': line.thickness_range or False,
|
'x_fc_thickness_range': line.thickness_range or False,
|
||||||
|
# Express Orders per-line flags (2026-05-26) — carry to
|
||||||
|
# the SO line so the override-application helper can read
|
||||||
|
# them at job creation time.
|
||||||
|
'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,
|
||||||
# Sub 9 — explicit tax override from the wizard line.
|
# Sub 9 — explicit tax override from the wizard line.
|
||||||
# When blank, Odoo will compute taxes from the product
|
# When blank, Odoo will compute taxes from the product
|
||||||
# defaults at SO-line save time (the standard behaviour).
|
# defaults at SO-line save time (the standard behaviour).
|
||||||
@@ -762,6 +768,28 @@ class FpDirectOrderWizard(models.Model):
|
|||||||
continue
|
continue
|
||||||
if line.thickness_range and not part.x_fc_default_thickness_range:
|
if line.thickness_range and not part.x_fc_default_thickness_range:
|
||||||
part.x_fc_default_thickness_range = line.thickness_range
|
part.x_fc_default_thickness_range = line.thickness_range
|
||||||
|
|
||||||
|
# Express Orders part-default write-back (2026-05-26).
|
||||||
|
# Always-on (no push_to_defaults check): the spec says type-once,
|
||||||
|
# saves to part. Empty cells DON'T clobber existing defaults
|
||||||
|
# (otherwise an empty bake cell would erase a part's bake default
|
||||||
|
# — bad UX). Masking is a Boolean so always written.
|
||||||
|
for line in self.line_ids:
|
||||||
|
if line.is_one_off:
|
||||||
|
continue
|
||||||
|
part = resolved_parts.get(line.id) or line.part_catalog_id
|
||||||
|
if not part:
|
||||||
|
continue
|
||||||
|
wb_vals = {}
|
||||||
|
if line.line_description and not part.default_specification_text:
|
||||||
|
wb_vals['default_specification_text'] = line.line_description
|
||||||
|
if line.bake_instructions and not part.default_bake_instructions:
|
||||||
|
wb_vals['default_bake_instructions'] = line.bake_instructions
|
||||||
|
# Masking is always written (Boolean has no notion of empty).
|
||||||
|
if part.default_masking_enabled != line.masking_enabled:
|
||||||
|
wb_vals['default_masking_enabled'] = line.masking_enabled
|
||||||
|
if wb_vals:
|
||||||
|
part.sudo().write(wb_vals)
|
||||||
so.message_post(body=_(
|
so.message_post(body=_(
|
||||||
'Quotation created from PO %s with %d line(s). '
|
'Quotation created from PO %s with %d line(s). '
|
||||||
'Review and confirm manually when ready.'
|
'Review and confirm manually when ready.'
|
||||||
|
|||||||
Reference in New Issue
Block a user