Stock, Dispatch & Billing for a Construction Materials Manufacturer
A custom operations platform for a business that manufactures and distributes tuff tiles, curbstones and concrete pavers, alongside cement, gravel and other raw materials — replacing scattered spreadsheets and handwritten dispatch notes with one browser-based hub.

At a glance
Where things stood
The business runs multiple production plants making tuff tiles, curbstones and concrete pavers, and separately buys and resells raw materials like cement and gravel. Before this system, stock movements, dispatch notes and billing were handled on paper and in spreadsheets, with each plant tracking its own numbers.
What it was costing
Warehouse and sales teams had no shared, live view of what stock existed where, so dispatch relied on someone physically checking or phoning around. Transport documents (\"bilti\") were typed up separately from the invoice for the same order, so the same information was entered more than once and could drift out of sync. Raw material purchases, contractor labour costs and daily expenses were tracked in yet another set of records, making it hard for management to see true material cost against what was being produced and shipped.
What success meant
- One system for finished-goods stock across plants and product lines, with in/out summaries management can actually read.
- Dispatch and billing paperwork — bilti, invoices, gate passes — generated from the same order data, not retyped per document.
- Raw material and labour cost tracking alongside production, so material cost and job costing sit next to the numbers they affect.
- Role-based access with a clean user lifecycle (deactivation, password reset, session control) for a multi-plant team.
Decisions & trade-offs
This was built as a classic Laravel monolith with Blade views and Yajra DataTables for fast, searchable listings across every module — appropriate for an operations tool used by warehouse and admin staff rather than a public-facing product. We split stock and dispatch workflows by product line (tuff tiles vs. ceramic/chemical tiles) rather than forcing one generic form, since the two lines have different size, unit and production conventions on the ground. We didn't build a customer-facing portal in this phase — the priority was giving the internal team one system before opening any part of it externally.
How it's built
Screenshot & purpose, module by module.

Stock management
Finished-goods stock by plant, product and size, with filterable in/out summaries and PDF export for stock records.

Dispatch & logistics
Separate dispatch workflows per product line, with listing, filtering and soft-delete/recovery so mistakes don't mean lost records.

Bilti & transport documents
Transport documents generated directly from dispatch data — vehicle, driver, route and product details in one printable form.

Payments & billing
Customer payments, cement and raw-material payments, and daily expenses, tied back to bank accounts through a dedicated payments module.

Raw materials
Cement, gravel & sand and other raw materials tracked with price updates and payment records, separate from finished-goods stock.

Workforce & contractors
Labour records, contractor job costing and contractor salary with advance tracking and printable salary slips.
Phasing & go-live
Stock and dispatch went live first, since that's where the business had the least visibility day-to-day, followed by billing and payments once dispatch data was reliable, then raw materials and workforce tracking. User accounts and permissions were rolled out per plant as each site came onto the system.
What changed
- Warehouse, sales and admin now work from one live stock and dispatch record instead of separate plant-level spreadsheets.
- Bilti, invoices and gate passes generate from the same order data, removing a second manual re-entry of the same shipment.
- Raw material and contractor costs are tracked in the same system as production, giving management a fuller picture of material cost.
- Soft-delete and account lifecycle controls mean mistakes and staff changes no longer require direct database access to fix.
What we'd do differently
The product-line split (tuff tiles vs. ceramic/chemical tiles) was the right call operationally, but it means some logic is duplicated across two sets of controllers and views. With hindsight we'd factor out the shared stock/dispatch logic into a shared service layer from day one, so future product lines can be added without copying a whole module.

