← Back to Projects
Invoicing / Finance

SoloBill

A contractor invoicing tool built for a journeyman plumber who needed a paper trail. Generates, tracks, and exports invoices entirely inside Google Workspace.

Role
Designer & Builder
Stack
Google Apps Script, Vanilla JS, Google Sheets, PDF via Drive
Built for
Independent contractor, new to private work
Status
MVP complete, in refinement
solobill · demo mode · calculations live, save requires GAS deployment
Open full screen ↗

A journeyman with jobs done and nothing to show for it

A friend of mine, a journeyman plumber, did work on my house while I was getting it ready to sell. He was new to private contract work and had no system for tracking invoices. As we worked together it became clear he had other customers he hadn't billed yet because the process of documenting and invoicing felt like too much overhead on top of the job itself.

The need was twofold. He needed a way to quickly generate invoices and keep a record of what he'd done for each client. I needed a paper trail. When real estate agents representing potential buyers started making inspection inquiries, I needed documentation that verified the work had been completed. An invoice isn't just a billing document. In that context, it was evidence.

No external dependencies. Must run on Google Workspace alone.

The constraint was self-imposed and intentional: zero external services. No Stripe, no paid PDF library, no cloud database. Everything had to live in tools a Google Workspace user already has for free.

That meant Google Sheets as the database, Google Apps Script as the backend and compute layer, Google Drive for PDF storage, and HtmlService for the UI. It's not the most scalable architecture, but it's the most deployable one for the target user.

A full invoicing flow in a browser tab

SoloBill is a web app served by Google Apps Script. The invoice form has live line-item calculation: enter a quantity and a rate, the line total and overall totals update instantly in the browser, no server round-trip needed. All lookups, client list, contractor types, units, come from named tabs in the connected Sheet.

Hitting Save writes a header row to the Invoices sheet and individual line rows to InvoiceLines, with an auto-generated invoice number. Preview PDF renders the invoice using an HtmlService template and saves it to a designated folder in Google Drive, then opens it in a new tab.

The demo above is fully interactive. Add line items, change quantities, watch the totals move. That calculation runs entirely client-side.

Multi-tab Sheet as a relational store

The data model uses four Sheet tabs: Invoices for header rows, InvoiceLines for line item detail, Clients for the client dropdown, and Lookups for status, contractor type, and unit options. Settings pulls company name, address, and default tax rate at runtime so nothing is hardcoded in the app.

  • Live totals: qty × rate per row, summed to subtotal, tax applied, total calculated, all in the browser before any save
  • PDF template uses GAS HtmlService with template syntax, Utilities.formatDate for consistent date formatting
  • Invoice numbers are sequential: INV-YYYY-#### format, derived from row count at save time
  • OAuth scopes request only Spreadsheets and Drive, nothing broader
  • Installation is copy-paste into GAS editor, no clasp or CLI required

MVP is functional. Report tab and email integration are next.

The core loop, create an invoice, save it to Sheets, preview the PDF in Drive, is complete and working. The Report tab will list all invoices with status tracking (New, Sent, Paid, Late) and running balances. The Settings tab will expose company details and tax configuration in-app rather than requiring manual Sheet edits.

Email integration is planned: a single button to send the PDF directly to the client from within the app, using Gmail API via GAS.

← CanvassKit All Projects →