The growth story is real and attractive — +29.5% Q2 year-over-year revenue with operating margin expanding from 11.0% to 16.8%, and the transaction-backed revenue base more than doubled inside the TTM. But three findings would dominate any Quality of Earnings review: 85% of GL income is booked through recurring journal entries, zero accounting periods have been closed in 25 months, and half of open receivables are aged past 90 days — including the entire relationship value of three top-10 "customers" who have never paid. Each is fixable before a process starts — and fixing them is worth real enterprise value.
| Class | Revenue | Share % | Lines |
|---|---|---|---|
| Home & Decor | $623,032 | 35.7 | 151 |
| (No class assigned) | $613,056 | 35.2 | 20 |
| Apparel | $341,993 | 19.6 | 426 |
| Beauty | $142,516 | 8.2 | 317 |
| Miscellaneous | $12,175 | 0.7 | 11 |
| Channel | Revenue | Orders | Avg ticket |
|---|---|---|---|
| LA Distribution Center | $630,858 | 100 | $6,309 |
| (No location) | $613,056 | 20 | $30,653 |
| Miami | $364,751 | 45 | $8,106 |
| San Francisco Store | $80,881 | 441 | $183 |
| New York Store | $54,235 | 335 | $162 |
| Priority | Invoice | Customer | Due date | Days overdue | Open amount | Note |
|---|---|---|---|---|---|---|
| P1 | INV790 | Global Information | 2025-12-03 | 250 | $110,579 | Top-10 customer, only order — unpaid |
| P1 | INV782 | Red Rivers Consulting | 2026-03-20 | 143 | $102,906 | Top-10 customer, only order — unpaid |
| P1 | INV791 | Mercury Co. | 2025-05-19 | 448 | $80,079 | 448 days — assess collectability now |
| P1 | INV789 | Gotter inc. | 2025-12-09 | 244 | $68,119 | Top-12 customer, only order — unpaid |
| P2 | INV788 | Haskell Associates | 2025-09-29 | 315 | $43,941 | 315 days |
| P2 | INV784 | John G. Roche Opticians | 2026-04-15 | 117 | $31,810 | |
| P2 | INV780 | Informics International | 2026-03-23 | 140 | $29,239 | |
| P3 | INV786 | Ghetti Ltd | 2025-11-08 | 275 | $2,741 | |
| P3 | INV792 | Schmidt & Sons Consulting | 2025-07-05 | 401 | $1,770 | 401 days — reserve candidate |
| P3 | INV785 | Magneto Services | 2026-04-21 | 111 | $787 | |
| P3 | INV781 | The Abbott Inc. | 2026-04-26 | 106 | $416 | |
| P3 | INV787 | Jasper and Associates | 2025-12-13 | 240 | $264 | |
| P3 | INV793 | Kasson Ltd | 2025-04-03 | 494 | $262 | 494 days — reserve candidate |
| Total over 90 days | $472,913 | |||||
| ✅ Mature, full-cycle ERP usage: ~7,900 transactions across complete order-to-cash and procure-to-pay cycles, plus light manufacturing |
| ✅ Clean multi-entity structure: 4 subsidiaries incl. proper elimination entity, single currency |
| ✅ Modern automation stack: Fixed Assets, SuiteTax, Electronic Bank Payments, Ship Central bundles |
| ✅ Small local-customization footprint — most custom objects are bundle-owned, limiting technical-debt risk |
| ✅ AI/agent tooling with a persistent audit trail (every agent mutation logged) |
| 🔴 Plain-text credential stored in a custom vendor field (CUSTENTITY_PS_PASSWORD) — jumps straight into the security section of any diligence report |
| 🟡 7 active Administrator users — broad unrestricted access dilutes segregation-of-duties answers |
| 🟡 209 future-dated posted transactions ($596K) — symptom of missing period controls |
| 🟡 Duplicate location names (multiple "Quarantine Area" / "Return to Vendor") — minor, but data-hygiene questions compound |
For each "Beg Balance Entries" JE, attach the sub-ledger or source-system detail that supports it — or migrate the activity to transaction-level records going forward. This single item determines whether $10.2M of revenue is bankable in a QoE.
Close Jul 2024 – Jun 2026 after review, lock AR/AP/GL, adopt a standing close calendar (lock by business day 10), and resolve the 209 future-dated postings. Converts "the past can change" into "the past is signed off."
Four invoices, $361.7K — 76% of the aged AR, and three of them are the unpaid single-order top-10 accounts. Collect, negotiate payment plans, or formally reserve under a documented policy. This workstream simultaneously fixes the concentration optics (item 6).
Remove the plain-text credential field (move secrets to NetSuite's credential APIs or an external vault) and cut Administrator count from 7 to 2–3 with purpose-built roles for the rest.
Assign class and location to the ~20 unattributed transactions ($613K, 35% of itemized revenue) and add validation so new transactions can't post without them.
After collections are resolved, run a deliberate second-order campaign on the surviving single-order top-10 accounts. Two conversions to repeat status meaningfully shifts the recurring-revenue narrative.
Re-run this assessment monthly and trend the composite score (57 today; items 1–3 alone lift it to ≈80). Walking into management meetings with a self-audited, improving readiness score changes the negotiating posture from defensive to prepared.
Every figure in this report can be independently re-derived by running these read-only SuiteQL queries against the account. Hand this appendix to a buyer's analyst and they can verify the report in an afternoon — that reproducibility is itself a diligence asset.
SELECT TO_CHAR(t.trandate,'YYYY') AS yr, TO_CHAR(t.trandate,'Q') AS qtr,
a.accttype, ROUND(SUM(-tal.amount),2) AS amt
FROM transactionaccountingline tal
JOIN transaction t ON tal.transaction = t.id
JOIN account a ON tal.account = a.id
WHERE t.posting = 'T'
AND t.trandate >= TO_DATE('2024-07-01','YYYY-MM-DD')
AND t.trandate < TO_DATE('2026-07-01','YYYY-MM-DD')
AND a.accttype IN ('Income','OthIncome','COGS','Expense','OthExpense')
GROUP BY TO_CHAR(t.trandate,'YYYY'), TO_CHAR(t.trandate,'Q'), a.accttype
ORDER BY 1, 2, 3SELECT COALESCE(cl.name,'(none)') AS product_class,
ROUND(SUM(ABS(tl.netamount)),2) AS revenue, COUNT(DISTINCT t.id) AS tx_count
FROM transaction t
JOIN transactionline tl ON tl.transaction = t.id AND tl.mainline='F' AND tl.taxline='F'
LEFT JOIN classification cl ON tl.class = cl.id
WHERE t.type IN ('CustInvc','CashSale') AND t.posting='T'
AND t.trandate >= TO_DATE('2025-07-01','YYYY-MM-DD')
AND t.trandate < TO_DATE('2026-07-01','YYYY-MM-DD')
AND tl.subsidiary <> 4
GROUP BY COALESCE(cl.name,'(none)')
ORDER BY SUM(ABS(tl.netamount)) DESC
-- Channel version: replace classification join with
-- LEFT JOIN location l ON tl.location = l.id-- Top customers (TTM)
SELECT c.entityid, ROUND(SUM(ABS(tl.netamount)),2) AS ttm_revenue, COUNT(DISTINCT t.id) AS orders
FROM transaction t
JOIN customer c ON t.entity = c.id
JOIN transactionline tl ON tl.transaction = t.id AND tl.mainline='F' AND tl.taxline='F'
WHERE t.type IN ('CustInvc','CashSale') AND t.posting='T'
AND t.trandate >= TO_DATE('2025-07-01','YYYY-MM-DD')
AND t.trandate < TO_DATE('2026-07-01','YYYY-MM-DD') AND tl.subsidiary <> 4
GROUP BY c.entityid ORDER BY 2 DESC FETCH FIRST 15 ROWS ONLY
-- Retention: FULL OUTER JOIN of DISTINCT prior-year vs current-year
-- customer sets on the same filters (69 retained / 3 churned / 25 new)SELECT CASE WHEN t.duedate >= TRUNC(SYSDATE) OR t.duedate IS NULL THEN '1_current'
WHEN TRUNC(SYSDATE)-TRUNC(t.duedate) <= 30 THEN '2_1-30'
WHEN TRUNC(SYSDATE)-TRUNC(t.duedate) <= 60 THEN '3_31-60'
WHEN TRUNC(SYSDATE)-TRUNC(t.duedate) <= 90 THEN '4_61-90'
ELSE '5_over90' END AS bucket,
COUNT(*) AS invoices, ROUND(SUM(t.foreignamountunpaid),2) AS open_amount
FROM transaction t
WHERE t.type='CustInvc' AND t.status='A' AND t.foreignamountunpaid > 0
GROUP BY /* same CASE */ 1 ORDER BY 1
-- AP version: t.type='VendBill'
-- Worklist: add tranid, customer, duedate; filter duedate < SYSDATE-90SELECT TO_CHAR(t.trandate,'YYYY-MM') AS mo,
CASE WHEN t.type='Journal' THEN 'journal' ELSE 'billed' END AS src,
ROUND(SUM(-tal.amount),2) AS income
FROM transactionaccountingline tal
JOIN transaction t ON tal.transaction = t.id
JOIN account a ON tal.account = a.id
WHERE t.posting='T' AND a.accttype IN ('Income','OthIncome')
AND t.trandate >= TO_DATE('2025-07-01','YYYY-MM-DD')
AND t.trandate < TO_DATE('2026-07-01','YYYY-MM-DD')
GROUP BY TO_CHAR(t.trandate,'YYYY-MM'),
CASE WHEN t.type='Journal' THEN 'journal' ELSE 'billed' END
ORDER BY 1, 2-- Period locks (0 of 25 closed)
SELECT p.periodname, p.closed, p.aplocked, p.arlocked, p.alllocked
FROM accountingperiod p
WHERE p.isquarter='F' AND p.isyear='F' AND p.isadjust='F'
AND p.startdate >= TO_DATE('2024-07-01','YYYY-MM-DD')
ORDER BY p.startdate
-- Future-dated posted transactions (209 / $596K)
SELECT COUNT(*) FROM transaction t
WHERE t.posting='T' AND t.trandate > TO_DATE('2026-08-10','YYYY-MM-DD')
-- Active Administrators (7)
SELECT COUNT(DISTINCT e.id) FROM employee e
JOIN employeerolesforsearch er ON er.entity = e.id
JOIN role r ON er.role = r.id
WHERE e.isinactive='F' AND r.name LIKE '%dministrator%'