Files
gsinghpal f08f328688 changes
2026-04-27 00:11:18 -04:00

108 lines
4.0 KiB
Python

# Step 3 — Sarah hits "Create Order" in wizard, then confirms SO.
# Watch every side-effect: SO state, fp.job auto-spawn, fp.receiving
# auto-spawn, fp.racking.inspection, portal.job mirror, QC check.
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) # 2CM INNOVATIVE
part = Part.search([('x_fc_default_coating_config_id', '!=', False)], limit=1)
# Build the wizard exactly the way Sarah would after Step 1+2 fixes.
w = W.create({
'partner_id': target.id,
'po_number': 'PO-STEP3-001',
'po_pending': False,
'customer_job_number': 'CUSTJOB-STEP3',
'planned_start_date': fields.Date.today(),
'customer_deadline': fields.Date.add(fields.Date.today(), days=14),
'invoice_strategy': 'net_terms',
'delivery_method': 'shipping_partner',
'po_attachment_file': b'fake-pdf-bytes',
'po_attachment_filename': 'po.pdf',
})
w._onchange_partner_id()
print(f'[Sarah] Created wizard {w.name} for {target.display_name}')
ln = Line.new({'wizard_id': w.id})
ln.part_catalog_id = part
ln._onchange_part_clears_variant()
ln_vals = ln._convert_to_write({n: ln[n] for n in ln._fields})
ln_vals.update({
'wizard_id': w.id,
'quantity': 25,
'unit_price': 12.50,
'line_description': 'EN plating per part default coating',
'internal_description': 'Standard recipe; bake within 4h.',
})
real_line = Line.create(ln_vals)
print(f'[Sarah] Added line: part={real_line.part_catalog_id.part_number}, '
f'coating={real_line.coating_config_id.name}, qty={real_line.quantity}')
# Hit Create Order.
print('[Sarah] Clicking "Create Order"...')
result = w.action_create_order()
so_id = (result or {}).get('res_id')
SO = env['sale.order']
so = SO.browse(so_id) if so_id else SO.search(
[('x_fc_po_number', '=', 'PO-STEP3-001')], order='id desc', limit=1,
)
print(f' -> SO created: {so.name} (state={so.state})')
# Now confirm the SO (Sarah does this from the SO form, not the wizard).
print('[Sarah] Confirming SO...')
try:
so.action_confirm()
print(f' -> SO state={so.state}, x_fc_receiving_status={so.x_fc_receiving_status}')
except Exception as e:
print(f' ❌ confirm failed: {e}')
env.cr.rollback()
raise SystemExit
# Verify side-effects.
print()
print('=== Side effects of SO confirm ===')
Job = env['fp.job']
jobs = Job.search([('sale_order_id', '=', so.id)])
print(f' fp.job auto-spawn: {len(jobs)} job(s)')
for j in jobs:
print(f' {j.name}: state={j.state}, qty={j.qty}, recipe={j.recipe_id.name or "(no recipe)"}, steps={len(j.step_ids)}')
Receiving = env['fp.receiving']
receivings = Receiving.search([('sale_order_id', '=', so.id)])
print(f' fp.receiving auto-spawn: {len(receivings)} record(s)')
for r in receivings:
print(f' {r.name}: state={r.state}, expected_qty={r.expected_qty}')
if 'fp.racking.inspection' in env:
Inspection = env['fp.racking.inspection']
racks = Inspection.search([('sale_order_id', '=', so.id)])
print(f' fp.racking.inspection auto-spawn: {len(racks)} record(s)')
for ri in racks:
print(f' {ri.name}: state={ri.state if "state" in ri._fields else "?"}, x_fc_job_id={ri.x_fc_job_id.name if ri.x_fc_job_id else None}')
PortalJob = env['fusion.plating.portal.job']
portal_jobs = PortalJob.search([('x_fc_job_id', 'in', jobs.ids)])
print(f' portal.job mirror: {len(portal_jobs)} record(s)')
for pj in portal_jobs:
print(f' {pj.name}: state={pj.state}')
QC = env['fusion.plating.quality.check']
qcs = QC.search([('job_id', 'in', jobs.ids)])
print(f' QC checks: {len(qcs)} (customer x_fc_requires_qc={getattr(target, "x_fc_requires_qc", "NOFIELD")})')
for qc in qcs:
print(f' {qc.name}: state={qc.state}, lines={len(qc.line_ids)}')
# x_fc_receiving_status check
print()
print(f' SO x_fc_receiving_status (post-confirm, no receipt yet): {so.x_fc_receiving_status}')
print(f' Expected: not_received (parts haven\'t arrived)')
env.cr.commit()
print()
print(f'== Step 3 complete. SO ID for next steps: {so.id} ==')