feat(configurator): SO-line template picker + dual descriptions + onchange (Sub 2 Task 15)

Surfaces the per-part description template on the SO line list alongside
a hidden-by-default internal description column. Picking a template
fires an onchange that copies `customer_facing_description` into Odoo's
standard `name` (customer-visible) and `internal_description` into
x_fc_internal_description (shop-floor / WO only). Estimator can edit
either field after the template is applied.

The template picker's domain filters by the line's part, and the field
stays hidden until a part is chosen — avoids showing every global
template when the line is blank.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-21 22:49:49 -04:00
parent d1c855698a
commit a659eba8f5
2 changed files with 25 additions and 1 deletions

View File

@@ -3,7 +3,7 @@
# License OPL-1 (Odoo Proprietary License v1.0)
# Part of the Fusion Plating product family.
from odoo import fields, models
from odoo import api, fields, models
class SaleOrderLine(models.Model):
@@ -66,6 +66,22 @@ class SaleOrderLine(models.Model):
'preserved for audit. Useful when a part is cancelled mid-order.',
)
@api.onchange('x_fc_description_template_id')
def _onchange_description_template(self):
"""When estimator picks a template, auto-fill both descriptions.
The customer-facing text goes into `name` (Odoo's line description,
prints on customer docs). The internal text goes into
x_fc_internal_description (prints on WO / traveler only).
Estimator can edit either field after the template is applied.
"""
if self.x_fc_description_template_id:
tpl = self.x_fc_description_template_id
if tpl.customer_facing_description:
self.name = tpl.customer_facing_description
if tpl.internal_description:
self.x_fc_internal_description = tpl.internal_description
def action_archive_line(self):
self.write({'x_fc_archived': True})
return True