← All projects

In production

ERP for an industrial instrumentation manufacturer

An ERP in real daily use for sales, job orders, purchasing, warehouse, invoicing and technical support. The two previous developers had left without any handover.

Role
Inherited project
Period
Since October 2026
Status
In production, used every day by the client.
Stack
Laravel 12
Livewire 3
Flux
Pest
Spatie Permission
Browsershot
Reverb
TipTap
Barcode
Forge

In less than two weeks I developed and released to production, in batches, all 97 open issues.

Invoicing

  • 8 document types with separate numbering series, and VAT with the exemption codes required by the Italian e-invoicing system.
  • The number is assigned only when the invoice is issued. From then on it is locked and can only be corrected with a credit note.
  • Due dates calculated from 14 payment terms, with August and December bank receipts postponed as Italian practice requires.
  • PDFs with a DRAFT watermark until the invoice is issued.

Quotes and final bills from job reports

  • A technician’s hours, travel, materials and mileage become a quote or a final bill, with prices taken from the client first, then the contract, then the price list.

Warehouse, in 9 phases

  • Stock reserved for job orders, and picking.
  • Barcode scanner support on 7 screens.
  • Van stock, deducted automatically from the technician’s job report.
  • Year-end inventory.

Order fulfilment

  • From job order to delivery note, and from purchase orders to goods received.
  • Documents sent by email, with history.

Day one: nobody could get in

On my first day on the project, nobody could log in anymore. Connected to the server over SSH, I ruled out causes one by one: the route cache had been generated in debug mode and never rebuilt, so the login JavaScript wasn’t loading.

I fixed it and turned it into a release rule, so it can’t happen again.

Invoices with the same number

Invoice numbering was producing duplicates. I fixed it with a database lock, so two invoices issued at the same moment can’t get the same number.

Stock and prices that can’t go wrong

Only one service can write stock levels, always inside a transaction. Prices are checked again on the server, so they can’t be tampered with from the browser.

Careful releases

Before every release I take a backup and run the migrations forwards and backwards on a copy of production. One single release carried 27 of them.

Someone else’s code, without rewriting it

Around 39,000 lines of components written by others. I followed their conventions instead of imposing mine, so the code stays consistent.

97/97 issues developed and released in under two weeks
139 commits in 3 weeks
~37,700 lines added
2,080 → 3,125 tests in the suite
3 production releases