The client's distribution platform had been running for years and knew how much stock existed, but not where any of it was. Pickers found goods by memory, and when memory failed they searched. ELIVTECH modernised the existing CodeIgniter system into a bin-level warehouse platform, working inside a codebase the business could not afford to pause, and delivered it branch by branch without a day of interrupted dispatch.
The client distributes goods to a branch network from several regional warehouses on a CodeIgniter platform built incrementally over many years. Stock was tracked at warehouse level, so the system could confirm quantity but never location, and every pick depended on staff knowledge. Transfers between warehouses were recorded on despatch and again on arrival with nothing in between, leaving stock invisible while in transit. Batch and expiry data lived in spreadsheets. ELIVTECH introduced a bin-level location model, rebuilt receiving, picking and despatch around scanning, added Elasticsearch lookup across SKU, batch and location, and moved the platform onto AWS with a proper release pipeline, all as staged changes to the running system rather than a replacement.
At a glance
The challenge
A system that could count stock accurately and locate none of it.
Stock held without a location
Inventory was recorded against a warehouse and nothing finer. Pickers relied on knowing where goods were usually kept, so a relocated pallet or an unfamiliar line meant physically searching the floor. New staff were slow for months, and that cost was accepted as the nature of the work rather than treated as a system gap.
Transfers invisible while moving
Inter-warehouse transfers were recorded on despatch and again on arrival. Between those events the stock belonged to neither location and appeared in no availability figure, so branches were told goods were unavailable while they were sitting on a vehicle already heading toward them.
Batch and expiry outside the system
Batch numbers and expiry dates were maintained in spreadsheets alongside the platform. Rotation depended on staff checking the right file, and tracing an affected batch across the network meant reconstructing movements manually from despatch notes and email.
Counting required closing the warehouse
Because the system held no location detail, verifying stock meant counting everything at once. Full counts required suspending operations for a weekend, which limited them to a few times a year and left long stretches where discrepancies accumulated unnoticed.
A codebase resistant to change
Years of incremental additions had left business rules duplicated across controllers with no automated tests. Any change carried real risk of breaking dispatch, so changes were avoided, which made the platform progressively less able to support how the business had grown.
Reporting assembled by hand
Operational reporting was exported and combined in spreadsheets each week. By the time a figure reached a manager it described a situation that had already changed, so decisions about replenishment and staffing were made against a picture that was several days old.
Our solution
A location model introduced underneath the running system, then workflows rebuilt on top of it.
Assessment and Location Modelling
Four weeks working in the warehouses to design a location hierarchy of zone, aisle, rack and bin that matched how each site is physically organised, rather than imposing one shape on all of them. Alongside it, the existing codebase was assessed to identify which modules could be extended safely and which needed rebuilding, producing a sequence that kept dispatch running throughout.
Bin-Level Inventory Beneath the Existing System
The location model was added to MySQL with stock movements written as append-only ledger entries rather than quantity updates, so a balance is derived from its movements and every change is attributable. The legacy warehouse-level views continued reading a derived total during the transition, which let the new model run underneath the old interface until each workflow was ready to switch. Balances are materialised per bin and refreshed on write, so a picking screen reads a current figure without recomputing the ledger on every request.
Scanned Workflows and In-Transit Visibility
Receiving, putaway, picking, packing, despatch and transfer were rebuilt around barcode scanning on handheld devices, with batch and expiry captured at receipt and carried through every movement. Transfers gained an in-transit state, so stock on a vehicle is visible and can be committed against a branch order before it physically arrives. Scans queue on the handheld when warehouse coverage drops and replay against idempotent endpoints, so a picker in a steel-racked aisle is never blocked by a weak signal.
Elasticsearch Lookup, Cycle Counting and Reporting
Elasticsearch indexes SKU, batch, supplier reference and location so staff can find stock by whatever detail they happen to have. Cycle counting replaced the annual shutdown by counting bins on a rolling schedule weighted toward high-movement lines. Operational reporting reads the movement ledger directly rather than from weekly exports, so replenishment and staffing decisions are made against current figures. The platform now runs on AWS with a tested release pipeline and monitoring on scan failures and ledger reconciliation.
Technology stack
Results
Measured once every warehouse and branch had moved to the bin-level workflows.
Before and after: platform engineering measures
- Stock recorded at warehouse level with no location detail
- Picking dependent on individual staff knowledge of the floor
- Transfers invisible between despatch and arrival
- Batch and expiry maintained in spreadsheets beside the system
- Stock verification required suspending operations
- Business rules duplicated across controllers with no tests
- Operational reporting assembled by hand each week
- Bin-level location across zone, aisle, rack and bin
- Scanned putaway and picking directed by the system
- In-transit stock visible and committable to branch orders
- Batch and expiry captured at receipt and carried through movements
- Rolling cycle counts weighted toward high-movement lines
- Rebuilt workflows covered by an automated test suite
- Reporting read directly from the movement ledger
Project timeline
Assessment and Location Modelling
On-site observation across warehouses, location hierarchy design per site layout, legacy codebase assessment for extension versus rebuild, and a migration sequence that kept dispatch operating throughout.
Inventory Foundation
Location schema and append-only movement ledger in MySQL, derived balance views for legacy screens, database migration tooling, characterisation tests around existing dispatch logic, and the AWS deployment pipeline.
Scanned Warehouse Workflows
Receiving and putaway with batch and expiry capture, directed picking, packing and despatch, transfer flows with an in-transit state, and handheld interfaces designed for gloved, one-handed operation on the floor.
Search, Counting and Reporting
Elasticsearch indexing across SKU, batch, supplier reference and location, cycle count scheduling weighted by movement, variance investigation workflow, and operational reporting built on the movement ledger.
Warehouse-by-Warehouse Rollout
Bin labelling and opening stock capture per site, parallel running with legacy screens during transition, floor training, monitoring on scan failure and ledger reconciliation, then progressive switch-off of the legacy workflows.
Key takeaways
What shaped the engineering decisions
- Modernise underneath, not alongside: A parallel replacement system was rejected because it would have required running two sources of stock truth during a long transition. Introducing the location model beneath the existing screens meant one record throughout, with interfaces switching over individually.
- A ledger, not a quantity column: Updating a stock figure in place destroys the explanation for how it got there. Append-only movements make every balance derivable and every discrepancy traceable to the action that caused it, which is what made cycle counting workable.
- Let each site keep its own shape: Imposing a single location hierarchy across warehouses with different physical layouts was rejected as something staff would work around. A configurable hierarchy matched what people already had in their heads.
- Model in-transit as a real state: Treating transfers as instantaneous made stock disappear for the duration of a journey. An explicit in-transit state let branches commit against goods that exist and are already on their way.
- Write tests around the old code before touching it: Characterisation tests were built around existing dispatch logic before any change, so the untested legacy behaviour was pinned down first and each modernisation step had something to verify against.
- Design handhelds for the floor, not the desk: Scanning interfaces were built for gloved, one-handed use with large targets and audible confirmation, because a workflow that is awkward on the floor gets bypassed and the location data quietly stops being true.
Want results like these?
Let's discuss how ELIVTECH can drive measurable outcomes for your business.
Start your project