feat(configurator): Phase C polish — to-node picker, WO description, one-off flag
C1: start_at_node_id per wizard line, mirrors to x_fc_start_at_node_id on sale.order.line. Domain filters to nodes descending from the coating_config's recipe so the estimator only picks valid resume points. bridge_mrp will use this in a follow-up to skip ancestor steps in the generated work order. C2: part_wo_description (separate from customer-facing line_description) lets the planner add internal-only notes that appear on the travelling sheet only. Mirrors to x_fc_part_wo_description on sale.order.line. C5: is_one_off flag for prototype / non-catalog parts. Mirrors to x_fc_is_one_off. Actual skip-catalog behaviour will be wired in a later pass. All three fields appear in the wizard line drill-in form (under a new "Work Order (internal)" group) and as togglable columns on the sale.order.line tree. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,3 +25,19 @@ class SaleOrderLine(models.Model):
|
|||||||
help='Lines sharing a tag (e.g. "WO#1") will be batched into one '
|
help='Lines sharing a tag (e.g. "WO#1") will be batched into one '
|
||||||
'manufacturing order when bridge_mrp generates MOs.',
|
'manufacturing order when bridge_mrp generates MOs.',
|
||||||
)
|
)
|
||||||
|
x_fc_part_wo_description = fields.Text(
|
||||||
|
string='On Work Order',
|
||||||
|
help='Extra detail printed on the work order travelling sheet. '
|
||||||
|
'Separate from the customer-facing line description.',
|
||||||
|
)
|
||||||
|
x_fc_start_at_node_id = fields.Many2one(
|
||||||
|
'fusion.plating.process.node',
|
||||||
|
string='Start at Node',
|
||||||
|
help='For re-work jobs: pick the recipe step where this job '
|
||||||
|
'should begin. bridge_mrp skips ancestor steps.',
|
||||||
|
)
|
||||||
|
x_fc_is_one_off = fields.Boolean(
|
||||||
|
string='One-off Part',
|
||||||
|
help='Flag for prototype / non-catalog parts that should not be '
|
||||||
|
'reused after this order.',
|
||||||
|
)
|
||||||
|
|||||||
@@ -101,6 +101,8 @@
|
|||||||
<field name="x_fc_treatment_ids" widget="many2many_tags" optional="hide"/>
|
<field name="x_fc_treatment_ids" widget="many2many_tags" optional="hide"/>
|
||||||
<field name="x_fc_part_deadline" optional="hide"/>
|
<field name="x_fc_part_deadline" optional="hide"/>
|
||||||
<field name="x_fc_wo_group_tag" optional="hide"/>
|
<field name="x_fc_wo_group_tag" optional="hide"/>
|
||||||
|
<field name="x_fc_start_at_node_id" optional="hide"/>
|
||||||
|
<field name="x_fc_is_one_off" optional="hide"/>
|
||||||
<field name="x_fc_rush_order" optional="hide"/>
|
<field name="x_fc_rush_order" optional="hide"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
|
|||||||
@@ -85,6 +85,25 @@ class FpDirectOrderLine(models.TransientModel):
|
|||||||
'will be batched into one manufacturing order.',
|
'will be batched into one manufacturing order.',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# ---- Phase C: polish ----
|
||||||
|
part_wo_description = fields.Text(
|
||||||
|
string='On Work Order',
|
||||||
|
help='Extra detail printed on the work order travelling sheet. '
|
||||||
|
'Kept separate from the customer-facing description.',
|
||||||
|
)
|
||||||
|
start_at_node_id = fields.Many2one(
|
||||||
|
'fusion.plating.process.node',
|
||||||
|
string='Start at Node',
|
||||||
|
domain="[('parent_id', 'child_of', coating_config_id and coating_config_id.recipe_id.id)]",
|
||||||
|
help='For re-work jobs: pick the recipe step where this job should '
|
||||||
|
'begin. Skips ancestor steps in the generated work order.',
|
||||||
|
)
|
||||||
|
is_one_off = fields.Boolean(
|
||||||
|
string='One-off Part',
|
||||||
|
help='Do not save this as a reusable part in the catalog after the '
|
||||||
|
'order is created. Useful for quote-only or prototype parts.',
|
||||||
|
)
|
||||||
|
|
||||||
# ---- Description ----
|
# ---- Description ----
|
||||||
description_template_id = fields.Many2one(
|
description_template_id = fields.Many2one(
|
||||||
'fp.sale.description.template',
|
'fp.sale.description.template',
|
||||||
|
|||||||
@@ -243,6 +243,9 @@ class FpDirectOrderWizard(models.TransientModel):
|
|||||||
'x_fc_part_deadline': line.part_deadline,
|
'x_fc_part_deadline': line.part_deadline,
|
||||||
'x_fc_rush_order': line.rush_order,
|
'x_fc_rush_order': line.rush_order,
|
||||||
'x_fc_wo_group_tag': line.wo_group_tag or False,
|
'x_fc_wo_group_tag': line.wo_group_tag or False,
|
||||||
|
'x_fc_part_wo_description': line.part_wo_description or False,
|
||||||
|
'x_fc_start_at_node_id': line.start_at_node_id.id or False,
|
||||||
|
'x_fc_is_one_off': line.is_one_off,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
# 5. Create + confirm
|
# 5. Create + confirm
|
||||||
|
|||||||
@@ -149,6 +149,14 @@
|
|||||||
nolabel="1" colspan="2"
|
nolabel="1" colspan="2"
|
||||||
placeholder="Pick a template above, then tweak the text here."/>
|
placeholder="Pick a template above, then tweak the text here."/>
|
||||||
</group>
|
</group>
|
||||||
|
<group string="Work Order (internal)">
|
||||||
|
<field name="part_wo_description"
|
||||||
|
nolabel="1" colspan="2"
|
||||||
|
placeholder="Extra detail for the travelling sheet. Not shown to the customer."/>
|
||||||
|
<field name="start_at_node_id"
|
||||||
|
options="{'no_create': True}"/>
|
||||||
|
<field name="is_one_off"/>
|
||||||
|
</group>
|
||||||
</form>
|
</form>
|
||||||
</field>
|
</field>
|
||||||
<group class="mt-3">
|
<group class="mt-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user