[object Object]

← back to Filemaker Mcp

add watch-real-units-order.mjs — live watcher for next real order's per-line breakdown

f7c8106967b565deccfece5ef074ecbda55047f4 · 2026-07-09 22:08:19 -0700 · Steve Abrams

Files touched

Diff

commit f7c8106967b565deccfece5ef074ecbda55047f4
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Jul 9 22:08:19 2026 -0700

    add watch-real-units-order.mjs — live watcher for next real order's per-line breakdown
---
 scripts/watch-real-units-order.mjs | 50 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/scripts/watch-real-units-order.mjs b/scripts/watch-real-units-order.mjs
new file mode 100644
index 0000000..c051483
--- /dev/null
+++ b/scripts/watch-real-units-order.mjs
@@ -0,0 +1,50 @@
+// 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.`);

← d9b2cbf invoice: show real units + real per-unit price (not lumped Q  ·  back to Filemaker Mcp  ·  invoice: all money on FIRST invoice, just the SKU on each su 5703973 →