Flag Odoo vendor bills that need a human before you pay
Every weekday morning we check new vendor bills against their purchase orders, then post only the ones with price gaps, duplicates or no PO to Slack.
Every weekday at 8am, review the vendor bills that have landed in my Odoo instance since the last run and tell me which ones a human actually needs to look at before we pay them. The goal is exception reporting for accounts payable, not a daily summary of everything.
Start by pulling the new bills. Use Odoo Search & Read Records (search_read) on the account.move model, filtered to vendor bills with a domain on move_type equal to in_invoice, and restricted to bills created since the previous run. Keep track of the timestamp of the last successful run between runs so no bill is reviewed twice and none are skipped. On the very first run, look back over the previous 7 days. Read the fields needed for the checks, including the vendor (partner_id), the vendor reference (ref), the bill name or number, invoice_date, amount_total, currency, the source document (invoice_origin), and the bill lines with their product, quantity and unit price.
For each bill, find the purchase order it references. The invoice_origin field on the bill usually carries the purchase order name. Use Search & Read Records (search_read) on purchase.order to locate that order, then Search & Read Records (search_read) on purchase.order.line to pull its lines with product, product_qty, price_unit and subtotal. Compare the bill against the purchase order line by line: unit price billed versus unit price ordered, quantity billed versus quantity ordered, and the bill total versus the order total. Match lines on product where possible rather than assuming the lines are in the same order.
Detect suspected duplicates. For each bill, use Odoo Count Records (search_count) on account.move to check whether another vendor bill already exists from the same vendor with the same vendor reference, and separately whether one exists from the same vendor with the same amount. Exclude the bill being checked from its own count. A count above zero on either check means a suspected duplicate. Also flag any bill that has no matching purchase order at all, whether the source document is empty or the referenced order cannot be found.
Apply a tolerance so the alert stays worth reading. Only report price or quantity variances that exceed 5 percent of the expected line value or 250 in the bill currency, whichever is larger. Make this tolerance easy to change in one place, since different finance teams set it differently. Suspected duplicates and bills with no purchase order are always reported regardless of size, because a duplicate payment costs the full amount rather than just the difference, and an unmatched bill has nothing to check it against.
Report the exceptions as a single Slack message to our finance channel using Slack Bot Send a Message. Group the exceptions by issue type, with headings for price variances, quantity variances, suspected duplicates, and bills with no purchase order. Under each heading list one line per bill showing the vendor name, the bill amount, the specific variance found stated concretely (for example billed at 42.00 per unit against 38.00 ordered, a 10.5 percent gap on 120 units), and the bill reference or number so someone can find it in Odoo immediately. Use Slack mrkdwn formatting, with single asterisks for bold. Lead with a one-line count of how many bills were reviewed and how many need attention.
Stay completely silent when nothing is anomalous. If every new bill matched its purchase order within tolerance and no duplicates or unmatched bills were found, post nothing at all, so the channel does not get trained to ignore the alert. Never post an all clear message.
What does this prompt do?
- Each weekday morning, picks up every vendor bill that has landed in Odoo since the last check.
- Matches each bill back to the purchase order it references and compares unit prices, quantities and totals line by line.
- Looks for the same bill arriving twice, meaning another bill from the same vendor with the same reference or the same amount, and for bills with no purchase order behind them at all.
- Posts one Slack message grouped by problem type, with the vendor, the amount and the exact gap found, and stays completely quiet on days when everything looks right.
What do I need to use this?
- An Odoo account that can see your vendor bills and purchase orders.
- A Slack workspace and a channel where your finance team already looks.
- Purchase orders recorded in Odoo, since the price and quantity matching is what makes this useful.
- On Odoo Online (odoo.com), outside access to your data requires a Custom pricing plan. Self-hosted and Odoo.sh instances have no such restriction.
How can I customize it?
- Change when it runs, for example every morning including weekends, or twice a day during month end.
- Adjust how large a price or quantity gap has to be before it is worth flagging. The default is 5 percent or 250 in your currency, whichever is larger.
- Send it to a different Slack channel, or route bills above a certain amount to a separate approvals channel.
FAQs
What happens on days when nothing looks wrong?
Will this work if we do not raise purchase orders for everything?
Does it pay, approve or change anything in Odoo?
Will it flag the same bill again every morning?
How does it decide that two bills are duplicates?
Will this work on Odoo Online?
Related templates
When someone leaves, we check which shared passwords they used in their final months and post a ranked rotation list to your security channel.
Every Monday, check every S3 bucket for public exposure, missing encryption and weak backup settings, then get the risks ranked in Slack.
Twice every weekday, the conversations from your social inbox land on the right HubSpot contact timelines, with a Slack recap for sales.
Every morning, find the addresses that hard bounced or filed a spam complaint, update the matching HubSpot contacts, and post a short Slack recap.
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.
When you merge a fix in GitHub, this agent checks the matching dead-letter queue, replays the failed messages, and reports back on the pull request and in Slack.
Stop paying vendor bills nobody checked.
Let an agent read every new bill against its purchase order each morning and speak up only when something is genuinely off.