[object Object]

← back to Designer Wallcoverings

cadence: support MAP-priced vendors (sellExpr) — Kravet family sells at MAP, not cost/0.65/0.85

4a502d3cfa7073f96aa470faaa9f07b0841fbbf4 · 2026-06-12 07:45:29 -0700 · SteveStudio2

Files touched

Diff

commit 4a502d3cfa7073f96aa470faaa9f07b0841fbbf4
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date:   Fri Jun 12 07:45:29 2026 -0700

    cadence: support MAP-priced vendors (sellExpr) — Kravet family sells at MAP, not cost/0.65/0.85
---
 shopify/scripts/cadence/cadence-import.js | 11 +++++++----
 shopify/scripts/cadence/vendors.js        |  6 +++++-
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/shopify/scripts/cadence/cadence-import.js b/shopify/scripts/cadence/cadence-import.js
index 3f975306..a5f773f6 100644
--- a/shopify/scripts/cadence/cadence-import.js
+++ b/shopify/scripts/cadence/cadence-import.js
@@ -153,14 +153,16 @@ function saveCursor(c) { fs.mkdirSync(DATADIR,{recursive:true}); fs.writeFileSyn
 // ---- select next M net-new costed SKUs for a vendor ----
 function selectSkus(cfg, limit) {
   const cols = 'dw_sku, mfr_sku, pattern_name, color_name, collection, width, image_url, product_type, material, roll_length, pattern_repeat';
-  const sql = `SELECT ${cols}, (${cfg.costExpr})::numeric AS cost
+  // sellExpr (optional): vendor sells at MAP, not cost/0.65/0.85 (e.g. Kravet family).
+  const sellSel = cfg.sellExpr ? `, (${cfg.sellExpr})::numeric AS sell` : '';
+  const sql = `SELECT ${cols}, (${cfg.costExpr})::numeric AS cost${sellSel}
     FROM ${cfg.table}
     WHERE coalesce(shopify_product_id::text,'')='' AND (${cfg.costExpr})::numeric > 0
     ORDER BY dw_sku LIMIT ${limit};`;
   const out = psql(sql);
   if (!out) return [];
-  const keys = [...cols.split(', '), 'cost'];
-  return out.split('\n').map(line => { const v=line.split('\t'); const o={}; keys.forEach((k,i)=>o[k]=v[i]); o.cost=parseFloat(o.cost); return o; });
+  const keys = [...cols.split(', '), 'cost', ...(cfg.sellExpr ? ['sell'] : [])];
+  return out.split('\n').map(line => { const v=line.split('\t'); const o={}; keys.forEach((k,i)=>o[k]=v[i]); o.cost=parseFloat(o.cost); if(cfg.sellExpr) o.sell=parseFloat(o.sell); return o; });
 }
 
 // ---- build the Shopify productSet input (generic across standard-schema vendors) ----
@@ -252,7 +254,8 @@ async function createProduct(table, row, payload) {
     const skus = selectSkus(r.cfg, SKUS_PER_VENDOR);
     console.log(`\n${r.vendor} — ${skus.length} SKU(s) (cost ${r.cfg.costExpr}):`);
     for (const row of skus) {
-      const retail = RETAIL(row.cost);
+      // MAP-priced vendors (sellExpr) sell at MAP; everyone else at cost/0.65/0.85.
+      const retail = (r.cfg.sellExpr && row.sell > 0) ? Math.round(row.sell * 100) / 100 : RETAIL(row.cost);
       const payload = buildInput(r.vendor, r.cfg, row, retail);
       plan.push({ vendor:r.vendor, dw_sku:row.dw_sku, cost:row.cost, retail, sample:SAMPLE_PRICE, title:payload.title });
       if (!COMMIT) { console.log(`  · ${row.dw_sku}  cost $${row.cost.toFixed(2)} → roll $${retail}  sample $${SAMPLE_PRICE}  | ${payload.title.slice(0,52)}`); continue; }
diff --git a/shopify/scripts/cadence/vendors.js b/shopify/scripts/cadence/vendors.js
index 0c13d7bb..3a9317cb 100644
--- a/shopify/scripts/cadence/vendors.js
+++ b/shopify/scripts/cadence/vendors.js
@@ -28,7 +28,11 @@ module.exports = {
   'WallQuest':  { table: 'wallquest_catalog',        costExpr: 'price_retail::numeric', soldBy: 'Single Roll', productType: 'Wallcovering' },
   // Kravet: cost loaded from authoritative GDrive wholesale list (Kravet Price list 1-20-26.xlsx,
   // eff 2026-01-17) into cost_price = NEW WHLS incl tariff; sell floored at NEW MAP (Steve 2026-06-11).
-  'Kravet':     { table: 'kravet_catalog',           costExpr: 'cost_price',           soldBy: 'Single Roll', productType: 'Wallcovering', discountNote: 'cost from GDrive Jan-2026 wholesale list (incl 5% tariff)' },
+  // Kravet + ALL subbrands (Brunschwig, Lee Jofa, GP&J Baker, Cole & Son, Donghia,
+  // Mulberry, Threads, Baker Lifestyle, Gaston y Daniela, Clarke & Clarke, etc.):
+  // Steve 2026-06-11 "use the MAP pricing for all kravet and subbrands" — sell = MAP
+  // (price_retail_new = NEW MAP from Jan-2026 list, fallback price_retail), NOT cost/0.65/0.85.
+  'Kravet':     { table: 'kravet_catalog',           costExpr: 'cost_price', sellExpr: 'COALESCE(NULLIF(price_retail_new,0),NULLIF(price_retail,0))', soldBy: 'Single Roll', productType: 'Wallcovering', discountNote: 'cost from GDrive Jan-2026 wholesale list (incl 5% tariff); SELL AT MAP' },
   // Schumacher: Designer Net (vendor_registry discount 0.00, confirmed) — cost = priceUsd
   // from the authenticated API recrawl (2026-06-11). retail = cost/0.65/0.85.
   'Schumacher': { table: 'schumacher_catalog',       costExpr: 'cost',                 soldBy: 'Single Roll', productType: 'Wallcovering', discountNote: 'Designer Net 0% — cost=priceUsd (authenticated API recrawl)' },

← 0d278a72 DWAE: price 166 from Schumacher net-cost API + activate + ta  ·  back to Designer Wallcoverings  ·  schumacher importer: dedup gallery images by URL at ingest ( a1d4c12e →