"""Sub 2 — test _fp_resolve_cert_requirement behaviour. Run via: cat docs/superpowers/tests/2026-04-21-sub2-cert-resolver-test.py | \ ssh pve-worker5 "pct exec 111 -- bash -c 'cat > /tmp/t.py && \ su - odoo -s /bin/bash -c \"/usr/bin/odoo shell -c /etc/odoo/odoo.conf -d admin --no-http --stop-after-init\" < /tmp/t.py'" """ import sys env = self.env def ok(msg): print(f" [OK] {msg}") def fail(msg): print(f" [FAIL] {msg}"); sys.exit(1) def hdr(t): print(f"\n=== {t} ===") # ---- Setup ---- hdr("Setup") Product = env['product.product'] product = Product.search([('active', '=', True)], limit=1) Partner = env['res.partner'] partner = Partner.create({ 'name': 'Sub2 CertResolver Test Co', 'is_company': True, 'customer_rank': 1, 'x_fc_send_coc': True, 'x_fc_send_thickness_report': False, }) PartCat = env['fp.part.catalog'] part_inherit = PartCat.create({ 'name': 'P-INHERIT', 'part_number': 'P-INHERIT', 'revision': 'A', 'partner_id': partner.id, 'certificate_requirement': 'inherit', }) part_none = PartCat.create({ 'name': 'P-NONE', 'part_number': 'P-NONE', 'revision': 'A', 'partner_id': partner.id, 'certificate_requirement': 'none', }) part_thick = PartCat.create({ 'name': 'P-THICK', 'part_number': 'P-THICK', 'revision': 'A', 'partner_id': partner.id, 'certificate_requirement': 'coc_thickness', }) ok(f"parts created: {part_inherit.id}, {part_none.id}, {part_thick.id}") def make_mo(lines): """Helper: builds an SO with the given part_catalogs, confirms it, returns MO.""" so_vals = { 'partner_id': partner.id, 'order_line': [ (0, 0, { 'product_id': product.id, 'product_uom_qty': 1, 'x_fc_part_catalog_id': pc.id, }) for pc in lines ], } if 'x_fc_po_number' in env['sale.order']._fields: so_vals['x_fc_po_number'] = 'TEST-PO' so = env['sale.order'].create(so_vals) so.action_confirm() mo = env['mrp.production'].create({ 'product_id': product.id, 'product_qty': 1, 'origin': so.name, }) mo.action_confirm() return mo # ---- Test 1: inherit → partner ---- hdr("1. Part=inherit + partner(coc=T, thick=F) → (T, F)") mo1 = make_mo([part_inherit]) want_coc, want_thickness = mo1._fp_resolve_cert_requirement() if (want_coc, want_thickness) != (True, False): fail(f"got ({want_coc}, {want_thickness}), expected (True, False)") ok("inherit falls through to partner correctly") # ---- Test 2: part=none overrides partner ---- hdr("2. Part=none + partner(coc=T) → (F, F)") mo2 = make_mo([part_none]) want_coc, want_thickness = mo2._fp_resolve_cert_requirement() if (want_coc, want_thickness) != (False, False): fail(f"got ({want_coc}, {want_thickness}), expected (False, False)") ok("part=none wins over partner=coc") # ---- Test 3: part=coc_thickness + partner(coc=F, thick=F) → (T, T) ---- hdr("3. Part=coc_thickness + partner=none → (T, T)") partner.x_fc_send_coc = False mo3 = make_mo([part_thick]) want_coc, want_thickness = mo3._fp_resolve_cert_requirement() if (want_coc, want_thickness) != (True, True): fail(f"got ({want_coc}, {want_thickness}), expected (True, True)") ok("part=coc_thickness wins over partner=off") partner.x_fc_send_coc = True # reset # ---- Test 4: multi-line MO strictest wins ---- hdr("4. Multi-line [none, coc_thickness] → (T, T)") mo4 = make_mo([part_none, part_thick]) want_coc, want_thickness = mo4._fp_resolve_cert_requirement() if (want_coc, want_thickness) != (True, True): fail(f"got ({want_coc}, {want_thickness}), expected (True, True)") ok("multi-line strictest wins") # ---- Test 5: MO without SO link → safe default ---- hdr("5. Orphan MO → (T, F) safe default") orphan = env['mrp.production'].create({ 'product_id': product.id, 'product_qty': 1, 'origin': 'NONEXISTENT-SO', }) want_coc, want_thickness = orphan._fp_resolve_cert_requirement() if (want_coc, want_thickness) != (True, False): fail(f"got ({want_coc}, {want_thickness}), expected (True, False)") ok("orphan MO falls back to safe default") hdr("ALL CERT RESOLVER TESTS PASS")