Do customers actually pay the way their assigned terms say they will? A payment-application-level analysis of every customer payment in the account — with anomalies, trends, and negotiating leverage surfaced along the way.
The receivables book is in excellent shape on paper — but the interesting findings are in the exceptions, the trend line, and the free float being left on the table.
Days-to-pay is measured at the payment-application level, not the invoice level — each application of a customer payment to an invoice is one observation, weighted by the dollars applied. This handles partial payments correctly and avoids the "last payment defines the invoice" distortion.
| Days to pay | TRUNC(payment date) − TRUNC(invoice date) per application. Measured from invoice date, not due date — this is what "Net 30" promises against. |
| Avg days | Simple mean across a customer's applications. Every invoice counts equally. |
| Weighted days | Σ(days × $applied) ÷ Σ($applied). When weighted ≫ simple, the customer's large invoices are the slow ones — the pattern that becomes a collections problem. |
| Variance | Avg days − assigned terms days. Positive = pays late; negative = pays early. |
| ≥ 3 invoices | Customer-level table requires at least 3 paid invoices — below that, an "average" is noise. 51 of 100 paying customers qualify; excluded customers still count in portfolio totals. |
| Paid invoices only | This measures behavior on invoices that got paid. Currently-open and never-paid invoices are out of scope (that's the A/R aging's job). Survivorship bias: true behavior is slightly worse than shown. |
| Payments only | linktype='Payment', CustInvc→CustPymt, positive applied amounts. Credit memos (49 in the account) and journal applications are excluded — they represent adjustments, not payment behavior. |
| Link-table dates | Dates come from nexttransactionlinelink.previousdate / nextdate (invoice and payment tran dates). Negative values were kept and reported as anomalies (Finding B), not silently dropped. |
| Currency | foreignamount = transaction currency. Dollar totals assume a single-currency book; if multi-currency is active, cross-currency sums are approximate. |
| No-terms customers | Treated as 0-day terms for variance math, and flagged separately (Finding C) rather than buried in averages. |
| "Within terms" | Application counted as compliant when days-to-pay ≤ the customer's terms days. For no-terms customers this is a harsh ≤0 test — the true portfolio compliance rate is therefore understated. |
How the 1,472 payment applications distribute, and how behavior has moved over 33 months.
All 51 customers with ≥3 paid invoices, ranked worst-to-best by variance from assigned terms. The bar shows how far behavior deviates from terms (red = late, green = early).
| Customer | Terms | Inv | $ Applied | Avg d | Wtd d | Worst | Variance | Flag | |
|---|---|---|---|---|---|---|---|---|---|
| BCP Customer 2 | — | 5 | 682 | 12.6 | 12.6 | 24 | +12.6 | NO TERMS | |
| Alpha Demand | — | 1,022 | 195,132 | 6.2 | 6.1 | 13 | +6.2 | NO TERMS | |
| Baxter Elementary School | Net 30 | 5 | 49,054 | 33.4 | 33.4 | 34 | +3.4 | LATE | |
| Bonita Inn | Net 30 | 3 | 8,677 | 33.0 | 33.0 | 33 | +3.0 | LATE | |
| Sam's Stop N Go | Net 30 | 5 | 21,781 | 32.4 | 32.3 | 34 | +2.4 | LATE | |
| Snaptags Consulting | Net 30 | 3 | 36,570 | 30.0 | 30.0 | 31 | 0.0 | AT TERMS | |
| Photolist Foundation | Net 30 | 3 | 47,970 | 30.0 | 30.0 | 31 | 0.0 | AT TERMS | |
| Realpoint Co. | Net 30 | 3 | 36,570 | 30.0 | 30.0 | 31 | 0.0 | AT TERMS | |
| Skibox LLC. | Net 30 | 4 | 320 | 29.5 | 29.5 | 31 | −0.5 | AT TERMS | |
| Oozz Incorporated | Net 30 | 5 | 134,155 | 29.0 | 29.6 | 31 | −1.0 | AT TERMS | |
| Riffpedia Company | Net 30 | 5 | 39,975 | 28.8 | 28.8 | 31 | −1.2 | AT TERMS | |
| Ntags Associates | Net 30 | 3 | 23,689 | 28.7 | 30.4 | 31 | −1.3 | AT TERMS | |
| Phasellus Vitae Mauris Inc. | Net 30 | 3 | 38,070 | 28.7 | 27.5 | 31 | −1.3 | AT TERMS | |
| Oyope Industries | Net 30 | 4 | 44,971 | 28.5 | 27.3 | 31 | −1.5 | AT TERMS | |
| Wapp Hardware Sales | Net 30 | 4 | 75,980 | 28.3 | 28.3 | 31 | −1.8 | AT TERMS | |
| Realcube Industries | Net 30 | 4 | 9,308 | 28.3 | 28.3 | 31 | −1.8 | AT TERMS | |
| Rhycero LP | Net 30 | 5 | 30,475 | 28.0 | 28.0 | 31 | −2.0 | AT TERMS | |
| Sem Corporation Associates | Net 30 | 5 | 200 | 28.0 | 28.0 | 31 | −2.0 | AT TERMS | |
| Keller PR | Net 30 | 6 | 99,275 | 28.0 | 28.0 | 31 | −2.0 | AT TERMS | |
| Meedoo Industries | Net 30 | 3 | 26,739 | 27.7 | 27.8 | 28 | −2.3 | AT TERMS | |
| Smith Pacific Northwest Store | Net 30 | 27 | 151,613 | 27.0 | 20.1 | 66 | −3.0 | ERRATIC | |
| Dab's Deli | Net 30 | 3 | 7,224 | 27.0 | 30.3 | 40 | −3.0 | WTD>TERMS | |
| Shuffle's Grocery | Net 30 | 7 | 62,395 | 26.1 | 25.9 | 28 | −3.9 | ||
| McEdwards & Whitwell Steakhouse | Net 30 | 4 | 13,181 | 25.0 | 25.0 | 25 | −5.0 | ||
| Wikizz Industries | Net 30 | 7 | 16,448 | 24.1 | 26.4 | 31 | −5.9 | ||
| Chatter's Candy Counter | Net 30 | 11 | 104,009 | 23.6 | 19.6 | 31 | −6.4 | ||
| Red Oak Country Club | Net 30 | 6 | 17,455 | 22.7 | 22.7 | 24 | −7.3 | ||
| Nightingale Senior Center | Net 30 | 11 | 183,262 | 22.5 | 23.5 | 31 | −7.5 | ||
| Vinder Commercial Cleaners | Net 30 | 5 | 92,330 | 20.0 | 9.4 | 25 | −10.0 | ||
| Crescent Street Grille | Net 30 | 7 | 8,191 | 19.6 | 23.7 | 27 | −10.4 | ||
| Camido Cocina | Net 30 | 10 | 44,845 | 18.6 | 24.9 | 28 | −11.4 | ||
| Frutti Di Mare Restaurant | Net 30 | 21 | 130,063 | 17.4 | 12.4 | 40 | −12.6 | ANOMALY | |
| Whole Markets | Net 30 | 21 | 302,227 | 16.9 | 19.5 | 34 | −13.1 | EARLY $ | |
| Abbott's Restaurant | Net 30 | 14 | 41,044 | 14.8 | 18.6 | 35 | −15.2 | ||
| DynaCare Health Stop | Net 30 | 7 | 36,978 | 13.9 | 13.9 | 15 | −16.1 | ||
| Meetz inc. | Net 30 | 21 | 86,279 | 13.9 | 26.3 | 31 | −16.1 | BIG=SLOW | |
| Webster Grill | Net 30 | 6 | 25,492 | 13.7 | 13.7 | 14 | −16.3 | ||
| Buzzie's Sandwiches | Net 30 | 4 | 6,008 | 13.0 | 20.8 | 28 | −17.0 | ANOMALY | |
| Cooper Concessions | Net 30 | 11 | 51,582 | 12.7 | 20.6 | 27 | −17.3 | ||
| Magna Janitorial Services | Net 30 | 8 | 136,481 | 12.1 | 5.8 | 14 | −17.9 | EARLY $ | |
| Restaurant Wholesale Inc | Net 30 | 11 | 94,577 | 11.6 | 13.2 | 114 | −18.4 | OUTLIER | |
| BCP Customer 3 | Net 30 | 10 | 1,364 | 11.6 | 11.6 | 23 | −18.4 | ||
| Telescope Knoll Country Club | Net 30 | 11 | 21,895 | 11.4 | 19.0 | 24 | −18.6 | ||
| Viva Cafe | Net 30 | 17 | 51,294 | 11.4 | 18.8 | 31 | −18.6 | ||
| Dubois Candy Emporium | Net 30 | 12 | 199,235 | 10.8 | 7.1 | 18 | −19.3 | EARLY $ | |
| Volutpat Industries | Net 30 | 6 | 13,001 | 10.3 | 10.3 | 11 | −19.7 | ||
| Acme Produce Market | Net 30 | 19 | 220,849 | 9.4 | 8.7 | 27 | −20.6 | EARLY $ | |
| BCP Customer 1 | Net 30 | 5 | 616 | 8.8 | 8.8 | 22 | −21.2 | ||
| Underwood Produce Market | Net 30 | 3 | 37,089 | 8.3 | 5.9 | 22 | −21.7 | ||
| Skipstorm Seafood | Net 30 | 6 | 16,792 | 5.0 | 5.4 | 8 | −25.0 | ||
| Moore Foods | Net 30 | 3 | 36,773 | 4.3 | 11.7 | 12 | −25.7 |
| Invoice | Inv Date | Due Date | Inv Total | Payment | Pay Date | Applied | Days |
|---|---|---|---|---|---|---|---|
| INV622 | 2026-05-02 | 2026-06-02 | 10,428.20 | PYMT377 | 2026-08-24 | 10,000.00 | 114 |
| INV1766 | 2025-11-11 | 2025-12-10 | 6,162.76 | PYMT1452 | 2025-11-13 | 6,162.76 | 2 |
| INV1767 | 2025-12-02 | 2026-01-02 | 6,279.88 | PYMT1453 | 2025-12-04 | 6,279.88 | 2 |
| INV1769 | 2026-05-18 | 2026-06-18 | 4,111.84 | PYMT1455 | 2026-05-20 | 4,111.84 | 2 |
| INV1768 | 2026-01-06 | 2026-02-05 | 3,115.06 | PYMT1454 | 2026-01-08 | 3,115.06 | 2 |
| INV1825 | 2025-05-02 | 2025-06-02 | 10,264.60 | PYMT1511 | 2025-05-03 | 10,264.60 | 1 |
| INV1779 | 2025-04-22 | 2025-05-21 | 10,428.20 | PYMT1465 | 2025-04-23 | 10,428.20 | 1 |
| INV1780 | 2025-10-17 | 2025-11-17 | 10,428.20 | PYMT1466 | 2025-10-18 | 10,428.20 | 1 |
| INV1781 | 2026-01-15 | 2026-02-14 | 13,093.54 | PYMT1467 | 2026-01-16 | 13,093.54 | 1 |
| INV1824 | 2025-02-28 | 2025-04-01 | 10,264.60 | PYMT1510 | 2025-03-01 | 10,264.60 | 1 |
| INV1778 | 2024-11-16 | 2024-12-15 | 10,428.20 | PYMT1464 | 2024-11-17 | 10,428.20 | 1 |
| Customer | Invoice | Inv Date | Payment | Pay Date | Applied | Days |
|---|---|---|---|---|---|---|
| Alpha Demand | INV1660 | 2026-08-31 ⚠ future | PYMT1381 | 2026-08-01 | 321.30 | −30 |
| Alpha Demand | INV1661 | 2026-08-31 ⚠ future | PYMT1382 | 2026-08-02 | 236.40 | −29 |
| Alpha Demand | INV1662 | 2026-08-31 ⚠ future | PYMT1383 | 2026-08-03 | 94.90 | −28 |
| Frutti Di Mare Restaurant | INV1721 | 2026-08-27 | PYMT1423 | 2026-08-10 | 1,170.00 | −17 |
| Buzzie's Sandwiches | INV503 | 2026-08-18 | PYMT239 | 2026-08-14 | 1,326.71 | −4 |
| Smith Pacific Northwest Store | 171 | 2026-08-15 | PYMT211 | 2026-08-13 | 4,050.00 | −2 |
Ordered by impact-per-effort. Items 1–3 can be executed directly from this session.
Every number in this report traces to one of these SuiteQL queries, run live against the account on Aug 16, 2026. Rerun any of them to reproduce or refresh the analysis.
SELECT c.id AS customer_id, COALESCE(c.companyname, c.entityid) AS customer, COALESCE(tm.name, '(no terms)') AS assigned_terms, COALESCE(tm.daysuntilnetdue, 0) AS terms_days, COUNT(DISTINCT l.previousdoc) AS invoices_paid, ROUND(SUM(l.foreignamount), 2) AS total_applied, ROUND(AVG(TRUNC(l.nextdate) - TRUNC(l.previousdate)), 1) AS avg_days_to_pay, ROUND(SUM((TRUNC(l.nextdate) - TRUNC(l.previousdate)) * l.foreignamount) / NULLIF(SUM(l.foreignamount), 0), 1) AS wtd_days_to_pay, MAX(TRUNC(l.nextdate) - TRUNC(l.previousdate)) AS worst_days, ROUND(AVG(TRUNC(l.nextdate) - TRUNC(l.previousdate)) - COALESCE(tm.daysuntilnetdue, 0), 1) AS variance_days FROM nexttransactionlinelink l JOIN transaction inv ON l.previousdoc = inv.id JOIN customer c ON inv.entity = c.id LEFT JOIN term tm ON c.terms = tm.id WHERE l.linktype = 'Payment' AND l.previoustype = 'CustInvc' AND l.nexttype = 'CustPymt' AND l.foreignamount > 0 GROUP BY c.id, COALESCE(c.companyname, c.entityid), COALESCE(tm.name, '(no terms)'), COALESCE(tm.daysuntilnetdue, 0) HAVING COUNT(DISTINCT l.previousdoc) >= 3 ORDER BY ROUND(AVG(TRUNC(l.nextdate) - TRUNC(l.previousdate)) - COALESCE(tm.daysuntilnetdue, 0), 1) DESC
SELECT COUNT(*) AS applications, COUNT(DISTINCT l.previousdoc) AS invoices, COUNT(DISTINCT inv.entity) AS customers, ROUND(SUM(l.foreignamount), 2) AS total_dollars, ROUND(AVG(TRUNC(l.nextdate) - TRUNC(l.previousdate)), 1) AS avg_days, ROUND(SUM((TRUNC(l.nextdate) - TRUNC(l.previousdate)) * l.foreignamount) / NULLIF(SUM(l.foreignamount),0), 1) AS wtd_days, SUM(CASE WHEN TRUNC(l.nextdate) - TRUNC(l.previousdate) <= COALESCE(tm.daysuntilnetdue, 0) THEN 1 ELSE 0 END) AS within_terms, -- bucket columns: 0-7, 8-14, 15-21, 22-30, 31-45, 45+ via CASE WHEN ... BETWEEN SUM(CASE WHEN TRUNC(l.nextdate) - TRUNC(l.previousdate) <= 7 THEN 1 ELSE 0 END) AS b_0_7 /* ... remaining buckets elided for brevity — same pattern ... */ FROM nexttransactionlinelink l JOIN transaction inv ON l.previousdoc = inv.id JOIN customer c ON inv.entity = c.id LEFT JOIN term tm ON c.terms = tm.id WHERE l.linktype = 'Payment' AND l.previoustype = 'CustInvc' AND l.nexttype = 'CustPymt' AND l.foreignamount > 0
SELECT TO_CHAR(l.nextdate, 'YYYY-MM') AS pay_month, COUNT(*) AS applications, ROUND(SUM(l.foreignamount), 2) AS dollars, ROUND(AVG(TRUNC(l.nextdate) - TRUNC(l.previousdate)), 1) AS avg_days, ROUND(SUM((TRUNC(l.nextdate) - TRUNC(l.previousdate)) * l.foreignamount) / NULLIF(SUM(l.foreignamount),0), 1) AS wtd_days FROM nexttransactionlinelink l JOIN transaction inv ON l.previousdoc = inv.id WHERE l.linktype = 'Payment' AND l.previoustype = 'CustInvc' AND l.nexttype = 'CustPymt' AND l.foreignamount > 0 GROUP BY TO_CHAR(l.nextdate, 'YYYY-MM') ORDER BY TO_CHAR(l.nextdate, 'YYYY-MM')
SELECT inv.tranid, TO_CHAR(inv.trandate,'YYYY-MM-DD') AS invoice_date, TO_CHAR(inv.duedate,'YYYY-MM-DD') AS due_date, inv.foreigntotal, pay.tranid AS payment_num, TO_CHAR(pay.trandate,'YYYY-MM-DD') AS payment_date, l.foreignamount AS applied, TRUNC(l.nextdate) - TRUNC(l.previousdate) AS days_to_pay FROM nexttransactionlinelink l JOIN transaction inv ON l.previousdoc = inv.id JOIN transaction pay ON l.nextdoc = pay.id WHERE l.linktype = 'Payment' AND l.previoustype = 'CustInvc' AND l.nexttype = 'CustPymt' AND inv.entity = 483 ORDER BY days_to_pay DESC
SELECT COALESCE(c.companyname, c.entityid) AS customer, inv.tranid, TO_CHAR(inv.trandate,'YYYY-MM-DD') AS invoice_date, pay.tranid AS payment_num, TO_CHAR(pay.trandate,'YYYY-MM-DD') AS payment_date, l.foreignamount, TRUNC(l.nextdate) - TRUNC(l.previousdate) AS days FROM nexttransactionlinelink l JOIN transaction inv ON l.previousdoc = inv.id JOIN transaction pay ON l.nextdoc = pay.id JOIN customer c ON inv.entity = c.id WHERE l.linktype = 'Payment' AND l.previoustype = 'CustInvc' AND l.nexttype = 'CustPymt' AND TRUNC(l.nextdate) < TRUNC(l.previousdate) ORDER BY days
nexttransactionlinelink with linktype='Payment' (verified: nexttransactionlink and previoustransactionlink carry no CustInvc→CustPymt rows here). Terms come from the term table (daysuntilnetdue); all terms in use are simple day-driven (no datedriven='T' terms encountered, so no end-of-month due-date math was needed). Amounts use foreignamount per the account's SuiteQL exposure. Account contains 1,865 CustInvc, 1,472 CustPymt, 49 CustCred.