Sell-Through Report
Sell-Through Report estimates what percentage of each product's available stock has sold in a chosen date range — units sold ÷ (units sold + units currently on hand) — and buckets every product into Dead stock, Slow mover, Moving or Fast mover so you can see which lines are performing and which are not.
Overview
The page combines two generic endpoints in parallel: sales data for the chosen date range from the top-selling-products report, and the full product catalog. It joins them client-side by product ID to build the sell-through percentage.
The sell-through formula used is: rate = units sold in the period ÷ (units sold + current stock on hand), rounded to a whole percentage. This is an approximation of true sell-through (which normally compares against units received during the period) — because there is no purchase/received-quantity feed wired into this page, it substitutes "current stock on hand" as a stand-in for "what is left of what was available." If you restocked a product partway through the date range, the percentage will not exactly match a textbook sell-through calculation.
The default date range is the last 3 months up to today, adjustable via From/To date pickers and an Apply button (the report also reloads automatically whenever From/To change).
Four summary chips — Dead stock (<15%), Slow mover (15–40%), Moving (40–70%), Fast mover (70%+) — show live counts, but those counts are computed from the currently filtered and sorted product list, not the whole unfiltered catalog, so applying a season filter or search term changes the chip counts too.
Before You Start
- Requires the "reports" plan feature to be enabled.
- The Season filter dropdown only appears if at least one product in the catalog has a Season value set.
- Unlike Age of Inventory, this page includes every active product regardless of current stock level (including products with zero stock, as long as they are active) — it is not restricted to in-stock items only.
Step-by-Step Guide
1 Set the reporting period
- Adjust the From and To date pickers (defaults to the last 3 months through today).
- The table and summary chips reload automatically whenever either date changes.
2 Identify dead stock and fast movers
- Check the four summary chips: Dead stock (<15%), Slow mover (15–40%), Moving (40–70%), Fast mover (70%+).
- Sort the table by "Lowest sell-through first" (the default) to see your worst performers at the top, or "Highest sell-through first" for the best.
- Each row also shows a mini progress bar and percentage badge colour-coded to the same four bands.
3 Filter and search the table
- Use the Season dropdown (if shown) to narrow to one season.
- Use the search box to filter by product name, SKU or brand.
- Use the sort dropdown for Most units sold, Highest revenue, Most stock remaining, or Name A-Z as alternatives to sell-through rate.
Every Field & Button, Explained
| Field / Button | What it does |
|---|---|
From / To | Date range the sales side of the calculation is drawn from; defaults to the last 3 months through today. |
Season dropdown | Filters to a single Season value; only shown if at least one product has Season set. |
Search box | Filters by product name, SKU, or brand. |
Sort dropdown | Lowest/highest sell-through first, Most units sold, Highest revenue, Most stock remaining, or Name A-Z. |
Dead stock / Slow mover / Moving / Fast mover chips | Live counts of the currently filtered+sorted product list falling into <15%, 15–40%, 40–70% and 70%+ sell-through bands respectively. |
Revenue in period | Sum of revenue across the currently filtered/sorted product list for the chosen date range. |
Table — Units Sold | Units sold in the selected date range, from the top-selling-products report. |
Table — Stock Left | Current stock quantity on hand (not stock as of the report's end date — this is the live figure at the time you load the page). |
Table — Revenue | Revenue attributed to that product in the selected date range. |
Table — Sell-through % | Units Sold ÷ (Units Sold + Stock Left), shown as a progress bar and colour-coded percentage badge. |
Tips & Best Practices
- Treat the sell-through % here as directional rather than exact if you restock frequently mid-period — it uses current stock on hand as a proxy for "what was originally available," not a true point-in-time received quantity.
- Sort by "Lowest sell-through first" as your default view — it puts the products most in need of a markdown or clearance decision at the top.
- Cross-check anything showing as Dead stock here against Age of Inventory before deciding to mark it down — a product can have a low sell-through rate simply because it was just added and has not had time to sell yet.
Troubleshooting & FAQ
The sell-through % doesn't match a manual "sold ÷ received" calculation I did.
The Dead stock / Slow mover / Moving / Fast mover counts changed when I searched or picked a season.
A product I know sold out completely still shows in the report with 100% and zero stock.
A brand-new product shows as "Dead stock" even though it just started selling.
🧑💻 Developer Notes
Source component(s):
frontend-app/pos-app-garment/src/pages/garment/SellThroughReportPage.jsx
Backend endpoints used:
GET /reports/sales/top-products (from, to, limit=2000) — generic top-selling-products report, not a garment-specific routeGET /products (limit=2000) — generic product listing
Related tables (db-core repositories):
SaleSaleItemProduct
Redux slices:
None — local component state only
Feature flag key: reports
No dedicated garment.routes.js endpoint backs this page. It joins the two generic endpoints client-side keyed on productId (falling back to id): rate = sold / (sold + max(stock, 0)) rounded to a whole percent. This is the same "stock on hand as a proxy for units available" approximation used nowhere else server-side — a true sell-through calculation would need a units-received figure per period, which this codebase does not currently track/expose. Products with zero recorded sales in the period still appear (with a 0% rate) as long as they are active, unlike Age of Inventory which filters to in-stock items only.