← back to Filemaker Mcp

scripts/watch-real-units-order.mjs

51 lines

// Watch for the NEXT Shopify order the sync processes (order_number > BASELINE),
// then print its FileMaker money-record breakdown showing REAL units (Q1/Q2) +
// REAL per-unit price (NET 1/NET 2), and exit. Read-only. Auto-exits after cap.
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
for (const l of readFileSync(join(ROOT, '.env'), 'utf8').split('\n')) {
  const m = l.match(/^([A-Z0-9_]+)=(.*)$/); if (m && !process.env[m[1]]) process.env[m[1]] = m[2].replace(/^['"]|['"]$/g, '');
}
const { findRecords } = await import('../src/fm-client.js');
const HDR = 'Invoice to Client Copy';
const LEDGER = join(ROOT, 'data', 'sync-ledger.jsonl');
const BASELINE = 32571;
const MAX_POLLS = 480, INTERVAL_MS = 30_000; // ~4 hours
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const seen = new Set();

function newProcessed() {
  let lines = [];
  try { lines = readFileSync(LEDGER, 'utf8').trim().split('\n'); } catch { return []; }
  const out = [];
  for (const l of lines) {
    try { const d = JSON.parse(l); if (d.action === 'processed' && Number(d.orderNumber) > BASELINE && !seen.has(d.orderNumber)) out.push(d); } catch {}
  }
  return out;
}

async function report(o) {
  const { records } = await findRecords('invoice', HDR, [{ 'Cust PO': '==' + o.orderNumber }],
    { limit: 60, sort: [{ fieldName: 'Invoice', sortOrder: 'ascend' }] }).catch(() => ({ records: [] }));
  const money = records[0]?.fieldData || {};
  console.log(`\n🆕 REAL ORDER #${o.orderNumber} (${o.company || ''}) at ${o.ts?.slice(0, 19)} — money invoice #${money['Invoice']}`);
  console.log(`   line 1: Q=${money['Q1(1)']}  NET=$${money['NET 1(1)']}  ${String(money['DETAIL 1(1)'] || '').slice(0, 30)}`);
  if (money['DETAIL 2']) console.log(`   line 2: Q=${money['Q2']}  NET=$${money['NET 2']}  ${String(money['DETAIL 2'] || '').slice(0, 30)}`);
  console.log(`   GRAND TOTAL=$${money['GRAND TOTAL']}  PAID=$${money['PAID ON ACCOUNT']}  ·  ${records.length - 1} $0 stub(s)`);
  const realUnits = Number(money['Q1(1)']) >= 1 && Number(money['NET 1(1)']) > 0;
  console.log(`   → ${realUnits ? '✅ real units + real per-unit price (new logic live)' : '⚠️ line 1 looks lumped — check'}`);
}

for (let i = 0; i < MAX_POLLS; i++) {
  const hits = newProcessed();
  if (hits.length) {
    for (const o of hits) { seen.add(o.orderNumber); await report(o); }
    console.log('\n(watcher done — next real order observed)');
    process.exit(0);
  }
  await sleep(INTERVAL_MS);
}
console.log(`No new order (> #${BASELINE}) within the watch window. Re-arm to keep watching.`);