Odoo bank vs book balance: why they drift and which to trust
Odoo rarely shows the exact amount your bank does. Here is why they drift, how to find the gap and which figure to start your forecast from.
You open the Accounting dashboard in Odoo and see one number. You log in to online banking and see another. The gap is €3,412 and you have no idea which one is right. Worse, you are about to start the quarterly cash forecast off the Odoo figure and your gut says do not.
A difference between what the bank shows and what Odoo shows does not mean something is broken. It is simply how any set of books looks on a day when the bank reconciliation is not finished. The useful question is how to understand the drift and decide which balance to build the forecast on. Short answer: always start the forecast from the real bank balance, and use the book balance to tell you what is already in flight. The rest of this article is how to get there without losing an afternoon.
What each balance actually means
The bank balance is the figure on your statement or online banking at a given date. It is a fact. If you walked into the branch, that is what you could move. It already carries bank charges, interest, cleared cheques and standing orders.
The book balance is the sum of the entries sitting in your bank journal in Odoo. It is the company’s view from the inside: invoice raised, payment registered, direct debit launched. It tries to describe what should be at the bank, assuming every entry is correct and the bank has already processed it.
The two never match on a random Tuesday. Bank reconciliation is the process that ticks off each line on both sides and explains the gap. Done weekly, the two numbers meet. Skipped for three months, the knot gets harder to untie.
A quirk inside Odoo trips people up. On the dashboard you can see a journal balance and a general ledger balance for the same account that do not agree with each other. The bank journal running balance adds statements plus journal entries on that journal; the general ledger shows every entry that touched the bank account, including miscellaneous operations like an opening balance or a payroll entry posted to the wrong account. When those two numbers disagree inside Odoo, the problem is in-house. It is not the bank.
The eight real causes
Almost every discrepancy falls into one of these buckets. I have ranked them by how often they show up in a 20-person SME.
1. Payments registered but not reconciled
Someone enters a supplier invoice in Odoo and clicks Register Payment on the invoice itself. Odoo posts an entry, but by default the money lands in an outstanding payments account, a holding account that sits between the ledger and the bank. Until you import the statement and match that payment to the actual bank debit, the money lives in a clearing account, not in the bank. The book has already moved it, the bank has not. The two drift.
This is the single most common cause. Checking how much sits in the outstanding payments and outstanding receipts accounts is the first place to look.
2. Statements not imported or still in draft
Busy month, nobody uploaded the CSV. Or it was uploaded but the statement sits in Draft and never got validated. The book carries on registering payments and the real bank balance carries on moving. Odoo simply has not been shown the statement to match them.
3. Bank charges, interest and fees
The bank charges €42 for monthly account fees, €328 for interest on the short-term facility and €95 for the card reader rental. From its side those are normal postings; from your side they are expenses nobody has entered. The bank has already deducted them, the book has not.
4. Direct debit runs and batched collections
You submit a direct debit run for 23 customers totalling €1,820. In the book it shows as a single pending collection. For the three days between submission and settlement, with maybe one or two returns, the money is in no man’s land. If the eventual bank credit is not reconciled line by line against the batch, the book stays inflated until someone goes back to tidy it up.
5. Uncleared cheques and in-flight transfers
You post a cheque for €920 to a supplier on the 28th. They bank it on the 7th of the following month. For ten days the book has subtracted the amount and the bank has not. Same story with a wire payment ordered late in the day that settles the next working day.
6. Value dates
The bank books a credit on today’s date but the value date is two working days later. For statement purposes it has arrived; for interest it has not. If your bank feed brings one date and your eye is on the other, the daily cut can push a transaction from one month into the next. At month-end a couple of thousand euros can look missing while nothing is actually broken.
7. Duplicate statement imports
You import a statement covering the 1st to the 20th, then a safety-net one from the 18th to the 25th. The 18th, 19th and 20th have come in twice. If any transaction on those days got reconciled through both imports, you have just collected the same payment twice in the book. Odoo tries to warn when it spots repeated transaction identifiers, but with plain CSV it is not foolproof.
8. A wrong opening balance
The day the company moved onto Odoo, someone typed the opening balance with the wrong sign, a misplaced decimal or against the wrong clearing account. That bad seed carries a constant offset that will not disappear by reconciling the months that follow. You have to go back and post an adjusting journal against the opening entry.
A worked example that balances
Picture Thornbury Logistics Ltd, an 18-person SME in the West Midlands, one company, one operational account.
- Bank statement balance on 31 October: €48,230.00.
- Odoo bank journal balance on 31 October: €51,642.00.
- Gap to explain: €3,412.00, with the book sitting above the bank.
Chasing the eight causes, Priya, the finance manager, finds this:
| Cause | Amount |
|---|---|
| Monthly account fee not posted | €42.00 |
| Short-term facility interest not posted | €328.00 |
| Card reader rental not posted | €95.00 |
| Direct debit run awaiting settlement | €1,820.00 |
| Customer transfer recorded before it cleared | €480.00 |
| Transaction duplicated by overlapping statement imports | €320.00 |
| Opening balance mis-entered at go-live | €327.00 |
| Total | €3,412.00 |
Once Priya posts the three bank-side expenses (€465), deletes the duplicate line and corrects the opening entry, the gap narrows to €2,300 in transit: the €1,820 direct debit run and the €480 customer transfer, explained line by line and ready to clear as soon as the bank credits them. It takes an afternoon the first time and twenty minutes a week after that.
How to find the gap, step by step
This works on Enterprise and, with the right community module, on Community too. The native reconciliation widget has not come with Community for several versions now, so without a community add-on the reconciliation screen is simply not there.
- Freeze a cut-off date. Pick a closed day, ideally end of month. No moving targets, not “today”, not “yesterday”.
- Write down the real bank balance at that date. Read it off the statement PDF or online banking, not the Odoo dashboard.
- Write down the Odoo bank journal balance at the same date. If the dashboard shows two different numbers for that account (journal and general ledger), write both.
- Subtract: book minus bank. That is the number you need to explain.
- Open the outstanding payments and outstanding receipts accounts. Any balance there is cause one. Match each entry to a bank movement as it arrives.
- Confirm every statement up to the cut-off is imported and validated, with no live drafts.
- List bank charges and interest for the last three months on the statement. Make sure every one is posted.
- Look for uncleared cheques and ordered transfers. They should sit on a clearing account, not simply have disappeared from the book.
- Hunt for duplicates by matching dates and amounts. A filter by amount and label on the bank journal does the job.
- If a lump remains, revisit the opening balance and the first few weeks of entries after go-live.
What rarely helps: tweaking numbers by hand until the dashboard looks right. A “manual adjustment” without a journal entry behind it fixes the screen and breaks the accounts.
Which balance you use for the forecast
To project the next three, six or twelve months, you always start from the real bank balance on the cut-off date. It is the only number nobody can argue with and it is the one your bank will look at if you ask for a facility. On that starting point you add what you are going to collect and subtract what you are going to pay, with their real due dates.
The Odoo book balance plays a different role. It tells you what is already in flight. If the book sits €2,180 below the bank, that money is on its way out soon and belongs in week one of the forecast. If the book sits €1,820 above the bank because of a direct debit run, those collections have a probable settlement date and go into week one too. Reading the ledger as a list of pending movements, not as an alternative balance, is far more useful.
If you want to lock the method in, our guide on how to build a cash flow forecast from scratch picks up right here, and the piece on the cash KPIs owners should check every week gives you a short list so you do not spend your morning in a spreadsheet. For the wider map of running treasury inside Odoo, the guide on cash flow forecasting with Odoo frames the whole thing.
A twenty-minute weekly routine
- Monday, 09:00. Import the previous week’s statements, or wait for the automatic feed to drop them.
- Monday, 09:10. Run the reconciliation. Match what matches on its own, review the rest.
- Monday, 09:20. Write down the real bank balance and the book balance in a short note. If the gap is bigger than usual, open a ticket to yourself.
Twenty minutes a week saves you an afternoon every quarter. And it means the forecast you send to the board or show the bank comes off a figure you can defend.
This is the kind of chore a tool like Kashbi quietly removes. Kashbi reads your Odoo, shows the real money across every account up to date, and emails you before projected cash drops below the floor you set. It changes nothing in your accounting.
Frequently asked questions
Can I trust the number on Odoo’s accounting dashboard?
Trust it if you have reconciled up to today, if the last statement’s charges and interest are posted, and if the outstanding payments and outstanding receipts accounts are not holding stale entries. Any of those three missing and the dashboard will show a figure that is not the real one. When money is on the line, go to the statement.
What about Odoo Community without the reconciliation module?
Odoo Community does not ship the native reconciliation widget. Without a community add-on that puts it back, the matching screen is not there. You can still import statements and post manual journals, but it is slow and mistakes multiply. If you run more than one operational account, installing a community reconciliation module or moving the workflow outside Odoo pays back quickly.
How big a gap between book and bank is normal on any given day?
It depends on your volume of pending collections and payments. In a 20-person SME with monthly direct debit runs it is normal to see €2,000 to €3,000 of gap in the days around a run, and close to zero the day after the weekly reconciliation. The amount matters less than being able to explain every euro of it in under a minute.
Where do I start if I have not reconciled for six months?
Start with the oldest unreconciled statement. Each skipped week makes a bigger knot. If you are far behind, block a morning, reconcile month by month and, at the end, post a single adjusting journal for anything you cannot identify, with the balancing side in a clearing account. Better to close the backlog with a small adjustment and begin the weekly routine than to carry the lump forward forever.