customer_woo_sync.py: WooCommerce online customers (wc_customer_lookup+billing) → RecordGod
customer CRM, links-by-email/refresh-by-wp_user_id/insert-new, never clobbers POS rows; added
as refresh.sh step 5 (after the --clean push). shipping_sync.py mirrors disc_post_flat_rates
(+zones) → post_flat_rate/post_zone. /sales/shipping/quote (units|weight_g → 280g/record →
≤5kg parcels → flat rate × parcels, Parcel Post + Express). POS Register '📦 post' quotes the
cart + adds a postage line. AusPost +5% lands 2026-07-01 — re-pull rates then.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
86 lines
3.8 KiB
Python
86 lines
3.8 KiB
Python
#!/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()
|