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>
69 lines
2.4 KiB
Python
69 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
||
"""Mirror WowPlatter's AusPost flat-rate + zone tables → RecordGod Postgres.
|
||
|
||
python3 shipping_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'
|
||
|
||
post_flat_rate = service × size/weight bracket → price (Parcel Post / Express, own packaging).
|
||
post_zone = postcode range → zone (kept for future distance/zone pricing; flat rate is weight-only).
|
||
NOTE: AusPost rates rise ~+5% on 2026-07-01 — re-pull from the WowPlatter table (PDF→Gemini path) after the update.
|
||
"""
|
||
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"
|
||
|
||
SCHEMA = """
|
||
DROP TABLE IF EXISTS post_flat_rate, post_zone CASCADE;
|
||
CREATE TABLE post_flat_rate (service_key text, packaging_type text, size_label text,
|
||
weight_min_g int, weight_max_g int, price numeric(10,2));
|
||
CREATE TABLE post_zone (postcode_start int, postcode_end int, zone_code text);
|
||
CREATE INDEX ON post_flat_rate (service_key, weight_min_g, weight_max_g);
|
||
CREATE INDEX ON post_zone (postcode_start, postcode_end);
|
||
"""
|
||
|
||
FR = ["service_key", "packaging_type", "size_label", "weight_min_g", "weight_max_g", "price"]
|
||
ZN = ["postcode_start", "postcode_end", "zone_code"]
|
||
|
||
|
||
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 block(out, table, cols, rows):
|
||
out.write(f"COPY {table} ({','.join(cols)}) FROM stdin;\n")
|
||
for r in rows:
|
||
out.write("\t".join(cp(r[c]) for c in cols) + "\n")
|
||
out.write("\\.\n\n")
|
||
print(f" {table:16} {len(rows):>4}", file=sys.stderr)
|
||
|
||
|
||
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_disc_"
|
||
out = sys.stdout
|
||
out.write(SCHEMA)
|
||
c.execute(f"SELECT {','.join(FR)} FROM {P}post_flat_rates")
|
||
block(out, "post_flat_rate", FR, c.fetchall())
|
||
c.execute(f"SELECT {','.join(ZN)} FROM {P}post_zones")
|
||
block(out, "post_zone", ZN, c.fetchall())
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|