Mealwheelz runs its restaurants on two systems that never talk to each other. Sales live in QuickBill POS. Purchases live in Odoo. Both are fine at what they do. Neither gives you a profit and loss statement.
So every month the finance team did what most restaurant groups do. They exported reports from both sides, pasted them into spreadsheets, and reconciled by hand. It took days. There was no food-cost view at all, because the numbers needed to compute one sat in two different databases. If an owner asked "what did we actually make last week?", the honest answer was "give us until Friday".
We were asked to fix that without replacing either system.
The obvious approach is to ask both vendors for API access, collect keys, and build integrations on top. We did not do that, for two practical reasons.
First, key management is a burden for a small finance team. Keys expire, get rotated, get pasted into the wrong place. Second, one of the systems did not expose the data we needed through a clean public API anyway.
Instead we built web-login adapters. The module signs in the same way a person does, with the client's own credentials, and then talks to each system through the interfaces it already exposes to a logged-in user:
No new accounts, no keys to store, no vendor tickets. If a staff member's password changes, they update it once in the module and everything keeps working.
Hitting two live systems every time someone opens a report is slow and fragile. So the module does not do that. Instead, a sync step pulls sales, items and purchases from both sources and writes them into a Postgres cache that we control.
That cache is what the reports read from. Because the data is in one database with one schema, we can do things that were impossible before:
The reports are built in Next.js, so they run in the browser with no installs, and the finance team can open them from anywhere. Filters are just controls on the page. Change one and the numbers update.
Two pieces of month-end work used to eat the most time, so we made them permanent parts of the system rather than monthly chores.
**GST.** Sales tax in the client's jurisdiction is 13%. The module computes GST on synced sales automatically, so the tax figures fall out of the same data as everything else. There is no separate GST spreadsheet to maintain, and no risk of the tax report disagreeing with the sales report because they were built from different exports.
**Food cost.** This is the number restaurant owners care about most and the one they almost never have. We added a recipe layer: each menu item maps to the ingredients it uses, and those ingredients map to the purchase lines coming in from Odoo. With that mapping in place, food cost is computed continuously rather than estimated once a quarter. When a supplier raises prices, you see the effect on margin the next time you sync, not at the end of the quarter.
The short version: days of reconciliation became one click.
Month-end now looks like this. Someone presses "Sync". The module logs into Odoo and QuickBill, pulls the period, updates the cache, and the reports are current. The P&L, GST figures and food-cost view are all there, built from the same data, with filters instead of formulas.
A few other things changed along the way:
You probably do not need to replace your POS or your accounting system. What you need is a layer that reads from both, stores the result somewhere you control, and gives your team reports they can filter themselves. Web-login adapters make that possible even when vendors are slow to hand out API access, and a Postgres cache makes it fast.
If your month-end still involves exporting two systems into one spreadsheet, this is a solved problem.
Want this for your business? Message us on WhatsApp +92 320 0496154.