mcs150 handler: service-aware todos/notifications/emails (stop mislabeling UCR as MCS-150)

UCR (and other admin-assisted DOT services) route through MCS150UpdateHandler,
which hardcoded 'MCS-150' and self.SERVICE_SLUG in the admin todo, the Telegram
fulfillment notification, and the customer status email -- so approving Paul's
UCR produced an 'MCS-150 Review / mcs150-update / PDF: not generated' alert and
an 'MCS-150 biennial update' customer email, both wrong.

Add SERVICE_DISPLAY_NAMES + _service_label(slug); use the actual slug everywhere.
Admin-assisted services now show 'UCR Annual Registration — FILE NOW ... file
manually on the portal (no auto-generated form)' instead of MCS-150/PDF wording,
and the customer email names the right service.
This commit is contained in:
justin 2026-06-16 03:02:53 -05:00
parent 326aee7714
commit 6c10c6a6cd

View file

@ -97,6 +97,25 @@ class MCS150UpdateHandler:
(1001, 10**9, "1001+"),
]
# Human-readable names per slug for todos / notifications, so an admin-assisted
# service (e.g. UCR) routed through this handler is not mislabeled as "MCS-150".
SERVICE_DISPLAY_NAMES = {
"mcs150-update": "MCS-150 Biennial Update",
"dot-registration": "New USDOT Registration",
"usdot-reactivation": "USDOT Reactivation",
"dot-full-compliance": "DOT Full Compliance",
"ucr-registration": "UCR Annual Registration",
"boc3-filing": "BOC-3 Process Agent Filing",
"mc-authority": "MC Operating Authority",
"dot-audit-prep": "New Entrant Safety Audit Prep",
"emergency-temporary-authority": "Emergency Temporary Authority",
}
def _service_label(self, slug: str) -> str:
"""Friendly service name for the given slug (falls back to a title-cased
slug). Keeps todos/notifications accurate for non-MCS-150 services."""
return self.SERVICE_DISPLAY_NAMES.get(slug) or slug.replace("-", " ").title()
async def process(self, order_data: dict) -> list[str]:
"""Entry point called by job_server. Delegates to handle()."""
order_number = order_data.get("order_number", order_data.get("name", ""))
@ -403,16 +422,31 @@ class MCS150UpdateHandler:
conn = psycopg2.connect(os.environ.get("DATABASE_URL", ""))
filed_method = filing_result.get("method", "pending") if filing_result else "pending"
filed_ok = filing_result.get("success", False) if filing_result else False
svc_label = self._service_label(slug)
is_form = slug in self.MCS150_FORM_SLUGS
todo_title = f"MCS-150 {'Filed' if filed_ok else 'Review'}{entity_name} (DOT {dot_number})"
todo_priority = "low" if filed_ok else "normal"
todo_description = (
f"MCS-150 for {entity_name} (DOT {dot_number}).\n"
f"Filing method: {filed_method}\n"
f"Status: {'SUBMITTED — verify in 5-10 days' if filed_ok else 'NEEDS MANUAL FILING'}\n"
f"Customer: {customer_email}\n"
f"PDF: {minio_path or 'not generated'}"
)
if is_form:
todo_title = f"{svc_label} {'Filed' if filed_ok else 'Review'}{entity_name} (DOT {dot_number})"
todo_priority = "low" if filed_ok else "normal"
todo_description = (
f"{svc_label} for {entity_name} (DOT {dot_number}).\n"
f"Filing method: {filed_method}\n"
f"Status: {'SUBMITTED — verify in 5-10 days' if filed_ok else 'NEEDS MANUAL FILING'}\n"
f"Customer: {customer_email}\n"
f"PDF: {minio_path or 'not generated'}"
)
else:
# Admin-assisted service (UCR, MC authority, etc.): no auto-filing
# and no generated form. Approval means it's ready for a human to
# file on the relevant government portal.
todo_title = f"{svc_label} — FILE NOW — {entity_name} (DOT {dot_number})"
todo_priority = "high"
todo_description = (
f"{svc_label} for {entity_name} (DOT {dot_number}).\n"
f"Status: APPROVED — file manually on the {svc_label} portal.\n"
f"This service has no auto-generated form; submit it directly.\n"
f"Customer: {customer_email}"
)
with conn.cursor() as cur:
cur.execute("""
@ -425,7 +459,7 @@ class MCS150UpdateHandler:
"filing",
todo_priority,
order_number,
self.SERVICE_SLUG,
slug,
todo_description,
json.dumps({
"order_number": order_number,
@ -438,7 +472,7 @@ class MCS150UpdateHandler:
notify_fulfillment_todo(
title=todo_title,
order_number=order_number,
service_slug=self.SERVICE_SLUG,
service_slug=slug,
priority=todo_priority,
description=todo_description,
)
@ -447,7 +481,7 @@ class MCS150UpdateHandler:
LOG.error("[%s] Failed to create admin todo: %s", order_number, exc)
# Step 7: Send client status email
self._send_status_email(order_number, entity_name, dot_number, customer_email)
self._send_status_email(order_number, entity_name, dot_number, customer_email, slug)
return [minio_path] if minio_path else []
@ -840,16 +874,29 @@ class MCS150UpdateHandler:
import psycopg2
conn = psycopg2.connect(os.environ.get("DATABASE_URL", ""))
sig = "client SIGNED" if client_signed else "no signature required"
todo_title = f"VERIFY before filing — {entity_name} (DOT {dot_number})"
todo_description = (
f"{slug} for {entity_name} (DOT {dot_number}).\n"
f"Status: READY TO FILE — held for admin verification ({sig}).\n"
f"ACTION: review the prepared PDF, confirm it is correct, then\n"
f"approve & submit (re-dispatch with admin_approved=true).\n"
f"We do NOT submit to FMCSA until you approve.\n"
f"PDF: {minio_path or 'not generated'}\n"
f"Customer: {customer_email}"
)
svc_label = self._service_label(slug)
todo_title = f"VERIFY before filing — {svc_label}{entity_name} (DOT {dot_number})"
if slug in self.MCS150_FORM_SLUGS:
todo_description = (
f"{svc_label} for {entity_name} (DOT {dot_number}).\n"
f"Status: READY TO FILE — held for admin verification ({sig}).\n"
f"ACTION: review the prepared PDF, confirm it is correct, then\n"
f"approve & submit (re-dispatch with admin_approved=true).\n"
f"We do NOT submit to FMCSA until you approve.\n"
f"PDF: {minio_path or 'not generated'}\n"
f"Customer: {customer_email}"
)
else:
# Admin-assisted service: no generated form to review; approval
# just clears it for a human to file on the government portal.
todo_description = (
f"{svc_label} for {entity_name} (DOT {dot_number}).\n"
f"Status: READY TO FILE — held for admin verification.\n"
f"ACTION: confirm the order details, then approve in the admin\n"
f"dashboard. This service has no auto-generated form; you file\n"
f"it manually on the {svc_label} portal after approving.\n"
f"Customer: {customer_email}"
)
with conn.cursor() as cur:
cur.execute(
"""
@ -952,31 +999,32 @@ class MCS150UpdateHandler:
LOG.warning("[%s] Failed to persist submission evidence: %s", order_number, exc)
return evidence
def _send_status_email(self, order_number, entity_name, dot_number, customer_email):
"""Send client an email that we're working on their update."""
def _send_status_email(self, order_number, entity_name, dot_number, customer_email, slug=None):
"""Send client an email that we're working on their order."""
if not customer_email:
return
try:
import smtplib
from email.mime.text import MIMEText
svc_label = self._service_label(slug) if slug else "MCS-150 Biennial Update"
body = (
f"Hi,\n\n"
f"We've received your MCS-150 biennial update order for "
f"We've received your {svc_label} order for "
f"{entity_name} (DOT# {dot_number}).\n\n"
f"Order: {order_number}\n\n"
f"Our team will review your intake information and complete "
f"Our team will review your information and complete "
f"the filing within 1-2 business days. We'll send you a "
f"confirmation with your updated company snapshot once it's done.\n\n"
f"If we need your FMCSA Portal login credentials, we'll reach "
f"out via a separate secure email.\n\n"
f"confirmation once it's done.\n\n"
f"If we need any additional information or portal credentials, "
f"we'll reach out via a separate secure email.\n\n"
f"Questions? Reply to this email or call (888) 411-0383.\n\n"
f"Performance West Inc.\n"
f"DOT Compliance Services\n"
)
msg = MIMEText(body)
msg["Subject"] = f"MCS-150 Update In Progress — {entity_name} (DOT {dot_number})"
msg["Subject"] = f"{svc_label} In Progress — {entity_name} (DOT {dot_number})"
msg["From"] = "noreply@performancewest.net"
msg["To"] = customer_email