"""NECA OCN / Company Code registration handler. Generates the NECA Company Code Request Form packet for a carrier and creates an ERPNext admin ToDo for the Accounting Advisor to mail/fax/email the packet to NECA along with the required fee. Once NECA assigns the OCN (10 business days standard / 5 expedited), the admin records it on the telecom_entity — subsequent compliance checkups and 499-A filings read it from there. Because NECA does not offer an API or self-service submission, this handler is inherently human-in-the-loop — there is no Playwright flow for this service. The auto-filing toggle is therefore not gated: the handler only produces the packet + ToDo, never submits directly. """ from __future__ import annotations import logging import os from datetime import datetime from .base_handler import BaseServiceHandler logger = logging.getLogger(__name__) class OCNRegistrationHandler(BaseServiceHandler): SERVICE_SLUG = "ocn-registration" SERVICE_NAME = "NECA OCN / Company Code Registration" REQUIRES_LLM = False async def process(self, order_data: dict) -> list[str]: work_dir = self._make_work_dir() order_number = order_data["name"] entity = order_data.get("entity", {}) intake = order_data.get("intake_data") or {} generated: list[str] = [] # Service category defaults to IPES (VoIP) unless intake specifies. category = (intake.get("service_category") or "IPES").upper() expedited = bool(intake.get("expedited", False)) operating_states = intake.get("operating_states") or [] # Derive contact info from the entity; default requestor to PW. from scripts.document_gen.templates.ocn_request_form_generator import ( generate_ocn_request_packet, ) date_str = datetime.now().strftime("%Y%m%d") packet_docx = os.path.join( work_dir, f"ocn_request_packet_{order_number}_{date_str}.docx", ) result = generate_ocn_request_packet( entity_name=entity.get("legal_name", ""), legal_entity_full=entity.get("legal_name", ""), company_contact_name=entity.get("contact_name", ""), company_contact_voice=entity.get("contact_phone", ""), company_contact_email=entity.get("contact_email", ""), company_contact_address=", ".join(filter(None, [ entity.get("address_street", ""), entity.get("address_city", ""), f"{entity.get('address_state', '')} {entity.get('address_zip', '')}".strip(), ])), service_category=category, operating_states=operating_states, expedited=expedited, output_path=packet_docx, ) if result: generated.append(result) try: generated.append(self._convert_to_pdf(result)) except Exception as exc: logger.warning("OCN packet PDF conversion failed: %s", exc) self._create_admin_todo( order_number=order_number, entity=entity, category=category, expedited=expedited, ) return generated def _create_admin_todo( self, *, order_number: str, entity: dict, category: str, expedited: bool, ) -> None: try: from scripts.workers.erpnext_client import ERPNextClient fee = "$675 (5 business days)" if expedited else "$550 (10 business days)" description = ( f"[{self.SERVICE_SLUG}] {order_number}\n\n" f"Submit NECA Company Code request on behalf of this client.\n\n" f"Entity legal name: {entity.get('legal_name', '')}\n" f"DBA: {entity.get('dba_name', '')}\n" f"FRN: {entity.get('frn', 'N/A')}\n" f"Service category: {category}\n" f"Processing: {fee}\n\n" f"Steps:\n" f" 1. Gather supporting docs (Articles of Incorporation for all " f"categories; interconnection agreements + customer invoices for " f"IPES; state PUC cert for CLEC/ULEC).\n" f" 2. Send the generated packet (in MinIO) + supporting docs + " f"fee to NECA via fax 973-993-1063 or ccfees@neca.org.\n" f" 3. Pay NECA fee via Relay virtual debit card (SID-0002).\n" f" 4. On OCN assignment: update telecom_entities.ocn and " f"telecom_entities.ocn_assigned_at on this carrier.\n" f" 5. Email client with the assigned OCN." ) ERPNextClient().create_resource( "ToDo", { "description": description, "priority": "High", "role": "Accounting Advisor", }, ) except Exception as exc: logger.error("Could not create OCN admin ToDo: %s", exc)