Daily Odoo low stock brief that skips what is already on order
Every weekday morning we work out which products will genuinely run out, ignore the ones with deliveries already booked, and post a ranked brief to Slack.
Every weekday at 7am, work out which products in my Odoo inventory are genuinely about to run out, and brief my operations team on them.
Start with current stock. Use Odoo Search & Read Records (search_read) on stock.quant to get on hand quantities per product, restricted to internal stock locations so you are not counting stock sitting in customer, supplier or virtual locations. Then use Search & Read Records on product.product to pull the details needed for the brief: name, internal reference or SKU, list price, and whether the product is still active. Skip anything archived (active is false) or marked discontinued, and ignore service type products that do not hold stock at all.
Next work out how fast each product is selling. Use Read Grouped Aggregates (read_group) on sale.order.line grouped by product, filtered to confirmed orders from the last 30 days, summing both quantity sold and line revenue. Divide the 30 day quantity by 30 to get a daily velocity per product. If a product sold nothing in that window it has no meaningful velocity, so leave it out of the brief rather than reporting infinite days of cover.
Then find out what is already on the way. Use Search & Read Records on purchase.order.line to pull open purchase order lines per product, with quantity ordered, quantity already received, and the expected receipt date. Only count lines belonging to confirmed purchase orders, not drafts or cancelled ones.
Now apply the judgement, which is the whole point of this workflow. For each product compute days of cover as quantity on hand divided by daily velocity, then estimate a stockout date as today plus days of cover. Exclude any product where a confirmed inbound purchase order is expected to arrive before that stockout date, because that gap is already handled and flagging it just creates noise. What remains is the genuine risk list. Odoo's native reordering rules fire on a static minimum quantity with no awareness of sales velocity or of inbound stock already covering the gap, which is exactly what generates alert fatigue, so do not simply reproduce them.
Rank the risk list by days of cover ascending first, then by revenue at risk descending as the tiebreaker, where revenue at risk is roughly daily velocity multiplied by list price across the expected replenishment window. For each product suggest a reorder quantity that covers the supplier lead time plus a safety buffer, using the product's configured lead time in Odoo where one exists and a sensible default where it does not.
Post the brief to Slack using Send a Message to my operations channel. Keep it to the top items, around ten, rather than dumping the whole catalogue. For each product show the name and SKU, days of cover, recent daily velocity, quantity on hand, suggested reorder quantity and revenue at risk, ordered worst first. Close with a single line saying how many further products were low but excluded because stock is already inbound, so the team can see they were considered.
Finally, append one row per at risk product to my Google Sheets tracking sheet using Append Values, so we build a history of stockout near misses over time. Each row should carry the run date, product name, SKU, quantity on hand, daily velocity, days of cover, revenue at risk, suggested reorder quantity, and whether an inbound purchase order exists. If nothing is at risk on a given morning, post a short all clear to Slack and append nothing to the sheet.
Example output
What does this prompt do?
- Checks your Odoo inventory every weekday morning and works out how many days of cover each product has left, based on how fast it has actually been selling over the last 30 days.
- Ignores products that already have a delivery booked to arrive before they would run out, so you only hear about the shortages nobody is handling yet.
- Posts a ranked brief to your operations Slack channel showing the product, days of cover, recent sales rate and a suggested reorder quantity.
- Logs every at risk product to a Google Sheet so you build a history of stockout near misses and can spot the lines that keep catching you out.
What do I need to use this?
- An Odoo account with access to your inventory, sales and purchasing records.
- A Slack workspace and the channel where your operations team wants the morning brief.
- A Google Sheets spreadsheet to use as the tracking log, with a tab ready to receive rows.
- If you are on Odoo Online (odoo.com), outside access to your data requires a Custom plan. Self hosted and Odoo.sh accounts have no such restriction.
How can I customize it?
- Change the timing. Weekday mornings at 7am suits most teams, but you can run it daily including weekends, or twice a week if your stock moves slowly.
- Adjust how many products the Slack brief lists and how tight the risk threshold is, so the message stays short enough that people actually read it.
- Change the sales window from 30 days to something shorter for fast moving lines, or longer for seasonal products where a month is not representative.
FAQs
How is this different from Odoo's built in reordering rules?
Will it nag me about products that already have stock on the way?
Does this work with Odoo Online?
What happens to products that have not sold recently?
Can I send the brief somewhere other than my ops channel?
Related templates
When your flight moves, your calendar times get corrected automatically and you get a Slack note naming the meetings you're about to miss.
Every 15 minutes, forwarded phishing reports get traced back to the server that really sent them, with a verdict in Slack and the worst senders reported.
Every Monday, check every S3 bucket for public exposure, missing encryption and weak backup settings, then get the risks ranked in Slack.
Every weekday at 7am, sign in to the tender portals you track, filter new notices against your bid criteria, and open a deal for the ones worth chasing.
Every weekday at 4pm, spot the threads that went quiet, stage a ready-to-send nudge in your mailbox, and get a ranked Slack recap.
Every Monday, rank the week's matches by expected demand, put the big ones on your venue calendar, and post a rota-ready summary to Slack.
Stop hearing about stockouts from your customers.
Get a short, ranked stock risk brief in Slack every weekday morning, with the already handled shortages filtered out.