Revert "feat(jobs): step sequences are 1, 2, 3, ... not 10, 20, 30, ..."
This reverts commit 32d48ea44d.
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
'name': 'Fusion Plating',
|
'name': 'Fusion Plating',
|
||||||
'version': '19.0.18.12.1',
|
'version': '19.0.18.12.2',
|
||||||
'category': 'Manufacturing/Plating',
|
'category': 'Manufacturing/Plating',
|
||||||
'summary': 'Core plating / metal finishing ERP: facilities, processes, tanks, baths, jobs, operators.',
|
'summary': 'Core plating / metal finishing ERP: facilities, processes, tanks, baths, jobs, operators.',
|
||||||
'description': """
|
'description': """
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class FpRecipeController(http.Controller):
|
|||||||
'name': name,
|
'name': name,
|
||||||
'node_type': node_type,
|
'node_type': node_type,
|
||||||
'parent_id': parent.id,
|
'parent_id': parent.id,
|
||||||
'sequence': max_seq + 1,
|
'sequence': max_seq + 10,
|
||||||
}
|
}
|
||||||
if vals:
|
if vals:
|
||||||
data.update(vals)
|
data.update(vals)
|
||||||
@@ -132,7 +132,7 @@ class FpRecipeController(http.Controller):
|
|||||||
Node = request.env['fusion.plating.process.node']
|
Node = request.env['fusion.plating.process.node']
|
||||||
try:
|
try:
|
||||||
for idx, nid in enumerate(node_ids):
|
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}
|
return {'ok': True}
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
_logger.exception('Recipe reorder failed')
|
_logger.exception('Recipe reorder failed')
|
||||||
@@ -195,7 +195,7 @@ class FpRecipeController(http.Controller):
|
|||||||
if a_seq == b_seq:
|
if a_seq == b_seq:
|
||||||
# Sequences collided — renumber everyone cleanly, then swap
|
# Sequences collided — renumber everyone cleanly, then swap
|
||||||
for i, s in enumerate(siblings, 1):
|
for i, s in enumerate(siblings, 1):
|
||||||
s.sequence = i
|
s.sequence = i * 10
|
||||||
a_seq, b_seq = node.sequence, other.sequence
|
a_seq, b_seq = node.sequence, other.sequence
|
||||||
node.sequence, other.sequence = b_seq, a_seq
|
node.sequence, other.sequence = b_seq, a_seq
|
||||||
return {'ok': True}
|
return {'ok': True}
|
||||||
@@ -260,7 +260,7 @@ class FpRecipeController(http.Controller):
|
|||||||
vals['sequence'] = base_seq
|
vals['sequence'] = base_seq
|
||||||
new_node = Node.create(vals)
|
new_node = Node.create(vals)
|
||||||
for i, child in enumerate(src_node.child_ids.sorted('sequence'), 1):
|
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
|
return new_node
|
||||||
|
|
||||||
# Phase 1 — create every copied top-level child, tracking their
|
# Phase 1 — create every copied top-level child, tracking their
|
||||||
@@ -308,8 +308,8 @@ class FpRecipeController(http.Controller):
|
|||||||
+ existing_top[anchor_idx:]
|
+ existing_top[anchor_idx:]
|
||||||
)
|
)
|
||||||
for i, node in enumerate(final_order, 1):
|
for i, node in enumerate(final_order, 1):
|
||||||
if node.sequence != i:
|
if node.sequence != i * 10:
|
||||||
node.sequence = i
|
node.sequence = i * 10
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'ok': True,
|
'ok': True,
|
||||||
@@ -341,7 +341,7 @@ class FpRecipeController(http.Controller):
|
|||||||
max_seq = max((c.sequence for c in parent.child_ids), default=0)
|
max_seq = max((c.sequence for c in parent.child_ids), default=0)
|
||||||
node.write({
|
node.write({
|
||||||
'parent_id': parent.id,
|
'parent_id': parent.id,
|
||||||
'sequence': max_seq + 1,
|
'sequence': max_seq + 10,
|
||||||
})
|
})
|
||||||
return {'ok': True}
|
return {'ok': True}
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ class SimpleRecipeController(http.Controller):
|
|||||||
'template_id': tpl.id,
|
'template_id': tpl.id,
|
||||||
'name': (payload or {}).get('name') or 'New Prompt',
|
'name': (payload or {}).get('name') or 'New Prompt',
|
||||||
'input_type': (payload or {}).get('input_type') or 'text',
|
'input_type': (payload or {}).get('input_type') or 'text',
|
||||||
'sequence': existing_max + 1,
|
'sequence': existing_max + 10,
|
||||||
'required': bool((payload or {}).get('required')),
|
'required': bool((payload or {}).get('required')),
|
||||||
})
|
})
|
||||||
return {'ok': True, 'input_id': rec.id,
|
return {'ok': True, 'input_id': rec.id,
|
||||||
@@ -356,26 +356,25 @@ class SimpleRecipeController(http.Controller):
|
|||||||
return {'id': new_node.id, 'sequence': new_node.sequence}
|
return {'id': new_node.id, 'sequence': new_node.sequence}
|
||||||
|
|
||||||
def _sequence_for_position(self, recipe, position):
|
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')
|
siblings = recipe.child_ids.sorted('sequence')
|
||||||
if not siblings:
|
if not siblings:
|
||||||
return 1
|
return 10
|
||||||
pos = max(0, min(position, len(siblings)))
|
if position >= len(siblings):
|
||||||
# Make room: siblings before `pos` keep their 1-based index;
|
return siblings[-1].sequence + 10
|
||||||
# siblings at or after `pos` shift up by one so the new step
|
if position <= 0:
|
||||||
# lands at sequence (pos + 1).
|
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):
|
for idx, sib in enumerate(siblings):
|
||||||
target = idx + 1 if idx < pos else idx + 2
|
new_seq = (idx + 1) * 10
|
||||||
if sib.sequence != target:
|
if sib.sequence != new_seq:
|
||||||
sib.sequence = target
|
sib.sequence = new_seq
|
||||||
return pos + 1
|
return position * 10 + 5
|
||||||
|
|
||||||
def _copy_inputs_from_template(self, tpl, new_node):
|
def _copy_inputs_from_template(self, tpl, new_node):
|
||||||
NodeInput = request.env['fusion.plating.process.node.input']
|
NodeInput = request.env['fusion.plating.process.node.input']
|
||||||
@@ -413,7 +412,7 @@ class SimpleRecipeController(http.Controller):
|
|||||||
def step_reorder(self, node_ids):
|
def step_reorder(self, node_ids):
|
||||||
Node = request.env['fusion.plating.process.node']
|
Node = request.env['fusion.plating.process.node']
|
||||||
for i, nid in enumerate(node_ids, start=1):
|
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}
|
return {'ok': True}
|
||||||
|
|
||||||
# -------------------------------------------------------------- template
|
# -------------------------------------------------------------- template
|
||||||
@@ -522,7 +521,7 @@ class SimpleRecipeController(http.Controller):
|
|||||||
'input_type': (payload or {}).get('input_type') or 'text',
|
'input_type': (payload or {}).get('input_type') or 'text',
|
||||||
'kind': 'step_input',
|
'kind': 'step_input',
|
||||||
'collect': True,
|
'collect': True,
|
||||||
'sequence': existing_max + 1,
|
'sequence': existing_max + 10,
|
||||||
'required': bool((payload or {}).get('required')),
|
'required': bool((payload or {}).get('required')),
|
||||||
})
|
})
|
||||||
return {'ok': True, 'input_id': rec.id}
|
return {'ok': True, 'input_id': rec.id}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
"name": "Fusion Plating — MRP Bridge",
|
"name": "Fusion Plating — MRP Bridge",
|
||||||
'version': '19.0.13.0.1',
|
'version': '19.0.13.0.2',
|
||||||
'category': 'Manufacturing/Plating',
|
'category': 'Manufacturing/Plating',
|
||||||
'summary': 'Bridge Fusion Plating facilities, baths and tanks to Odoo MRP work orders.',
|
'summary': 'Bridge Fusion Plating facilities, baths and tanks to Odoo MRP work orders.',
|
||||||
'description': """
|
'description': """
|
||||||
|
|||||||
@@ -572,7 +572,7 @@ class MrpProduction(models.Model):
|
|||||||
# Walk tree and collect operation WO values
|
# Walk tree and collect operation WO values
|
||||||
wo_vals_list = []
|
wo_vals_list = []
|
||||||
wo_steps = {} # {sequence: instruction text} — posted to WO chatter after create
|
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):
|
def _is_node_included(node):
|
||||||
"""Determine if a node should be included based on opt-in/out
|
"""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)
|
wo_vals_list.append(vals)
|
||||||
if steps:
|
if steps:
|
||||||
wo_steps[seq_counter[0]] = '\n'.join(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'):
|
elif node.node_type in ('recipe', 'sub_process'):
|
||||||
# Container nodes — recurse into children
|
# Container nodes — recurse into children
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||||
{
|
{
|
||||||
'name': 'Fusion Plating — Native Jobs',
|
'name': 'Fusion Plating — Native Jobs',
|
||||||
'version': '19.0.8.17.4',
|
'version': '19.0.8.17.5',
|
||||||
'category': 'Manufacturing/Plating',
|
'category': 'Manufacturing/Plating',
|
||||||
'summary': 'Native plating job model — replaces mrp.production / mrp.workorder bridge.',
|
'summary': 'Native plating job model — replaces mrp.production / mrp.workorder bridge.',
|
||||||
'author': 'Nexa Systems Inc.',
|
'author': 'Nexa Systems Inc.',
|
||||||
|
|||||||
@@ -606,12 +606,7 @@ class FpJob(models.Model):
|
|||||||
|
|
||||||
step_vals_list = []
|
step_vals_list = []
|
||||||
wo_steps = {} # {sequence: instruction text}
|
wo_steps = {} # {sequence: instruction text}
|
||||||
# Sequences increment by 1 (operator-friendly: Step 1, 2, 3,
|
seq_counter = [10]
|
||||||
# ...) 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]
|
|
||||||
|
|
||||||
def _is_node_included(node):
|
def _is_node_included(node):
|
||||||
"""Determine if a node should be included based on
|
"""Determine if a node should be included based on
|
||||||
@@ -764,7 +759,7 @@ class FpJob(models.Model):
|
|||||||
step_vals_list.append(vals)
|
step_vals_list.append(vals)
|
||||||
if instructions:
|
if instructions:
|
||||||
wo_steps[seq_counter[0]] = '\n'.join(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'):
|
elif node.node_type in ('recipe', 'sub_process'):
|
||||||
for child in node.child_ids.sorted('sequence'):
|
for child in node.child_ids.sorted('sequence'):
|
||||||
|
|||||||
Reference in New Issue
Block a user