Adds the previously-unmapped fields so every variant fills fully:
- Q25 hazmat C/S/B/NB matrix (HAZMAT_ROW_MAP x HAZMAT_COL_MAP, 156 boxes)
- MCS-150B states-of-operation checkboxes (full name or 2-letter code), HMSP
Hazard/Permit/Security radios, and accident count (32accidentNumber)
- MCS-150C intermodal equipment counts (20owned/leased/serviced) + correct
field renumbering (17dunbrad/18irs/19eMail) + USDOT Button + named-export
Reason/Mailing radios
- Structured fleet via intake['vehicles'] = {vehicle_type: {owned, term_leased,
trip_leased}} across all Q26 vehicle rows; non-CMV count; cell/fax; second
officer
- _set_button now resolves a candidate tuple against each field's actual export
states, so numeric (/0../4) and named (/Yes,/Biennial...) radios both work
verify_mcs150_variants.py exercises all three variants end-to-end: ALL PASS.
88 lines
4.3 KiB
Python
88 lines
4.3 KiB
Python
"""Smoke-test all three MCS-150 variants fill the right fields/boxes.
|
|
|
|
Reads the filled PDF's AcroForm values (and the appearance streams for text)
|
|
to confirm each variant populates its expected fields, including the 150B
|
|
hazmat-matrix + states-of-operation and 150C intermodal numbering.
|
|
"""
|
|
import sys
|
|
sys.path.insert(0, "/app")
|
|
from pypdf import PdfReader
|
|
from scripts.document_gen.templates.mcs150_pdf_filler import fill_mcs150
|
|
|
|
BASE = dict(
|
|
legal_name="ALLENS SCRAP METAL LLC", dot_number="1609564", ein="264625451",
|
|
address_street="3838 DANNY RD", address_city="LORIS", address_state="SC",
|
|
address_zip="29569", phone="8435551234", email="m@allenscrapmetal.com",
|
|
annual_miles="42000", carrier_operation="private_property",
|
|
cargo_types=["metal", "general"], interstate_intrastate="interstate",
|
|
power_units="2", drivers="2", signer_name="Mitchell W Allen",
|
|
signer_title="Owner",
|
|
)
|
|
|
|
|
|
def btn_on(fields):
|
|
return {n: str(f.get("/V")) for n, f in fields.items()
|
|
if str(f.get("/FT")) == "/Btn" and f.get("/V") and str(f.get("/V")) != "/Off"}
|
|
|
|
|
|
def tx(fields, name):
|
|
return (fields.get(name) or {}).get("/V")
|
|
|
|
|
|
def check(label, cond):
|
|
print(f" [{'OK ' if cond else 'MISS'}] {label}")
|
|
return cond
|
|
|
|
|
|
ok = True
|
|
|
|
# ── Base MCS-150 ─────────────────────────────────────────────────────
|
|
print("=== MCS-150 (base) ===")
|
|
r = PdfReader(fill_mcs150(BASE, "CO-V150"))
|
|
f = r.get_fields() or {}
|
|
b = btn_on(f)
|
|
ok &= check(f"3 pages (got {len(r.pages)})", len(r.pages) == 3)
|
|
ok &= check("Q22 interstate (22aBox)", b.get("22aBox") == "/Yes")
|
|
ok &= check("Q23 private property (23cBox)", b.get("23cBox") == "/Yes")
|
|
ok &= check("Q24 cargo metal+general", b.get("24aBox") == "/Yes" and b.get("24cBox") == "/Yes")
|
|
ok &= check("Reason=Biennial", b.get("Reason Button") == "/1")
|
|
ok &= check("Mailing=same", b.get("Mailing Button") == "/0")
|
|
ok &= check("Revoke=No (/1)", b.get("Revoke Button") == "/1")
|
|
ok &= check("email + mileage set", tx(f, "20eMail") and tx(f, "21carrierMileage") == "42000")
|
|
ok &= check("certifyBox NOT set (freight)", "certifyBox" not in b)
|
|
|
|
# ── MCS-150B (hazmat permit) ─────────────────────────────────────────
|
|
print("=== MCS-150B (hazmat permit) ===")
|
|
hz = dict(BASE, hazmat="yes", needs_hmsp=True,
|
|
interstate_intrastate="intrastate_hazmat",
|
|
operating_states=["SC", "NC", "GA"],
|
|
hazmat_materials={"class_3": ["carrier", "bulk"], "class_8": ["shipper"]},
|
|
hmsp_accident_count="0", hmsp_security_plan="yes",
|
|
cargo_types=["chemicals"])
|
|
r = PdfReader(fill_mcs150(hz, "CO-V150B"))
|
|
f = r.get_fields() or {}
|
|
b = btn_on(f)
|
|
ok &= check(f"4 pages (got {len(r.pages)})", len(r.pages) == 4)
|
|
ok &= check("states SC/NC/GA", all(b.get(s) == "/Yes" for s in ("South Carolina", "North Carolina", "Georgia")))
|
|
ok &= check("hazmat class_3 carrier+bulk", b.get("25oCBox") == "/Yes" and b.get("25oBBox") == "/Yes")
|
|
ok &= check("hazmat class_8 shipper", b.get("25ddSBox") == "/Yes")
|
|
ok &= check("accident count 0", tx(f, "32accidentNumber") == "0")
|
|
ok &= check("Security Button yes (/0)", b.get("Security Button") == "/0")
|
|
|
|
# ── MCS-150C (intermodal) ────────────────────────────────────────────
|
|
print("=== MCS-150C (intermodal) ===")
|
|
iep = dict(BASE, is_intermodal_equipment_provider=True,
|
|
iep_owned="10", iep_leased="3", iep_serviced="2")
|
|
r = PdfReader(fill_mcs150(iep, "CO-V150C"))
|
|
f = r.get_fields() or {}
|
|
b = btn_on(f)
|
|
ok &= check(f"2 pages (got {len(r.pages)})", len(r.pages) == 2)
|
|
ok &= check("legal name set", tx(f, "1bizName") == "ALLENS SCRAP METAL LLC")
|
|
ok &= check("EIN in 18irsNumber (150C numbering)", tx(f, "18irsNumber") == "264625451")
|
|
ok &= check("email in 19eMail (150C numbering)", bool(tx(f, "19eMail")))
|
|
ok &= check("iep counts 10/3/2", tx(f, "20owned") == "10" and tx(f, "20leased") == "3" and tx(f, "20serviced") == "2")
|
|
ok &= check("Reason named-export resolves", b.get("Reason Button") in ("/Biennial Update or Changes", "/1"))
|
|
ok &= check("USDOT Button = No", b.get("USDOT Button") == "/No")
|
|
|
|
print("\n" + ("ALL PASS" if ok else "FAILURES ABOVE"))
|
|
sys.exit(0 if ok else 1)
|