From 926468a8b5b65ff93b49a55083af582163fa2272 Mon Sep 17 00:00:00 2001 From: type-two Date: Sat, 27 Jun 2026 11:13:48 +1000 Subject: [PATCH] =?UTF-8?q?feat(distro):=20RareWaves=20order=20ingest=20?= =?UTF-8?q?=E2=86=92=20cost-tracked=20NEW=20stock=20+=20approval=20landing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit End-to-end: PRICEGOD scrapes a RareWaves order (account.rarewaves.com/orders/) → POST /admin/intake/distro → resolve barcode→release_id (normalised: DB barcodes stored inconsistently, functional index on digits-only + EAN/UPC leading-zero variants; Discogs barcode-search fallback) → stage one NEW copy per qty with cost_price + cost_source, in_stock=false. Idempotent per order. New '/admin/newstock' approval queue: staff confirm/re-pick the release (trgm search), set retail, flip new/used → publish (staged=f, in_stock=t). Bulk publish-all-matched-&-priced. Backend verified e2e (ingest→queue→approve→live, unapproved stay staged). PRICEGOD: rarewaves.js content script + account.rarewaves.com host perm + wowplatter.distro + bg rwDistro handler (needs extension reload to test live). Co-Authored-By: Claude Opus 4.8 --- app/admin_routes.py | 61 + app/intake_routes.py | 83 +- app/main.py | 3 + rarwacct.txt | 52 + rarworder.txt | 52 + rarworder2.txt | 52 + rarwwish1.txt | 10164 +++++++++++++++++++++++ rarwwish2.txt | 18405 +++++++++++++++++++++++++++++++++++++++++ site/admin.html | 67 +- 9 files changed, 28932 insertions(+), 7 deletions(-) create mode 100644 rarwacct.txt create mode 100644 rarworder.txt create mode 100644 rarworder2.txt create mode 100644 rarwwish1.txt create mode 100644 rarwwish2.txt diff --git a/app/admin_routes.py b/app/admin_routes.py index 4dcaa7c..2796a76 100644 --- a/app/admin_routes.py +++ b/app/admin_routes.py @@ -190,6 +190,67 @@ async def timecards(days: int = Query(14), staff_id: int | None = None, return {"shifts": shifts, "totals": totals, "days": days} +# ── New stock (distro purchases awaiting approval) — confirm release_id + set retail, then publish ── +@router.get("/newstock") +async def newstock_list(ident=Depends(require_token), db=Depends(get_db)): + rows = [dict(r) for r in (await db.execute(text(""" + SELECT i.sku, i.title, i.identifier AS barcode, i.release_id, i.cost_price, i.price, + i.condition_type, i.cost_source, i.est_market_value, + COALESCE(dc.thumb, dr.thumb) AS thumb, dr.artists_sort AS artist, dr.year, + (i.attributes->>'resolved')::bool AS resolved, i.attributes->>'slug' AS slug + FROM inventory i + LEFT JOIN disc_cache dc ON dc.release_id = i.release_id + LEFT JOIN disc_release dr ON dr.id = i.release_id + WHERE i.store_id = :s AND i.staged AND i.cost_source IS NOT NULL + ORDER BY i.cost_source DESC, i.title NULLS LAST, i.sku"""), + {"s": ident["store_id"]})).mappings()] + return {"items": rows, "count": len(rows)} + + +class NewStockIn(BaseModel): + release_id: int | None = None + title: str | None = None + price: float | None = None + condition_type: str | None = None + publish: bool = False + + +@router.post("/newstock/{sku}") +async def newstock_update(sku: str, body: NewStockIn, ident=Depends(require_token), db=Depends(get_db)): + """Staff approve a distro copy: re-pick the release / set retail / flip new-used, then publish (un-stage).""" + sets, params = [], {"sku": sku, "sid": ident["store_id"]} + if body.release_id is not None: + sets.append("release_id = :rid"); params["rid"] = body.release_id + if body.title is not None: + sets.append("title = :t"); params["t"] = body.title + if body.price is not None: + sets.append("price = :p"); params["p"] = body.price + if body.condition_type in ("new", "used"): + sets.append("condition_type = :ct"); params["ct"] = body.condition_type + if body.publish: + sets += ["staged = false", "status = 'publish'", "in_stock = true"] + if not sets: + return {"ok": True, "unchanged": True} + sets.append("updated_at = now()") + r = await db.execute(text( + f"UPDATE inventory SET {', '.join(sets)} WHERE sku = :sku AND store_id = :sid"), params) + await db.commit() + if not r.rowcount: + raise HTTPException(404, "not found") + return {"ok": True, "published": body.publish} + + +@router.post("/newstock/publish-all") +async def newstock_publish_all(ident=Depends(require_token), db=Depends(get_db)): + """Publish every resolved copy that already has a retail price (the bulk 'ship it' button).""" + r = await db.execute(text(""" + UPDATE inventory SET staged = false, status = 'publish', in_stock = true, updated_at = now() + WHERE store_id = :s AND staged AND cost_source IS NOT NULL + AND release_id IS NOT NULL AND price IS NOT NULL"""), {"s": ident["store_id"]}) + await db.commit() + return {"ok": True, "published": r.rowcount} + + @router.get("/inventory") async def inventory(q: str = Query(""), kind: str = Query(""), crate_id: int | None = Query(None), page: int = Query(1, ge=1), ident=Depends(require_token), db=Depends(get_db)): diff --git a/app/intake_routes.py b/app/intake_routes.py index 22c7b80..b9625ab 100644 --- a/app/intake_routes.py +++ b/app/intake_routes.py @@ -611,14 +611,19 @@ ITEM_IMG_DIR = Path(os.getenv("DISC_IMAGE_DIR", "/app/disc_images")) / "items" async def _resolve_barcode(db, barcode): - """barcode → release_id. Local disc_release_identifier first (16.5k 'Barcode' rows, instant), - then the Discogs barcode search on a miss.""" + """barcode → release_id. Local disc_release_identifier first — NORMALISED (DB barcodes are stored + inconsistently: '5 018775 901762' vs '042285768916'), matched on a functional index over the + digits-only form, trying the EAN-13/UPC-A leading-zero variants. Discogs barcode search on a miss.""" if not barcode: return None - bc = barcode.strip() + digits = re.sub(r"\D", "", str(barcode)) + if len(digits) < 6: + return None + cands = list({digits, digits.lstrip("0"), "0" + digits}) row = (await db.execute(text( - "SELECT release_id FROM disc_release_identifier WHERE value=:b AND type='Barcode' LIMIT 1"), - {"b": bc})).first() + "SELECT release_id FROM disc_release_identifier " + "WHERE type='Barcode' AND regexp_replace(value,'[^0-9]','','g') = ANY(:c) LIMIT 1"), + {"c": cands})).first() if row: return row[0] try: @@ -626,7 +631,7 @@ async def _resolve_barcode(db, barcode): async with c: if not ok: return None - r = await c.get("/database/search", params={"barcode": bc, "type": "release", "per_page": 1}) + r = await c.get("/database/search", params={"barcode": digits, "type": "release", "per_page": 1}) if r.status_code == 200: res = r.json().get("results", []) if res: @@ -714,6 +719,72 @@ async def intake_scan(body: ScanIn, ident=Depends(require_token), db=Depends(get return {"staged": staged, "errors": errors} +# --- Distro purchase ingest: scrape a distributor order → cost-tracked NEW stock ------------------ +# RareWaves (Shopify) order pages give barcode (in the /products/- handle) + title + qty + +# unit cost ($X.XX/ea). The PRICEGOD extension scrapes the order and POSTs it here; we resolve the +# barcode → release_id, stage one NEW copy per qty with cost_price + cost_source, for staff approval. + +class DistroItem(BaseModel): + barcode: str | None = None + release_id: int | None = None + title: str | None = None + artist: str | None = None + year: int | None = None + qty: int = 1 + unit_cost: float | None = None + slug: str | None = None + variant_id: str | None = None + image: str | None = None + + +class DistroIn(BaseModel): + source: str = "rarewaves" + order_ref: str + items: list[DistroItem] + + +@router.post("/distro") +async def intake_distro(body: DistroIn, ident=Depends(require_token), db=Depends(get_db)): + """Ingest a distributor order → staged NEW stock with per-copy cost. Idempotent per order + (re-scraping the same order is a no-op). Unresolved barcodes still stage (staff pick the release).""" + sid = ident["store_id"] + cost_source = f"{body.source} #{body.order_ref}" + existing = (await db.execute(text( + "SELECT count(*) FROM inventory WHERE cost_source=:cs AND store_id=:sid"), + {"cs": cost_source, "sid": sid})).scalar() + if existing: + return {"ok": True, "already_ingested": True, "existing": existing, "cost_source": cost_source} + + staged, errors = [], [] + for it in body.items: + try: + rid = it.release_id or await _resolve_barcode(db, it.barcode) + meta = await _enrich(db, rid) if rid else None + title = it.title or (meta or {}).get("title") + weight = (meta or {}).get("weight") + for _ in range(max(1, it.qty)): + sku = _new_sku() + attrs = {"source": body.source, "order_ref": body.order_ref, "slug": it.slug, + "variant_id": it.variant_id, "year": it.year, + "resolved": rid is not None, "scrape_image": it.image} + await db.execute(text(""" + INSERT INTO inventory (sku, store_id, kind, release_id, identifier, title, + cost_price, cost_source, condition_type, condition, weight_g, attributes, + staged, in_stock, status) + VALUES (:sku,:sid,'vinyl',:rid,:bc,:title,:cost,:cs,'new','M',:wt, + CAST(:attrs AS jsonb), true, false, 'staged') + ON CONFLICT (sku) DO NOTHING"""), + {"sku": sku, "sid": sid, "rid": rid, "bc": it.barcode, "title": title, + "cost": it.unit_cost, "cs": cost_source, "wt": weight, "attrs": json.dumps(attrs)}) + staged.append({"sku": sku, "release_id": rid, "title": title, "resolved": rid is not None}) + except Exception as e: + errors.append({"barcode": it.barcode, "error": str(e)}) + await db.commit() + resolved = sum(1 for s in staged if s["resolved"]) + return {"ok": True, "source": body.source, "order_ref": body.order_ref, "cost_source": cost_source, + "staged": len(staged), "resolved": resolved, "unresolved": len(staged) - resolved, "errors": errors} + + def _selfcheck(): # SKU from a Google-Form timestamp (both ISO and en-AU slash formats) → YYYYMMDDHHMMSS assert _sku_from_ts("2025-01-30T14:01:02.821Z") == "20250130140102" diff --git a/app/main.py b/app/main.py index c754ad2..b97cab8 100644 --- a/app/main.py +++ b/app/main.py @@ -110,6 +110,9 @@ _STARTUP_DDL = [ "ALTER TABLE inventory ADD COLUMN IF NOT EXISTS cost_price numeric(10,2)", "ALTER TABLE inventory ADD COLUMN IF NOT EXISTS cost_source text", # e.g. 'rarewaves #592619' "ALTER TABLE inventory ADD COLUMN IF NOT EXISTS condition_type text NOT NULL DEFAULT 'used'", # 'new' | 'used' + # normalised-barcode lookup (DB barcodes stored inconsistently: '5 018775 901762' vs clean digits) + "CREATE INDEX IF NOT EXISTS disc_rel_id_barcode_norm ON disc_release_identifier " + "(regexp_replace(value,'[^0-9]','','g')) WHERE type='Barcode'", ] diff --git a/rarwacct.txt b/rarwacct.txt new file mode 100644 index 0000000..de1d8a7 --- /dev/null +++ b/rarwacct.txt @@ -0,0 +1,52 @@ +https://account.rarewaves.com/orders?buyer_flags=eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJyYXJld2F2ZXMubXlzaG9waWZ5LmNvbSIsImZsYWdzIjpbXSwiZXhwIjoxNzgzMTI0NTAxLCJuYmYiOjE3ODI1MTk3MDF9._6vHtwLAajbCu2DyE4HwfkBniybBYG4Vxl2JuRRMXwI&locale=en®ion_country=AU + + +
Skip to content

Orders

  • Order #592619

    Order includes Rumours, Underground Vibes (30th Anniversary Edition), DJ Kicks: Moodyman, and 4 more products

    #592619$639.69 AUD
  • Order #581565

    Order includes Enter the Wu-Tang (36 Chambers)

    #581565$113.49 AUD
  • Order #580433

    Order includes The Truth, 50 Years of Hip-hop: The MC Crew Jams, Cooleyhighharmony, and 11 more products

    #580433$929.36 AUD
  • Order #542493

    Order includes Music to Make Love to Your Old Lady By: Instrumental Version (RSD Essential 2022), X-tra Wicked: Bobby Digital Reggae Anthology, The Music Scene

    #542493$133.05 AUD
  • Order #536697

    Order includes Enter the Wu-Tang (36 Chambers), Demon Days, Underground Vibes (30th Anniversary Edition), and 4 more products

    #536697$432.70 AUD
  • Order #530444

    Order includes Meat Puppets I, Illmatic XX, Illmatic

    #530444$146.11 AUD
  • Order #529677

    Order includes Soundpieces: Da Antidote!

    #529677$268.73 AUD
  • Order #529646

    Order includes The Now Now, Song Machine: Season 1: Strange Timez, Tomorrow Comes Today, and 4 more products

    #529646$334.68 AUD
  • Order #518892

    Order includes Third, Blue Lines, Action Adventure, and 5 more products

    #518892$696.46 AUD
  • Order #514308

    Order includes The K&D Sessions, 10,000 Gecs, O.S.T., and 1 more products

    #514308$324.63 AUD
  • Order #500772

    Order includes A Son Of The Sun, The K&D Sessions, Entroducing..... 25, and 7 more products

    #500772$889.73 AUD
  • Order #459369

    Order includes Unknown Pleasures, Rage Against the Machine, Selected Ambient Works 85-92, and 7 more products

    #459369$720.73 AUD
  • Order #428698

    Order includes Anjuna25 Anniversary Vinyl Box Set, Papua New Guinea

    #428698$108.87 AUD
  • Order #424639

    Order includes The Pulse E.P. - Volume 3

    #424639$184.95 AUD
  • Order #199657

    Order includes O.S.T.

    #199657$50.00 AUD
  • Order #184336

    Order includes Freddie, Primitive Plus, O.S.T., and 11 more products

    #184336$1,073.30 AUD
  • Order #158820

    Order includes 10,000 Gecs, Time? Astonishing!

    #158820$70.07 AUD
  • Order #158223

    Order includes Nujabes Pray Reflections, Hydeout Productions: Second Collection

    #158223$270.96 AUD
  • Order #124257

    Order includes I Ain't No Joke, Down By Law/Subway Beat (Kenny Dope Edits), Soul Supreme, and 13 more products

    #124257$574.67 AUD
  • Order #60209

    Order includes - `Uyama Hiroto - A Son Of The Sun [2LP] (Japanese import, includes Nujabes production, gatefold, limited)` VINYL

    #60209$164.97 AUD
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/rarworder.txt b/rarworder.txt new file mode 100644 index 0000000..2431d93 --- /dev/null +++ b/rarworder.txt @@ -0,0 +1,52 @@ +https://account.rarewaves.com/orders/13057121386870 + + +
Skip to content

Order #592619

Confirmed 29 May

Fulfillment status: On its way

On its way

  1. Confirmed

Fulfillment status: Confirmed

Confirmed

We're preparing these items for shipping.

Order summary

Order items

Rumours
$42.99/ea

$171.96

Underground Vibes (30th Anniversary Edition)

$48.99

DJ Kicks: Moodyman

$62.99

DJ Kicks: Theo Parrish

$59.99

DJ Kicks: Disclosure

$31.99

The Prodigy Experience

$59.99

Action Adventure

$47.99

DJ Kicks: Kruder & Dorfmeister (The Complete Mix Edition)
$108.99/ea

$217.98

Order totals

Item
Value
Subtotal · 12 items
$701.88
Order discount
RWMAY10
-$70.18
Shipping
$7.99
Total
AUD$639.69

Including $0.00 in taxes

TOTAL SAVINGS $70.18

Order details

Contact

jingkohn@gmail.com

Ship to

John King

10 Wolseley Street

Paddington Queensland 4064

Australia

Method

International Shipping

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/rarworder2.txt b/rarworder2.txt new file mode 100644 index 0000000..2b7fdea --- /dev/null +++ b/rarworder2.txt @@ -0,0 +1,52 @@ +https://account.rarewaves.com/orders/4926188945505 + + +
Skip to content

Order #124257

Confirmed 28 Jan 2023

Payment status

$26.97 AUD

Refunded 30 Jan 2023

You received a partial refund for this order.

Fulfillment status: On its way

Royal Mail -

On its way

  1. Confirmed

Fulfillment status: On its way

Royal Mail -

On its way

  1. Confirmed

Fulfillment status: On its way

Royal Mail -

On its way

  1. Confirmed

Fulfillment status: On its way

Royal Mail -

On its way

  1. Confirmed

Fulfillment status: On its way

Royal Mail -

On its way

  1. Confirmed

Fulfillment status: On its way

Royal Mail -

On its way

  1. Confirmed

Fulfillment status: On its way

Royal Mail -

On its way

  1. Confirmed

Order summary

Order items

I Ain't No Joke

$15.99

Down By Law/Subway Beat (Kenny Dope Edits)

$14.99

Quantity5
In the Corn Belt
$17.99/ea

$89.95

Soul Supreme

$43.99

Just Do You

$15.99

I Know You Got Soul

$15.99

Some Kazoos

$13.99

Lyrical King
$15.99/ea

$79.95

Pandæmonium

$5.99

The Rough Guide to Hillbilly Blues: Reborn and Remastered

$11.99

Quantity1
Harlem Underground

$15.99

Music Madness

$15.99

The Rough Guide to Unsung Heroes of Country Blues

$11.99

Quantity5
Where's the Party At?
$15.99/ea

$79.95

Flat Beat
$8.99/ea

$0.00

Order totals

Item
Value
Subtotal · 29 items
$567.68
Shipping
$6.99
Total
AUD$574.67

Including $0.00 in taxes

Refunded
-$26.97

Order details

Contact

jingkohn@gmail.com

Ship to

John King

10 Wolseley Street

PADDINGTON Queensland 4064

Australia

0413375748

Method

International Shipping

Payment

Visa6160

Visa

$601.64 AUD28 Jan 2023

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/rarwwish1.txt b/rarwwish1.txt new file mode 100644 index 0000000..c78f3ed --- /dev/null +++ b/rarwwish1.txt @@ -0,0 +1,10164 @@ +https://www.rarewaves.com/pages/wishlist?country=AU&shop_sign_in=true + + + + + Skip to content + +
+ + + + + + + + + + + + +
+
+
+
+
+
+ +

+ 10% OFF SITEWIDE +

+ | +

+

+ USE CODE: RWJUNE10 +

+
+
+
+
+
+ +

+ AVATAR FIRE & ASH +

+ | +

+

+ OUT NOW +

+
+
+
+
+
+ +

+ NEW ARROW TITLES! +

+ | +

+

+ PRE-ORDER NOW +

+
+
+
+
+
+ +

+ 4K UHD BLU-RAY +

+ | +

+

+ 2 FOR £30 +

+
+
+
+
+ +

+ 10% OFF SITEWIDE +

+ | +

+

+ USE CODE: RWJUNE10 +

+
+
+
+
+ +

+ AVATAR FIRE & ASH +

+ | +

+

+ OUT NOW +

+
+
+
+
+ +

+ NEW ARROW TITLES! +

+ | +

+

+ PRE-ORDER NOW +

+
+
+
+
+ +

+ 4K UHD BLU-RAY +

+ | +

+

+ 2 FOR £30 +

+
+
+
+
+ +

+ 10% OFF SITEWIDE +

+ | +

+

+ USE CODE: RWJUNE10 +

+
+
+
+
+ +

+ AVATAR FIRE & ASH +

+ | +

+

+ OUT NOW +

+
+
+
+
+ +

+ NEW ARROW TITLES! +

+ | +

+

+ PRE-ORDER NOW +

+
+
+
+
+ +

+ 4K UHD BLU-RAY +

+ | +

+

+ 2 FOR £30 +

+
+
+
+
+ +

+ 10% OFF SITEWIDE +

+ | +

+

+ USE CODE: RWJUNE10 +

+
+
+
+
+ +

+ AVATAR FIRE & ASH +

+ | +

+

+ OUT NOW +

+
+
+
+
+ +

+ NEW ARROW TITLES! +

+ | +

+

+ PRE-ORDER NOW +

+
+
+
+
+ +

+ 4K UHD BLU-RAY +

+ | +

+

+ 2 FOR £30 +

+
+
+
+
+ +
+ +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + +
+ +

Your Wishlists

+ + + + + + + +
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +
+ +
+ + +
+
+ + + + + + + + + + +
+ + + + + + + +
+ + +
+ + + + + + + + +
+ + +

Become A Member

\ No newline at end of file diff --git a/rarwwish2.txt b/rarwwish2.txt new file mode 100644 index 0000000..4eccbaa --- /dev/null +++ b/rarwwish2.txt @@ -0,0 +1,18405 @@ + + + Skip to content + +
+ + + + + + + + + + + + +
+
+
+
+
+
+ +

+ 10% OFF SITEWIDE +

+ | +

+

+ USE CODE: RWJUNE10 +

+
+
+
+
+
+ +

+ AVATAR FIRE & ASH +

+ | +

+

+ OUT NOW +

+
+
+
+
+
+ +

+ NEW ARROW TITLES! +

+ | +

+

+ PRE-ORDER NOW +

+
+
+
+
+
+ +

+ 4K UHD BLU-RAY +

+ | +

+

+ 2 FOR £30 +

+
+
+
+
+ +

+ 10% OFF SITEWIDE +

+ | +

+

+ USE CODE: RWJUNE10 +

+
+
+
+
+ +

+ AVATAR FIRE & ASH +

+ | +

+

+ OUT NOW +

+
+
+
+
+ +

+ NEW ARROW TITLES! +

+ | +

+

+ PRE-ORDER NOW +

+
+
+
+
+ +

+ 4K UHD BLU-RAY +

+ | +

+

+ 2 FOR £30 +

+
+
+
+
+ +

+ 10% OFF SITEWIDE +

+ | +

+

+ USE CODE: RWJUNE10 +

+
+
+
+
+ +

+ AVATAR FIRE & ASH +

+ | +

+

+ OUT NOW +

+
+
+
+
+ +

+ NEW ARROW TITLES! +

+ | +

+

+ PRE-ORDER NOW +

+
+
+
+
+ +

+ 4K UHD BLU-RAY +

+ | +

+

+ 2 FOR £30 +

+
+
+
+
+ +

+ 10% OFF SITEWIDE +

+ | +

+

+ USE CODE: RWJUNE10 +

+
+
+
+
+ +

+ AVATAR FIRE & ASH +

+ | +

+

+ OUT NOW +

+
+
+
+
+ +

+ NEW ARROW TITLES! +

+ | +

+

+ PRE-ORDER NOW +

+
+
+
+
+ +

+ 4K UHD BLU-RAY +

+ | +

+

+ 2 FOR £30 +

+
+
+
+
+ +
+ +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + +
+ + +
+
+ + + + + + + + + + + + + + + + +
+ +

Your Wishlists

+ + + + + + + +
+
+ + +
+ +
+
+
+ +
+ + + + + + +
+
+
+
+ + + +
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Method Man

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $59.99 +
+
+ Regular price + + + + $59.99 + + + Sale price + + $59.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + Sold Out + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Wu-Tang Clan

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $35.99 +
+
+ Regular price + + + + + + + Sale price + + $35.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Wu-Tang Clan

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $41.99 +
+
+ Regular price + + + + + + + Sale price + + $41.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Method Man

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $58.99 +
+
+ Regular price + + + + + + + Sale price + + $58.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Boyz II Men

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $30.99 +
+
+ Regular price + + + + + + + Sale price + + $30.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Various Artists

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $40.99 +
+
+ Regular price + + + + + + + Sale price + + $40.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + Sold Out + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Various Artists

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $27.99 +
+
+ Regular price + + + + + + + Sale price + + $27.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Prince

+ + + + + +
+ Vinyl + + +Save +33% + + + +
+
Regular price + + $41.99 +
+
+ Regular price + + + + $62.99 + + + Sale price + + $41.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Booker T. and The M.G.'s

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $27.99 +
+
+ Regular price + + + + + + + Sale price + + $27.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Sun Ra and His Astro-Intergalactic Infinity Arkestra

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $27.99 +
+
+ Regular price + + + + + + + Sale price + + $27.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Gorillaz

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $42.99 +
+
+ Regular price + + + + $37.99 + + + Sale price + + $42.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Various Artists

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $26.99 +
+
+ Regular price + + + + + + + Sale price + + $26.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + Sold Out + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Various Artists

+ + + + + +
+ Vinyl + + +Save +9% + + + +
+
Regular price + + $28.99 +
+
+ Regular price + + + + $31.99 + + + Sale price + + $28.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Gregory Isaacs

+ + + + + +
+ Vinyl + + +Save +25% + + + +
+
Regular price + + $26.99 +
+
+ Regular price + + + + $35.99 + + + Sale price + + $26.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Cold Crush Brothers

+ + + + + +
+ Vinyl + + +Save +25% + + + +
+
Regular price + + $26.99 +
+
+ Regular price + + + + $35.99 + + + Sale price + + $26.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Jimmy Castor

+ + + + + +
+ Vinyl + + +Save +25% + + + +
+
Regular price + + $26.99 +
+
+ Regular price + + + + $35.99 + + + Sale price + + $26.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Madness

+ + + + + +
+ Vinyl + + +Save +36% + + + +
+
Regular price + + $28.99 +
+
+ Regular price + + + + $44.99 + + + Sale price + + $28.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Lonnie Smith

+ + + + + +
+ Vinyl + + +Save +24% + + + +
+
Regular price + + $31.99 +
+
+ Regular price + + + + $41.99 + + + Sale price + + $31.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Sam & Dave

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $36.99 +
+
+ Regular price + + + + $36.99 + + + Sale price + + $36.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

The Maytones

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $25.99 +
+
+ Regular price + + + + + + + Sale price + + $25.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

The Streets

+ + + + + +
+ Vinyl + + +Save +11% + + + +
+
Regular price + + $33.99 +
+
+ Regular price + + + + $37.99 + + + Sale price + + $33.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Whitney Houston

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $45.99 +
+
+ Regular price + + + + + + + Sale price + + $45.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Prince

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $45.99 +
+
+ Regular price + + + + $45.99 + + + Sale price + + $45.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Dubmatix

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $17.99 +
+
+ Regular price + + + + + + + Sale price + + $17.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Dig

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $20.99 +
+
+ Regular price + + + + + + + Sale price + + $20.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Maxïmo Park

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $20.99 +
+
+ Regular price + + + + + + + Sale price + + $20.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Charles Mingus

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $20.99 +
+
+ Regular price + + + + + + + Sale price + + $20.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Oceanlab

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $384.99 +
+
+ Regular price + + + + + + + Sale price + + $384.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Various Artists

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $70.99 +
+
+ Regular price + + + + + + + Sale price + + $70.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Fleetwood Mac

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $41.99 +
+
+ Regular price + + + + + + + Sale price + + $41.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Gloria Jones

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $37.99 +
+
+ Regular price + + + + + + + Sale price + + $37.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

TOKiMONSTA

+ + + + + +
+ Vinyl + + +Save +32% + + + +
+
Regular price + + $33.99 +
+
+ Regular price + + + + $49.99 + + + Sale price + + $33.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Grateful Dead

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $46.99 +
+
+ Regular price + + + + + + + Sale price + + $46.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Black Sabbath

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $42.99 +
+
+ Regular price + + + + + + + Sale price + + $42.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Led Zeppelin

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $51.99 +
+
+ Regular price + + + + + + + Sale price + + $51.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Guns N' Roses

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $46.99 +
+
+ Regular price + + + + + + + Sale price + + $46.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

DJ Nature

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $34.99 +
+
+ Regular price + + + + + + + Sale price + + $34.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Elvis Presley

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $50.99 +
+
+ Regular price + + + + + + + Sale price + + $50.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Sun Ra

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $31.99 +
+
+ Regular price + + + + + + + Sale price + + $31.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+ + +
+ + + + + + + +
+ +
+ + +
+ +
+ + + +
+ + + + +
+ +
+ + +
+ Music +
+ +
+ +
+ + + + + +

Sun Ra & His Arkestra

+ + + + + +
+ Vinyl + + + + + +
+
Regular price + + $30.99 +
+
+ Regular price + + + + + + + Sale price + + $30.99 + +
+ +
+ +
+ + +
+ + +
+ + + + + + + + + + + + Sold Out + + + + +
+ + + +
+
+
+ + Page 1 of 3 + +
+
+
+
+
+ + + +
+
+
+ + + +
+
+ +
+ +
+ + +
+
+ + + + + + + + + + +
+ + + + + + + +
+ + +
+ + + + + + + + +
+ + +

Become A Member

\ No newline at end of file diff --git a/site/admin.html b/site/admin.html index 97b30d6..0aa7cce 100644 --- a/site/admin.html +++ b/site/admin.html @@ -71,6 +71,7 @@ 📝 Wantlist
Catalog
📥 Intake + 📦 New stock 🩹 Heal 🗺️ Store map 🗄️ Crates @@ -112,7 +113,7 @@ document.querySelectorAll('nav a[data-v]').forEach(a => a.onclick = () => go(a.d function go(v){ if(ROLE!=='admin' && (v==='connections'||v==='staff'||v==='system')) v='dashboard'; // staff can't reach admin views document.querySelectorAll('nav a[data-v]').forEach(a => a.classList.toggle('on', a.dataset.v===v)); - ({dashboard:vDash, inventory:vInv, orders:vOrders, customers:vCustomers, wantlist:vWantlist, intake:vIntake, heal:vHeal, storemap:vStoreMap, crates:vCrates, reports:vReports, connections:vConn, staff:vStaff, system:vSystem}[v])(); + ({dashboard:vDash, inventory:vInv, orders:vOrders, customers:vCustomers, wantlist:vWantlist, intake:vIntake, newstock:vNewstock, heal:vHeal, storemap:vStoreMap, crates:vCrates, reports:vReports, connections:vConn, staff:vStaff, system:vSystem}[v])(); } // ---------- Dashboard (fast tiles first, charts lazy) ---------- @@ -736,6 +737,70 @@ async function healRun(){ : '
All gaps closed. Re-scan to confirm.
'); } +// ---------- New stock (distro purchases → approve → publish) ---------- +async function vNewstock(){ + $('#content').innerHTML = '

New stock · approve distro purchases, then publish

' + + '
loading…
'; + nsLoad(); +} +async function nsLoad(){ + const d = await api('/newstock'); + if(!d.items.length){ $('#ns_bar').innerHTML='
✓ Nothing pending — scrape a distro order with the PRICEGOD extension and it lands here.
'; $('#ns_body').innerHTML=''; return; } + const resolved = d.items.filter(i=>i.release_id).length, priced = d.items.filter(i=>i.price!=null).length; + $('#ns_bar').innerHTML = `${d.count} copies pending · ${resolved} matched · ${priced} priced ` + + ``; + const groups = {}; d.items.forEach(i=>{ (groups[i.cost_source]=groups[i.cost_source]||[]).push(i); }); + $('#ns_body').innerHTML = Object.entries(groups).map(([src,items])=> + `

${escapeH(src)} · ${items.length} copies

+
${items.map(nsCard).join('')}
`).join(''); +} +function nsCard(it){ + const cover = it.thumb ? `` + : '
'; + return `
${cover} +
+
${escapeH(it.title||it.barcode||'?')}
+
${escapeH(it.artist||'')}${it.year?' · '+it.year:''} · ${escapeH(it.barcode||'')}
+
${it.release_id?`✓ rel ${it.release_id}`:'⚠ needs release'} · cost ${money(it.cost_price)}
+
+ + + + +
+
+
`; +} +async function nsPublish(sku){ + const c=$('#nsc_'+sku), price=parseFloat(c.querySelector('.ns_pr').value)||null, ct=c.querySelector('.ns_ct').value, msg=c.querySelector('.ns_msg'); + if(price==null){ msg.innerHTML='set a retail price first'; return; } + msg.textContent='publishing…'; + const r=await fetch('/admin/newstock/'+encodeURIComponent(sku),{method:'POST',headers:hdr(),body:JSON.stringify({price,condition_type:ct,publish:true})}); + if(r.ok){ c.style.opacity=.4; msg.innerHTML='✓ published & live'; } + else msg.innerHTML='failed'; +} +async function nsPublishAll(){ + if(!confirm('Publish every matched copy that has a retail price?')) return; + const d=await fetch('/admin/newstock/publish-all',{method:'POST',headers:hdr()}).then(r=>r.json()); + alert('Published '+d.published+' copies.'); nsLoad(); +} +function nsRepick(sku){ + const c=$('#nsc_'+sku); + c.innerHTML=`
`; + c.querySelector('.ns_q').focus(); +} +async function nsSearch(sku){ + const c=$('#nsc_'+sku), q=c.querySelector('.ns_q').value.trim(); if(!q) return; + const res=c.querySelector('.ns_res'); res.innerHTML='searching…'; + const d=await api('/intake/search?q='+encodeURIComponent(q)); window['_nsres_'+sku]=d.items||[]; + res.innerHTML=(d.items||[]).slice(0,8).map((r,idx)=>`
${escapeH(r.artist||'')} – ${escapeH(r.title||'')} ${escapeH(r.year||'')} ${escapeH(r.country||'')}
`).join('')||'no matches — try the barcode or fewer words'; +} +async function nsSetRelease(sku,idx){ + const r=(window['_nsres_'+sku]||[])[idx]; if(!r) return; + await fetch('/admin/newstock/'+encodeURIComponent(sku),{method:'POST',headers:hdr(),body:JSON.stringify({release_id:r.release_id,title:(r.artist?r.artist+' – ':'')+(r.title||'')})}); + nsLoad(); +} + // ---------- Crates ---------- async function vCrates(){ const m = $('#content'); m.innerHTML = '

Crates

loading…
';