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:
parent
bd0d8c0e2c
commit
71404810c4
1 changed files with 82 additions and 0 deletions
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue