mcs150: backfill signer name from signed cert + re-stamp signed form

- When intake lacks signer_name, backfill it from the name the client
  typed when signing the perjury certification (that name is exactly what
  belongs in the form's print/type-name field, certifyName).
- After a client-approved re-dispatch, re-point the signed esign record at
  the freshly filled form and re-stamp the signature, so the signed PDF an
  admin reviews reflects the current complete form (not a stale earlier
  fill). Field layout (and thus signature anchors) is unchanged across
  fills, so the recorded anchor coordinates stay valid.
This commit is contained in:
justin 2026-06-10 12:41:27 -05:00
parent bd0d8c0e2c
commit 71404810c4

View file

@ -113,6 +113,17 @@ class MCS150UpdateHandler:
LOG.warning("[%s] No FMCSA census data for DOT %s -- form may be sparse",
order_number, dot_number)
# Backfill the signer's printed name from the signed certification when
# the intake didn't carry one. For a typed signature the client typed
# their full legal name, which is exactly what belongs in the form's
# "print/type name" certification field (certifyName).
if not intake.get("signer_name"):
signed_name = self._signed_signer_name(order_number)
if signed_name:
intake["signer_name"] = signed_name
LOG.info("[%s] Backfilled signer_name from signed certification: %s",
order_number, signed_name)
# Step 1: Fill the official MCS-150 PDF
pdf_path = None
try:
@ -145,6 +156,13 @@ class MCS150UpdateHandler:
except Exception as exc:
LOG.error("[%s] MinIO upload failed: %s", order_number, exc)
# If the client already signed (re-dispatched after signature), the
# signed PDF that the admin reviews must reflect the form we just
# (re)filled, not a stale earlier fill. Re-point the esign record at the
# fresh document and re-stamp the signature onto it.
if client_approved and minio_path:
self._restamp_signed_form(order_number, minio_path)
# Step 3: Check for photo ID
photo_id_path = None
if intake.get("photo_id_uploaded"):
@ -337,6 +355,70 @@ class MCS150UpdateHandler:
return [minio_path] if minio_path else []
def _restamp_signed_form(self, order_number: str, document_key: str) -> None:
"""Point the signed esign record at ``document_key`` (the freshly filled
form) and re-stamp the signature onto it, so the signed PDF an admin
reviews reflects the current, complete form."""
try:
import psycopg2
conn = psycopg2.connect(os.environ.get("DATABASE_URL", ""))
try:
with conn.cursor() as cur:
cur.execute(
"""SELECT id FROM esign_records
WHERE order_number = %s AND status = 'signed'
ORDER BY signed_at DESC LIMIT 1""",
(order_number,),
)
row = cur.fetchone()
if not row:
return
rec_id = row[0]
# Re-point at the fresh document and clear the stale signed
# key so the stamper regenerates it.
cur.execute(
"""UPDATE esign_records
SET document_minio_key = %s,
signed_document_minio_key = NULL,
updated_at = NOW()
WHERE id = %s""",
(document_key, rec_id),
)
conn.commit()
finally:
conn.close()
from scripts.workers.services.esign_stamp import stamp_esign_document
signed_key = stamp_esign_document(int(rec_id))
if signed_key:
LOG.info("[%s] Re-stamped signature onto fresh form -> %s",
order_number, signed_key)
except Exception as exc:
LOG.warning("[%s] Re-stamp of signed form failed: %s", order_number, exc)
def _signed_signer_name(self, order_number: str) -> str:
"""Return the full name the client typed when signing the perjury
certification for this order (empty if no typed signature on file)."""
try:
import psycopg2
conn = psycopg2.connect(os.environ.get("DATABASE_URL", ""))
try:
with conn.cursor() as cur:
cur.execute(
"""SELECT signature_data FROM esign_records
WHERE order_number = %s AND status = 'signed'
AND signature_type = 'typed'
ORDER BY signed_at DESC LIMIT 1""",
(order_number,),
)
row = cur.fetchone()
return (row[0] or "").strip() if row else ""
finally:
conn.close()
except Exception as exc:
LOG.warning("[%s] Could not read signed signer name: %s", order_number, exc)
return ""
def _fetch_fmcsa_carrier(self, dot_number: str) -> dict:
"""Fetch the raw FMCSA carrier census record for a DOT number."""
try: