Quote and invoice builder demo

Three independent workspaces, one for Vietnam, one for the USA and one for the EU, each with its own currency, tax treatment and numbering. Unglamorous, entirely client-side, and the thing small businesses actually shop for.

Open the demo

Opens quote-invoice.taiphamsolutions.com in a new tab. No account, no signup, and nothing you do in it leaves your browser.

What it does

The editor is the same in all three workspaces: editable line items, customer details, a shipping address, payment instructions, inclusive or exclusive pricing, and totals that recompute as you type. What changes between them is the tax model. Vietnam has VND with 8% and 10% VAT presets. The USA has USD with editable additive state and local components. The EU has country presets with an adjustable rate, a VAT ID, IBAN and BIC, a supply date, and reverse charge.

Money is stored in integer minor units and never in a float. Tax-exclusive lines round their net value and each tax component half up. Inclusive lines preserve the gross amount, round the net half up, and distribute the remaining tax across components by largest remainder, so the parts always add back to the total the customer was shown.

A draft is unnumbered and freely editable. Issuing it is atomic: one IndexedDB transaction takes the next number and freezes the contents, with separate sequences per region, document type and issue year, as in VN-INV-2026-0001. After that the contents are immutable. A mistake is cancelled rather than edited, and the number is never reused. Counters stay monotonic even through a backup restore.

Issue an invoice, then try to change its total. Cancel it instead, and watch the number stay used rather than come back around.

Features

Three demo workspaces with fictional customers and products, plus one-click fill, random customer and random items while you are exploring.

Three tax regimes

Vietnam, USA and EU workspaces with their own currency, presets and numbering, plus explicit zero-rated, exempt and reverse-charge treatments that require a note.

Editor and totals

Line items, customer and shipping details, payment instructions, inclusive or exclusive prices, and live totals computed in integer minor units.

Issuing and lifecycle

Atomic numbering, immutable issued contents, manual status tracking, cancellation without number reuse, duplication, and a link from a quote to the invoice it became.

Getting it out

An A4 and Letter print stylesheet with repeating table headings across pages, save as PDF from the browser print dialog, CSV export of the list, and versioned JSON backup.

The flow it closes, end to end

Every step below happens inside the demo. There is no point in it where the work leaves the browser and comes back.

  1. Pick a workspace and open a draft

    The workspace decides the currency, the tax model, the numbering sequence and the document language before anything is typed.

  2. Build the document

    Customer, line items, and a choice between inclusive and exclusive pricing. The tax treatment is explicit, and exemption or reverse charge will not save without a note.

  3. Watch the totals settle

    Rounding happens per component in integer minor units, so what is printed is what adds up rather than what a float happened to produce.

  4. Issue it

    One transaction numbers the document and snapshots the customer, business, currency, language, tax treatment and paper size into it.

  5. Track, cancel, or convert

    Status is tracked by hand, a cancellation leaves the number spent, and a quote carries a link to the invoice it turned into.

  6. Print or export

    A print stylesheet that repeats table headings across pages, or CSV for the list, or a versioned JSON backup of all three workspaces.

What is real, and what is not

There is no server behind any of this, which decides both columns. The left one is what that constraint made worth building properly. The right one is what it rules out.

Actually handled

  • Rounding that reconciles on inclusive and exclusive prices alike
  • Numbering that cannot double-issue, and counters that survive a restore
  • Issued documents that stop being editable, with cancellation as the only correction
  • Cross-tab conflict checks on documents, customers, products and settings

Deliberately not real

  • This is a billing workflow, not a tax filing or government e-invoice submission system
  • Presets are editable examples. They do not decide the treatment that applies to a real transaction
  • There is no currency conversion, and nothing is emailed or uploaded anywhere
  • Numbering is unique within one browser workspace. Two devices are not coordinated

How it is built

The write-up sells harder than the application does, so it is on the page rather than in a repository nobody can open.

Stack
Svelte 5, TypeScript and Vite, with IndexedDB for every record and decimal.js-light for the arithmetic.
Money
Integer minor units throughout, đồng for VND and hundredths elsewhere. No floating point anywhere near a total.
Offline
The build generates a service worker that precaches the bundle, fonts and icons, so after one successful visit the app opens, creates documents, saves and prints with no network. Updating the bundle never rewrites the business data.
Tests
Browser suites over the three regional workflows plus regressions for tax defaults, numeric input, navigation, cross-tab settings and directory edits, pending-save dialogs, and customer editing during item randomisation.

The services this is evidence for

A demo exists to prove something on the offer list rather than to be impressive on its own. These are the ones this one argues for.

Want the version of this with your rules in it?

This one was built to a constraint nobody would choose. Yours would have a server, real accounts, and the parts of the domain that are actually hard. Tell us what the software has to do and we will tell you what it takes.

Bring the messy version of the problem. That is the conversation we enjoy most.

Email us