Sales Reports
Sales Reports is a dedicated report workbench with 15 different sales breakdowns in a left-hand menu — from daily/hourly trends to by-product, by-customer, by-salesman, discount and profit-margin analysis — each with its own filters and one-click export.
Overview
Unlike the tabbed Key Reports page, Sales Reports uses a left-hand navigation list of 15 report types. Clicking a report loads it in the panel on the right; the selection is stored in the URL as ?r= (e.g. ?r=by-product) so any report can be bookmarked directly.
Every individual report has its own summary cards, its own date range or filter controls, and (where you have Export permission) its own Export button that downloads exactly what is on screen — not the whole report set.
The 15 reports are: Daily Sales Report, Hourly Sales Report, Monthly/Yearly Sales, Sales by Product, Sales by Category, Sales by Brand, Sales by Customer, Sales by Salesman/Cashier, Sales by Payment Mode, Invoice-wise Sales Report, Cancelled Bills Report, Void Bills Report, Discount Report, Profit Margin Report and Return/Refund Report.
Before You Start
- Requires a role with Reports permission and the store on the Advanced plan tier or above (reports feature).
- Export buttons on each report only appear for roles with Export permission.
- Sales by Salesman/Cashier only produces meaningful rows if sales are recorded against a salesman/cashier.
- Sales by Category and Profit Margin Report both rely on the profit engine, so products need a Cost Price set for gross profit figures to be non-zero.
Step-by-Step Guide
1 Read time-based sales trends
Covers Daily Sales Report, Hourly Sales Report and Monthly/Yearly Sales.
- Open Daily Sales Report and pick a date; the four summary cards (Total Sales, Revenue, Discount, Tax) and payment-method chips update, followed by a full bill-by-bill table you can export.
- Open Hourly Sales Report for the same idea broken into 24 hourly buckets for one day; the busiest hour is highlighted with a PEAK badge and a distribution bar per hour.
- Open Monthly/Yearly Sales and pick a year from the dropdown; the current month row is highlighted with a NOW badge, and each month shows count, revenue, tax, discount and a trend bar.
2 Break sales down by product, category and brand
- Open Sales by Product, set a From/To date range, and read products ranked by revenue with quantity sold and a share-of-total bar.
- Open Sales by Category — this reuses the profit engine, so each category shows Revenue, COGS, Gross Profit and a colour-coded Margin % (green ≥30%, amber ≥15%, red below).
- Open Sales by Brand for the same ranking idea grouped by product brand instead of category.
3 See who bought and who sold
- Open Sales by Customer to rank your customers by revenue and invoice count for the selected date range, with average order value per customer.
- Open Sales by Salesman / Cashier to rank staff by revenue, transaction count, average order value and discount given — useful for reviewing cashier performance.
4 Analyse payment modes and the full invoice list
- Open Sales by Payment Mode to see Cash/Card/UPI/Wallet/Credit/Split broken down by transaction count, amount and % of total, each with a distribution bar.
- Open Invoice-wise Sales Report for a paginated (25 per page) list of every bill in the date range; filter by payment status (Completed/Pending/Refunded) with the dropdown, and page through results with the Prev/Next controls at the bottom.
5 Investigate cancelled, void, discounted and returned bills
- Open Cancelled Bills Report or Void Bills Report — both currently pull bills with REFUNDED status; the Void Bills view shows a note explaining that void and cancelled bills share the same status in this system.
- Open Discount Report to see every bill that had a discount applied, with gross amount, discount amount, net amount and a colour-coded discount % (red if over 20%).
- Open Return / Refund Report for a dedicated list of refunded bills with total refund amount and average refund per bill.
6 Check overall profitability
- Open Profit Margin Report, set a date range (defaults to year-to-date), and review the six-card P&L summary (Revenue, COGS, Gross Profit, Expenses, Net Profit, Net Margin).
- Scroll to Top Products by Profit and By Category tables, each ranked by gross profit with a colour-coded margin %.
Every Field & Button, Explained
| Field / Button | What it does |
|---|---|
Left-hand report menu | Lists all 15 report types; the active one is stored in the URL as ?r= |
Daily Sales Report | Single-date bill list with Total Sales, Revenue, Discount and Tax cards plus a payment-method chip row. |
Hourly Sales Report | Same day broken into 24 hourly buckets with a PEAK badge on the busiest hour. |
Monthly / Yearly Sales | Twelve-month table for a chosen year with a NOW badge on the current month and a revenue trend bar per row. |
Sales by Product | Products ranked by revenue in a date range, with quantity sold and share-of-total bar. |
Sales by Category | Category breakdown using the profit engine — Revenue, COGS, Gross Profit and colour-coded Margin %. |
Sales by Brand | Same ranking as Sales by Product but grouped by product brand. |
Sales by Customer | Customers ranked by revenue with invoice count and average order value. |
Sales by Salesman / Cashier | Staff ranked by revenue, transaction count, average order value and discount given. |
Sales by Payment Mode | Cash/Card/UPI/Wallet/Credit/Split breakdown with transaction count, amount and % share. |
Invoice-wise Sales Report | Paginated (25/page) full bill list with a payment-status filter dropdown. |
Cancelled Bills Report / Void Bills Report | Both currently query bills with REFUNDED status; Void view shows an explanatory note that void and cancelled share one status today. |
Discount Report | Bills with discount > 0, showing gross/discount/net amounts and a colour-coded discount %. |
Profit Margin Report | Year-to-date-by-default P&L summary plus Top Products by Profit and By Category tables. |
Return / Refund Report | Dedicated refunded-bills list with total and average refund amount. |
Date range picker + This Month/Last Month/This Year quick buttons | Shared filter control used by most of the 15 reports (Daily/Hourly use a single date instead). |
Export button | Downloads exactly the table currently on screen for that one report; only shown with Export permission. |
Tips & Best Practices
- Bookmark a specific report's URL (e.g.
/sales-reports?r=by-salesman) so staff open straight into the report they use every shift. - Record a salesman/cashier against each sale if you want Sales by Salesman/Cashier to be meaningful — sales with no salesman recorded will not show up there.
- Use the This Month / Last Month / This Year quick-range buttons instead of typing dates for routine checks.
- Remember Cancelled and Void Bills currently show the same REFUNDED-status data — do not expect them to differ until separate void tracking is enabled in Settings.
Troubleshooting & FAQ
Sales by Salesman / Cashier is empty or missing staff.
Cancelled Bills Report and Void Bills Report show identical data.
Sales by Category or Profit Margin Report shows zero gross profit.
Export button is missing on a report.
🧑💻 Developer Notes
Source component(s):
frontend-app/packages/pos-react-lib/src/pages/SalesReportsPage.jsx
Backend endpoints used:
GET /reports/sales/daily (params: date) — Daily & Hourly reportsGET /reports/sales (params: from, to, groupBy) — Monthly/Yearly, Sales by Customer, Sales by Payment ModeGET /reports/sales/top-products (params: startDate, endDate, limit) — Sales by ProductGET /reports/profit (params: from, to) — Sales by Category, Profit Margin ReportGET /reports/sales/by-brand (params: from, to) — Sales by BrandGET /reports/sales/by-salesman (params: from, to) — Sales by Salesman / CashierGET /sales (params: startDate, endDate, paymentStatus, page, limit) — Invoice-wise, Cancelled/Void (paymentStatus=REFUNDED), Discount Report (client-filtered), Return/Refund Report
Related tables (db-core repositories):
SaleSaleItemProductCustomer
Redux slices:
scope (selectCurrentScope / getScopeQueryParams)
Feature flag key: reports (requires advanced plan tier or above)
Each of the 15 reports is its own React component mapped by id in a COMPONENTS lookup table, dispatched via the ?r= query param — this is why every report can be deep-linked and why adding a new report is just adding a new map entry. Every data-fetching report component owns an AbortController so navigating away mid-request never sets state on an unmounted view.