Matrix Billing
Matrix Billing is a fast-entry screen for garment sales — search for one style, then fill in quantities across a Size × Colour grid in a single pass instead of adding each size/colour combination as a separate line item.
Overview
The page has two panels: a product search and Size × Colour quantity grid on the left, and a running cart on the right that stays pinned to the screen as you keep adding styles.
Searching a product calls the same generic product search used everywhere else in BazaarPOS (GET /products, debounced 300ms after you stop typing). Selecting a result calls GET /products/:id/variants and parses each variant's JSON attributes field for size and colour keys to build the grid's row and column headers.
If a style has size variants but no colour variants, the grid still renders with a single "Standard" column so every product can use the same Size × Colour layout even when colour does not apply.
The grid keeps a running row total, column total and grand total live as you type, and a filled cell is tinted with your theme's primary colour so it is easy to see at a glance which combinations you have entered a quantity for.
Clicking Add to Cart converts every non-zero cell into its own cart line (one per size/colour combination with a quantity), clears the grid, and lets you immediately search for the next style — so a single multi-style order is built up as a series of quick grid entries.
Before You Start
- The product you search for must already have size (and, if you want a colour axis, colour) variants defined — this is normally done from the Variant Matrix / product-variant screens under Products; Matrix Billing only reads variants, it does not let you create them.
- A product with no size variants at all shows "No size variants found. Add variants in the Variant Matrix first." instead of a grid.
- The route only requires the "billing" plan feature — there is no plan-tier gate.
Step-by-Step Guide
1 Add one style's quantities in a single grid
- Type a product name or SKU into the search box at the top — matching results appear in a dropdown after a short pause.
- Click a result to select it — its Size × Colour grid loads below, built from that product's saved variants.
- Type a quantity into any cell where you want to sell that size/colour combination; row, column and grand totals update as you type.
- Click Add to Cart — every cell with a quantity greater than zero becomes its own line in the Cart panel on the right, and the grid resets so you can search for the next style.
2 Review and adjust the cart
- Each cart line shows the product name, size/colour and quantity, plus its line total.
- Click the trash icon on a line to remove just that line, or click Clear in the cart header (with a confirmation prompt) to empty the whole cart.
- The cart footer shows a running grand Total across every line as you add or remove items.
3 Hand off to checkout
- Click Process Order at the bottom of the cart panel.
Every Field & Button, Explained
| Field / Button | What it does |
|---|---|
Product search box | Debounced (300ms) search against GET /products by name or SKU; shows up to 20 matches with name, SKU/category and price. |
Size × Colour grid | Rows are every distinct "size" value and columns are every distinct "colour" value found across the selected product's variants (parsed from each variant's JSON attributes field); one numeric quantity input per cell. |
Row / Column / Grand totals | Live-calculated sums shown in the rightmost column, bottom row, and bottom-right corner of the grid as you type quantities. |
Add to Cart | Converts every non-zero grid cell into one cart line, then clears the selected product and grid so you can search for the next style. |
Cart panel | Sticky right-hand panel listing every line added so far, with a delete icon per line, a Clear button, and a running Total. |
Process Order | Bottom button on the cart panel — currently a placeholder that only shows a "coming soon" toast and does not create a sale. |
Tips & Best Practices
- Set up Size and Colour variants for a style once (in the Variant Matrix) and Matrix Billing will immediately be able to grid-enter quantities for it — there is no separate configuration step on this page itself.
- Use this screen when a customer is buying several sizes/colours of the same style at once (e.g. a family buying the same kurta in 3 sizes) — it is much faster than adding each combination as a separate cart line on the normal Sales screen.
- Because Process Order does not yet complete a sale, use this page to work out the exact size/colour/quantity breakdown, then re-key that same breakdown on the Sales screen to actually bill and collect payment.
Troubleshooting & FAQ
I selected a product but no grid appeared.
I clicked Process Order and nothing happened to my cart or my sales records.
A colour column labelled "Standard" showed up even though I didn't set any colours for this product.
Add to Cart said "Enter at least one quantity."
🧑💻 Developer Notes
Source component(s):
frontend-app/pos-app-garment/src/pages/garment/MatrixBillingPage.jsx
Backend endpoints used:
GET /productsGET /products/:id/variants
Related tables (db-core repositories):
ProductProductVariant
Redux slices:
None — local component state only (useState/useCallback/useRef)
Feature flag key: billing
This page has no dedicated garment.routes.js endpoints at all — it is purely a client-side quantity-entry convenience layer over the existing generic products/variants APIs shared by every BazaarPOS variant. The size/colour axes are derived entirely by JSON.parse-ing each ProductVariant.attributes string and pulling out "size"/"colour" keys; a variant missing those keys, or with malformed JSON (the parse is wrapped in a silent try/catch), is simply skipped when building the grid rather than surfacing an error. Most notably, the "Process Order" button is a stub — `toast('Transfer to billing coming soon')` — with no call into the sales-creation flow, so despite the page title and "Add to Cart"/"Process Order" language, no sale is ever actually created from this screen; it looks like a partially-built feature rather than a finished quick-billing flow.