Skip to content

Commit fdd909d

Browse files
author
CodingKitten
committed
feat: Enhance Invoice Editor with tax settings and invoice number field
- Added optional fields for tax rate, prices include tax, rounding mode, and tax mode in InvoiceEditor component. - Introduced invoice number input with error handling in the InvoiceEditor. - Updated item rows to support per-line tax percentages. - Implemented tax summary display in InvoiceDetail for better visibility of tax breakdown. - Enhanced invoice creation and editing routes to handle new tax-related fields. - Removed DemoToast component and its references from the project. - Updated settings page to include default tax rate, prices include tax, and rounding mode configurations.
1 parent 9fd4fbe commit fdd909d

23 files changed

Lines changed: 1582 additions & 637 deletions

File tree

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,30 @@
1111
---
1212

1313
## 🌟 Why Invio?
14+
1415
- Built for doing, not configuring — create an invoice, send a link, get paid. No CRMs, projects, or bloat getting in your way.
1516
- You really own it — self‑hosted by default. Your data lives where you put it, and exporting is always an option.
1617
- Fast & dependable — Deno + Fresh on the frontend and Hono + SQLite on the backend keep things simple and quick.
1718
- Client‑friendly — share a secure public link—no accounts or passwords required to view invoices.
1819

1920
## 📚 More info
21+
2022
Please go to the docs for more info: https://invio.codingkitten.dev/
2123
To log in to the demo, the username and password is demo/demo.
2224

2325
## 🤝 Contributing
26+
2427
Invio thrives on community contributions!
28+
2529
- Found a bug or have an idea? Open an issue.
2630
- Want to add a feature or fix something? Fork and submit a PR.
2731
- All experience levels welcome — we’re excited to build with you.
2832

2933
## ☕ Support the Creator
34+
3035
If you like Invio and want to support development:
3136
- Buy me a coffee: https://ko-fi.com/codingkitten
3237

33-
---
3438

39+
---
3540
Made with 💖 by <a href="https://github.com/kittendevv">kittendevv</a> and contributors — if you find this useful, please ⭐️ the repo!

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.8.1
1+
0.9.0

backend/README.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,28 +196,35 @@ curl -s "http://localhost:3000/api/v1/public/invoices/<token>/ubl.xml" -o invoic
196196

197197
### UBL / PEPPOL settings
198198

199-
The UBL generator uses business settings for seller data and invoice/customer data for buyer details. Optional PEPPOL endpoint IDs can be configured via settings:
199+
The UBL generator uses business settings for seller data and invoice/customer
200+
data for buyer details. Optional PEPPOL endpoint IDs can be configured via
201+
settings:
200202

201203
- `peppolSellerEndpointId` (e.g., `0192:123456785`)
202204
- `peppolSellerEndpointSchemeId` (e.g., `0192`)
203205
- `peppolBuyerEndpointId`
204206
- `peppolBuyerEndpointSchemeId`
205207
- `companyCountryCode` (ISO alpha-2, default `US`)
206208

207-
If these are left empty, the XML remains valid but omits the corresponding EndpointID elements.
209+
If these are left empty, the XML remains valid but omits the corresponding
210+
EndpointID elements.
208211

209212
### Demo mode
210213

211-
When `DEMO_MODE=true`, the API is fully writable so you can try creating and editing
212-
data. The database automatically resets to a pristine snapshot every 3 hours by default.
214+
When `DEMO_MODE=true`, the API is fully writable so you can try creating and
215+
editing data. The database automatically resets to a pristine snapshot every 3
216+
hours by default.
213217

214218
Environment variables:
215219

216220
- `DEMO_MODE=true` — enable demo mode
217-
- `DEMO_DB_PATH` — path to the pristine demo database file (e.g. `/app/data/invio-demo.db`)
218-
- `DATABASE_PATH` — active database file that the app writes to (e.g. `/app/data/invio.db`)
221+
- `DEMO_DB_PATH` — path to the pristine demo database file (e.g.
222+
`/app/data/invio-demo.db`)
223+
- `DATABASE_PATH` — active database file that the app writes to (e.g.
224+
`/app/data/invio.db`)
219225
- `DEMO_RESET_HOURS` — interval in hours between resets (default: `3`)
220-
- `DEMO_RESET_ON_START` — whether to perform a reset on startup (default: `true`)
226+
- `DEMO_RESET_ON_START` — whether to perform a reset on startup (default:
227+
`true`)
221228

222229
On each reset, the server briefly closes the DB connection, copies the pristine
223230
demo DB over the active DB, and reinitializes migrations and built-in templates.

backend/deno.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
"tailwindcss": "npm:tailwindcss@^4.1.12",
3737
"uuid": "https://deno.land/std@0.224.0/uuid/mod.ts",
3838
"pdf-lib": "npm:pdf-lib@^1.17.1",
39-
"crypto": "https://deno.land/std@0.224.0/crypto/mod.ts",
40-
"dotenv": "https://deno.land/std@0.224.0/dotenv/mod.ts",
41-
"yaml": "https://deno.land/std@0.224.0/yaml/mod.ts"
39+
"crypto": "https://deno.land/std@0.224.0/crypto/mod.ts",
40+
"dotenv": "https://deno.land/std@0.224.0/dotenv/mod.ts",
41+
"yaml": "https://deno.land/std@0.224.0/yaml/mod.ts"
4242
}
4343
}

backend/src/app.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ try {
1717
const demoMode = (Deno.env.get("DEMO_MODE") || "").toLowerCase() === "true";
1818
if (demoMode) {
1919
const hours = Number(Deno.env.get("DEMO_RESET_HOURS") || "3");
20-
const initial = (Deno.env.get("DEMO_RESET_ON_START") || "true").toLowerCase() !== "false";
20+
const initial =
21+
(Deno.env.get("DEMO_RESET_ON_START") || "true").toLowerCase() !== "false";
2122
if (initial) {
2223
// Perform a reset at startup to ensure a pristine state
2324
resetDatabaseFromDemo();
@@ -68,7 +69,9 @@ app.get("/health", (c: Context) => {
6869
const rawPort = Deno.env.get("BACKEND_PORT") || Deno.env.get("PORT");
6970
const port = rawPort ? parseInt(rawPort, 10) : 3000;
7071
if (Number.isNaN(port) || port <= 0) {
71-
console.warn(`Invalid port in BACKEND_PORT/PORT (${rawPort}), falling back to 3000`);
72+
console.warn(
73+
`Invalid port in BACKEND_PORT/PORT (${rawPort}), falling back to 3000`,
74+
);
7275
}
7376
const listenPort = Number.isFinite(port) && port > 0 ? port : 3000;
7477
console.log(`Starting backend on port ${listenPort}`);

0 commit comments

Comments
 (0)