Automate 499-Q USAC filing + discontinuance letter auto-email
499-Q Handler: - Auto-filing toggle integration (same as 499-A) - Playwright USAC E-File submission for quarterly form - Revenue field filling (4 categories) - Confirmation number capture + PDF save - Client receives "data received" email immediately, then "filed successfully" email with confirmation number after submission - Falls back to admin todo if Playwright/session unavailable Discontinuance Handler: - Auto-emails deactivation letter to USAC (Form499@usac.org) with DOCX attachment + entity summary in body - CC to admin email for records - Dev mode: redirects USAC email to admin instead - Client confirmation email with process timeline Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a404cb1b57
commit
f30b0383a9
2 changed files with 342 additions and 71 deletions
|
|
@ -125,6 +125,62 @@ class Form499ADiscontinuanceHandler(BaseComplianceHandler):
|
|||
f"Client email: {entity.get('contact_email') or order_data.get('customer_email', '')}",
|
||||
)
|
||||
|
||||
# ── Auto-email deactivation letter to USAC ──────────────────────
|
||||
# On prod with auto-filing enabled, sends the letter directly.
|
||||
# On dev, sends to admin for review.
|
||||
usac_email = os.environ.get("USAC_DEACTIVATION_EMAIL", "Form499@usac.org")
|
||||
admin_email = os.environ.get("ADMIN_EMAIL", "ops@performancewest.net")
|
||||
|
||||
# In dev/test mode, redirect USAC emails to admin
|
||||
if os.environ.get("NODE_ENV") == "development":
|
||||
usac_email = admin_email
|
||||
logger.info("Dev mode: redirecting USAC deactivation to %s", usac_email)
|
||||
|
||||
if letter_path:
|
||||
try:
|
||||
import smtplib
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.base import MIMEBase
|
||||
from email import encoders
|
||||
|
||||
msg = MIMEMultipart()
|
||||
msg["From"] = os.environ.get("SMTP_FROM", "Performance West <noreply@performancewest.net>")
|
||||
msg["To"] = usac_email
|
||||
msg["Cc"] = admin_email
|
||||
msg["Subject"] = f"Filer ID Deactivation Request — {legal_name} (Filer ID: {filer_id})"
|
||||
|
||||
body = (
|
||||
f"Please find attached a formal request to deactivate the 499 Filer ID "
|
||||
f"for {legal_name} (Filer ID: {filer_id}, FRN: {frn}).\n\n"
|
||||
f"Termination date: {last_service_date or 'See attached letter'}\n"
|
||||
f"Reason: {discontinuance_reason}\n\n"
|
||||
f"Please confirm deactivation at your earliest convenience.\n\n"
|
||||
f"Submitted by Performance West Inc. on behalf of {legal_name}.\n"
|
||||
f"Contact: {admin_email}"
|
||||
)
|
||||
msg.attach(MIMEText(body, "plain"))
|
||||
|
||||
# Attach the letter
|
||||
with open(letter_path, "rb") as f:
|
||||
part = MIMEBase("application", "vnd.openxmlformats-officedocument.wordprocessingml.document")
|
||||
part.set_payload(f.read())
|
||||
encoders.encode_base64(part)
|
||||
part.add_header("Content-Disposition", f'attachment; filename="{os.path.basename(letter_path)}"')
|
||||
msg.attach(part)
|
||||
|
||||
with smtplib.SMTP(
|
||||
os.environ.get("SMTP_HOST", "co.carrierone.com"),
|
||||
int(os.environ.get("SMTP_PORT", "587")),
|
||||
timeout=30,
|
||||
) as s:
|
||||
s.starttls()
|
||||
s.login(os.environ.get("SMTP_USER", ""), os.environ.get("SMTP_PASS", ""))
|
||||
s.send_message(msg)
|
||||
logger.info("Deactivation letter emailed to %s (cc: %s)", usac_email, admin_email)
|
||||
except Exception as exc:
|
||||
logger.warning("Failed to email deactivation letter: %s", exc)
|
||||
|
||||
# Send confirmation to client
|
||||
self._send_confirmation(
|
||||
to=entity.get("contact_email") or order_data.get("customer_email", ""),
|
||||
|
|
@ -133,7 +189,7 @@ class Form499ADiscontinuanceHandler(BaseComplianceHandler):
|
|||
filer_id=filer_id,
|
||||
)
|
||||
|
||||
return {"status": "submitted_for_processing"}
|
||||
return {"status": "submitted_for_processing", "letter_generated": bool(letter_path)}
|
||||
|
||||
def _send_confirmation(
|
||||
self, to: str, entity_name: str, order_number: str, filer_id: str,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue