new-site/scripts/generate_all_templates.py
justin 97dd08c821 Fix flagged items: CRTC email submission, BITS todo, selector docs, stale plans
- CRTC letter now auto-emailed to secretary.general@crtc.gc.ca after eSign
- BITS admin todo updated to reference electronic + physical submission
- COLIN selectors.py: documented verification status per step
- BC config: added CRTC Secretary General email address
- plan.md: marked completed items (eSign, portal auth, CRTC email)
- go-live-todo.md: marked Compliance Calendar DocType as imported

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 11:33:45 -05:00

273 lines
11 KiB
Python

#!/usr/bin/env python3
"""Generate sample documents from every DOCX template and email them."""
import os
import smtplib
import tempfile
from datetime import datetime
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
WORK = tempfile.mkdtemp(prefix="pw_template_test_")
DATE_STR = datetime.now().strftime("%Y%m%d")
TODAY = datetime.now().strftime("%B %d, %Y")
generated = []
def try_gen(num, name, func):
try:
result = func()
if result:
generated.append((name, result))
print(f"{num}. {name}: {'OK' if result else 'FAIL'}")
except Exception as e:
print(f"{num}. {name}: ERROR - {str(e)[:150]}")
# ── Common kwargs for CPNI variants ────────────────────────────────
CPNI_COMMON = dict(
entity_name="Acme Telecom LLC", frn="0015341902",
filer_id_499="829999",
address_street="1712 Pioneer Ave, Suite 200",
address_city="Cheyenne", address_state="WY", address_zip="82001",
officer_name="John Smith", officer_title="CEO",
contact_email="john@acmetelecom.example",
contact_phone="(307) 555-0142",
reporting_year=2025, complaints_count=0,
)
# ── Common kwargs for CALEA variants ───────────────────────────────
CALEA_COMMON = dict(
entity_name="Acme Telecom LLC", frn="0015341902",
law_enforcement_contact={
"name": "Jane Doe",
"phone": "(307) 555-0199",
"email_24h": "compliance@acmetelecom.example",
},
signatory_name="John Smith", signatory_title="CEO",
)
# 1. RMD Letter
def gen1():
from scripts.document_gen.templates.rmd_letter_generator import generate_rmd_letter
return generate_rmd_letter(
entity_name="Acme Telecom LLC", frn="0015341902",
provider_classification="voice_service_provider",
carrier_category="interconnected_voip",
stir_shaken_status="partial_implementation",
upstream_provider_name="Bandwidth.com",
address_street="1712 Pioneer Ave, Suite 200",
address_city="Cheyenne", address_state="WY", address_zip="82001",
contact_name="John Smith", contact_title="CEO",
contact_email="john@acmetelecom.example", contact_phone="(307) 555-0142",
ceo_name="John Smith", ceo_title="CEO",
output_path=os.path.join(WORK, f"01_rmd_letter.docx"),
)
try_gen(1, "RMD Certification Letter", gen1)
# 2. RMD Exhibit A
def gen2():
from scripts.document_gen.templates.rmd_exhibit_a_generator import generate_exhibit_a
return generate_exhibit_a(
entity_name="Acme Telecom LLC", frn="0015341902",
carrier_role="ucaas", rmd_option="option2",
upstream_provider_name="Bandwidth.com",
contact_name="John Smith", contact_title="CEO",
contact_email="john@acmetelecom.example", contact_phone="(307) 555-0142",
address="1712 Pioneer Ave, Suite 200, Cheyenne, WY 82001",
principals=["John Smith (CEO)"],
output_path=os.path.join(WORK, f"02_rmd_exhibit_a.docx"),
)
try_gen(2, "RMD Exhibit A (Robocall Mitigation Plan)", gen2)
# 3. CPNI Certification Letter (generic)
def gen3():
from scripts.document_gen.templates.cpni_cert_letter_generator import generate_cpni_cert_letter
return generate_cpni_cert_letter(
entity_name="Acme Telecom LLC", frn="0015341902",
filer_id_499="829999",
address_street="1712 Pioneer Ave, Suite 200",
address_city="Cheyenne", address_state="WY", address_zip="82001",
officer_name="John Smith", officer_title="CEO",
contact_email="john@acmetelecom.example", contact_phone="(307) 555-0142",
reporting_year=2025, complaints_count=0,
output_path=os.path.join(WORK, f"03_cpni_cert_generic.docx"),
)
try_gen(3, "CPNI Certification Letter (Generic)", gen3)
# 4. CPNI Procedure Statement
def gen4():
from scripts.document_gen.templates.cpni_procedure_statement_generator import generate_cpni_procedure_statement
return generate_cpni_procedure_statement(
entity_name="Acme Telecom LLC",
signatory_name="John Smith", signatory_title="CEO",
support_email="support@acmetelecom.example",
output_path=os.path.join(WORK, f"04_cpni_procedures.docx"),
)
try_gen(4, "CPNI Procedure Statement", gen4)
# 5. CALEA SSI Plan (generic VoIP)
def gen5():
from scripts.document_gen.templates.calea_ssi_generator import generate_calea_ssi_plan
return generate_calea_ssi_plan(
**CALEA_COMMON,
output_path=os.path.join(WORK, f"05_calea_ssi_voip.docx"),
)
try_gen(5, "CALEA SSI Plan (VoIP)", gen5)
# 6. Discontinuance Letter
def gen6():
from scripts.document_gen.templates.form_499a_discontinuance_letter_generator import generate_discontinuance_letter
return generate_discontinuance_letter(
entity_name="Acme Telecom LLC", filer_id="829999", frn="0015341902",
ein="87-1234567", address="1712 Pioneer Ave, Suite 200, Cheyenne, WY 82001",
officer_name="John Smith", officer_title="CEO",
officer_email="john@acmetelecom.example", officer_phone="(307) 555-0142",
termination_date="April 30, 2026",
discontinuance_reason="Company no longer providing telecommunications services",
output_path=os.path.join(WORK, f"06_discontinuance.docx"),
)
try_gen(6, "USAC Discontinuance Letter", gen6)
# 7. OCN Request Form
def gen7():
from scripts.document_gen.templates.ocn_request_form_generator import generate_ocn_request_packet
return generate_ocn_request_packet(
entity_name="Acme Telecom LLC",
company_contact_name="John Smith",
company_contact_voice="(307) 555-0142",
company_contact_email="john@acmetelecom.example",
company_contact_address="1712 Pioneer Ave, Suite 200, Cheyenne, WY 82001",
service_category="IPES",
operating_states=["WY", "CO", "MT"],
output_path=os.path.join(WORK, f"07_ocn_request.docx"),
)
try_gen(7, "NECA OCN Request Form", gen7)
# 8. Reseller Certification
def gen8():
from scripts.document_gen.templates.reseller_cert_attestation_generator import generate_reseller_cert_attestation
return generate_reseller_cert_attestation(
output_path=os.path.join(WORK, f"08_reseller_cert.docx"),
filer_legal_name="Acme Telecom LLC",
filer_filer_id_499="829999",
reseller_legal_name="Upstream Carrier Inc",
reseller_filer_id_499="123456",
reporting_year=2025,
filer_contact_name="John Smith",
filer_contact_email="john@acmetelecom.example",
)
try_gen(8, "Reseller Certification Attestation", gen8)
# 9. CRTC Letter
def gen9():
from scripts.document_gen.templates.crtc_letter_generator import generate_crtc_letter
return generate_crtc_letter(
entity_name="1234567 B.C. Ltd.",
incorporation_number="BC1234567",
registered_office="123 W Georgia St, Vancouver, BC V6B 1J5",
services_description="Interconnected VoIP and UCaaS services",
director_name="John Smith",
ca_domain="acmetelecom.ca",
output_path=os.path.join(WORK, f"09_crtc_letter.docx"),
)
try_gen(9, "CRTC Registration Letter", gen9)
# 10-18. CPNI variants
CPNI_VARIANTS = [
("cpni_clec_generator", "generate_cpni_clec", "CPNI CLEC (Facilities)"),
("cpni_ixc_generator", "generate_cpni_ixc", "CPNI IXC (Facilities)"),
("cpni_wireless_generator", "generate_cpni_wireless", "CPNI Wireless (CMRS)"),
("cpni_clec_reseller_generator", "generate_cpni_clec_reseller", "CPNI CLEC Reseller"),
("cpni_ixc_reseller_generator", "generate_cpni_ixc_reseller", "CPNI IXC Reseller"),
("cpni_wireless_mvno_generator", "generate_cpni_wireless_mvno", "CPNI Wireless MVNO"),
("cpni_private_line_generator", "generate_cpni_private_line", "CPNI Private Line"),
("cpni_satellite_generator", "generate_cpni_satellite", "CPNI Satellite"),
("cpni_audio_bridge_generator", "generate_cpni_audio_bridge", "CPNI Audio Bridge"),
]
for i, (module, func_name, label) in enumerate(CPNI_VARIANTS, 10):
def make_gen(m=module, fn=func_name, n=i):
def gen():
mod = __import__(f"scripts.document_gen.templates.{m}", fromlist=[fn])
func = getattr(mod, fn)
return func(**CPNI_COMMON, output_path=os.path.join(WORK, f"{n:02d}_{m}.docx"))
return gen
try_gen(i, label, make_gen())
# 19-24. CALEA variants
CALEA_VARIANTS = [
("calea_wireless_generator", "generate_calea_wireless", "CALEA Wireless (CMRS)"),
("calea_ixc_ss7_generator", "generate_calea_ixc_ss7", "CALEA IXC SS7"),
("calea_clec_ss7_generator", "generate_calea_clec_ss7", "CALEA CLEC SS7"),
("calea_satellite_generator", "generate_calea_satellite", "CALEA Satellite"),
("calea_wireless_mvno_generator", "generate_calea_wireless_mvno", "CALEA Wireless MVNO"),
("calea_audio_bridge_generator", "generate_calea_audio_bridge", "CALEA Audio Bridge"),
]
for i, (module, func_name, label) in enumerate(CALEA_VARIANTS, 19):
def make_gen(m=module, fn=func_name, n=i):
def gen():
mod = __import__(f"scripts.document_gen.templates.{m}", fromlist=[fn])
func = getattr(mod, fn)
return func(**CALEA_COMMON, output_path=os.path.join(WORK, f"{n:02d}_{m}.docx"))
return gen
try_gen(i, label, make_gen())
# 25. Engagement Letter (499-A)
def gen25():
from scripts.document_gen.templates.engagement_letter_499a import generate_engagement_letter
return generate_engagement_letter(
entity_name="Acme Telecom LLC",
contact_name="John Smith",
contact_email="john@acmetelecom.example",
order_number="CO-TEST-ENG",
filing_years=[2023, 2024, 2025],
output_path=os.path.join(WORK, f"25_engagement_letter.docx"),
)
try_gen(25, "Engagement Letter (499-A Past-Due)", gen25)
print(f"\n=== Generated {len(generated)} documents ===")
# Email all
if generated:
msg = MIMEMultipart()
msg["From"] = "Performance West <noreply@performancewest.net>"
msg["To"] = "justin@performancewest.net"
msg["Subject"] = f"All Templates: {len(generated)} documents ({TODAY})"
msg["Reply-To"] = "info@performancewest.net"
body = f"{len(generated)} document templates generated with sample data.\n\n"
body += "Entity: Acme Telecom LLC (FRN: 0015341902)\n\n"
for name, path in generated:
size = os.path.getsize(path)
body += f" {name}: {os.path.basename(path)} ({size:,} bytes)\n"
msg.attach(MIMEText(body, "plain"))
for name, path in generated:
with open(path, "rb") as f:
part = MIMEBase("application", "octet-stream")
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header("Content-Disposition", f'attachment; filename="{os.path.basename(path)}"')
msg.attach(part)
with smtplib.SMTP("email-smtp.us-east-2.amazonaws.com", 587, timeout=30) as s:
s.starttls()
s.login("AKIAYEWLMNWPHSHQWCRD", "BKrUBud+KjyaRA1RiA26FFu1R+hqR4cpFShwbZf7RUzG")
s.send_message(msg)
print(f"\nEmailed {len(generated)} documents to justin@performancewest.net")