#!/usr/bin/env python3 """Sync WooCommerce online customers → RecordGod's unified `customer` CRM (NON-destructive). python3 customer_woo_sync.py | ssh -C root@100.94.195.115 \ 'docker exec -i recordgod-db psql -U recordgod -d recordgod -q -v ON_ERROR_STOP=1' Source = wc_customer_lookup (+ billing_phone / billing_address_1 from usermeta). Upsert order: 1. link an existing in-store customer to its Woo account by EMAIL (set wp_user_id), keep their entered data, 2. refresh by wp_user_id (only fill BLANK fields — never clobber POS-entered data), 3. insert genuinely-new online customers. Woo stays source-of-truth for online accounts; POS rows are never overwritten. Re-run after a clone refresh. """ import re import pathlib import sys import pymysql WP_CONFIG = "/opt/homebrew/var/www/monsterrobot.localsite/wp-config.php" SOCK = "/opt/homebrew/var/mysql/mysql.sock" UPSERT = r""" -- 1. an in-store customer with the same email IS this Woo account → link it (keep their data) UPDATE customer c SET wp_user_id = w.wp_user_id, phone = coalesce(nullif(c.phone,''), w.phone), address = coalesce(nullif(c.address,''), w.address) FROM _woo w WHERE c.wp_user_id IS NULL AND w.email <> '' AND lower(c.email) = lower(w.email); -- 2. already linked → only fill blanks (never overwrite POS-entered values) UPDATE customer c SET email = coalesce(nullif(c.email,''), w.email), phone = coalesce(nullif(c.phone,''), w.phone), address = coalesce(nullif(c.address,''), w.address) FROM _woo w WHERE c.wp_user_id = w.wp_user_id; -- 3. brand-new online customer (no wp_user_id match AND no email match) INSERT INTO customer (wp_user_id, first_name, last_name, email, phone, address, is_guest) SELECT w.wp_user_id, w.first_name, w.last_name, w.email, w.phone, w.address, false FROM _woo w WHERE NOT EXISTS (SELECT 1 FROM customer c WHERE c.wp_user_id = w.wp_user_id) AND NOT EXISTS (SELECT 1 FROM customer c WHERE w.email <> '' AND lower(c.email) = lower(w.email)); """ def creds(): t = pathlib.Path(WP_CONFIG).read_text() g = lambda k: re.search(rf"'{k}',\s*'([^']*)'", t).group(1) return g("DB_NAME"), g("DB_USER"), g("DB_PASSWORD") def cp(v): if v is None or v == "": return r"\N" return (str(v).replace("\\", "\\\\").replace("\t", "\\t") .replace("\n", "\\n").replace("\r", "\\r")) def main(): name, user, pw = creds() my = pymysql.connect(unix_socket=SOCK, user=user, password=pw, database=name, cursorclass=pymysql.cursors.DictCursor) c = my.cursor() P = "wp_rmp_" c.execute(f""" SELECT cl.user_id, cl.first_name, cl.last_name, cl.email, cl.city, cl.state, cl.postcode, cl.country, (SELECT meta_value FROM {P}usermeta WHERE user_id=cl.user_id AND meta_key='billing_phone' LIMIT 1) AS phone, (SELECT meta_value FROM {P}usermeta WHERE user_id=cl.user_id AND meta_key='billing_address_1' LIMIT 1) AS addr1 FROM {P}wc_customer_lookup cl WHERE cl.user_id IS NOT NULL AND cl.email IS NOT NULL AND cl.email <> ''""") rows = c.fetchall() out = sys.stdout out.write("CREATE TEMP TABLE _woo (wp_user_id bigint, first_name text, last_name text, email text, phone text, address text);\n") out.write("COPY _woo (wp_user_id, first_name, last_name, email, phone, address) FROM stdin;\n") for r in rows: parts = [r["addr1"], r["city"], f'{r["state"]} {r["postcode"]}'.strip(), r["country"]] addr = ", ".join(p for p in parts if p and str(p).strip()) out.write("\t".join([cp(r["user_id"]), cp(r["first_name"]), cp(r["last_name"]), cp(r["email"]), cp(r["phone"]), cp(addr)]) + "\n") out.write("\\.\n") out.write(UPSERT) print(f"staged {len(rows)} Woo customers", file=sys.stderr) if __name__ == "__main__": main()