feat(sub12a): extend process.node + process.node.input
process.node — additive only: is_template, source_template_id, tank_ids (M2M to fusion.plating.tank with new join table fp_node_tank_rel), material_callout, time/temp targets + units, voltage_target, viscosity_target, requires_rack_assignment, requires_transition_form, default_kind, preferred_editor. process.node.input — additive only: kind (step_input/transition_input, default step_input so existing rows keep working), target_min/target_max/target_unit, compliance_tag, plus 9 new typed input_type values (time_hms, time_seconds, temperature, thickness, pass_fail, date, signature, location_picker, customer_wo). No removed fields, no removed selection values. Tree editor + every existing battle test (S14/S15/S17/S18/S19) untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -284,6 +284,88 @@ class FpProcessNode(models.Model):
|
||||
string='Operator Inputs',
|
||||
)
|
||||
|
||||
# ===== Sub 12a — Simple Editor + Step Library extensions =================
|
||||
# All fields are additive; tree editor + runtime are unaffected. Drag-drop
|
||||
# from the library snapshot-copies these into a new node (no live ref).
|
||||
|
||||
is_template = fields.Boolean(
|
||||
string='Use as Starter Template',
|
||||
help='When True (and node_type=recipe), this recipe appears in the '
|
||||
'Simple Editor\'s "Import starter from template" dropdown.',
|
||||
)
|
||||
source_template_id = fields.Many2one(
|
||||
'fp.step.template',
|
||||
string='Source Library Template',
|
||||
ondelete='set null',
|
||||
index=True,
|
||||
help='Snapshot trace — set when this node was created by dragging '
|
||||
'a library step in. Editing the template later does not change '
|
||||
'this node (snapshot semantics).',
|
||||
)
|
||||
tank_ids = fields.Many2many(
|
||||
'fusion.plating.tank',
|
||||
'fp_node_tank_rel', 'node_id', 'tank_id',
|
||||
string='Allowed Stations',
|
||||
help='Stations the operator may pick at runtime.',
|
||||
)
|
||||
material_callout = fields.Char(
|
||||
string='Material Callout',
|
||||
help='Short string for traveller "Material" column. Defaults to '
|
||||
'process type name if blank.',
|
||||
)
|
||||
time_min_target = fields.Float(string='Time Min')
|
||||
time_max_target = fields.Float(string='Time Max')
|
||||
time_unit = fields.Selection(
|
||||
[('sec', 'Seconds'), ('min', 'Minutes'), ('hr', 'Hours')],
|
||||
string='Time Unit', default='min',
|
||||
)
|
||||
temp_min_target = fields.Float(string='Temp Min')
|
||||
temp_max_target = fields.Float(string='Temp Max')
|
||||
temp_unit = fields.Selection(
|
||||
[('F', '°F'), ('C', '°C')],
|
||||
string='Temp Unit', default='F',
|
||||
)
|
||||
voltage_target = fields.Float(string='Voltage Target')
|
||||
viscosity_target = fields.Float(string='Viscosity Target')
|
||||
requires_rack_assignment = fields.Boolean(
|
||||
string='Requires Rack Assignment',
|
||||
help='Sub 12b — triggers Rack Parts sub-dialog at runtime.',
|
||||
)
|
||||
requires_transition_form = fields.Boolean(
|
||||
string='Requires Transition Form',
|
||||
help='Sub 12b — opens the transition form before Mark Done.',
|
||||
)
|
||||
default_kind = fields.Selection(
|
||||
[
|
||||
('cleaning', 'Cleaning'),
|
||||
('etch', 'Etch'),
|
||||
('rinse', 'Rinse'),
|
||||
('plate', 'Plating'),
|
||||
('bake', 'Bake'),
|
||||
('inspect', 'Inspection'),
|
||||
('racking', 'Racking'),
|
||||
('derack', 'De-Racking'),
|
||||
('mask', 'Masking'),
|
||||
('demask', 'De-Masking'),
|
||||
('dry', 'Drying'),
|
||||
('wbf_test', 'Water Break Free Test'),
|
||||
('final_inspect', 'Final Inspection'),
|
||||
('ship', 'Shipping'),
|
||||
('gating', 'Gating'),
|
||||
],
|
||||
string='Step Kind',
|
||||
)
|
||||
preferred_editor = fields.Selection(
|
||||
[
|
||||
('tree', 'Tree Editor'),
|
||||
('simple', 'Simple Editor'),
|
||||
('auto', 'Use Company Default'),
|
||||
],
|
||||
string='Preferred Editor', default='auto',
|
||||
help='Which editor opens when this recipe is selected from the '
|
||||
'menu list. "Auto" follows the company-level default.',
|
||||
)
|
||||
|
||||
# ---- SQL constraints -----------------------------------------------------
|
||||
|
||||
_sql_constraints = [
|
||||
@@ -504,6 +586,16 @@ class FpProcessNodeInput(models.Model):
|
||||
('boolean', 'Yes / No'),
|
||||
('selection', 'Selection'),
|
||||
('photo', 'Photo'),
|
||||
# Sub 12a — typed inputs the simple editor + traveller need
|
||||
('time_hms', 'Time (HH:MM:SS)'),
|
||||
('time_seconds', 'Time (seconds)'),
|
||||
('temperature', 'Temperature'),
|
||||
('thickness', 'Thickness'),
|
||||
('pass_fail', 'Pass / Fail'),
|
||||
('date', 'Date / Time'),
|
||||
('signature', 'Signature'),
|
||||
('location_picker', 'Location Picker'),
|
||||
('customer_wo', 'Customer WO #'),
|
||||
],
|
||||
string='Input Type',
|
||||
required=True,
|
||||
@@ -529,3 +621,28 @@ class FpProcessNodeInput(models.Model):
|
||||
string='Unit',
|
||||
help='Unit label (e.g. °C, min, psi).',
|
||||
)
|
||||
|
||||
# ===== Sub 12a — kind + target ranges + compliance tag ==================
|
||||
kind = fields.Selection(
|
||||
[
|
||||
('step_input', 'Step Measurement'),
|
||||
('transition_input', 'Transition Form Field'),
|
||||
],
|
||||
string='Kind', default='step_input', index=True,
|
||||
help='step_input = recorded during the step. transition_input = '
|
||||
'recorded when leaving the step (Sub 12b uses these in the '
|
||||
'Move Parts dialog).',
|
||||
)
|
||||
target_min = fields.Float(string='Target Min')
|
||||
target_max = fields.Float(string='Target Max')
|
||||
target_unit = fields.Char(string='Target Unit')
|
||||
compliance_tag = fields.Selection(
|
||||
[
|
||||
('none', 'None'),
|
||||
('as9100', 'AS9100'),
|
||||
('nadcap', 'Nadcap'),
|
||||
('cgp', 'Controlled Goods'),
|
||||
('nuclear', 'Nuclear'),
|
||||
],
|
||||
string='Compliance Tag', default='none',
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user