← back to Dwjs Consolidation 2026 04 23

hollywood_mfr_dryrun.js

110 lines

// Dry-run: find Hollywood Wallcoverings products, look up real mfr SKU in fmpro, report what would change.
const fs = require('fs');
const TOKEN=(process.env.SHOPIFY_ADMIN_TOKEN || '');
const SHOP='designer-laboratory-sandbox.myshopify.com';
const API=`https://${SHOP}/admin/api/2024-10/graphql.json`;

// Build fmpro lookup: concatKey → { dashed, mfr, vendor_code, vendor_name }
function loadFmpro() {
  const raw = fs.readFileSync('/tmp/fmpro.csv','utf8');
  const recs = raw.replace(/\r\n/g,'\n').replace(/\r/g,'\n').split('\n');
  const map = new Map();
  for (const line of recs) {
    if (!line.trim()) continue;
    // CSV with quoted fields
    const m = line.match(/^"([^"]*)","([^"]*)","([^"]*)","([^"]*)","?([^"]*)"?$/);
    if (!m) continue;
    const [,concat,dashed,mfr,vcode,vname] = m;
    map.set(concat.toUpperCase(), { dashed, mfr, vcode, vname });
    // Also index dashed (e.g. XWA-73265) and dashless variants
    map.set(dashed.toUpperCase(), { dashed, mfr, vcode, vname });
  }
  return map;
}

async function gql(q, vars) {
  const r = await fetch(API, {
    method:'POST',
    headers:{'X-Shopify-Access-Token':TOKEN,'Content-Type':'application/json'},
    body: JSON.stringify({ query: q, variables: vars }),
  });
  return r.json();
}

async function fetchAllHollywood() {
  const all = [];
  let cursor = null;
  while (true) {
    const q = `query($c:String){
      products(first:100, after:$c, query:"vendor:'Hollywood Wallcoverings'") {
        pageInfo { hasNextPage endCursor }
        nodes {
          id title status
          variants(first:5) { nodes { sku } }
          mfr: metafield(namespace:"custom", key:"manufacturer_sku") { value }
        }
      }
    }`;
    const j = await gql(q, { c: cursor });
    const data = j.data?.products;
    if (!data) { console.error('GQL err', JSON.stringify(j).slice(0,500)); break; }
    all.push(...data.nodes);
    if (!data.pageInfo.hasNextPage) break;
    cursor = data.pageInfo.endCursor;
    process.stdout.write(`  fetched ${all.length}...\r`);
  }
  return all;
}

(async () => {
  console.log('Loading fmpro...');
  const fmpro = loadFmpro();
  console.log(`  ${fmpro.size} fmpro keys\n`);

  console.log('Fetching Hollywood Wallcoverings products from Shopify...');
  const products = await fetchAllHollywood();
  console.log(`  ${products.length} products total\n`);

  let resolved=0, alreadyCorrect=0, willUpdate=0, noMatch=0, missingSku=0;
  const changes = [];
  const unmatched = [];

  for (const p of products) {
    // Take the bolt SKU first, fall back to sample-stripped
    const skus = p.variants.nodes.map(v=>v.sku).filter(Boolean);
    const boltSku = skus.find(s => !/-sample$/i.test(s)) || skus[0];
    if (!boltSku) { missingSku++; continue; }
    // Strip -sample suffix and try multiple keys
    const base = boltSku.replace(/-sample$/i,'').toUpperCase();
    const baseNoDash = base.replace(/-/g,'');
    const fm = fmpro.get(base) || fmpro.get(baseNoDash);
    if (!fm) { noMatch++; unmatched.push(boltSku); continue; }
    resolved++;
    const newMfr = fm.mfr;
    const cur = p.mfr?.value || '';
    if (cur === newMfr) { alreadyCorrect++; continue; }
    willUpdate++;
    changes.push({ id:p.id, title:p.title, status:p.status, sku:boltSku, currentMfr:cur, newMfr, vendor:fm.vname||fm.vcode });
  }

  console.log(`\nFmpro lookup:`);
  console.log(`  resolved:        ${resolved}`);
  console.log(`  no fmpro match:  ${noMatch}`);
  console.log(`  missing SKU:     ${missingSku}`);
  console.log(`\nMetafield delta:`);
  console.log(`  already correct: ${alreadyCorrect}`);
  console.log(`  will update:     ${willUpdate}`);

  if (unmatched.length) {
    console.log(`\nFirst 10 unmatched SKUs:`);
    unmatched.slice(0,10).forEach(s=>console.log(' -',s));
  }
  if (changes.length) {
    console.log(`\nFirst 10 changes:`);
    changes.slice(0,10).forEach(c=>console.log(` - ${c.sku.padEnd(20)} cur=${(c.currentMfr||'(none)').padEnd(15)} → new=${c.newMfr}`));
  }

  fs.writeFileSync(__dirname + '/hollywood_changes.json', JSON.stringify(changes,null,2));
  console.log(`\nWrote ${changes.length} change rows to hollywood_changes.json`);
})();