Websites and Google rankings for growing companies. Taking on new clients now. hello@joharcreativ.com
Case study, custom software

The CRM a furniture retailer runs on, built from scratch.

The client was locked out of their own CRM by the party who held it, on a server that was being switched off. This is what replaced it: an application they own outright, carrying ten years of their history, that the showroom and the office both work in every day.

Client
A Dutch furniture and bedding retailer
Built in
Python and Django
Replaces
A system they did not control
Owned by
The client, from day one

Client not named, at their request. Counts taken from the project itself, vendor code excluded.

22
data models describing the business
28
test suites, 11,756 lines
10
years of history migrated in
1,117
scripts written across the engagement

Where it started

The urgent problem was not that the CRM was old. It was that it belonged to somebody else and was about to be switched off. Those are different problems, and treating them as one is how a business ends up buying a rushed rebuild under a deadline it did not set.

So the old system was rescued and rehosted first. That alone removed the deadline and kept a working fallback alive, which turned an emergency back into a decision: buy something off the shelf, build, or keep what exists. Building won because of what furniture retail actually looks like in a data model, and because they wanted to stop renting the thing their business runs on.

BeforeAfter
A CRM held by somebody else, on a server being switched off
An application they own outright, on hosting in their name
Ten years of orders reachable only through the old system
Ten years migrated in as a read only archive, still queryable
Order updates typed out by hand, one customer at a time
Sent automatically, with replies landing where the team can see them
Bookkeeping entries retyped into the accounting system
Pushed across directly from the sale that created them
Late custom orders discovered when the customer rang
Flagged by the system before the customer notices
Customer email in a separate inbox, disconnected from the sale
Read and answered inside the CRM, attached to the order
Stock and prices maintained twice, in the shop and the store
One source, synced, so the two cannot drift apart
No tests, because there was no code they controlled
11,756 lines of tests that run before anything changes

Everything it does

Three views of the same system: what the business runs on it, what stopped being done by hand, and what had to be built underneath.

What the business runs on it

  • Sales from first enquiry through to delivered and paid
  • Purchase orders to suppliers, with supplier codes reconciled
  • Deliveries planned onto trucks, with a printable load list
  • Payments recorded and matched against each sale
  • Products, variants and fabric colours, the real shape of furniture stock
  • Customers with nationality and language, because the showroom serves both
  • Notes and replies against every sale, so context is not in someone's head

What stopped being done by hand

  • Order update messages, now sent automatically over WhatsApp
  • Customer emails, read and replied to from inside the CRM rather than a separate inbox
  • Bookkeeping entries, pushed to their Dutch accounting system instead of retyped
  • Payment links, generated and reconciled automatically
  • Order status warnings, raised by the system before a customer has to ring
  • Delivery paperwork, generated rather than assembled
  • Product and price sync with the online store, instead of two lists drifting apart

What was built to make that possible

  • 22 data models describing how this business actually works
  • 28 test suites, 11,756 lines covering bookkeeping, payments, purchasing and sync
  • 6,157 lines of application logic behind the screens staff use
  • An admin for the office and a separate sales screen for the showroom floor
  • Permissions and invites, so staff see what they should and nothing else
  • Dutch and English throughout, because half the customers are not Dutch
  • 1,117 scripts written across the whole engagement, excluding vendor code

The build, in six parts

The decision first, then how it was made.

01

The rescue came before the rebuild

The deadline was removed first, so the decision could be made calmly rather than under it.

The client's system was held by another party, on a server being switched off. The urgent problem was not that the CRM was old, it was that it was about to disappear. Those are different problems with different fixes, and fusing them is how businesses end up paying for a rushed rebuild. The old application was rescued and rehosted first. That removed the deadline, kept a working fallback alive, and only then was there a real choice between buying something off the shelf, building, and simply keeping what existed.

02

A data model that matches furniture, not software

22 models, because a sofa in three fabrics with a ten week lead time is not a line item.

Products have variants, variants have fabric colours, and a supplier code that does not match the one in the shop. Sales have lines, lines have costs, deliveries go on trucks, and payments arrive in parts. Off the shelf systems flatten most of that, and the flattening is exactly where the manual work reappears. The model was written from how the business actually sells, which is why the screens above it are short.

03

Ten years of history, kept rather than replayed

A decade of orders, customers and payments migrated in as a read only archive.

Old records are not replayed into a new accounting engine, because that rewrites history and breaks reconciliation. They come in as an archive that stays queryable, so a member of staff can still look up what a customer bought in 2017 while all new work runs forward cleanly. There are dedicated tests for exactly this, because it is the part that would fail silently.

04

Built for someone standing up with a customer waiting

An admin for the office, and a separate sales screen for the showroom floor.

The person using this most is not technical, is on their feet, and has a customer in front of them. That single constraint decides the whole interface, and it is the part most custom software gets wrong by handing everyone the same admin panel. The showroom screen does the few things that happen at the point of sale and nothing else.

05

The integrations that removed the retyping

Accounting, payments, the online store and WhatsApp, all connected to the sale that created the work.

Bookkeeping entries go to their Dutch accounting system instead of being retyped. Payment links are generated and reconciled. Product and price data stays in step with the online store rather than drifting. Customer email is read and answered inside the CRM, attached to the order it belongs to. Each of these is a job somebody used to do twice.

06

Tests, because it is somebody's livelihood

28 test suites and 11,756 lines of them, covering bookkeeping, payments, purchasing, deliveries, sync and search.

Most software built for a small business has no tests at all, which is fine until the first change breaks invoicing and nobody notices for a week. Here the areas where a silent failure would cost real money have tests that run before anything ships. It is the least visible part of this build and the reason the business can keep asking for changes.

Honest notes

What this page does not claim

There is no hours-saved figure here. The automation is real and listed above, item by item, but nobody measured the before and after, so any number I printed would be invented. I would rather show you exactly what stopped being typed by hand and let you judge what that is worth in your own business.

The counts are from the project directory with the virtual environment and vendor code excluded, so they describe work written rather than libraries installed. The system is still being extended; this is a description of software in use, not a finished monument.

The rest of this account

Three storefronts, three ad accounts and the software around them

The CRM is one part of a larger engagement: three Shopify storefronts, product feeds, Google and Meta advertising, email flows and a certification review.

373products migrated822feed offers34findings fixed
Read the full case study

Something in your business runs on software you do not own?

Tell me what it is and what happens if it disappears. You get an honest answer about whether to rescue it, replace it, or buy something off the shelf instead.