Invoice Generation Service
This is a FastAPI application for generating and managing invoices. It allows you to create, read, update, and delete invoices without requiring user signup.
Features
- Generate invoices with automatic invoice number generation
- Store invoice details in SQLite database
- Retrieve invoice information by ID or invoice number
- Update invoice details and status
- Delete invoices
- Web-based user interface for invoice management
- Health check endpoint
Technical Stack
- Framework: FastAPI
- Database: SQLite with SQLAlchemy ORM
- Migrations: Alembic
- Validation: Pydantic
- Frontend: Jinja2 Templates, HTML, CSS, JavaScript
- Linting: Ruff
Project Structure
.
├── alembic.ini # Alembic configuration file
├── app # Application package
│ ├── api # API routes
│ │ └── routes # API route modules
│ │ ├── __init__.py # Routes initialization
│ │ ├── invoices.py # Invoice API routes
│ │ └── frontend.py # Frontend routes
│ ├── core # Core functionality
│ │ ├── config.py # Application settings
│ │ ├── database.py # Database connection setup
│ │ └── utils.py # Utility functions
│ ├── models # SQLAlchemy models
│ │ ├── __init__.py # Models initialization
│ │ └── invoice.py # Invoice and InvoiceItem models
│ ├── schemas # Pydantic schemas
│ │ ├── __init__.py # Schemas initialization
│ │ └── invoice.py # Invoice-related schemas
│ ├── static # Static files
│ │ ├── css # CSS styles
│ │ │ └── styles.css # Main stylesheet
│ │ └── js # JavaScript files
│ │ └── main.js # Main JavaScript file
│ └── templates # Jinja2 templates
│ ├── base.html # Base template with layout
│ ├── home.html # Home page
│ ├── create_invoice.html # Invoice creation form
│ ├── search_invoice.html # Search for invoices
│ └── invoice_details.html # Invoice details page
├── main.py # Application entry point
├── migrations # Alembic migrations
│ ├── env.py # Alembic environment
│ ├── script.py.mako # Migration script template
│ └── versions # Migration scripts
│ └── ef0aaab3a275_initial_database_tables.py # Initial migration
├── requirements.txt # Project dependencies
└── pyproject.toml # Ruff configuration
API Endpoints
Health Check
GET /health
: Check if the service is running
Invoice Management API
POST /api/v1/invoices
: Create a new invoiceGET /api/v1/invoices
: List all invoices (with pagination)- Query parameters:
skip
: Number of records to skip (default: 0)limit
: Maximum number of records to return (default: 100)fields
: Comma-separated list of fields to include in the response (e.g., "id,invoice_number,total_amount")
- Query parameters:
GET /api/v1/invoices/{invoice_id}
: Get a specific invoice by ID- Query parameters:
fields
: Comma-separated list of fields to include in the response (e.g., "id,invoice_number,total_amount")
- Query parameters:
POST /api/v1/invoices/find
: Find an invoice by invoice numberPATCH /api/v1/invoices/{invoice_id}
: Update an invoicePATCH /api/v1/invoices/{invoice_id}/status
: Update invoice statusDELETE /api/v1/invoices/{invoice_id}
: Delete an invoice
Frontend Routes
GET /
: Home page with list of recent invoicesGET /create
: Form to create a new invoicePOST /create
: Process invoice creation formGET /search
: Form to search for invoices by numberPOST /search
: Process invoice searchGET /invoice/{invoice_id}
: View invoice detailsPOST /invoice/{invoice_id}/status
: Update invoice status
Setup and Installation
- Clone the repository
- Install dependencies:
pip install -r requirements.txt
- Run migrations:
alembic upgrade head
- Start the application:
uvicorn main:app --reload
API Documentation
Once the application is running, you can access:
- Interactive API documentation at
/docs
(Swagger UI) - Alternative API documentation at
/redoc
(ReDoc)
Web Interface
The application comes with a full web interface that allows users to:
- View a list of recent invoices on the home page
- Create new invoices using a dynamic form
- Search for existing invoices by invoice number
- View detailed invoice information
- Update invoice status (PENDING, PAID, CANCELLED)
- Print invoices
Invoice Number Format
Invoices are automatically assigned a unique invoice number with the format:
INV-YYYYMM-XXXXXX
, where:INV
is a fixed prefixYYYYMM
is the year and month (e.g., 202307 for July 2023)XXXXXX
is a random alphanumeric string
Field Filtering
The API supports field filtering for GET operations. This allows clients to request only the specific fields they need, which can improve performance and reduce bandwidth usage.
How to Use Field Filtering:
- Add a
fields
query parameter to GET requests - Specify a comma-separated list of field names to include in the response
Example:
To get only the ID, invoice number, and total amount of invoices:
GET /api/v1/invoices?fields=id,invoice_number,total_amount
This would return:
[
{
"id": 1,
"invoice_number": "INV-202307-A1B2C3",
"total_amount": 100.0
},
{
"id": 2,
"invoice_number": "INV-202307-D4E5F6",
"total_amount": 200.0
}
]
Available Fields:
Invoices have the following fields that can be filtered:
id
invoice_number
date_created
due_date
total_amount
status
customer_name
customer_email
customer_address
notes
items
(this includes related invoice items)
Description
Languages
Python
68.1%
HTML
18.6%
JavaScript
6.7%
CSS
6%
Mako
0.6%