Home / Help Center / pos-app-wholesale / wholesale / Wholesale Reports
📊 wholesale

Wholesale Reports

Wholesale Reports is a five-tab analytics page — Top Buyers, Account Statement, Credit Utilisation, Price List Usage and Gross Margin — each backed by its own report endpoint, covering buyer ranking, per-customer running-balance statements, trade-account credit health, which price-list entries are actually driving orders, and profitability per customer.

📍 Menu path: Wholesale → Wholesale Reports
👤 Who uses it: All roles with the Billing feature enabled

Overview

The five tabs are independent: switching tabs does not share state, and each tab fetches its own data lazily on first render (except Account Statement, which only fetches after you type a customer name and search).

Top Buyers ranks customers by total order value (top 50), excluding CANCELLED orders, and shows Orders, Total Value, Paid and Outstanding per customer.

Account Statement requires you to type a customer name exactly and press Enter/click "View Statement" — it matches order.customerName as an exact string, not a fuzzy or partial search, and shows a running balance down the order history.

Credit Utilisation reads from Wholesale Trade Accounts (not the separate wholesale Customers list), showing only accounts that have a creditLimit greater than zero, with a colour-coded utilisation bar (green under 70%, amber 70–89%, red 90%+).

Price List Usage cross-references every WholesalePriceList entry against actual order-item data to show how many orders and how much revenue each list/tier/price-break combination has actually generated, including entries that have never been used.

Gross Margin computes Revenue − COGS per customer from delivered/confirmed/dispatched order line items using each product's stored cost price — the on-page caption "Only confirmed/dispatched/delivered orders included" is a simplification of the underlying rule, which is any order status other than DRAFT or CANCELLED.

Before You Start

Step-by-Step Guide

1 Find your best wholesale customers

  1. Open Wholesale → Wholesale Reports, the "Top Buyers" tab loads by default.
  2. Read the ranked list of up to 50 customers by Total Value, with Orders, Paid and Outstanding columns alongside.

2 Pull a running statement for one customer

  1. Switch to the "Account Statement" tab.
  2. Type the customer's name exactly as it appears on their orders and press Enter or click "View Statement".
  3. Review the order-by-order table with Date, Order #, Status, Total, Paid, Balance and a cumulative Running Balance column, plus the Total Outstanding figure above it.

3 Check which accounts are near their credit limit

  1. Switch to the "Credit Utilisation" tab.
  2. Scan the Utilisation column's colour bar — red bars (90%+) are the accounts closest to being blocked from new credit orders; a CREDIT HOLD tag appears under any account already on hold.

4 See which price-list entries are actually being used

  1. Switch to the "Price List Usage" tab.
  2. Sort mentally by the Orders/Qty Sold/Revenue columns to spot price-list rows with zero orders — candidates for cleanup — versus your highest-revenue tier/product combinations.

5 Compare customer profitability

  1. Switch to the "Gross Margin" tab.
  2. Compare the Gross Margin % bar across customers (green ≥30%, amber 15–29%, red under 15%) to spot high-revenue but low-margin accounts.

Every Field & Button, Explained

Field / ButtonWhat it does
Top Buyers → Orders / Total Value / Paid / OutstandingOrder count and totals per customer, aggregated from all non-CANCELLED wholesale orders, sorted by Total Value descending, capped at the top 50 customers.
Account Statement → search boxExact-match customer-name lookup (case-sensitive equality against order.customerName) — not an autocomplete or partial search.
Account Statement → Running BalanceA cumulative sum of balanceDue across the customer's orders in orderDate order, not a true chronological ledger of individual payment transactions.
Credit Utilisation → Credit Limit / Used / AvailableFrom the Trade Account's creditLimit and creditUsed fields; Available = Limit − Used.
Credit Utilisation → Utilisation %Used ÷ Limit as a rounded percentage, drawn as a coloured progress bar.
Credit Utilisation → CREDIT HOLD tagShown under the business name when the account's creditHold flag is set (managed on Trade Accounts, not here).
Price List Usage → Orders / Qty Sold / RevenueCounts and sums of order items whose productName matches the price-list row's productName, from non-CANCELLED orders only.
Price List Usage → ActiveWhether the underlying price-list entry is currently active — inactive entries can still show historical Orders/Revenue.
Gross Margin → Revenue / COGS / Gross Margin / Margin %Revenue = sum of order-item line totals; COGS = quantity × the product's stored cost price; Gross Margin = Revenue − COGS; Margin % = Gross Margin ÷ Revenue.

Tips & Best Practices

Troubleshooting & FAQ

Credit Utilisation shows every account at 0 used / 0% even though they clearly have outstanding orders.
This is a real gap: creditUsed on the Trade Account record defaults to 0 at creation and there is no code path in the wholesale module that increments it when orders are placed or decrements it on payment — TradeAccountPage's own edit form doesn't expose a creditUsed field either. In practice, unless something calls PUT /wholesale/trade-accounts/:id with a creditUsed value directly, every account will show 0% utilisation here regardless of real activity. For an accurate up-to-date picture of what a customer actually owes, use AR Ageing or the Account Statement tab instead, which both compute balances live from WholesaleOrder.balanceDue.
Account Statement says nothing was found for a customer I know has orders.
The lookup is an exact string match on order.customerName — any difference in spacing, capitalisation, or a name typed differently on different orders will return an empty (but not erroring) result. Try the exact name as it appears in the Top Buyers tab.
Gross Margin shows 100% margin for a customer, which seems too good to be true.
If the ordered products don't have a costPrice set in the catalogue, COGS is computed as quantity × 0, so Gross Margin equals Revenue and Margin % shows 100. This is a data-completeness issue, not a real margin — check that Products have cost prices filled in.
A price-list entry I retired months ago still shows up with high historical revenue.
Price List Usage always shows every WholesalePriceList row (active or not) alongside its lifetime order/revenue totals — deactivating or deleting a price-list entry does not remove its historical rows from this report, and Active = No is the only signal that it is retired.
The Gross Margin tab caption says "confirmed/dispatched/delivered" but I have an order in a different status showing up too.
The underlying query actually includes any order whose status is NOT DRAFT or CANCELLED — so a status like PARTIALLY_DISPATCHED or another custom in-between status would still be counted even though the caption only names three statuses explicitly.