104 lines
3.5 KiB
Python
104 lines
3.5 KiB
Python
# Step 6 — Lisa walks the QC checklist for a customer that requires QC.
|
|
# Test:
|
|
# A) Customer requires QC but no template configured → spawn fails gracefully?
|
|
# B) Customer requires QC + template configured → check auto-spawns on confirm
|
|
# C) Lisa walks the checklist, marks lines, action_pass
|
|
# D) Job mark_done now lets through
|
|
|
|
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']
|
|
Tpl = env['fp.qc.checklist.template']
|
|
TplLine = env['fp.qc.checklist.template.line']
|
|
QC = env['fusion.plating.quality.check']
|
|
|
|
# Find or create a QC template (default, no partner_id) for the test.
|
|
default_tpl = Tpl.search([('partner_id', '=', False), ('active', '=', True)], limit=1)
|
|
if not default_tpl:
|
|
default_tpl = Tpl.create({
|
|
'name': 'Default QC Template (E2E)',
|
|
'active': True,
|
|
})
|
|
TplLine.create({'template_id': default_tpl.id, 'sequence': 10, 'name': 'Visual inspection — appearance'})
|
|
TplLine.create({'template_id': default_tpl.id, 'sequence': 20, 'name': 'Thickness measurement (Fischerscope)'})
|
|
TplLine.create({'template_id': default_tpl.id, 'sequence': 30, 'name': 'Tape adhesion test'})
|
|
print(f'[setup] Created default QC template: {default_tpl.name} ({len(default_tpl.line_ids)} lines)')
|
|
else:
|
|
print(f'[setup] Using existing default QC template: {default_tpl.name}')
|
|
|
|
# Mark our test customer as requires_qc.
|
|
target = P.browse(2529)
|
|
target.x_fc_requires_qc = True
|
|
print(f'[setup] Set {target.display_name}.x_fc_requires_qc = True')
|
|
|
|
# Build a fresh SO + job for QC test.
|
|
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-STEP6-001',
|
|
'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)
|
|
print(f'[Sarah] Confirmed SO {so.name} → job {job.name}')
|
|
|
|
# Did QC auto-spawn?
|
|
qcs = QC.search([('job_id', '=', job.id)])
|
|
print(f'[Lisa] QC checks auto-spawned: {len(qcs)}')
|
|
for qc in qcs:
|
|
print(f' {qc.name}: state={qc.state}, lines={len(qc.line_ids)}, partner_id={qc.partner_id.name}')
|
|
|
|
if not qcs:
|
|
print(' ❌ Customer requires QC but no check spawned!')
|
|
raise SystemExit
|
|
|
|
qc = qcs[0]
|
|
|
|
# Lisa walks every checklist line.
|
|
print()
|
|
print('[Lisa] Walks the checklist:')
|
|
for ln in qc.line_ids.sorted('sequence'):
|
|
print(f' - {ln.name}: result before={ln.result}')
|
|
ln.result = 'pass'
|
|
ln.notes = 'OK on inspection'
|
|
|
|
# Try to action_pass.
|
|
print()
|
|
print('[Lisa] Clicks "Pass":')
|
|
try:
|
|
qc.action_pass()
|
|
print(f' ✓ QC state={qc.state}, overall_result={qc.overall_result}')
|
|
except Exception as e:
|
|
print(f' ❌ {e}')
|
|
|
|
# Now job mark_done should work (steps need to be walked first).
|
|
print()
|
|
print('[Carlos+Lisa] Walking steps then marking job done:')
|
|
for s in job.step_ids.sorted('sequence'):
|
|
if s.state in ('pending', 'ready'):
|
|
s.button_start()
|
|
if s.state == 'in_progress':
|
|
s.button_finish()
|
|
try:
|
|
job.button_mark_done()
|
|
print(f' ✓ Job done — state={job.state}')
|
|
except Exception as e:
|
|
print(f' ❌ Job mark_done blocked: {e}')
|
|
|
|
# Reset partner flag for test independence.
|
|
target.x_fc_requires_qc = False
|
|
|
|
env.cr.commit()
|
|
print()
|
|
print('== Step 6 complete ==')
|