[object Object]

← back to Filemaker Mcp

auto-save: 2026-07-07T08:56:34 (2 files) — scripts/tmp-probe-net.mjs scripts/tmp-probe-net2.mjs

f3f4718e73282803efa8e07e8a56523fe7ef1ac8 · 2026-07-07 08:56:39 -0700 · Steve Abrams

Files touched

Diff

commit f3f4718e73282803efa8e07e8a56523fe7ef1ac8
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jul 7 08:56:39 2026 -0700

    auto-save: 2026-07-07T08:56:34 (2 files) — scripts/tmp-probe-net.mjs scripts/tmp-probe-net2.mjs
---
 scripts/tmp-probe-net.mjs  | 63 ++++++++++++++++++++++++++++++++++++++++++++++
 scripts/tmp-probe-net2.mjs | 18 +++++++++++++
 2 files changed, 81 insertions(+)

diff --git a/scripts/tmp-probe-net.mjs b/scripts/tmp-probe-net.mjs
new file mode 100644
index 0000000..5a4c405
--- /dev/null
+++ b/scripts/tmp-probe-net.mjs
@@ -0,0 +1,63 @@
+// READ-ONLY probe: recent invoices + multi-sample total mechanism. No writes.
+import { findRecords } from '../src/fm-client.js';
+import { loadEnv, num } from '../lib/fm-script-helpers.js';
+loadEnv(import.meta.url);
+
+const HDR = 'Invoice to Client Copy';
+const FIELDS = ['Invoice','Cust PO','Date','SOLD NAME','DETAIL 1(1)',
+  'Q1(1)','RETAIL 1(1)','NET 1(1)','Unit 1(1)',
+  'NET 1(2)','NET 1(3)','NET 1(4)','Q1(2)','Q1(3)','Q1(4)',
+  'DETAIL 1(2)','DETAIL 1(3)','DETAIL 1(4)',
+  'MERCHANDISE TOTAL','GRAND TOTAL','GRAND TOTAL 2','PAID ON ACCOUNT',
+  'SALES TAX','SHIPPING  HANDLING'];
+
+const g = (f,k)=> (k in f ? f[k] : undefined);
+
+function dump(f, label='') {
+  const o = {};
+  for (const k of FIELDS) { const v = g(f,k); if (v!==undefined && v!=='') o[k]=v; }
+  console.log(label, JSON.stringify(o));
+}
+
+async function main() {
+  // 1. Most recent ~18 numeric invoices, descending.
+  const { records } = await findRecords('invoice', HDR, { 'Invoice': '>100000' },
+    { limit: 18, sort: [{ fieldName: 'Invoice', sortOrder: 'descend' }] });
+  console.log(`\n===== ${records.length} MOST-RECENT INVOICES (Invoice desc) =====`);
+  const rows = [];
+  for (const r of records) {
+    const f = r.fieldData || {};
+    const inv = f['Invoice'], q1 = num(f['Q1(1)']), net1 = num(f['NET 1(1)']);
+    const merch = num(f['MERCHANDISE TOTAL']), gt = num(f['GRAND TOTAL']);
+    const gt2 = num(f['GRAND TOTAL 2']), paid = num(f['PAID ON ACCOUNT']);
+    rows.push({inv, po:f['Cust PO'], name:(f['SOLD NAME']||'').slice(0,18),
+      detail:(f['DETAIL 1(1)']||'').slice(0,32), q1, net1, merch, gt, gt2, paid,
+      date:f['Date']});
+  }
+  for (const r of rows) {
+    console.log(
+      `#${r.inv} ${String(r.date||'').padEnd(10)} q1=${String(r.q1).padEnd(4)} NET1=${String(r.net1).padEnd(7)}`+
+      ` MERCH=${String(r.merch).padEnd(8)} GT=${String(r.gt).padEnd(8)} GT2=${String(r.gt2).padEnd(8)} PAID=${String(r.paid).padEnd(8)}`+
+      ` | ${r.name.padEnd(18)} | ${r.detail}`);
+  }
+
+  // 2. Multi-sample analysis: q1>1
+  console.log(`\n===== MULTI-QTY (Q1(1) > 1) MECHANISM CHECK =====`);
+  const multi = rows.filter(r=>r.q1>1);
+  if (!multi.length) console.log('(none in this window)');
+  for (const r of multi) {
+    const ext = +(r.q1 * r.net1).toFixed(2);
+    const matchesExt = Math.abs(r.gt - ext) < 0.01;
+    const matchesNet = Math.abs(r.gt - r.net1) < 0.01;
+    console.log(`#${r.inv}: q1=${r.q1} × NET1=${r.net1} = ext ${ext} | GT=${r.gt} MERCH=${r.merch} PAID=${r.paid}`+
+      ` => GT ${matchesExt?'== Qty×NET (CORRECT)':matchesNet?'== NET-only (BUG!)':'== ??? ('+r.gt+')'}`+
+      ` | PAID ${Math.abs(r.paid-ext)<0.01?'=ext OK':Math.abs(r.paid-r.net1)<0.01?'=NET STUCK(BUG)':'=?'} `);
+  }
+
+  // 3. Specific: #102540 Braxton
+  console.log(`\n===== INVOICE #102540 (Braxton) =====`);
+  const { records: r540 } = await findRecords('invoice', HDR, { 'Invoice': '==102540' }, { limit: 2 });
+  if (!r540.length) console.log('NOT FOUND');
+  for (const r of r540) dump(r.fieldData||{}, '#102540');
+}
+main().catch(e=>{console.error('probe error:', e.message, e.fmCode||'');process.exit(1);});
diff --git a/scripts/tmp-probe-net2.mjs b/scripts/tmp-probe-net2.mjs
new file mode 100644
index 0000000..62a643d
--- /dev/null
+++ b/scripts/tmp-probe-net2.mjs
@@ -0,0 +1,18 @@
+import { findRecords } from '../src/fm-client.js';
+import { loadEnv } from '../lib/fm-script-helpers.js';
+loadEnv(import.meta.url);
+const HDR = 'Invoice to Client Copy';
+const KEYS = ['Invoice','Cust PO','DETAIL 1(1)','Q1(1)','RETAIL 1(1)','NET 1(1)',
+  'DETAIL 1(2)','Q1(2)','NET 1(2)','DETAIL 1(3)','Q1(3)','NET 1(3)',
+  'MERCHANDISE TOTAL','GRAND TOTAL','GRAND TOTAL 2','PAID ON ACCOUNT','SALES TAX','SHIPPING  HANDLING'];
+for (const n of ['102538','102540']) {
+  console.log(`\n===== INVOICE ${n} =====`);
+  try {
+    const { records } = await findRecords('invoice', HDR, [{ Invoice: `==${n}` }], { limit: 1 });
+    const f = records?.[0]?.fieldData || {};
+    for (const k of KEYS) if (k in f) console.log(`  ${k.padEnd(20)} = ${JSON.stringify(f[k])}`);
+  } catch (e) { console.log('  ERR', e.message, e.fmCode || ''); }
+}
+const top = await findRecords('invoice', HDR, { 'Invoice': '10*' }, { limit: 8, sort: [{ fieldName: 'Invoice', sortOrder: 'descend' }] });
+console.log('\n===== TOP 8 INVOICE NUMBERS NOW =====');
+for (const r of top.records) console.log(`  #${r.fieldData['Invoice']}  PO ${r.fieldData['Cust PO']||''}  paid ${r.fieldData['PAID ON ACCOUNT']||''}  ${String(r.fieldData['DETAIL 1(1)']||'').slice(0,40)}`);

← 7b8fa26 add read-only dry-run pipeline test: proves 1-invoice-per-or  ·  back to Filemaker Mcp  ·  auto-save: 2026-07-07T08:57:11 (2 files) — scripts/tmp-probe f903c3b →