#!/usr/bin/env python3 """Build data/accounts.json from the ISG territory CSV export. Mapping (decided with the rep): accountId <- OEC Account Number (canonical; ties to entitlements) accountName <- Customer Company Name domain <- Website host (fallback: Authorized Email Domain) industry <- Licensee Industry (fallback: Parent Account Industry) accountTier <- Classification: Strategic->strategic, Corporate->enterprise assignedRep <- Owner; email synthesized first.last@broadcom.com targetContacts <- Primary Contact / Contact Email / Contact Phone (if present) reference <- parent + account IDs and CRM metadata for entitlement matching Usage: python3 scripts/import_accounts.py /path/to/territory.csv """ from __future__ import annotations import csv import json import re import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent OUT = ROOT / "data" / "accounts.json" TIER_MAP = {"strategic": "strategic", "corporate": "enterprise"} EMAIL_DOMAIN = "broadcom.com" def clean_domain(website: str, email_domain: str) -> str: w = (website or "").strip() if w: w = re.sub(r"^https?://", "", w, flags=re.I) w = re.sub(r"^www\.", "", w, flags=re.I) w = w.split("/")[0].strip().lower() if "." in w: return w return (email_domain or "").strip().lower() def rep_identity(owner: str) -> dict: name = (owner or "").strip() if not name: return {"id": "rep_unassigned", "name": "(unassigned)", "email": ""} tokens = [re.sub(r"[^a-z0-9]", "", t.lower()) for t in name.split()] tokens = [t for t in tokens if t] slug = "_".join(tokens) # first.last for the email local-part (collapse middle tokens out) local = f"{tokens[0]}.{tokens[-1]}" if len(tokens) >= 2 else tokens[0] return {"id": f"rep_{slug}", "name": name, "email": f"{local}@{EMAIL_DOMAIN}"} def target_contacts(row: dict) -> list[dict]: name = (row.get("Primary Contact") or "").strip() email = (row.get("Contact Email") or "").strip() phone = (row.get("Contact Phone") or "").strip() if not (name or email): return [] return [{ "name": name or "(primary contact)", "email": email, "phone": phone, "inCrm": True, }] def main(csv_path: str) -> None: rows = list(csv.DictReader(open(csv_path, newline="", encoding="utf-8-sig"))) accounts = [] for r in rows: g = lambda k: (r.get(k) or "").strip() classification = g("Classification") accounts.append({ "accountId": g("OEC Account Number"), "accountName": g("Customer Company Name"), "domain": clean_domain(g("Website"), g("Authorized Email Domain")), "industry": g("Licensee Industry") or g("Parent Account Industry"), "accountTier": TIER_MAP.get(classification.lower(), "enterprise"), "crmClassification": classification, "subClass": g("Sub Class"), "assignedRep": rep_identity(g("Owner")), "currentProducts": [], "targetContacts": target_contacts(r), "reference": { "oecAccountNumber": g("OEC Account Number"), "erpAccountNumber": g("Erp Account Number"), "parentId": g("Parent ID"), "parentName": g("Rpt Parent Name") or g("Parent Account"), "globalParentId": g("Global Parent ID"), "globalParentName": g("Global Parent Name"), "classification": classification, "subClass": g("Sub Class"), "salesRegion": g("Sales Region"), "salesArea": g("Sales Area"), "salesTerritory": g("Sales Territory"), "renewalOwner": g("Renewal Owner"), "country": g("Country"), "state": g("State"), "website": g("Website"), "emailDomain": g("Authorized Email Domain"), }, "lastRunAt": None, }) doc = { "_note": ( "Imported from ISG Customer Sales Assignments territory CSV " "(scripts/import_accounts.py). accountId = OEC Account Number. " "Tier: Classification Strategic->strategic, Corporate->enterprise " "(verbatim in crmClassification/subClass). Rep email synthesized " "first.last@broadcom.com (UNVERIFIED). reference.parentId is the " "Parent Account ID for future product-entitlement matching. " "currentProducts empty until entitlement data is loaded." ), "accounts": accounts, } OUT.write_text(json.dumps(doc, indent=2)) print(f"wrote {len(accounts)} accounts -> {OUT}") if __name__ == "__main__": main(sys.argv[1])