diff --git a/docs/MCS-150 Form.pdf b/docs/MCS-150 Form.pdf index 96dade3..44198d2 100644 Binary files a/docs/MCS-150 Form.pdf and b/docs/MCS-150 Form.pdf differ diff --git a/docs/MCS-150B Form.pdf b/docs/MCS-150B Form.pdf index 99e430f..d443103 100644 Binary files a/docs/MCS-150B Form.pdf and b/docs/MCS-150B Form.pdf differ diff --git a/docs/MCS-150C Form.pdf b/docs/MCS-150C Form.pdf index 7a4d7ef..c73b11d 100644 Binary files a/docs/MCS-150C Form.pdf and b/docs/MCS-150C Form.pdf differ diff --git a/scripts/document_gen/templates/diag_mcs150.py b/scripts/document_gen/templates/diag_mcs150.py deleted file mode 100644 index 22d4f00..0000000 --- a/scripts/document_gen/templates/diag_mcs150.py +++ /dev/null @@ -1,55 +0,0 @@ -"""Diagnostic: inspect the actual MCS-150 fill output. -Reports, per page: the AcroForm fields present (name + value + rect), and the -rendered text, so we can see WHERE data lands vs WHERE the blank/example fields -are. Run in the workers container against the live template + a fresh fill. -""" -import sys, json -sys.path.insert(0, "/app") -from pypdf import PdfReader - -TEMPLATE = "/app/docs/MCS-150 Form.pdf" - - -def field_rows(reader, label): - print(f"\n===== {label} =====") - for i, pg in enumerate(reader.pages): - annots = pg.get("/Annots") - if not annots: - continue - annots = annots.get_object() if hasattr(annots, "get_object") else annots - rows = [] - for a in annots: - o = a.get_object() - t = o.get("/T") - if t is None and o.get("/Parent"): - t = o["/Parent"].get_object().get("/T") - v = o.get("/V") - rect = o.get("/Rect") - ft = o.get("/FT") - if t: - rows.append((str(t), str(ft), str(v) if v is not None else "", [round(float(x)) for x in rect] if rect else None)) - if rows: - print(f"-- PDF page {i+1} ({len(rows)} fields) --") - for name, ft, val, rect in rows: - vstr = f" = {val!r}" if val else "" - print(f" {name} [{ft}]{vstr} rect={rect}") - - -# 1) the template as-is — what fields + any example values? -r = PdfReader(TEMPLATE) -field_rows(r, "TEMPLATE (original)") - -# 2) a fresh fill -from scripts.document_gen.templates.mcs150_pdf_filler import fill_mcs150 -intake = { - "dot_number": "1609564", "legal_name": "MITCHELL W ALLEN", - "dba_name": "", "entity_type": "sole_proprietorship", - "business_street": "123 Main St", "business_city": "Town", - "business_state": "TX", "business_zip": "75001", - "phone": "5125551234", "ein": "123456789", - "signer_name": "Mitchell W Allen", "signer_title": "Owner", - "power_units": "2", "drivers": "1", -} -p = fill_mcs150(intake, order_number="DIAG") -print("\nfilled file:", p) -field_rows(PdfReader(p), "FILLED") diff --git a/scripts/document_gen/templates/mcs150_pdf_filler.py b/scripts/document_gen/templates/mcs150_pdf_filler.py index d3a72ed..49d39fb 100644 --- a/scripts/document_gen/templates/mcs150_pdf_filler.py +++ b/scripts/document_gen/templates/mcs150_pdf_filler.py @@ -4,10 +4,12 @@ Fills the official FMCSA MCS-150/150B/150C fillable PDF forms using intake data from the order. Produces a ready-to-fax or electronically submit PDF. -Forms stored at: - docs/MCS-150 Form.pdf — standard (289 fields) - docs/MCS-150B Form.pdf — hazmat safety permit (349 fields) - docs/MCS-150C Form.pdf — intermodal equipment (33 fields) +Forms stored at (FORM pages only -- the FMCSA instruction/example pages are +trimmed off the source PDFs so the filled output is fax/submit-ready and never +includes the instruction pages): + docs/MCS-150 Form.pdf — standard (3 pages, 289 fields) + docs/MCS-150B Form.pdf — hazmat safety permit (4 pages, 349 fields) + docs/MCS-150C Form.pdf — intermodal equipment (2 pages, 33 fields) Usage: from scripts.document_gen.templates.mcs150_pdf_filler import fill_mcs150 @@ -209,9 +211,10 @@ def fill_mcs150(intake: dict, order_number: str = "") -> str: checkbox_on["certifyBox"] = True # ── Apply fields to PDF ────────────────────────────────────────── - # Apply text-field values to every page. The fields live on pages 9-11 of - # the official form, so we update across all pages (pypdf silently ignores - # field names not present on a given page). auto_regenerate=True makes pypdf + # Apply text-field values to every page. The template ships with only the + # fillable FORM pages (the FMCSA instruction pages are trimmed off the + # source PDF so we never fax/submit them), so we update across all pages + # (pypdf silently ignores field names not present on a given page). auto_regenerate=True makes pypdf # build appearance streams from the values, so viewers that ignore # /NeedAppearances (Preview, Chrome) still render the text. text_values = {k: v for k, v in field_updates.items() if v}