feat(shipping): use current AusPost own-packaging rates (RecordGod not live pre-1-Jul, no dating needed)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ef4769784f
commit
bfe6a08dfb
@ -380,9 +380,7 @@ async def shipping_quote(units: int | None = None, weight_g: int | None = None,
|
|||||||
rows = await db.execute(text(
|
rows = await db.execute(text(
|
||||||
"SELECT service_key, price::float AS price FROM post_flat_rate "
|
"SELECT service_key, price::float AS price FROM post_flat_rate "
|
||||||
"WHERE :w BETWEEN weight_min_g AND weight_max_g"), {"w": per})
|
"WHERE :w BETWEEN weight_min_g AND weight_max_g"), {"w": per})
|
||||||
seen = {}
|
seen = {r["service_key"]: r["price"] for r in rows.mappings()}
|
||||||
for r in rows.mappings():
|
|
||||||
seen.setdefault(r["service_key"], r["price"])
|
|
||||||
opts = [{"service": k, "label": k.replace("_", " ").title(), "price": round(v * parcels, 2)}
|
opts = [{"service": k, "label": k.replace("_", " ").title(), "price": round(v * parcels, 2)}
|
||||||
for k, v in sorted(seen.items(), key=lambda x: x[1])]
|
for k, v in sorted(seen.items(), key=lambda x: x[1])]
|
||||||
return {"weight_g": weight_g, "parcels": parcels, "per_parcel_g": per, "options": opts}
|
return {"weight_g": weight_g, "parcels": parcels, "per_parcel_g": per, "options": opts}
|
||||||
|
|||||||
@ -4,9 +4,10 @@
|
|||||||
python3 shipping_sync.py | ssh -C root@100.94.195.115 \
|
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'
|
'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_flat_rate = service × size/weight bracket → price (Parcel Post / Express). post_zone = postcode range.
|
||||||
post_zone = postcode range → zone (kept for future distance/zone pricing; flat rate is weight-only).
|
Prices use AusPost's 2026-07-01 "own packaging, postage only" rates (the bracket the shop ships records in) —
|
||||||
NOTE: AusPost rates rise ~+5% on 2026-07-01 — re-pull from the WowPlatter table (PDF→Gemini path) after the update.
|
loaded straight in since RecordGod isn't live before the change. Update RATES below from the next Post Charges
|
||||||
|
Guide (John's PDF→Gemini path) and re-run.
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
import pathlib
|
import pathlib
|
||||||
@ -26,6 +27,12 @@ CREATE INDEX ON post_flat_rate (service_key, weight_min_g, weight_max_g);
|
|||||||
CREATE INDEX ON post_zone (postcode_start, postcode_end);
|
CREATE INDEX ON post_zone (postcode_start, postcode_end);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Current AusPost rates — own packaging, postage only, by weight (effective 2026-07-01 Post Charges Guide).
|
||||||
|
RATES = { # service_key -> {size_label: price}
|
||||||
|
"PARCEL_POST": {"XS": "10.20", "S": "11.70", "M": "16.00", "L": "20.25", "XL": "24.45"},
|
||||||
|
"EXPRESS_POST": {"XS": "13.20", "S": "15.20", "M": "20.00", "L": "24.75", "XL": "32.95"},
|
||||||
|
}
|
||||||
|
|
||||||
FR = ["service_key", "packaging_type", "size_label", "weight_min_g", "weight_max_g", "price"]
|
FR = ["service_key", "packaging_type", "size_label", "weight_min_g", "weight_max_g", "price"]
|
||||||
ZN = ["postcode_start", "postcode_end", "zone_code"]
|
ZN = ["postcode_start", "postcode_end", "zone_code"]
|
||||||
|
|
||||||
@ -58,8 +65,13 @@ def main():
|
|||||||
P = "wp_rmp_disc_"
|
P = "wp_rmp_disc_"
|
||||||
out = sys.stdout
|
out = sys.stdout
|
||||||
out.write(SCHEMA)
|
out.write(SCHEMA)
|
||||||
c.execute(f"SELECT {','.join(FR)} FROM {P}post_flat_rates")
|
c.execute(f"SELECT {','.join(FR)} FROM {P}post_flat_rates") # structure (brackets) from WowPlatter
|
||||||
block(out, "post_flat_rate", FR, c.fetchall())
|
rows = c.fetchall()
|
||||||
|
for r in rows: # …prices overridden with the current AusPost ones
|
||||||
|
new = RATES.get(r["service_key"], {}).get(r["size_label"])
|
||||||
|
if new is not None:
|
||||||
|
r["price"] = new
|
||||||
|
block(out, "post_flat_rate", FR, rows)
|
||||||
c.execute(f"SELECT {','.join(ZN)} FROM {P}post_zones")
|
c.execute(f"SELECT {','.join(ZN)} FROM {P}post_zones")
|
||||||
block(out, "post_zone", ZN, c.fetchall())
|
block(out, "post_zone", ZN, c.fetchall())
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user