diff --git a/fusion_plating/fusion_plating/models/fp_process_node.py b/fusion_plating/fusion_plating/models/fp_process_node.py index 0915cce2..8f877e7e 100644 --- a/fusion_plating/fusion_plating/models/fp_process_node.py +++ b/fusion_plating/fusion_plating/models/fp_process_node.py @@ -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', + )