← back to Hollywood Price 2026
build_plan.py
78 lines
#!/usr/bin/env python3
"""Build the Hollywood/Momentum pricing plan.
Scope (Steve 2026-07-12): price ACTIVE + Needs-Price Hollywood Wallcoverings products
whose custom.dw_sku matches the Momentum feed. EXCLUDE DWHW2- (garbage prefix).
Price = feed `hw` (Hollywood retail = Momentum list x 1.448). Unit = feed `uom`.
Output: plan.csv (gid, dw_sku, sample_sku_base, uom, hw, pattern, color, width, title). $0."""
import sys
import os
import json
import csv
import collections
sys.path.insert(0, "lib")
from shopify import gql
FEED = os.path.expanduser("~/Projects/hollywood-import/momentum-feed/acoustic-golive.json")
OUT = "plan.csv"
Q = """query($q:String!,$after:String){ products(first:200, after:$after, query:$q){
pageInfo{hasNextPage endCursor}
edges{ node{ id legacyResourceId handle title
dwsku: metafield(namespace:"custom", key:"dw_sku"){ value }
variants(first:5){ edges{ node{ sku title } } } } } } }"""
SEARCH = "vendor:'Hollywood Wallcoverings' status:active tag:Needs-Price"
def sample_base(node):
for e in node["variants"]["edges"]:
sk = (e["node"]["sku"] or "")
low = sk.lower()
if low.endswith("-sample"):
return sk[:-len("-sample")]
return None
def main():
feed = json.load(open(FEED))
by_dw = {str(r.get("dw_sku")).strip(): r for r in feed if r.get("dw_sku")}
prods, cur = [], None
while True:
d = gql(Q, {"q": SEARCH, "after": cur})
p = d["products"]; prods += [e["node"] for e in p["edges"]]
if not p["pageInfo"]["hasNextPage"]:
break
cur = p["pageInfo"]["endCursor"]
rows, skipped = [], {"dwhw2": 0, "no_dwsku": 0, "no_feed": 0, "no_hw": 0, "no_sample": 0}
for n in prods:
dw = (n.get("dwsku") or {}).get("value")
if not dw:
skipped["no_dwsku"] += 1; continue
if dw.startswith("DWHW2"):
skipped["dwhw2"] += 1; continue
fr = by_dw.get(dw.strip())
if not fr:
skipped["no_feed"] += 1; continue
hw = fr.get("hw")
if not hw or float(hw) <= 0:
skipped["no_hw"] += 1; continue
sb = sample_base(n)
if not sb:
skipped["no_sample"] += 1; continue
rows.append({
"gid": n["id"], "product_id": n["legacyResourceId"], "handle": n["handle"],
"title": n["title"], "dw_sku": dw, "sample_sku_base": sb,
"uom": fr.get("uom"), "hw": hw, "pattern": fr.get("pattern"),
"color": fr.get("color"), "width": fr.get("width"),
})
with open(OUT, "w", newline="") as f:
w = csv.DictWriter(f, fieldnames=list(rows[0].keys()))
w.writeheader(); w.writerows(rows)
print(f"PLAN: {len(rows)} priceable products -> {OUT}")
print(" skipped:", skipped)
print(" uom:", dict(collections.Counter(r["uom"] for r in rows)))
hws = sorted(float(r["hw"]) for r in rows)
print(f" hw range: ${hws[0]:.2f} - ${hws[-1]:.2f} median ${hws[len(hws)//2]:.2f}")
if __name__ == "__main__":
main()