Sample output from the Cost & Gross Margin Review with Inventory Investment Diagnostic prompt in the Sonar AI Prompt Library, run against a NetSuite test account. Every name and number here is test data. Back to the post · The library
Sonar AI · Finance Analytics
Account TD3016323 · Production
Prepared 18 September 2026
Basis: NetSuite general ledger & inventory, live extract

Cost & Gross Margin Review
FY2026 year to date

Reported gross margin is 39.1%, up two points on last year. Beneath the reported figure, the business holds 600 days of inventory — two-thirds of it in excess of any plausible demand — concentrated in the lowest-margin category. Working capital, not unit cost, is the primary cost problem.

39.1%
Reported gross margin, FY26 YTD
37.1% same span FY25
0.61×
Inventory turns, trailing 12 months
≈ 600 days on hand
$740K
Inventory above 180 days of supply
66% of $1.117M on hand
$40K
Dead stock — no sales in 12 months
48 SKUs, $5.6K more on open PO

Contents

  1. 01Executive summary
  2. 02Gross margin — reported vs. transactional
  3. 03Cost of goods by category
  4. 04Inventory investment
  5. 05Excess, dead and stranded stock
  6. 06Inbound commitments (open POs)
  7. 07Operating expenses
  8. 08Recommendations & financial impact
  9. 0990-day action plan
  10. 10Assumptions & methodology
  11. 11Data caveats & risks
  12. AAppendix A — Queries
  13. BAppendix B — Source documents

01Executive summary

Three findings, in order of financial weight.

1. Inventory is the cost problem. $1,116,806 is on hand against $679,211 of trailing-twelve-month cost of sales — 0.61 turns, roughly 600 days of supply, against a retail norm of 45–90 days. $739,751 sits above a 180-day supply threshold. Only one of 185 stocked SKUs has less than six months of supply.

2. Apparel is where the capital is trapped. Apparel holds 56% of inventory dollars ($627,511), generates 35% of cost of sales, turns 0.38× and carries the thinnest margin of any category (40.9%). Eight leather-goods and bag SKUs alone account for $457K of stock, $409K of it excess, with 3–8 years of supply each.

3. Purchasing is un-governed. Reorder points exist on four items. Open purchase orders are still landing units into SKUs that already have multi-year supply or have not sold in twelve months — including PO395 ($5,620) entirely into dead stock.

On the P&L itself, the reported gross margin improvement (37.1% → 39.1%) is driven wholly by the account 5310 Purchases ratio, which is 100% synthetic in this ledger (see §11). Real transactional margin is 63.6% blended, ~44% on physical product, and improved materially year on year.

Releasing the excess inventory to a 180-day supply level would free approximately $740K of working capital. At a conservative 20% annual carrying cost, the excess is costing $148K per year to hold — equivalent to 16% of real gross profit.

Carrying-cost rate is an assumption; see §10.

02Gross margin — reported vs. transactional

The general ledger contains monthly "Beg Balance Entries" journals (JE102–JE149) that post synthetic revenue and cost in both subsidiaries. They constitute ~86% of GL revenue. Both views are presented; the transactional view is the one that reflects operational decisions.

Reported GL — Jan–Sep 2026 vs. Jan–Sep 2025

LineFY26 YTD% RevFY25 YTD% RevChange
Revenue (4210, 4310, 4320, 4450)$9,299,857100.0%$7,892,757100.0%+17.8%
5310 COGS : Purchases$4,633,33049.8%$4,098,81451.9%+13.0%
5340 COGS : Cost of Sales$524,9335.6%$414,2535.2%+26.7%
5360 COGS : 3rd Party Contracting$515,0755.5%$454,7945.8%+13.3%
5205 Purchase Price Variance$3,1600.0%——new
5370 Stock Adjustment (credit)($9,049)(0.1%)——new
Total cost of goods sold$5,667,44960.9%$4,967,86162.9%+14.1%
Gross margin$3,632,40839.1%$2,924,89637.1%+2.0 pts

Subsidiaries 1–3; elimination subsidiary excluded. Ties to the Income Statement by posting period.

Transactional only — synthetic journals excluded

LineFY26 YTDFY25 YTDChange
Product revenue (4210)$1,411,306$834,446+69.1%
Freight revenue (4450)$15,936$4,561+249%
Returns & allowances (4320)$282—
Revenue$1,427,524$839,007+70.1%
5340 Cost of Sales$524,933$414,253+26.7%
5205 PPV + 5310 Purchases$3,223—
5370 Stock Adjustment($9,049)—
Cost of goods sold$519,106$414,253+25.3%
Gross margin$908,418 · 63.6%$424,754 · 50.6%+13.0 pts

Blended margin is flattered by ~$546K of service/uncategorized revenue carrying almost no item cost; product-only margin is approximately 44%.

Reading the two views together. The 2-point reported improvement comes entirely from the synthetic Purchases line falling from 51.9% to 49.8% of revenue. Real transactional activity improved far more (50.6% → 63.6%), largely through revenue mix. Cost-reduction effort should therefore target the balance sheet (inventory) rather than the unit-cost lines of the P&L.

03Cost of goods by category

Real cost of sales, FY2026 YTD, attributed via item class with the Merchandise Hierarchy level-1 segment as fallback. Apparel is the category with the highest cost ratio; Home Goods carries the largest absolute cost.

CategoryFY26 revenueFY26 COGSCOGS %GM %FY25 GM %Share of COGS
Home Goods$479,025$266,81655.7%44.3%44.0%51%
Apparel$307,929$179,98558.4%41.6%38.5%35%
Beauty$73,800$39,67253.8%46.2%46.1%8%
Miscellaneous$20,925$8,30039.7%60.3%—2%
Electronics$0$3,223n/acost, no revenue—1%
Uncategorized (services, misc.)$545,844$21,1113.9%96.1%83.1%4%
Gross margin by physical-product category — FY26 YTD
Beauty
46.2%
Home Goods
44.3%
Apparel
41.6%
Scale 0–60%. Miscellaneous (60.3%, $21K revenue) omitted as immaterial.

04Inventory investment

All figures from inventoryitemlocations at extract time (item-location rows with non-zero on-hand or on-order; 568 rows, 185 SKUs, 5 stocking locations). Velocity is trailing-twelve-month units invoiced or cash-sold.

MeasureValueReference
Inventory value on hand$1,116,806Sum of onhandvaluemli
Real cost of sales, trailing 12 months$679,211COGS accounts, synthetic journals excluded
Inventory turns0.61×Retail / wholesale norm 4–8×
Days inventory on hand~600Norm 45–90
Value above 180 days of supply$739,75166% of on-hand
SKUs with reorder point set4 of 185inventoryitemlocations.reorderpoint

Days of supply distribution

Over 2 years — 33 SKUs, $503,442 1–2 years — 49 SKUs, $228,127 6–12 months — 54 SKUs, $344,623 No sales in 12 months — 48 SKUs, $39,924 Under 6 months — 1 SKU, $690

By category

CategoryOn handSKUs12-mo COGSTurnsExcess >180dDeadGM % (12-mo)
Apparel$627,51152$238,7370.38×$485,829—40.9%
Home Goods$303,43927$333,0711.10×$121,748—44.2%
Beauty$99,79131$56,4030.57×$68,696—45.9%
Uncategorized$49,62653$39,4780.80×$29,048$11,82344.6%
Miscellaneous$23,67413$00$21,665$15,336—
Electronics$12,7659$3,2230.25×$12,765$12,765—
Total$1,116,806185$679,2110.61×$739,751$39,924
Inventory on hand by category
Apparel
$627,511
Home Goods
$303,439
Beauty
$99,791
Uncategorized
$49,626
Miscellaneous
$23,674
Electronics
$12,765

By location

LocationValueUnitsSKUsDead stock value
03: Los Angeles Distribution Center (5)$352,4957,870141$23,798
01: San Francisco Store (1)$308,7524,294168$9,126
05: Miami (12)$212,0693,696119—
02: New York Store (3)$200,9692,042118—
04: Chicago Distribution Center (8)$42,52058022$7,000

The San Francisco store carries more SKUs (168) than either distribution center — a store operating as a de facto warehouse.

05Excess, dead and stranded stock

Excess capital — top 12 SKUs

Excess is the on-hand value above a 180-day supply at trailing-twelve-month velocity. These twelve items hold $551K of stock, $450K of it excess.

ItemCategoryOn handValueSold 12 moDays supplyGM %Excess
Black Leather JacketApparel552$110,400902,23928.7$101,525
Black Leather ValiseApparel584$75,336882,42262.9$69,737
Brown Leather SatchelApparel209$62,698711,07422.3$52,190
Gold Watch with Leather StrapApparel270$59,400731,35037.4$51,480
Brown Leather ValiseApparel283$45,280871,18736.2$38,414
Canvas BackpackApparel328$40,016522,30250.0$36,887
Indigo Relaxed FitBeauty*525$36,750672,86048.5$34,437
Olive Utility PackApparel276$27,600681,48148.1$24,246
Estes Park ChairHome Goods54$16,605355632.6$11,296
The Bindel JacketApparel71$19,8806738710.0$10,633
Black Leather BeltApparel300$11,100701,56418.4$9,823
Patriarch Luxury Firm T MHome Goods36$14,4002552654.8$9,472

* "Indigo Relaxed Fit" is classed as Beauty in the item master; it is almost certainly apparel. See §11, data hygiene.

Days of supply — top excess SKUs (180-day target shown for scale)
Indigo Relaxed Fit
2,860 d
Black Leather Valise
2,422 d
Canvas Backpack
2,302 d
Black Leather Jacket
2,239 d
Black Leather Belt
1,564 d
Olive Utility Pack
1,481 d
Gold Watch
1,350 d
180-day target
180 d

Dead stock — no sales in 12 months (top 10 of 48)

ItemCategoryQtyValueLocation (qty)On order
ASUS PG348Q 34" Curved MonitorUncategorized11$9,081LA DC 11+1
INV_2-Layer CopperElectronics461$7,816SF Store 211 · LA DC 250—
INV_BLT001Miscellaneous154$6,622LA DC 54 · Chicago DC 100—
INV_Solder Mask – BlueElectronics773$3,865SF Store 250 · LA DC 523—
INV_CAP001Miscellaneous154$3,850LA DC 54 · Chicago DC 100—
INV_RIM001Miscellaneous22$2,200LA DC 22+10
INV_PCB005Uncategorized10$1,270SF Store 10—
INV_NUT001Miscellaneous54$1,080LA DC 54+110
INV_SPK001Miscellaneous472$944LA DC 472+50
INV_KBA001Uncategorized35$893SF Store 35—
Interpretation. The Electronics and Miscellaneous items (copper, solder mask, nuts, bolts, caps, speakers) have the profile of manufacturing components rather than finished goods. Raw material is legitimate inventory if it feeds work orders — but nothing has consumed these in twelve months, and Electronics posted $3,223 of cost against zero revenue this year. Confirm against open work orders (24 exist) before writing down. Holding 461 units of copper in a retail store (San Francisco) is difficult to justify on any reading.

Stranded stock

$159,929 across 97 item-location pairs sits at a location where that item has recorded no sales in twelve months, while the same item sells elsewhere. This is inventory that is neither dead nor excess in aggregate — it is simply in the wrong place.

Margin-negative stock

Items with gross margin below 25% and more than $3,000 on hand. Holding cost on these likely exceeds their contribution.

ItemOn handValueDays supplyGM %On order
Brown Leather Satchel209$62,6981,07422.3+1
The Bindel Jacket71$19,88038710.0—
Estes Park Chair54$16,6055632.6—
Black Leather Belt300$11,1001,56418.4+6
Salida Backpack GR65$5,20051617.6—
Salida Backpack BU63$5,04052317.5—

06Inbound commitments — open purchase orders

Open PO lines for items already dead or above 365 days of supply. Total open exposure is modest ($8,084) but the pattern matters more than the amount: purchasing is replenishing SKUs that will not sell for years.

PODateVendorItemOpen qtyOpen valueDestinationStock status
PO3952026-06-01Johnson SupplyINV_NUT001100$2,000Chicago DCDead
PO3952026-06-01Johnson SupplyINV_FRM00110$1,850Chicago DC1,004 d supply
PO3952026-06-01Johnson SupplyINV_RIM00110$1,000Chicago DCDead
PO11712026-08-25China ManufacturerASUS PG348Q Monitor1$750SF StoreDead · pending approval
PO3952026-06-01Johnson SupplyINV_HDW00210$670Chicago DC1,004 d supply
PO394 / 1183 / 1178 / 1157 / 364 / 314 / 375 / 374Sep 2026Generation N, IntercoINV_Grey Cotton Hoodie37$1,140SF, LA, NY, Miami521 d supply
PO11772026-07-01Generation NBrown Leather Satchel1$300SF Store1,074 d · 22% GM
PO11862026-09-15Johnson SupplyINV_NUT00110$200SF StoreDead
PO3952026-06-01Johnson SupplyINV_SPK00150$100Chicago DCDead
PO1175 / 1176Jun–Sep 2026Generation NBlack Leather Belt2$74SF Store1,564 d · 18% GM
Total — 18 open lines231$8,084

PO395 alone: $5,620 to Chicago DC, every line into dead or multi-year stock. Eight separate small POs for Grey Cotton Hoodie in one month indicate no consolidated replenishment logic.

07Operating expenses

Real (transactional) operating expense is small relative to cost of goods and is concentrated in Sales. Administration, Product Development and Merchandising expense in the GL is entirely synthetic.

DepartmentFY26 realFY25 realFY26 synthetic
Sales$361,408$332,850—
(no department)$62,680$0—
Store Operations$650——
Administration$392—$1,647,597
Warehouse Operations$74——
Merchandising——$164,039
Product Development——$149,393

Largest real expense accounts

AccountFY26 YTDFY25 YTDChange
6060 Advertising$188,936$169,290+11.6%
6655 Computer – Office Expense$73,817$70,003+5.4%
6671 Telephone – Regular Service$61,514$58,335+5.4%
6260 Training Expense$53,550$0new
6240 Supplies Expense$24,488$23,223+5.4%
6640 Other Utilities$7,381$7,000+5.4%
6630 Repairs & Maintenance$5,272$5,000+5.4%
6250 Automobile Expense$3,000$0new
6610 Rent Expense$2,880$0new

A uniform +5.4% across five unrelated accounts suggests a contractual or indexed uplift rather than activity-driven cost growth.

08Recommendations & financial impact

Ranked by financial weight. Impact figures are indicative and depend on the assumptions in §10.

1
Liquidate the Apparel leather-goods overhang
Working capitalHigh impact

Eight SKUs (Black Leather Jacket, both Valises, Brown Satchel, Gold Watch, Canvas Backpack, Olive Utility Pack, Indigo Relaxed Fit) hold $457K, of which $409K is excess at 3–8 years of supply. Run a structured markdown, outlet or wholesale clearance to a 180-day target. Even at 30% below cost, units that would otherwise take years to sell are converted to cash.

$285K–$410Kcash released (70–100% cost recovery on $409K excess)
2
Freeze replenishment above 365 days of supply; cancel PO395
ControlImmediate

Twelve SKUs have open PO quantity landing into dead or multi-year stock. Cancel PO395 (Johnson Supply, $5,620, Chicago DC — every line dead or 1,000+ days), reject PO1171 (monitor, pending approval), and defer the 37 Grey Cotton Hoodie units across eight POs. Institute a rule: no PO line where projected days of supply after receipt exceeds 365.

$8Kavoided now; prevents recurrence
3
Set reorder points and preferred stock levels on every stocked SKU
ControlStructural

Only 4 of 185 SKUs have a reorder point. Derive ROP and PSL per item-location from trailing velocity (target 60–90 days of supply, safety stock at lead time) and load them to inventoryitemlocations. This converts purchasing from judgement to policy and is the single change that keeps the problem from rebuilding.

Sustainsturns at 4× or better once excess is cleared
4
Consolidate stranded stock to where it sells
Working capitalOperational

$160K across 97 item-location pairs sits where the item has not sold in a year. Transfer to the location that does sell it (or to the LA DC as the primary node). Reduces store carrying cost, improves availability, and removes the need to buy more of items that are already owned.

$160Kredeployed without purchase
5
Write down or dispose of dead stock after work-order check
P&LHygiene

48 SKUs, $39,924, zero sales in twelve months. Confirm the Electronics/Miscellaneous components are not committed to open work orders; then scrap, return to vendor, or sell as surplus. Take the write-down in one period rather than carrying it.

$40Kone-time charge; $8K/yr carrying cost removed
6
Reprice, renegotiate or exit sub-25% margin SKUs
Margin

Estes Park Chair (2.6% GM), Bindel Jacket (10%), Salida Backpacks (~18%), Black Leather Belt (18%), Brown Leather Satchel (22%). Each is also over-stocked. Raise price where the market allows, renegotiate cost with Generation N, or discontinue after clearance. Do not reorder.

+1–2 ptsproduct GM once mix shifts
7
Close the department-coding gap and validate new expense lines
OpexHygiene

$62,680 of FY26 expense has no department (none in FY25). Training ($53,550), Automobile ($3,000) and Rent ($2,880) are new lines with no prior-year equivalent. Assign owners and confirm these are budgeted.

$120Kbrought under departmental accountability
8
Tie Advertising spend to sell-through, not revenue
Opex

Advertising is up $19.6K (+11.6%) while Apparel stock ages. Direct incremental marketing at the clearance program in Recommendation 1; measure cost per unit of excess cleared rather than cost per revenue dollar.

Redirects$189K to the highest-value use

Cash-release scenarios

ScenarioExcess addressedRecovery rateCash releasedAnnual carrying cost avoided*
Top 8 Apparel SKUs, aggressive clearance$409,00070%$286,300$81,800
Top 8 Apparel SKUs, at cost$409,000100%$409,000$81,800
All excess to 180 days, blended$739,75180%$591,800$148,000
Dead stock disposal$39,92410%$4,000$8,000

* At a 20% annual carrying-cost rate (capital, storage, shrink, obsolescence). Recovery rates are planning assumptions, not forecasts.

0990-day action plan

Days 1–14 · Stop the bleeding
  • Cancel PO395; reject PO1171; hold Grey Cotton Hoodie POs
  • Purchasing freeze on all SKUs > 365 days supply
  • Work-order check on Electronics / Misc. components
  • Assign departments to the $62.7K unclassified expense
Days 15–45 · Release capital
  • Launch Apparel clearance program (8 SKUs, $409K excess)
  • Transfer orders for stranded stock ($160K) to selling locations
  • Pricing / vendor review of six sub-25% GM items
  • Book dead-stock write-down
Days 46–90 · Institutionalize
  • Load ROP / PSL to all 185 SKUs from velocity model
  • Monthly days-of-supply and turns report by category and location
  • PO approval rule: projected DOS after receipt ≤ 365
  • Fix item classification (Indigo Relaxed Fit, Uncategorized)

10Assumptions & methodology

AssumptionBasis
Comparison spanFY26 YTD = posting periods Jan–Sep 2026; FY25 comparator = Jan–Sep 2025 (same nine months). Fiscal year is calendar year.
Synthetic-journal exclusionTransactions with memo LIKE 'Beg Balance%' are treated as synthetic (journals JE102–JE149, one per subsidiary per month). Excluded from all "real"/"transactional" figures; included in "reported" figures.
Subsidiary scopeSubsidiaries 1, 2, 3 via transactionline.subsidiary. Elimination subsidiary 4 excluded (zero P&L activity).
Revenue signGL stores revenue as credits (negative). Reported as -SUM(tal.amount). COGS/expense reported as SUM(tal.amount).
Category attributionitem.class where set (30 items); otherwise Merchandise Hierarchy level-1 segment (csegmh_cseg_1) on the item or its matrix parent; otherwise "Uncategorized". Category names Home Goods / Apparel / Beauty / Electronics / Miscellaneous come from the account.
Velocity windowTrailing 12 months from 2025-09-18, units on CustInvc and CashSale lines (mainline='F', taxline='F'). Daily rate = units ÷ 365.
Days of supplyOn-hand quantity ÷ daily rate, per item across all locations. Items with zero 12-month sales are "dead" (undefined DOS).
ExcessOn-hand value × (1 − 180 ÷ DOS) for items above 180 DOS; full on-hand value for dead items. 180 days chosen as a lenient threshold; a 90-day target would classify more as excess.
StrandedItem-location rows with on-hand > 0 and zero 12-month sales at that location, regardless of the item's sales elsewhere. Computed per transactionline.location.
Inventory valueinventoryitemlocations.onhandvaluemli (multi-location average cost). Rows with null value treated as zero.
TurnsTrailing 12-month real COGS ÷ current on-hand value (point-in-time, not average inventory). Average-inventory turns would be similar given the slow movement.
Carrying cost20% of inventory value per year — a conventional planning figure covering capital, storage, insurance, shrink and obsolescence. Not derived from this account.
Open PO exposurePurchOrd with status A/B/E (pending receipt, partially received, pending approval); open qty = ordered − quantityshiprecv; value pro-rated from line netamount.
BenchmarksRetail/wholesale inventory turns of 4–8× and 45–90 days on hand are general industry ranges, quoted for orientation only.

11Data caveats & risks

Items that could change the conclusions.

AAppendix A — Queries

All queries are SuiteQL, run live against this account on 2026-09-18 with the current user's Administrator role. Reproducible via the SuiteQL Query Tool.

A1 · Revenue and COGS by account, real vs synthetic, FY26 YTD vs FY25
SELECT a.acctnumber, a.fullname,
  CASE WHEN ap.startdate >= TO_DATE('2026-01-01','YYYY-MM-DD') THEN 'FY26' ELSE 'FY25' END AS fy,
  CASE WHEN t.memo LIKE 'Beg Balance%' THEN 'synthetic' ELSE 'real' END AS src,
  ROUND(SUM(-tal.amount),2) AS amount
FROM transactionaccountingline tal
JOIN transaction t            ON tal.transaction = t.id
JOIN transactionline tl       ON tl.transaction = tal.transaction AND tl.id = tal.transactionline
JOIN account a                ON tal.account = a.id
JOIN accountingperiod ap      ON t.postingperiod = ap.id
WHERE t.posting = 'T' AND tal.posting = 'T'
  AND tl.subsidiary IN (1,2,3)
  AND a.accttype IN ('Income','COGS')
  AND ((ap.startdate >= TO_DATE('2025-01-01','YYYY-MM-DD') AND ap.startdate < TO_DATE('2025-10-01','YYYY-MM-DD'))
    OR ap.startdate >= TO_DATE('2026-01-01','YYYY-MM-DD'))
GROUP BY a.acctnumber, a.fullname,
  CASE WHEN ap.startdate >= TO_DATE('2026-01-01','YYYY-MM-DD') THEN 'FY26' ELSE 'FY25' END,
  CASE WHEN t.memo LIKE 'Beg Balance%' THEN 'synthetic' ELSE 'real' END
ORDER BY a.acctnumber, fy, src
A2 · Real revenue and COGS by product category, FY26 vs FY25
SELECT
  COALESCE(c.name, BUILTIN.DF(i.csegmh_cseg_1), BUILTIN.DF(p.csegmh_cseg_1), 'Uncategorized') AS category,
  CASE WHEN ap.startdate >= TO_DATE('2026-01-01','YYYY-MM-DD') THEN 'FY26' ELSE 'FY25' END AS fy,
  ROUND(SUM(CASE WHEN a.accttype = 'Income' THEN -tal.amount ELSE 0 END),2) AS revenue,
  ROUND(SUM(CASE WHEN a.accttype = 'COGS'   THEN  tal.amount ELSE 0 END),2) AS cogs
FROM transactionaccountingline tal
JOIN transaction t        ON tal.transaction = t.id
JOIN transactionline tl   ON tl.transaction = tal.transaction AND tl.id = tal.transactionline
JOIN account a            ON tal.account = a.id
JOIN accountingperiod ap  ON t.postingperiod = ap.id
LEFT JOIN item i          ON tl.item = i.id
LEFT JOIN item p          ON i.parent = p.id
LEFT JOIN classification c ON i.class = c.id
WHERE t.posting = 'T' AND tal.posting = 'T'
  AND tl.subsidiary IN (1,2,3)
  AND a.accttype IN ('Income','COGS')
  AND (t.memo IS NULL OR t.memo NOT LIKE 'Beg Balance%')
  AND ((ap.startdate >= TO_DATE('2025-01-01','YYYY-MM-DD') AND ap.startdate < TO_DATE('2025-10-01','YYYY-MM-DD'))
    OR ap.startdate >= TO_DATE('2026-01-01','YYYY-MM-DD'))
GROUP BY COALESCE(c.name, BUILTIN.DF(i.csegmh_cseg_1), BUILTIN.DF(p.csegmh_cseg_1), 'Uncategorized'),
  CASE WHEN ap.startdate >= TO_DATE('2026-01-01','YYYY-MM-DD') THEN 'FY26' ELSE 'FY25' END
ORDER BY category, fy
A3 · Inventory on hand by item and location
SELECT iil.item, i.itemid,
  COALESCE(c.name, BUILTIN.DF(i.csegmh_cseg_1), BUILTIN.DF(p.csegmh_cseg_1), 'Uncategorized') AS category,
  iil.location, l.name AS locname,
  iil.quantityonhand AS qoh, iil.onhandvaluemli AS val, iil.quantityonorder AS qoo
FROM inventoryitemlocations iil
JOIN item i               ON iil.item = i.id
LEFT JOIN item p          ON i.parent = p.id
LEFT JOIN classification c ON i.class = c.id
JOIN location l           ON iil.location = l.id
WHERE iil.quantityonhand <> 0 OR iil.quantityonorder <> 0
A4 · Trailing-12-month units and revenue by item and location
SELECT tl.item, tl.location,
  SUM(ABS(tl.quantity)) AS units, SUM(ABS(tl.netamount)) AS rev
FROM transactionline tl
JOIN transaction t ON tl.transaction = t.id
WHERE t.type IN ('CustInvc','CashSale')
  AND tl.mainline = 'F' AND tl.taxline = 'F'
  AND tl.item IS NOT NULL AND tl.subsidiary IN (1,2,3)
  AND t.trandate >= TO_DATE('2025-09-18','YYYY-MM-DD')
GROUP BY tl.item, tl.location
A5 · Trailing-12-month real COGS by item
SELECT tl.item, SUM(tal.amount) AS cogs
FROM transactionaccountingline tal
JOIN transaction t      ON tal.transaction = t.id
JOIN transactionline tl ON tl.transaction = tal.transaction AND tl.id = tal.transactionline
JOIN account a          ON tal.account = a.id
WHERE t.posting = 'T' AND tal.posting = 'T'
  AND a.accttype = 'COGS' AND tl.subsidiary IN (1,2,3)
  AND (t.memo IS NULL OR t.memo NOT LIKE 'Beg Balance%')
  AND t.trandate >= TO_DATE('2025-09-18','YYYY-MM-DD')
  AND tl.item IS NOT NULL
GROUP BY tl.item
A6 · Reduction logic (JavaScript, applied to A3 + A4 + A5 in a sandboxed worker)
// per item: qoh, val, qoo summed across locations
// velocity u = 12-mo units; dos = qoh / (u / 365)
// band: u == 0 → dead; dos > 720 → >2 yrs; > 365 → 1–2 yrs; > 180 → 6–12 mo; else < 6 mo
// excess = u == 0 ? val : (dos > 180 ? val * (1 - 180/dos) : 0)
// gm% = (rev - cogs) / rev; turns = cogs / val
// stranded = item-location rows with qoh > 0 and zero sales at that location
// aggregates: totals, bands, byCategory, byLocation, topN excess / dead / low-margin / on-order-into-excess
A7 · Open PO lines for excess/dead items
SELECT t.tranid, TO_CHAR(t.trandate,'YYYY-MM-DD') AS podate, BUILTIN.DF(t.status) AS status,
  v.entityid AS vendor, i.itemid,
  ABS(tl.quantity) AS qty, COALESCE(tl.quantityshiprecv,0) AS received,
  ABS(tl.quantity) - COALESCE(tl.quantityshiprecv,0) AS open_qty,
  ROUND(ABS(tl.netamount) * (ABS(tl.quantity) - COALESCE(tl.quantityshiprecv,0)) / NULLIF(ABS(tl.quantity),0),2) AS open_value,
  l.name AS locname
FROM transactionline tl
JOIN transaction t     ON tl.transaction = t.id
JOIN item i            ON tl.item = i.id
LEFT JOIN vendor v     ON t.entity = v.id
LEFT JOIN location l   ON tl.location = l.id
WHERE t.type = 'PurchOrd' AND tl.mainline = 'F' AND tl.taxline = 'F'
  AND t.status IN ('A','B','E')
  AND ABS(tl.quantity) - COALESCE(tl.quantityshiprecv,0) > 0
  AND i.itemid IN (/* excess / dead item list from A6 */)
ORDER BY open_value DESC
A8 · Operating expense by department and by account, real vs synthetic
SELECT COALESCE(d.name,'(none)') AS department,
  ROUND(SUM(CASE WHEN ap.startdate >= TO_DATE('2026-01-01','YYYY-MM-DD')
                  AND (t.memo IS NULL OR t.memo NOT LIKE 'Beg Balance%') THEN tal.amount ELSE 0 END),0) AS fy26_real,
  ROUND(SUM(CASE WHEN ap.startdate >= TO_DATE('2026-01-01','YYYY-MM-DD')
                  AND t.memo LIKE 'Beg Balance%' THEN tal.amount ELSE 0 END),0) AS fy26_synth,
  ROUND(SUM(CASE WHEN ap.startdate <  TO_DATE('2025-10-01','YYYY-MM-DD')
                  AND (t.memo IS NULL OR t.memo NOT LIKE 'Beg Balance%') THEN tal.amount ELSE 0 END),0) AS fy25_real
FROM transactionaccountingline tal
JOIN transaction t       ON tal.transaction = t.id
JOIN transactionline tl  ON tl.transaction = tal.transaction AND tl.id = tal.transactionline
JOIN account a           ON tal.account = a.id
JOIN accountingperiod ap ON t.postingperiod = ap.id
LEFT JOIN department d   ON tl.department = d.id
WHERE t.posting = 'T' AND tal.posting = 'T' AND tl.subsidiary IN (1,2,3)
  AND a.accttype IN ('Expense','OthExpense')
  AND ((ap.startdate >= TO_DATE('2025-01-01','YYYY-MM-DD') AND ap.startdate < TO_DATE('2025-10-01','YYYY-MM-DD'))
    OR ap.startdate >= TO_DATE('2026-01-01','YYYY-MM-DD'))
GROUP BY COALESCE(d.name,'(none)')
ORDER BY 2 DESC
-- account-level variant: GROUP BY a.acctnumber, a.fullname; real only; FETCH FIRST 12 ROWS ONLY

BAppendix B — Source documents & data lineage

SourceUse in this report
NetSuite transactionaccountingline, transaction, transactionline, account, accountingperiodAll P&L, COGS and opex figures (§2, §3, §7). Posting flag on both transaction and accounting line; subsidiary from the transaction line.
inventoryitemlocations, item, classification, locationInventory quantity, value, on-order, reorder-point coverage (§4, §5).
transactionline on PurchOrd, vendorOpen purchase-order exposure (§6).
Custom segment csegmh_cseg_1 (Merchandise Hierarchy level 1)Category fallback where item.class is unset.
Sonar field notes for account TD3016323Known ledger characteristics: synthetic Beg Balance journals; subsidiary and location ids; inventory schema (only 5 of 15 locations hold stock; onhandvaluemli as value column; 4 items with reorder points).
"Boardroom Red" branding & formatting guidelines (attached, 1.5 KB)Typography (Helvetica Neue / Roboto), palette (#1A1A1A, #3C3C3C, #C74634, #1B2838, #EAEAEA), single-column layout, monochrome charts with single red highlight, muted risk boxes, 9-pt disclaimers, subtle top-corner branding. Applied throughout.

Suggested follow-on analyses

Available on request from the same data: (a) full 185-SKU item-location detail as CSV — on-hand, velocity, days of supply, margin, excess, on-order; (b) suggested reorder point and preferred stock level per item-location from the velocity model; (c) monthly turns and days-of-supply series by category to separate seasonal build from structural excess; (d) vendor-level cost trend for Generation N and Johnson Supply; (e) a standing monthly version of this review.