diff --git a/scripts/workers/services/mcs150_update.py b/scripts/workers/services/mcs150_update.py index 2d8ef4a..689a6b1 100644 --- a/scripts/workers/services/mcs150_update.py +++ b/scripts/workers/services/mcs150_update.py @@ -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