Inventory
Stock that counts itself, expiry that catches itself.
Mark an appointment completed and the back-bar drains in lockstep. Per-batch expiry with first-expiring-first-out so a $40 bottle never gets bypassed and rots while the salon used the fresh one by hand.
Built for salons that lose money quietly: forgotten back-bar deduction, expired toner found in March, the "wait, did we order that?" question on a Saturday. Stock that runs in the background so the answer is always there.
01/
Auto-deduction on completion. Real audit row.
When you mark an appointment Completed, the inventory requirements on every service in that visit deduct inside a single transaction that also writes an inventory_transactions audit row. No manual deduction step, no spreadsheet. Stock may go negative (the math reflects reality, not wishful thinking) and the UI surfaces the negative so you know to order. We don't block completion on it.
Per-service inventory requirements.
On any service, list the items consumed and the quantity. Variants override the parent service's list, which means a 90-min massage variant can consume different oil than a 30-min variant.
Walk-in Quick Sale services deduct too.
A walk-in blowdry consumes product the same as a booked one. When a Quick Sale references a catalog service and isn't linked to an appointment, the service's requirements drain automatically inside the sale's transaction.
Negative stock surfaces, doesn't block.
Low-stock threshold per item drives an amber dashboard card and the inventory list. Negative stock turns the row red. Completing the visit is never blocked; we surface it so you order.
Single chokepoint for the math.
Every adjustment (completion, refund, manual write-off, batch adjust, CSV import) flows through one server action that writes the audit row. No silent decrements anywhere.
02/
Per-batch expiry tracking with FEFO drain.
Every item can opt in to per-batch tracking. Each batch records quantity received, expiry date, received date, optional cost per unit, and an optional supplier lot or SKU code. When the auto-deduction runs, we drain the soonest-expiring batch first; oldest receipt date is the tiebreaker when two batches share an expiry. Items without batches still work the way they always did.
Track expiry on create.
The new-item form has a Track expiry toggle that swaps the Current stock field for first-batch fields (quantity, expiry, received date, lot, per-batch cost). One transaction creates the item and the first batch together.
No-expiry credits drain last.
When a client has both expiring and never-expiring credit, redemption drains the expiring batches first. The same FEFO rule on inventory protects you from rotting stock; the same rule on credit protects the client.
Adjust remaining.
FEFO drained the wrong batch (the stylist used the non-expired one but the system pulled the expired one)? The per-batch kebab has an Adjust remaining action. Set the remaining to any value with a required reason; writes a manual adjustment row.
Write off vs delete.
Two destructive actions per batch. Write off reflects reality (stock drops, batch row stays for history); delete is for batches entered in error (typo on quantity, wrong item) and removes the row entirely.
03/
Committed stock, so you see the future.
The Committed column on the inventory list shows how much of each item is already promised to upcoming non-completed appointments (Booked, Confirmed, Arrived). The math is the sum of per-service requirements across every in-flight booking. When committed stock exceeds current stock, the cell highlights amber and bolds. That's the "you owe more than you have on hand" case worth seeing before the day starts.
04/
Service and Retail in one item.
Pick Service, Retail, or Both on every item. A Both item is a Service item that also gets a retail price and a Taxable switch; it shows up on Quick Sale's retail tab and the appointment add-on picker alongside pure Retail items. The auto-deduction on completion still works when it's linked to a service. CSV import accepts BOTH or shorthand B.
Service.
Back-bar items that get used during a service. Not sold over the counter. Auto-deduction is the headline.
Retail.
Shampoo, conditioner, take-home products. Sold through Quick Sale or as add-on at appointment checkout. No service-completion deduction.
Both.
A bottle of treatment used during a service and sold as a take-home. Auto-deducts on completion AND appears on retail surfaces.
Branch-scoped or shared.
Assign an item to one branch or leave it shared. Deduction prefers the branch-scoped item first, falls back to shared. The bottle counts where it actually sits.
05/
Dashboard cards that catch you before reality does.
Inventory expiring soon card in the right rail of the dashboard lists up to 6 batches already expired or due in the next 30 days. The inventory list page has a Next expiry column (red for expired, amber for within 30 days, grey otherwise) and filter pills for Has expired batches and Expires within 30 days. CSV export includes Next expiry and Total batches columns so you can audit outside the app.
06/
CSV import, CSV export, both directions.
CSV import accepts every field on the item including Kind (SERVICE, RETAIL, BOTH), category, supplier, low-stock threshold, retail price, taxable flag, and optional first-batch fields. CSV export from the list page (filters preserved in URL params) gives you the same columns plus Committed and Next expiry. The shape that hands cleanly to a bookkeeper or a stocktake spreadsheet.
Common questions
Honest answers, including the ones we don't love.
What if a stylist uses product they didn't deduct in a service?
Two paths. Edit the service's inventory requirements going forward, then go to the appointment and re-mark complete (the math re-runs in a transaction; no double-deduction). Or do a one-off manual adjustment from the item page with a reason. Both leave audit rows.
Does refunding a payment add stock back?
A payment refund doesn't reverse stock; it reverses money. A service refund is also money-side, not stock-side. The right tool when a service was completed-and-then-undone is uncompleting the appointment, which reverses the deduction; we surface that as a kebab action on the appointment with a reason field.
How do you handle bottles that vary in usage per visit?
Two options. One: set the requirement on the service to the average usage, then write off the difference on a stocktake. Two: leave the service requirement at zero and use the manual deduction tool on the item per visit. Most salons land on option one for the volume and option two for the high-cost items.
Can I track inventory across branches?
Yes. Items live per branch (with a shared fallback). Deduction prefers the branch-scoped item first, so a bottle of toner counts at the branch where it sits. The reports surface includes a branch filter on inventory transactions.
What about recalls?
The optional supplier lot or SKU on every batch is the recall hook. Search the inventory list by lot, pull every batch with that lot, write off or quarantine. The clients who consumed that lot are reachable via the appointments those batches drained on; the audit row carries the link.
Pairs well with
Fourteen days. No card.
Try Flowesce on a real Saturday.
No card required, no auto-charge at the end. If Flowesce isn't for you, export everything in one click and walk.