"""FCC Form 499-A Discontinuance Filing Handler. For carriers who no longer provide telecommunications services and need to close out their USAC 499-A filing obligations. Files a final 499-A with zero revenue and requests discontinuance status from USAC. This is typically for: - Pure broadband resale ISPs who were incorrectly filing 499-A - Carriers who have ceased operations - Companies that were acquired and the FRN is being retired """ from __future__ import annotations import logging import os from datetime import datetime from .base_handler import BaseComplianceHandler logger = logging.getLogger("workers.services.form_499a_discontinuance") class Form499ADiscontinuanceHandler(BaseComplianceHandler): SERVICE_SLUG = "fcc-499a-discontinuance" SERVICE_NAME = "Form 499-A Discontinuance Filing" async def process(self, order_data: dict) -> dict | None: order_number = order_data.get("order_number", "") entity = order_data.get("entity", {}) intake_data = order_data.get("intake_data", {}) filer_id = intake_data.get("filer_id_499") or entity.get("filer_id_499", "") frn = intake_data.get("frn") or entity.get("frn", "") legal_name = entity.get("legal_name") or intake_data.get("entity_name", "") logger.info( "Form499ADiscontinuanceHandler: %s for %s (FRN: %s, Filer ID: %s)", order_number, legal_name, frn, filer_id, ) discontinuance_reason = intake_data.get("discontinuance_reason", "Ceased providing telecommunications services") last_service_date = intake_data.get("last_service_date", "") includes_zero_filing = not intake_data.get("has_separate_499a", False) # ── Generate USAC deactivation letter ────────────────────────── letter_path = None try: from scripts.document_gen.templates.form_499a_discontinuance_letter_generator import ( generate_discontinuance_letter, ) import tempfile work_dir = tempfile.mkdtemp(prefix=f"disc_{order_number}_") date_str = datetime.now().strftime("%Y%m%d") docx_path = os.path.join( work_dir, f"usac_deactivation_letter_{order_number}_{date_str}.docx", ) letter_path = generate_discontinuance_letter( entity_name=legal_name, filer_id=filer_id, frn=frn, ein=entity.get("ein", ""), address=entity.get("address", intake_data.get("address", "")), officer_name=intake_data.get("officer_name") or entity.get("contact_name", ""), officer_title=intake_data.get("officer_title") or entity.get("contact_title", ""), officer_email=entity.get("contact_email") or order_data.get("customer_email", ""), officer_phone=entity.get("contact_phone") or order_data.get("customer_phone", ""), termination_date=last_service_date, discontinuance_reason=discontinuance_reason, successor_entity=intake_data.get("successor_entity", ""), successor_filer_id=intake_data.get("successor_filer_id", ""), last_filing_year=int(entity.get("last_filing_year") or 0), includes_final_zero_filing=includes_zero_filing, outstanding_balances=intake_data.get("outstanding_balances", False), output_path=docx_path, ) if letter_path: logger.info("Discontinuance letter generated: %s", letter_path) # Upload to MinIO try: from scripts.workers.minio_client import upload_file minio_key = f"compliance/{order_number}/usac_deactivation_letter_{date_str}.docx" upload_file(letter_path, minio_key) logger.info("Uploaded to MinIO: %s", minio_key) except Exception as exc: logger.warning("MinIO upload failed: %s", exc) except Exception as exc: logger.warning("Discontinuance letter generation failed: %s", exc) # Per FCC 499-A Instructions: discontinuance requires TWO steps: # 1. File the final 499-A (may have actual revenue from the portion # of the year the company operated — NOT required to be zero) # 2. Submit a deactivation letter to USAC within 30 days of ceasing service # # Line 603: check TRS/LNP/NANPA exemption boxes, write # "Not in business as of filing date" on the explanation line self._create_admin_todo( order_number, f"FILE 499-A DISCONTINUANCE for {legal_name}\n\n" f"FRN: {frn}\n" f"Filer ID: {filer_id}\n" f"Reason: {discontinuance_reason}\n" f"Last service date: {last_service_date or 'Not specified'}\n\n" f"STEP 1 — File Final 499-A {'(ZERO REVENUE — included in this order)' if includes_zero_filing else '(filed separately via full 499-A order)'}:\n" f" Log in to USAC E-File (https://forms.universalservice.org/)\n" f" {'File a zero-revenue 499-A (all revenue lines $0).' if includes_zero_filing else 'The full 499-A with actual revenue is being filed under a separate order.'}\n" f" On Line 603, check all exemption boxes (TRS, LNP, NANPA)\n" f" and write 'Not in business as of {last_service_date or 'filing date'}'\n" f" on the explanation line.\n\n" f"STEP 2 — Submit USAC Deactivation Letter:\n" f" Send letter to USAC (Form499@usac.org) with:\n" f" - Company name: {legal_name}\n" f" - Filer ID: {filer_id}\n" f" - FRN: {frn}\n" f" - Termination date: {last_service_date or 'TBD'}\n" f" - Reason: {discontinuance_reason}\n" f" - Successor entity: {intake_data.get('successor_entity', 'None')}\n" f" Must be submitted within 30 days of ceasing service.\n" f" Processing takes up to 60-90 days.\n\n" f"STEP 3 — Update CORES:\n" f" Update FCC CORES registration to reflect inactive status.\n\n" f"STEP 4 — Related Filings:\n" f" Confirm CPNI, RMD, and BDC filings are also discontinued.\n\n" f"DEACTIVATION LETTER: {'Generated — check MinIO compliance/' + order_number + '/' if letter_path else 'GENERATION FAILED — draft manually'}\n\n" f"Client email: {entity.get('contact_email') or order_data.get('customer_email', '')}", ) # Send confirmation to client self._send_confirmation( to=entity.get("contact_email") or order_data.get("customer_email", ""), entity_name=legal_name, order_number=order_number, filer_id=filer_id, ) return {"status": "submitted_for_processing"} def _send_confirmation( self, to: str, entity_name: str, order_number: str, filer_id: str, ) -> None: if not to: return try: import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText subject = f"Form 499-A Discontinuance Filed — {entity_name}" html = f"""
We've received your request to discontinue the FCC Form 499-A filing obligation for {entity_name} (Filer ID: {filer_id}).
We will:
USAC processing takes 60-90 days. You'll receive a confirmation email at each step. During this period, you won't receive new invoices for USF contributions.
Order: {order_number}
Questions? Reply to this email or contact
ops@performancewest.net.