Back to Projects

Pune Sand

Turning a sand supplier's paper challans and hand-totalled GST invoices into a small, correct, print-perfect ERP.

Freelance — full-stack (client: KMK Spaces Pvt Ltd)
  • Django
  • DRF
  • Next.js
  • PostgreSQL
Cover coming soon

Pune Sand is the kind of project that never shows up in a framework tutorial: a real business running on carbon-copy delivery books and a calculator, asking whether a computer could just do the adding-up correctly. KMK Spaces supplies sand and construction material. Every trip out is a delivery challan; at the end of a cycle those challans get consolidated into one GST tax invoice. It was all being done by hand, and the maths — especially the tax maths — is exactly the kind of thing humans get quietly wrong.

The problem

The workflow itself was fine. Paper wasn't the enemy; re-keying and re-calculating was. The same customer, material, and rate got written out on a challan, then copied onto an invoice, then the GST split got worked out by hand, then the grand total got rounded "close enough." Every one of those steps was a chance for a number to drift, and once a number drifts on a tax document it becomes a compliance problem, not just a typo.

So the brief was narrow and unglamorous: digitize the existing flow — masters → challans → invoice → print — without inventing a new one, and make the totals impossible to get wrong.

What I built

A small ERP with a Django REST backend and a Next.js front end. You set up your masters once — customers, materials with their HSN codes and GST rates, units of measure, suppliers. Then the day-to-day is fast: create a challan per trip (pick a customer and the site address auto-fills, pick a material and its unit auto-fills), issue it when the goods are delivered, and later select a customer's issued-but-uninvoiced challans to roll them into a single draft invoice. One line per challan, every rate and HSN pulled straight from the masters.

The whole thing is built around guards rather than trust. A challan can belong to at most one invoice — enforced as a one-to-one constraint at the database level, not just in the UI. Only issued challans can be invoiced. Every challan on an invoice has to belong to the same customer. Once an invoice is issued, its source challans lock and can't be edited. Delete a draft invoice and they're released back. The rules that a careful clerk would hold in their head are now things the system simply won't let you violate.

Getting the tax right

The core of the value is one piece of logic that has to be correct every single time: the GST split. If the customer is in the company's own state, the tax is CGST + SGST at half the material's rate each; anyone out of state pays IGST at the full rate. The grand total is rounded to the rupee with an explicit round-off line so the document reconciles to the paisa. Totals are always recomputed server-side on save — the browser never gets to be the source of truth for a number that goes on a tax invoice. There's a test suite covering exactly these paths: numbering, CGST/SGST versus IGST, round-off, and the guard conditions.

For a business like this, the invoice on paper is the product. So both documents render in their real paper layouts — the challan reproduces the exact format they already use (PUNE SAND header, GSTIN, vehicle and driver lines, signature blocks), and the tax invoice reproduces the full banded table with tax totals, amount in words, bank details, and declaration. Print CSS strips the app chrome so "Save as PDF" from the browser produces a clean A4 document. The numbering series even continues from where their paper books left off, so there's no discontinuity in their records.

Where it stands

It runs the full loop the client actually does every day: sign in, manage masters, cut challans, consolidate them into a correct GST invoice, and print both. A company-profile settings page controls everything printed on the documents so they can update their own details without touching code. It's a deliberately small system — one admin login, one clear workflow — but within that scope it's complete and correct, which for a tax document is the only bar that matters.