"""South Carolina intrastate Certificate of Compliance (COC) flow. For-hire PROPERTY carriers based in / operating intrastate in SC register via the SCDMV Certificate of Compliance (COC) — NOT a PSC certificate (which only covers passenger, household-goods, and hazardous-waste-for-disposal carriers). Compliance steps we automate for an SC intrastate property carrier: 1. Confirm the carrier's liability insurance is (or will be) filed with SCDMV on a Form E by their INSURANCE COMPANY (SCDMV does not accept an ACORD cert). We email a simple yes/no question with a one-click response page. - YES -> proceed to bill the $25 COC fee + file the COC application. - NO -> open a broker-referral ticket so we connect them with an insurer that writes SC intrastate liability and can file the Form E. 2. Bill the exact $25 SCDMV COC new-application fee at cost (gov-fee child), reusing the standard payment-link flow. 3. Fill + submit the SCDMV Form COC (mail w/ $25 check to Blythewood, or fax), and confirm the Form E is on record. Coverage class (drives whether cargo insurance / Form H is needed, and is the basis for the state fee determination): - E-L : low-value commodities (scrap metal, dump-truck aggregates) — Form E liability only, no cargo insurance. - E-LC : property properly insured for any cargo — Form E + Form H. Insurance minimums (intrastate, non-hazmat liability): - GVWR >= 10,000 lbs: $750,000 - GVWR < 10,000 lbs: $300,000 """ from __future__ import annotations import json import logging import os import smtplib from email.mime.text import MIMEText LOG = logging.getLogger("workers.services.sc_coc_filing") SITE = os.getenv("PUBLIC_SITE_URL", "https://performancewest.net").rstrip("/") SMTP_HOST = os.getenv("SMTP_HOST", "co.carrierone.com") SMTP_PORT = int(os.getenv("SMTP_PORT", "587")) SMTP_USER = os.getenv("SMTP_USER", "") SMTP_PASS = os.getenv("SMTP_PASS", "") SMTP_FROM = os.getenv("SMTP_FROM", "Performance West ") FROM_ADDR = "noreply@performancewest.net" # Replies (carrier questions) route to the monitored info@ mailbox. REPLY_TO = os.getenv("SC_COC_REPLY_TO", "info@performancewest.net") # SCDMV COC submission coordinates (from SCDMV Form COC, rev 11/2025). SCDMV_COC = { "mail": "SCDMV, P.O. Box 1498, Blythewood, SC 29016-0027", "fax": "(803) 896-2698", "phone": "(803) 896-3870", "new_fee_usd": 25, } def liability_minimum_usd(intake: dict) -> int: """SC intrastate non-hazmat liability minimum by GVWR bracket.""" bracket = (intake.get("gross_weight_bracket") or "").lower() # Treat unknown / 26k / 80k brackets as the >=10k bucket (the common case). if bracket in ("under_10k", "lt_10k"): return 300_000 return 750_000 def insurance_response_url(order_number: str, answer: str) -> str: """One-click yes/no link the customer clicks from the email.""" return f"{SITE}/order/sc-insurance?order={order_number}&have={answer}" def send_insurance_question_email(order_number: str, customer_email: str, customer_name: str, entity_name: str, intake: dict) -> bool: """Email the carrier a simple yes/no: do they have SC intrastate liability insurance their insurer can file on a Form E with SCDMV?""" if not customer_email: return False minimum = liability_minimum_usd(intake) yes_url = insurance_response_url(order_number, "yes") no_url = insurance_response_url(order_number, "no") body = ( f"Hi {customer_name or 'there'},\n\n" f"We're getting your South Carolina intrastate authority set up for " f"{entity_name}. In SC, a for-hire carrier like yours registers with the " f"SCDMV (Certificate of Compliance) — and the one thing the state requires " f"from your insurance company is a liability filing called a \"Form E.\"\n\n" f"Quick question so we know how to proceed:\n\n" f"Does your current insurance company have (or can they file) a Form E " f"showing at least ${minimum:,} in liability coverage for South Carolina " f"intrastate operation?\n\n" f"(Note: this must be a Form E filed by your insurance COMPANY directly " f"with SCDMV — a regular ACORD certificate of insurance is not accepted.)\n\n" f"Not sure? Give your insurance agent a quick call and ask if they can " f"file a Form E with the SCDMV before choosing below — that way we pick " f"the right next step the first time.\n\n" f"✅ YES — my insurer can file the Form E:\n{yes_url}\n\n" f"❌ NO / NOT SURE — I need help getting the right insurance:\n{no_url}\n\n" f"If you click NO, no problem — we'll connect you with a broker who writes " f"SC intrastate trucking liability and can file the Form E for you.\n\n" f"Once your Form E is on file, we complete your SCDMV Certificate of " f"Compliance and you're cleared to operate.\n\n" f"Order: {order_number}\n" f"Questions? Just reply here or call (888) 411-0383.\n\n" f"Performance West Inc.\nDOT / State Motor Carrier Compliance\n" ) try: msg = MIMEText(body) msg["Subject"] = f"Quick question about your SC insurance — {entity_name}" msg["From"] = SMTP_FROM msg["To"] = customer_email msg["Reply-To"] = REPLY_TO with smtplib.SMTP(SMTP_HOST, SMTP_PORT, timeout=30) as s: s.starttls() if SMTP_USER and SMTP_PASS: s.login(SMTP_USER, SMTP_PASS) s.sendmail(FROM_ADDR, [customer_email], msg.as_string()) LOG.info("[%s] SC insurance question emailed to %s", order_number, customer_email) return True except Exception as exc: # noqa: BLE001 LOG.error("[%s] Failed to send SC insurance question: %s", order_number, exc) return False def record_insurance_answer(order_number: str, have_insurance: bool) -> bool: """Persist the carrier's yes/no into intake_data.sc_coc_insurance. Returns True on success. Idempotent.""" try: import psycopg2 conn = psycopg2.connect(os.environ.get("DATABASE_URL", "")) with conn.cursor() as cur: cur.execute( "SELECT intake_data FROM compliance_orders WHERE order_number = %s", (order_number,), ) row = cur.fetchone() if not row: conn.close() return False intake = row[0] or {} if isinstance(intake, str): intake = json.loads(intake) intake["sc_coc_insurance"] = "yes" if have_insurance else "no" from datetime import datetime, timezone intake["sc_coc_insurance_at"] = datetime.now(timezone.utc).isoformat() cur.execute( "UPDATE compliance_orders SET intake_data = %s, updated_at = now() " "WHERE order_number = %s", (json.dumps(intake), order_number), ) conn.commit() conn.close() LOG.info("[%s] Recorded SC COC insurance answer: %s", order_number, "yes" if have_insurance else "no") return True except Exception as exc: # noqa: BLE001 LOG.error("[%s] Failed to record insurance answer: %s", order_number, exc) return False def build_coc_package(order_number: str, intake: dict, coverage_class: str | None = None) -> str | None: """Fill the SCDMV Form COC for this order. Returns the filled PDF path.""" try: from scripts.document_gen.templates.sc_coc_pdf_filler import fill_sc_coc return fill_sc_coc(intake, order_number=order_number, coverage_class=coverage_class) except Exception as exc: # noqa: BLE001 LOG.error("[%s] Failed to build COC package: %s", order_number, exc) return None