[object Object]

← back to Designer Wallcoverings

cadence: vendor colOverrides (Newwall length→roll_length, repeat_v→pattern_repeat) — fixes Newwall SKU select; DRY-RUN validates cost=trade*0.80 → correct retail

1f1b3a64476ddc53f389eb6c4ee44667717d96cb · 2026-06-12 09:26:30 -0700 · SteveStudio2

Files touched

Diff

commit 1f1b3a64476ddc53f389eb6c4ee44667717d96cb
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date:   Fri Jun 12 09:26:30 2026 -0700

    cadence: vendor colOverrides (Newwall length→roll_length, repeat_v→pattern_repeat) — fixes Newwall SKU select; DRY-RUN validates cost=trade*0.80 → correct retail
---
 shopify/scripts/cadence/cadence-import.js | 9 +++++++--
 shopify/scripts/cadence/vendors.js        | 3 ++-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/shopify/scripts/cadence/cadence-import.js b/shopify/scripts/cadence/cadence-import.js
index 17f59446..f48d46ef 100644
--- a/shopify/scripts/cadence/cadence-import.js
+++ b/shopify/scripts/cadence/cadence-import.js
@@ -152,7 +152,12 @@ 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';
+  // Standard schema columns. cfg.colOverrides maps a canonical name to that vendor's
+  // actual column/expr when its catalog table differs (e.g. Newwall has length/repeat_v,
+  // not roll_length/pattern_repeat). Output keys stay canonical via SQL aliases.
+  const STD = ['dw_sku','mfr_sku','pattern_name','color_name','collection','width','image_url','product_type','material','roll_length','pattern_repeat'];
+  const ov = cfg.colOverrides || {};
+  const cols = STD.map(c => ov[c] ? `${ov[c]} AS ${c}` : c).join(', ');
   // 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}
@@ -161,7 +166,7 @@ function selectSkus(cfg, limit) {
     ORDER BY dw_sku LIMIT ${limit};`;
   const out = psql(sql);
   if (!out) return [];
-  const keys = [...cols.split(', '), 'cost', ...(cfg.sellExpr ? ['sell'] : [])];
+  const keys = [...STD, '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; });
 }
 
diff --git a/shopify/scripts/cadence/vendors.js b/shopify/scripts/cadence/vendors.js
index d17388a0..43229f26 100644
--- a/shopify/scripts/cadence/vendors.js
+++ b/shopify/scripts/cadence/vendors.js
@@ -34,7 +34,8 @@ module.exports = {
   // confirmed discount → costExpr returns NULL so they're never costed/imported.
   'Newwall':    { table: 'newwall_catalog',
                   costExpr: `CASE WHEN vendor_name IN ('Coordonné','17 Patterns','House of Hackney','Masi x Newwall','Tres Tintas','Wall&decò') AND price_trade > 0 THEN price_trade * 0.80 ELSE NULL END`,
-                  soldBy: 'Single Roll', productType: 'Wallcovering', discountNote: '20% off US trade net (price_trade); 6 confirmed lines only' },
+                  soldBy: 'Single Roll', productType: 'Wallcovering', discountNote: '20% off US trade net (price_trade); 6 confirmed lines only',
+                  colOverrides: { roll_length: 'length', pattern_repeat: 'repeat_v' } },
   // Brewster & York: downloaded price list already loaded into brewster_catalog —
   // cost = wholesale (populated on 8697/8715 rows), us_map = MAP, price_retail = MSRP.
   // discount_confirmed=true. retail = cost/0.65/0.85 (formula sits above us_map on samples,

← f486e785 Add scan-active-dups.js: reusable read-only both-active dupl  ·  back to Designer Wallcoverings  ·  worker-guard: harden tests — batched productCreate (input0/i 9979cea0 →