Case study · HVAC manufacturer’s representation
The 2016 server is gone, and one system carries a job from quote to commission.
Infrastructure modernization and a quote-to-commission CRM/ERP for an HVAC manufacturer’s rep.
Free · 30 minutes · No pitch. Ask me about work like this.
- 2016toGone the server that ran everything, retired
- 1 system quote, order, POs, invoice and commission
- No 2FAtoEntra ID Conditional Access and Intune on every device
- 98% fulltoOff-site the data drive; now Synology to Backblaze B2

The short version
MW Equipment, a 20-staff HVAC manufacturer’s rep, relied on one 2016 server, on its original drives, for everything from sign-in to accounting. I replaced it with Microsoft 365 and a hardened edge, and built them one application from quote to commission. Quotes, orders, POs, invoices and commission reports now come off one set of records.
At a glance
What changed, line by line.
| Before | After | |
|---|---|---|
| Server | One 2016 host running AD, DHCP, DNS, file shares and accounting, on original drives in RAID 5 | Switched off once nothing depended on it |
| Storage & backups | A failed cache battery and a data drive 98% full | Synology Active Backup, copied off-site to Backblaze B2 |
| Edge | The firewall’s management portal open to the internet | Protectli running OPNsense with a Cloudflare allow-list; services behind Cloudflare Zero Trust |
| Identity | On-prem Active Directory; no one on 2FA; old accounts active with passwords that never expired | Entra ID, with Intune baselines and Conditional Access |
| Email & documents | Google Workspace, paid for and under-used | Microsoft 365 and SharePoint |
| Workstations | Staff PCs on the on-prem domain | 8 new PCs, enrolled in Intune, encrypted with BitLocker, local admin passwords by LAPS |
| Sales process | No single system for quotes, orders, POs, invoices and commissions | One application from quote to commission report, on records that agree: Django 5.2, PostgreSQL and HTMX |
One server, and everything on it.
MW Equipment is an HVAC manufacturer’s rep firm in New York City. At the time of the migration it had 20 staff, and everything ran on one 2016 server: Active Directory, DHCP, DNS, file shares and the accounting software, on the original drives in RAID 5, with a failed cache battery and a data drive 98% full. One disk failure during a rebuild would have taken the office down for days.
The assessment found more. The firewall’s management portal was open to the internet. Google Workspace was paid for and under-used, with no one enrolled in two-factor authentication. Old accounts were still active with passwords that never expired, and the domain had no DMARC record.
The sales side needed the same attention. They bid HVAC packages into the New York City market, send the same quote to several competing contractors, and then carry the job they win through ordering, purchasing, invoicing and commission. All of that had to live in one system, on records that agree with each other. They had no in-house IT and wanted one person to take the whole thing on.
A new edge, Microsoft 365, and one application.
Google Workspace moved to Microsoft 365 and SharePoint. The on-prem Active Directory domain was retired in favor of Entra ID, and the staff moved onto eight new PCs. Once nothing depended on them, the 2016 host and the old firewall were switched off.
The new edge is a Protectli appliance running OPNsense with a Cloudflare allow-list. Published services sit behind Nginx Proxy Manager and Cloudflare Zero Trust, remote access runs over WireGuard, and MeshCentral is deployed to every endpoint through Intune. Intune baselines and Conditional Access govern the devices; BitLocker and LAPS cover disk encryption and local administrator passwords. A Synology NAS handles on-site storage with Active Backup and copies to a Backblaze B2 bucket off-site.
The sales side runs on a quote-to-commission application I built for them. It is Django 5.2 and PostgreSQL, server-rendered with HTMX, with WeasyPrint for the report PDFs, and it ships as a single-tenant Docker deployment.
The application follows the way they actually bid. A quote holds one row per manufacturer: equipment cost, shipping, startup and a bid markup percent. The bid value adds itself up as you type. Each quote also tracks the contractors bidding on that job, and one button converts the won quote into an order.
An order carries the contractor POs whose sum is its total sale, and the purchase orders the firm sends to manufacturers. Below those sit the cost add-ons and the firm’s own invoices, each with its paid amount and balance. Payments are allocated against them.
The money panel derives the rest. Deductions, gross profit and margin come off those records. So does the commission pool, split between the contractor and engineer sales reps by percentage, and then net profit. That math lives in exactly one place in the code.
Roles decide what each person may change, and a sales rep sees their own book. Every record keeps a change history written in words. Records link out to their SharePoint folder and to the same folder on the staff machine. There is a global search, and eight reports that export to CSV and PDF.
Diagram · The edge and backups after
Internet
- Cloudflare Zero Trust
In front of every published service
Allow-listed
Protectli · OPNsense
- Cloudflare allow-list at the edge
- Nginx Proxy Manager for published services
Replaced a firewall whose portal was open to the internet
Office LAN
Office
- 8 PCs Intune, BitLocker, LAPS
- Synology NAS Active Backup
Also The NAS copies off-site to a Backblaze B2 bucket. Remote access runs over WireGuard; MeshCentral reaches every endpoint through Intune.
The result: a locked-down edge, and one set of numbers.
MW Equipment runs on one identity platform and one document platform, with the 2016 host retired and no management ports open to the internet. Every one of the eight workstations is enrolled in Intune, encrypted and configured by policy, so a replacement is set up the same way as the rest.
Commission questions are answered from the commission report. The same records produce the quote, the purchase orders, the invoice and the commission report, so the numbers agree by construction.
Keep reading
Next case study

Case study 02 / 03
Re-keyedto20+ flows carrying customers, quotes, orders, stock and prices
Security camera distributor · 180 users · 11 locations
IT director · In-house
Three systems, one set of data.
- Before
- Acumatica, Salesforce and WooCommerce each kept their own customers, products, prices and stock.
- After
- One set of data. Customers, quotes, orders, stock by warehouse and prices move between all three.



