Skip to main content
LeafOne IT Solutions
Custom Software

RouteLedger: route sales, truck stock and shop credit for Bismi Foods

FMCG Distribution & Food Wholesale

Client
Bismi Foods
Year
2026
Status
Live in daily use

The intro and the screens

A 24-second intro and 5 screens — scroll sideways

A 24-second intro, shot from the running system — a sale taken with no signal, and the queue emptying itself back in range.
The RouteLedger driver app beside the admin console dashboard, showing today's sales, cash collected and shop credit
The office console and the driver app run on one database — the same sale, seen from both ends.
Three driver app screens: the route with its shops, the sale priced off truck stock, and the printed receipt
The whole counter flow: pick the shop, price the items off the truck's own stock, print or send the receipt.
The outstanding balances report, ranking every shop that owes money with a credit trend chart
Every shop that owes money, largest first, with the age of the oldest unpaid sale and whether credit is improving over the period.
The trips list showing planned, dispatched, active and closed runs across four trucks and five routes
Planned, dispatched, active and closed runs across every truck and route, each showing shops visited against shops planned.
The driver app offline, refusing to show a balance it cannot read, and back online with an empty sync queue
Offline, it refuses to guess a balance it cannot read. Back in range, the queue empties itself.

Every figure shown is real output from the application, running against a seeded demonstration database. Shop names, phone numbers and staff names are fixtures, not Bismi Foods' customer data.

The Challenge

Bismi Foods sells to grocery shops from vans across coastal and interior Kerala. Sales, collections, samples, returns and damages were written in a book and keyed in later, so the office was a day or two behind the money, stock on the truck was reconstructed from memory, and shop credit grew quietly across a stack of bills. Large parts of the route have no mobile signal at all.

The Goal

Let the driver bill, collect and print at the shop counter whatever the signal is doing — and let the office see the stock and the credit as soon as he does, instead of the next morning.

Our Strategy

We treated no-signal as the normal case rather than the edge case, and built the driver app around its own write queue first. Everything else followed from two rules: stock is never a stored number, and nothing happens outside a trip.

The Solution

LeafOne built RouteLedger: an installable driver app that prices a sale off that truck's own stock, takes payment and prints the receipt at the counter with no connection at all, and a full back-office console covering products, shops, trucks, routes, trips, warehouse and truck stock, payments, samples, damages, returns and seven reports.

Key Features

Sale entry priced from that truck's live stock, retail or wholesale
Part payment, full payment or pure credit on any sale
A payment can clear today's bill and eat into the older balance
Returns, damages and samples recorded separately and treated differently
Thermal receipt printing, PDF, or send on WhatsApp
Works fully offline — queued writes sync themselves when signal returns
Outstanding balances by shop, aged, with a credit trend over any period
Truck stock counts and route reconciliation, with shortages surfaced
Sale cancellation with a full audit trail, and credit notes
Three roles — admin, manager, driver — enforced server-side

Decisions worth talking about

Stock is never a stored number. It is always a sum.

RouteLedger never keeps a column saying "this truck has 73 bottles of oil". It keeps the movements — loaded, sold, returned, damaged, sampled — and adds them up every time it needs the figure. A stored number can be quietly edited and nobody will know; a list of movements cannot be. It costs a little performance on every read and buys a stock figure you can defend in an argument with a driver.

Everything happens inside a trip.

A sale is not a free-floating event. It happens on a trip, at a shop that is on that trip, from the truck of that trip, by the driver of that trip. So the system refuses to sell to a shop that isn't on today's route, from a truck that isn't the trip's truck, or onto a trip that's already closed. Those refusals aren't friction for its own sake — they are the reason the stock figures stay true.

Offline is the normal case, and the app says what it doesn't know.

A sale made with no signal is saved on the phone, the receipt prints immediately, and the queue drains by itself the moment the connection returns. The part we're proudest of is smaller: when it can't read the ledger, the payment screen doesn't guess. It shows "Can't check while offline" where the shop's balance would be, and caps what it will accept to the bill in front of it. A field app that invents a number to look complete is worse than one that admits the gap, because the driver is standing in front of a shopkeeper who remembers what he owes.

Technology Stack

Node.jsExpressMySQLJavaScriptPWA

Services Used

Design & Infrastructure

The driver app is built to be used one-handed, at a counter, in a hurry, possibly with no signal — large targets, one decision per screen, and a visible sync status he can tap to inspect, retry or discard. The console is the opposite: data-dense, scannable, with every report exportable.

Deployed as a Node.js service against MySQL, with the driver app installable from the browser as a PWA and a desktop wrapper for the office. Schema changes ship as numbered migrations, and the system carries its own backup and restore.

Engineering notes

  • Node.js, Express and MySQL with five production dependencies in total — dependencies are a liability, and this one has to keep running in a shop with nobody on call.
  • Around 6,200 lines of backend across 16 route modules, and 27 tables including an append-only audit log.
  • 28 SQL migrations as plain numbered files applied in order — no ORM, no migration framework, nothing between the schema and the person reading it.
  • Zero frontend dependencies: both apps are hand-written HTML, CSS and JavaScript with no framework, no bundler and no build step. The charts are hand-drawn SVG.
  • The service worker caches the shell and never the data, so the app always opens without a connection but a figure on screen is never a stale cached one.
  • JWT auth with bcrypt-hashed passwords, and every permission check on the server — clearing the phone or typing a URL changes nothing.
  • A 77,000-word operations manual ships with the system and is served inside the app, written for staff rather than developers.

Results

RouteLedger is live and in daily use. Sales are recorded at the counter with no mobile signal and the receipt printed on the spot; every stock figure traces back to the movement that produced it; and shop credit is visible by shop and by age on demand, without anyone adding it up by hand.

Live and in daily use for route sales, truck stock and shop credit
Sales recorded with no mobile signal, receipt printed at the counter
Every stock figure traceable to the movement that produced it

Have a similar challenge?