← back to Filemaker Mcp
scripts/test-real-units-live.mjs
54 lines
// LIVE test of the "all money on first invoice, just the SKU on each subsequent
// invoice" model. Creates a single-SKU order and a 2-sample order, reads back to
// prove: money record = ONE line (total units x per-unit price), GRAND/PAID =
// whole order, subsequent records = SKU only at $0. Then DELETES all records.
// Monitor is booted out by the wrapper so no Slack card posts.
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 { createInvoiceForOrder } = await import('../lib/invoice.js');
const fm = await import('../src/fm-client.js');
const HDR = 'Invoice to Client Copy';
const base = { total_tax: 0, customer: { first_name: 'ZZ-TEST', last_name: 'DELETE-ME' },
shipping_address: { company: 'ZZ Test Project', address1: '1 Main', city: 'LA', province_code: 'CA', zip: '90001', country_code: 'US' },
shipping_lines: [{ title: 'UPS', price: '0' }] };
const cases = [
{ label: 'SINGLE-SKU roll', po: 999301, items: [{ sku: 'DWTT-80502', name: 'Edwards', price: '44.18', quantity: 2, variant_title: 'Double Roll' }],
expect: { detail: 'DWTT-80502 — Edwards', qty: 2, net: 44.18, grand: 88.36, stubs: 0 } },
{ label: '2 SAMPLES @ $4.25', po: 999302, items: [
{ sku: 'DWHF-70193', name: 'Quintessence', price: '4.25', quantity: 1, variant_title: 'Sample' },
{ sku: 'DWTT-80714', name: 'Ribbon Floral', price: '4.25', quantity: 1, variant_title: 'Sample' }],
expect: { detail: 'Samples', qty: 2, net: 4.25, grand: 8.5, stubs: 1 } },
];
let allPass = true;
for (const c of cases) {
const order = { ...base, order_number: c.po, line_items: c.items };
await createInvoiceForOrder(order, 'ZZ-ACCT', { commit: true });
const { records } = await fm.findRecords('invoice', HDR, { 'Cust PO': '==' + c.po }, { limit: 20, sort: [{ fieldName: 'Invoice', sortOrder: 'ascend' }] });
const m = records[0]?.fieldData || {};
const grand = Number(m['GRAND TOTAL'] || 0), paid = Number(m['PAID ON ACCOUNT'] || 0);
console.log(`\n=== ${c.label} (PO ${c.po}) — money #${m['Invoice']} ===`);
console.log(` line: Q=${m['Q1(1)']} NET=$${m['NET 1(1)']} DETAIL="${String(m['DETAIL 1(1)']||'').slice(0,24)}" line2 DETAIL="${m['DETAIL 2']||''}"`);
console.log(` GRAND=$${grand} PAID=$${paid} | ${records.length - 1} SKU-only stub(s)`);
let ok = true;
if (String(m['DETAIL 1(1)']||'') !== c.expect.detail) { ok = false; console.log(` x detail != "${c.expect.detail}"`); }
if (Number(m['Q1(1)']) !== c.expect.qty || Number(m['NET 1(1)']) !== c.expect.net) { ok = false; console.log(' x units/price wrong'); }
if (m['DETAIL 2']) { ok = false; console.log(' x line 2 not cleared'); }
if (grand !== c.expect.grand || paid !== c.expect.grand) { ok = false; console.log(` x grand/paid != ${c.expect.grand}`); }
if ((records.length - 1) !== c.expect.stubs) { ok = false; console.log(` x stub count != ${c.expect.stubs}`); }
for (let i = 1; i < records.length; i++) { if (Number(records[i].fieldData['PAID ON ACCOUNT'] || 0) !== 0) { ok = false; console.log(' x stub carries dollars'); } }
console.log(` ${ok ? 'PASS' : 'FAIL'}`);
allPass = allPass && ok;
for (const r of records) { try { await fm.deleteRecord('invoice', HDR, r.recordId); } catch (e) { console.log(' del err', e.message); } }
console.log(` cleaned up ${records.length} record(s)`);
}
console.log(`\n${allPass ? 'ALL PASS — all money on first invoice; SKU-only $0 stubs' : 'SOME FAILED'}`);