Files
Odoo-Modules/fusion_plating/fusion_plating_quality/scripts/bt_s14_verify.py
gsinghpal f08f328688 changes
2026-04-27 00:11:18 -04:00

92 lines
3.2 KiB
Python

# Verify predecessor enforcement
from odoo import fields
W = env['fp.direct.order.wizard']
Line = env['fp.direct.order.line']
P = env['res.partner']
Part = env['fp.part.catalog']
target = P.browse(2529)
part = Part.search([('x_fc_default_coating_config_id', '!=', False)], limit=1)
w = W.create({
'partner_id': target.id, 'po_pending': True,
'po_number': 'PO-S14V-' + fields.Datetime.now().strftime('%H%M%S'),
'invoice_strategy': 'net_terms',
})
w._onchange_partner_id()
Line.create({
'wizard_id': w.id, 'part_catalog_id': part.id,
'coating_config_id': part.x_fc_default_coating_config_id.id,
'quantity': 5, 'unit_price': 20.0,
})
r = w.action_create_order()
so = env['sale.order'].browse(r['res_id'])
so.action_confirm()
job = env['fp.job'].search([('sale_order_id', '=', so.id)], limit=1)
# Find plating step + flag its recipe node as serial-required
plating = job.step_ids.filtered(lambda s: 'plating' in (s.name or '').lower())[:1]
if plating and plating.recipe_node_id:
plating.recipe_node_id.requires_predecessor_done = True
print(f' Recipe author flagged "{plating.name}" requires_predecessor_done')
plating.invalidate_recordset()
print(f' Step picks it up via related: {plating.requires_predecessor_done}')
# Try to start plating with earlier steps still ready
print()
print(f' [Operator] Tries to start plating WITHOUT finishing earlier steps:')
try:
plating.button_start()
print(f' ❌ Allowed early start! state={plating.state}')
except Exception as e:
print(f' ✓ Blocked: {str(e)[:200]}')
# Walk earlier steps to done
print()
print(f' [Operator] Walks earlier steps to done:')
for s in job.step_ids.sorted('sequence'):
if s == plating:
break
if s.state in ('pending', 'ready'):
s.button_start()
if s.state == 'in_progress':
s.button_finish()
print(f' Earlier steps now: {set(job.step_ids.filtered(lambda x: x.sequence < plating.sequence).mapped("state"))}')
# Try plating again
print()
print(f' [Operator] Tries plating again after earlier steps done:')
try:
plating.button_start()
print(f' ✓ Allowed: state={plating.state}')
except Exception as e:
print(f' ❌ Still blocked: {e}')
# Test manager bypass via context
print()
print(f' Test manager bypass on a fresh job:')
w2 = W.create({
'partner_id': target.id, 'po_pending': True,
'po_number': 'PO-S14B-' + fields.Datetime.now().strftime('%H%M%S'),
'invoice_strategy': 'net_terms',
})
w2._onchange_partner_id()
Line.create({
'wizard_id': w2.id, 'part_catalog_id': part.id,
'coating_config_id': part.x_fc_default_coating_config_id.id,
'quantity': 5, 'unit_price': 20.0,
})
r2 = w2.action_create_order()
so2 = env['sale.order'].browse(r2['res_id'])
so2.action_confirm()
job2 = env['fp.job'].search([('sale_order_id', '=', so2.id)], limit=1)
plating2 = job2.step_ids.filtered(lambda s: 'plating' in (s.name or '').lower())[:1]
# (the recipe_node already has requires_predecessor_done=True from earlier write)
print(f' Plating step requires_predecessor_done: {plating2.requires_predecessor_done}')
try:
plating2.with_context(fp_skip_predecessor_check=True).button_start()
print(f' ✓ Manager bypass: state={plating2.state}')
except Exception as e:
print(f' ❌ Bypass failed: {e}')
env.cr.commit()