#!/usr/bin/env python3 """Import terminated customers (status=4) with their terminate reason as Lead intelligence.""" import pymysql import psycopg2 import uuid from datetime import datetime, timezone from html import unescape LEGACY = {"host": "10.100.80.100", "user": "facturation", "password": "VD67owoj", "database": "gestionclient", "connect_timeout": 30, "read_timeout": 300} PG = {"host": "db", "port": 5432, "user": "postgres", "password": "123", "dbname": "_eb65bdc0c4b1b2d6"} ADMIN = "Administrator" GROUP_MAP = {1: "Individual", 4: "Commercial", 5: "Individual", 6: "Individual", 7: "Individual", 8: "Commercial", 9: "Government", 10: "Non Profit"} def uid(p=""): return p + uuid.uuid4().hex[:10] def now(): return datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S.%f") def clean(v): if not v: return "" return unescape(str(v)).strip() def log(msg): print(msg, flush=True) def main(): ts = now() log("=== Import Terminated Customers (status 3,4,5) ===") mc = pymysql.connect(**LEGACY) cur = mc.cursor(pymysql.cursors.DictCursor) cur.execute("SELECT * FROM account WHERE status IN (3,4,5) ORDER BY id") accounts = cur.fetchall() cur.execute("SELECT * FROM delivery WHERE account_id IN (SELECT id FROM account WHERE status IN (3,4,5)) ORDER BY account_id") deliveries = cur.fetchall() mc.close() log(" {} terminated accounts, {} deliveries".format(len(accounts), len(deliveries))) del_by = {} for d in deliveries: del_by.setdefault(d["account_id"], []).append(d) pg = psycopg2.connect(**PG) pgc = pg.cursor() pgc.execute('SELECT legacy_account_id FROM "tabCustomer" WHERE legacy_account_id > 0') existing = set(r[0] for r in pgc.fetchall()) c_ok = c_addr = c_skip = c_err = 0 for i, a in enumerate(accounts): aid = a["id"] if aid in existing: c_skip += 1 continue first = clean(a["first_name"]) last = clean(a["last_name"]) company = clean(a["company"]) if company: ctype, cname = "Company", company else: ctype, cname = "Individual", "{} {}".format(first, last).strip() or "Client-{}".format(aid) cust_id = uid("CUST-") group = GROUP_MAP.get(a["group_id"], "Individual") # Build customer_details with terminate info details = "" if a.get("terminate_reason"): details += "Raison départ: {}\n".format(clean(a["terminate_reason"])) if a.get("terminate_cie"): details += "Parti chez: {}\n".format(clean(a["terminate_cie"])) if a.get("terminate_note"): details += "Notes: {}\n".format(clean(a["terminate_note"])[:500]) if a.get("terminate_date"): details += "Date: {}\n".format(clean(a["terminate_date"])) try: pgc.execute(""" INSERT INTO "tabCustomer" ( name, creation, modified, modified_by, owner, docstatus, idx, naming_series, customer_name, customer_type, customer_group, territory, default_currency, language, disabled, legacy_account_id, legacy_customer_id, ppa_enabled, stripe_id, customer_pos_id, customer_details ) VALUES ( %s, %s, %s, %s, %s, 0, 0, 'CUST-.YYYY.-', %s, %s, %s, 'Canada', 'CAD', 'fr', 1, %s, %s, 0, %s, %s, %s ) """, (cust_id, ts, ts, ADMIN, ADMIN, cname, ctype, group, aid, clean(a.get("customer_id")), clean(a.get("stripe_id")) or None, clean(a.get("customer_id")), details or None)) c_ok += 1 # Contact email = clean(a.get("email")) if first or email: cont_id = uid("CONT-") full = "{} {}".format(first, last).strip() pgc.execute(""" INSERT INTO "tabContact" ( name, creation, modified, modified_by, owner, docstatus, idx, first_name, last_name, full_name, email_id, phone, mobile_no, status ) VALUES (%s, %s, %s, %s, %s, 0, 0, %s, %s, %s, %s, %s, %s, 'Open') """, (cont_id, ts, ts, ADMIN, ADMIN, first or cname, last or None, full or cname, email or None, clean(a.get("tel_home")) or None, clean(a.get("cell")) or None)) pgc.execute(""" INSERT INTO "tabDynamic Link" ( name, creation, modified, modified_by, owner, docstatus, idx, link_doctype, link_name, link_title, parent, parentfield, parenttype ) VALUES (%s, %s, %s, %s, %s, 0, 1, 'Customer', %s, %s, %s, 'links', 'Contact') """, (uid("DL-"), ts, ts, ADMIN, ADMIN, cust_id, cname, cont_id)) # Addresses for j, d in enumerate(del_by.get(aid, [])): addr1 = clean(d.get("address1")) city = clean(d.get("city")) if not addr1 and not city: continue addr_id = uid("ADDR-") pgc.execute(""" INSERT INTO "tabAddress" ( name, creation, modified, modified_by, owner, docstatus, idx, address_title, address_type, address_line1, city, state, pincode, country, is_primary_address, is_shipping_address ) VALUES (%s, %s, %s, %s, %s, 0, 0, %s, 'Shipping', %s, %s, %s, %s, 'Canada', %s, 1) """, (addr_id, ts, ts, ADMIN, ADMIN, clean(d.get("name")) or cname, addr1 or "N/A", city or "N/A", clean(d.get("state")) or "QC", clean(d.get("zip")), 1 if j == 0 else 0)) pgc.execute(""" INSERT INTO "tabDynamic Link" ( name, creation, modified, modified_by, owner, docstatus, idx, link_doctype, link_name, link_title, parent, parentfield, parenttype ) VALUES (%s, %s, %s, %s, %s, 0, %s, 'Customer', %s, %s, %s, 'links', 'Address') """, (uid("DL-"), ts, ts, ADMIN, ADMIN, j+1, cust_id, cname, addr_id)) c_addr += 1 except Exception as e: c_err += 1 pg.rollback() if c_err <= 10: log(" ERR #{} {} -> {}".format(aid, cname[:30], str(e)[:80])) continue if c_ok % 500 == 0: pg.commit() log(" [{}/{}] created={} addr={} skip={} err={}".format(i+1, len(accounts), c_ok, c_addr, c_skip, c_err)) pg.commit() pg.close() log("") log("=" * 60) log("Terminated Customers: {} created, {} skipped, {} errors".format(c_ok, c_skip, c_err)) log("Addresses: {}".format(c_addr)) log("All terminated customers have disabled=1 + terminate details in customer_details") log("=" * 60) if __name__ == "__main__": main()