Mandi Rates
Mandi Rates is where a grocery or kirana shop records the day's wholesale/market ("mandi") buying price for produce and other items — vegetables, fruits, grains, dairy and spices — and can push that rate straight into a product's cost price and selling price with one click.
Overview
Every row is a rate for one item on one specific date — the page defaults to today but you can pick any past date to view or backfill rates.
Rates are grouped into six categories (Vegetable, Fruit, Grain, Dairy, Spice, Other), each with its own colour, so the table is easy to scan visually.
The standout feature is "Set Price": pick a mandi rate row, search for the matching product, choose a margin percentage, and the page computes and applies a new cost price + selling price to that product in one step — this is the fastest way to keep produce pricing current with daily market moves.
Before You Start
- You must have the Billing feature enabled on your plan.
- To use "Set Price" you additionally need permission to edit Products, since it calls the same product-update endpoint as the Products page.
Step-by-Step Guide
1 Add today's mandi rates
- Open Grocery → Mandi Rates. The date field defaults to today; change it if you are backfilling an earlier day.
- Click "+ Add Rate", fill in Item Name, Category, Unit and Rate (Notes is optional), then click "Add Rate" to save.
- Repeat for each item you buy that day — vegetables and fruits are the categories most kirana stores update daily.
2 Edit or delete a rate
- Click "Edit" on any row to reopen the form with its values pre-filled — the Item Name field is locked while editing so you cannot accidentally rename it into a different item.
- Update Category, Unit, Rate or Notes as needed and click "Update".
- Click "Del" on a row to remove it entirely; you will be asked to confirm before it is deleted.
3 Filter and search the rate list
- Use the category chips (All, Vegetable, Fruit, Grain, Dairy, Spice, Other) to filter the table to one category at a time — click an already-active chip again to clear the filter back to All.
- Use the search box on the right to filter by item name as you type.
- Change the date field at any time to jump to a different day's rate sheet.
4 Apply a mandi rate to a product's price
- Click "Set Price" on the rate row you want to apply.
- The product search is pre-filled with the item's name — pick the matching product from the dropdown results (or search for a different one).
- Set the Margin % (defaults to 20%); the "New selling price" preview updates instantly as rate × (1 + margin/100), rounded to 2 decimals.
- Click "Update Price" — this sets the product's Cost Price to the mandi rate and its Selling Price to the computed value in one call.
Every Field & Button, Explained
| Field / Button | What it does |
|---|---|
Item Name | The produce/item name (e.g. Tomato, Onion, Rice). Locked and non-editable once a rate row exists for that name+date — to rename, delete the row and add a new one. |
Category | One of Vegetable, Fruit, Grain, Dairy, Spice or Other — drives both the colour coding and the category filter chips/counts. |
Unit | kg, g, dozen, piece, litre, packet or bundle — shown next to the rate everywhere it is displayed. |
Rate | The wholesale/mandi buying price for one unit on the selected date. Must be a valid number ≥ 0. |
Notes | Optional free-text note per rate row (e.g. "Nashik supply", "Grade A only"). |
Set Price — Margin % | Percentage markup applied on top of the mandi rate to compute the product's new selling price; defaults to 20%. |
Set Price — New selling price | Live preview: mandi rate × (1 + margin% / 100), rounded to 2 decimals — this is what gets written as the product's Price when you click Update Price. |
Tips & Best Practices
- Enter rates first thing every morning before billing starts, so cashiers are always quoting the current mandi-based price.
- Use "Set Price" instead of manually editing the product in Products — it keeps Cost Price and Selling Price consistent with the day's actual buying rate, which matters for accurate profit reports.
- If the same item is bought at different rates from different suppliers, use the Notes field to record which supplier/lot the rate is for.
Troubleshooting & FAQ
I cannot find the product I want in "Set Price".
Editing a rate does not seem to change the item name.
I added a rate for an item that already had one today — did it duplicate?
Can I see a price history / trend for one item?
🧑💻 Developer Notes
Source component(s):
frontend-app/pos-app-grocery/src/pages/grocery/MandiRatePage.jsx
Backend endpoints used:
GET /grocery/mandiPOST /grocery/mandiDELETE /grocery/mandi/:idGET /grocery/mandi/history (implemented server-side; not yet called by any frontend page)GET /products (search)PUT /products/:id
Related tables (db-core repositories):
GroceryMandiRateProduct
Rates are upserted server-side by matching itemName + date (+ store/tenant), not by row id — this is why the Item Name field is locked during edit. Every read/write/delete on GroceryMandiRate is scoped by both storeId and tenantId; previously only storeId was checked, which meant two different single-store tenants (storeId null for both) could read, silently overwrite, or delete each other's mandi rates for the same item/date — this has been fixed by adding a tenantId condition to all four grocery.js functions (getMandiRates, upsertMandiRate, deleteMandiRate, getMandiHistory) and to the delete route, which previously passed no tenant/store scope at all.