diff --git a/fusion_plating/fusion_plating/__manifest__.py b/fusion_plating/fusion_plating/__manifest__.py index dd796dcc..7bac50ef 100644 --- a/fusion_plating/fusion_plating/__manifest__.py +++ b/fusion_plating/fusion_plating/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Fusion Plating', - 'version': '19.0.18.12.1', + 'version': '19.0.18.12.2', 'category': 'Manufacturing/Plating', 'summary': 'Core plating / metal finishing ERP: facilities, processes, tanks, baths, jobs, operators.', 'description': """ diff --git a/fusion_plating/fusion_plating/controllers/recipe_controller.py b/fusion_plating/fusion_plating/controllers/recipe_controller.py index b69f6a56..a3f988b6 100644 --- a/fusion_plating/fusion_plating/controllers/recipe_controller.py +++ b/fusion_plating/fusion_plating/controllers/recipe_controller.py @@ -53,7 +53,7 @@ class FpRecipeController(http.Controller): 'name': name, 'node_type': node_type, 'parent_id': parent.id, - 'sequence': max_seq + 1, + 'sequence': max_seq + 10, } if vals: data.update(vals) @@ -132,7 +132,7 @@ class FpRecipeController(http.Controller): Node = request.env['fusion.plating.process.node'] try: for idx, nid in enumerate(node_ids): - Node.browse(int(nid)).write({'sequence': idx + 1}) + Node.browse(int(nid)).write({'sequence': (idx + 1) * 10}) return {'ok': True} except Exception as exc: _logger.exception('Recipe reorder failed') @@ -195,7 +195,7 @@ class FpRecipeController(http.Controller): if a_seq == b_seq: # Sequences collided — renumber everyone cleanly, then swap for i, s in enumerate(siblings, 1): - s.sequence = i + s.sequence = i * 10 a_seq, b_seq = node.sequence, other.sequence node.sequence, other.sequence = b_seq, a_seq return {'ok': True} @@ -260,7 +260,7 @@ class FpRecipeController(http.Controller): vals['sequence'] = base_seq new_node = Node.create(vals) for i, child in enumerate(src_node.child_ids.sorted('sequence'), 1): - _copy_subtree(child, new_node, i) + _copy_subtree(child, new_node, i * 10) return new_node # Phase 1 — create every copied top-level child, tracking their @@ -308,8 +308,8 @@ class FpRecipeController(http.Controller): + existing_top[anchor_idx:] ) for i, node in enumerate(final_order, 1): - if node.sequence != i: - node.sequence = i + if node.sequence != i * 10: + node.sequence = i * 10 return { 'ok': True, @@ -341,7 +341,7 @@ class FpRecipeController(http.Controller): max_seq = max((c.sequence for c in parent.child_ids), default=0) node.write({ 'parent_id': parent.id, - 'sequence': max_seq + 1, + 'sequence': max_seq + 10, }) return {'ok': True} except Exception as exc: diff --git a/fusion_plating/fusion_plating/controllers/simple_recipe_controller.py b/fusion_plating/fusion_plating/controllers/simple_recipe_controller.py index de11edb2..f6c3f1b6 100644 --- a/fusion_plating/fusion_plating/controllers/simple_recipe_controller.py +++ b/fusion_plating/fusion_plating/controllers/simple_recipe_controller.py @@ -271,7 +271,7 @@ class SimpleRecipeController(http.Controller): 'template_id': tpl.id, 'name': (payload or {}).get('name') or 'New Prompt', 'input_type': (payload or {}).get('input_type') or 'text', - 'sequence': existing_max + 1, + 'sequence': existing_max + 10, 'required': bool((payload or {}).get('required')), }) return {'ok': True, 'input_id': rec.id, @@ -356,26 +356,25 @@ class SimpleRecipeController(http.Controller): return {'id': new_node.id, 'sequence': new_node.sequence} def _sequence_for_position(self, recipe, position): - """Return the sequence value for a NEW step inserted at - `position` among the recipe's existing children. - - Always renumbers existing siblings so the result is contiguous - 1, 2, 3, ... matching what the operator sees on the work order. - (Pre-Sub 13c we used 10-spacing to allow midpoint inserts — - operators kept asking why their first step said "Step 10".) - """ siblings = recipe.child_ids.sorted('sequence') if not siblings: - return 1 - pos = max(0, min(position, len(siblings))) - # Make room: siblings before `pos` keep their 1-based index; - # siblings at or after `pos` shift up by one so the new step - # lands at sequence (pos + 1). + return 10 + if position >= len(siblings): + return siblings[-1].sequence + 10 + if position <= 0: + return max(1, siblings[0].sequence - 10) + before = siblings[position - 1].sequence + after = siblings[position].sequence + if after - before > 1: + return (before + after) // 2 + # Sequences are tightly packed (gap == 1 → midpoint == after, + # which collides). Renumber siblings to 10/20/30… first, then + # the new step lands cleanly between renumbered neighbours. for idx, sib in enumerate(siblings): - target = idx + 1 if idx < pos else idx + 2 - if sib.sequence != target: - sib.sequence = target - return pos + 1 + new_seq = (idx + 1) * 10 + if sib.sequence != new_seq: + sib.sequence = new_seq + return position * 10 + 5 def _copy_inputs_from_template(self, tpl, new_node): NodeInput = request.env['fusion.plating.process.node.input'] @@ -413,7 +412,7 @@ class SimpleRecipeController(http.Controller): def step_reorder(self, node_ids): Node = request.env['fusion.plating.process.node'] for i, nid in enumerate(node_ids, start=1): - Node.browse(nid).write({'sequence': i}) + Node.browse(nid).write({'sequence': i * 10}) return {'ok': True} # -------------------------------------------------------------- template @@ -522,7 +521,7 @@ class SimpleRecipeController(http.Controller): 'input_type': (payload or {}).get('input_type') or 'text', 'kind': 'step_input', 'collect': True, - 'sequence': existing_max + 1, + 'sequence': existing_max + 10, 'required': bool((payload or {}).get('required')), }) return {'ok': True, 'input_id': rec.id} diff --git a/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py b/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py index cd82356a..2688ce75 100644 --- a/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py +++ b/fusion_plating/fusion_plating_bridge_mrp/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Fusion Plating — MRP Bridge", - 'version': '19.0.13.0.1', + 'version': '19.0.13.0.2', 'category': 'Manufacturing/Plating', 'summary': 'Bridge Fusion Plating facilities, baths and tanks to Odoo MRP work orders.', 'description': """ diff --git a/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py b/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py index 7416d3b3..adfb9d66 100644 --- a/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py +++ b/fusion_plating/fusion_plating_bridge_mrp/models/mrp_production.py @@ -572,7 +572,7 @@ class MrpProduction(models.Model): # Walk tree and collect operation WO values wo_vals_list = [] wo_steps = {} # {sequence: instruction text} — posted to WO chatter after create - seq_counter = [1] # mutable for closure, increments by 1 + seq_counter = [10] # mutable for closure, increments by 10 def _is_node_included(node): """Determine if a node should be included based on opt-in/out @@ -695,7 +695,7 @@ class MrpProduction(models.Model): wo_vals_list.append(vals) if steps: wo_steps[seq_counter[0]] = '\n'.join(steps) - seq_counter[0] += 1 + seq_counter[0] += 10 elif node.node_type in ('recipe', 'sub_process'): # Container nodes — recurse into children diff --git a/fusion_plating/fusion_plating_jobs/__manifest__.py b/fusion_plating/fusion_plating_jobs/__manifest__.py index 8144a01e..81111cdd 100644 --- a/fusion_plating/fusion_plating_jobs/__manifest__.py +++ b/fusion_plating/fusion_plating_jobs/__manifest__.py @@ -3,7 +3,7 @@ # License OPL-1 (Odoo Proprietary License v1.0) { 'name': 'Fusion Plating — Native Jobs', - 'version': '19.0.8.17.4', + 'version': '19.0.8.17.5', 'category': 'Manufacturing/Plating', 'summary': 'Native plating job model — replaces mrp.production / mrp.workorder bridge.', 'author': 'Nexa Systems Inc.', diff --git a/fusion_plating/fusion_plating_jobs/models/fp_job.py b/fusion_plating/fusion_plating_jobs/models/fp_job.py index 61d56041..3e72606a 100644 --- a/fusion_plating/fusion_plating_jobs/models/fp_job.py +++ b/fusion_plating/fusion_plating_jobs/models/fp_job.py @@ -606,12 +606,7 @@ class FpJob(models.Model): step_vals_list = [] wo_steps = {} # {sequence: instruction text} - # Sequences increment by 1 (operator-friendly: Step 1, 2, 3, - # ...) instead of the legacy 10/20/30 spacing. The 10-spacing - # was originally there to allow midpoint inserts, but - # operators kept asking why their work order said "Step 10" - # for the first row. - seq_counter = [1] + seq_counter = [10] def _is_node_included(node): """Determine if a node should be included based on @@ -764,7 +759,7 @@ class FpJob(models.Model): step_vals_list.append(vals) if instructions: wo_steps[seq_counter[0]] = '\n'.join(instructions) - seq_counter[0] += 1 + seq_counter[0] += 10 elif node.node_type in ('recipe', 'sub_process'): for child in node.child_ids.sorted('sequence'):