Skip to content

morrismukiri/editableinvoice

Repository files navigation

Editable Invoice - Self-Hosted Web App

A self-hosted web application for creating, editing, and managing invoices. Converted from a static jQuery-based invoice template into a full Express + SQLite web app while preserving the original layout, print behavior, and user experience.

Features

  • Authentication: Secure login system with session management
  • Create, edit, and manage invoices
  • Search invoices by invoice number or customer
  • Duplicate invoices with automatic date and invoice number updates
  • Print-friendly layout (uses existing print.css)
  • Persistent storage with SQLite
  • Docker support for easy deployment

Stack

  • Backend: Node.js + Express
  • Database: SQLite (better-sqlite3)
  • Views: EJS (server-rendered)
  • Frontend: jQuery (preserves existing code style)
  • Styling: Existing CSS (style.css, print.css)
  • Deployment: Docker + docker-compose

Quick Start

Using Docker (Recommended)

  1. Build and start the application:
docker-compose up --build
  1. Open your browser and navigate to:
http://localhost:3000
  1. Login with default credentials:
    • Username: admin
    • Password: admin (or check console output on first run)

The SQLite database will be persisted in the ./data directory.

Local Development

  1. Install dependencies:
npm install
  1. Start the application:
npm start
  1. Open your browser and navigate to:
http://localhost:3000
  1. Login with default credentials:
    • Username: admin
    • Password: admin (or check console output on first run)

The SQLite database will be created in ./data/app.db.

Authentication

The application uses session-based authentication. On first run, a default admin user is automatically created:

  • Username: admin
  • Password: admin (or the value set in DEFAULT_PASSWORD environment variable)

Changing the Default Password

You can set a custom default password using an environment variable:

DEFAULT_PASSWORD=your-secure-password npm start

Or in Docker:

environment:
  - DEFAULT_PASSWORD=your-secure-password

Note: For production use, change the default password immediately after first login. You can do this by directly updating the database or by setting a custom DEFAULT_PASSWORD before first run.

Session Security

  • Sessions expire after 24 hours of inactivity
  • Set SESSION_SECRET environment variable in production for secure session cookies
  • For HTTPS deployments, set secure: true in session configuration (app.js)

Usage

Creating a New Invoice

  1. Click "New Invoice" from the invoice list page
  2. Fill in the invoice details:
    • Header (e.g., "INVOICE")
    • Your company address
    • Customer details
    • Invoice number and date
    • Line items (name, description, unit cost, quantity)
    • Payment terms
  3. Click "Save Invoice" to persist the invoice

Editing an Invoice

  1. Click "Edit" next to any invoice in the list
  2. Make your changes
  3. Click "Save Invoice" to update

Duplicating an Invoice

  1. From the invoice list, click "Duplicate" next to an invoice, OR
  2. From the invoice editor, click "Duplicate"
  3. The new invoice will have:
    • All fields and line items copied
    • A new invoice number (original + "-COPY")
    • Date set to today
    • Amount paid reset to $0.00

Printing

Click the "Print" button in the invoice editor, or use your browser's print function (Cmd/Ctrl+P). The print layout is optimized using the existing print.css.

Project Structure

editableinvoice/
├── app.js                 # Express application entry point
├── package.json           # Node.js dependencies
├── Dockerfile            # Docker image definition
├── docker-compose.yml    # Docker Compose configuration
├── db/
│   └── database.js       # SQLite database initialization and migrations
├── routes/
│   ├── invoices.js       # Invoice page routes (list, new, edit)
│   └── api.js            # Invoice API routes (create, update, duplicate)
├── views/
│   ├── invoice-list.ejs  # Invoice list page
│   └── invoice-editor.ejs # Invoice editor page
├── public/
│   ├── css/              # Stylesheets (style.css, print.css)
│   └── js/               # JavaScript (jQuery, example.js)
└── images/               # Logo images

API Endpoints

Pages

  • GET / - Redirects to invoice list
  • GET /invoices - List all invoices (supports ?search=query)
  • GET /invoices/new - New invoice page
  • GET /invoices/:id - Edit invoice page

API

  • POST /api/invoices - Create new invoice
  • PUT /api/invoices/:id - Update existing invoice
  • POST /api/invoices/:id/duplicate - Duplicate invoice

Database Schema

invoices

  • id (INTEGER PRIMARY KEY)
  • header (TEXT)
  • address (TEXT)
  • logo_url (TEXT)
  • customer_details (TEXT)
  • invoice_number (TEXT)
  • invoice_date (TEXT)
  • payment_terms (TEXT)
  • currency_prefix (TEXT, default: "$ ")
  • amount_paid (TEXT)
  • created_at (DATETIME)
  • updated_at (DATETIME)

invoice_items

  • id (INTEGER PRIMARY KEY)
  • invoice_id (INTEGER, FOREIGN KEY)
  • name (TEXT)
  • description (TEXT)
  • unit_cost (TEXT)
  • qty (TEXT)
  • sort_order (INTEGER)

Environment Variables

  • PORT - Server port (default: 3000)
  • DB_PATH - SQLite database file path (default: ./data/app.db)
  • DEFAULT_PASSWORD - Default password for admin user on first run (default: "admin")
  • SESSION_SECRET - Secret key for session cookies (default: "invoice-app-secret-key-change-in-production")

Notes

  • The application preserves the original invoice template's HTML structure and CSS selectors
  • Currency formatting supports any prefix (detected automatically from input)
  • Calculations are performed client-side; the backend stores structured data
  • No authentication is required (single-user system)
  • The database is automatically initialized on first run

License

ISC

About

An editable HTML invoice and quotation Template

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors