234 lines
7.6 KiB
Markdown

# 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 invoice
- `GET /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")
- `status`: Filter invoices by status (e.g., "PENDING", "PAID", "CANCELLED")
- `sort_order`: Sort by creation date, either "asc" (oldest first) or "desc" (newest first, default)
- `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")
- `GET /api/v1/invoices/find`: Find an invoice by invoice number
- Query parameters:
- `invoice_number`: Invoice number to search for (required)
- `fields`: Comma-separated list of fields to include in the response (e.g., "id,invoice_number,total_amount")
- `PATCH /api/v1/invoices/{invoice_id}`: Update an invoice
- `PATCH /api/v1/invoices/{invoice_id}/status`: Update invoice status
- `DELETE /api/v1/invoices/{invoice_id}`: Delete an invoice
### Frontend Routes
- `GET /`: Home page with list of recent invoices
- `GET /create`: Form to create a new invoice
- `POST /create`: Process invoice creation form
- `GET /search`: Form to search for invoices by number
- `POST /search`: Process invoice search
- `GET /invoice/{invoice_id}`: View invoice details
- `POST /invoice/{invoice_id}/status`: Update invoice status
## Setup and Installation
1. Clone the repository
2. Install dependencies:
```
pip install -r requirements.txt
```
3. Run migrations:
```
alembic upgrade head
```
4. 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 prefix
- `YYYYMM` is the year and month (e.g., 202307 for July 2023)
- `XXXXXX` is a random alphanumeric string
## Query Parameters
### 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:
1. Add a `fields` query parameter to GET requests
2. 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:
```json
[
{
"id": 1,
"invoice_number": "INV-202307-A1B2C3",
"total_amount": 100.0
},
{
"id": 2,
"invoice_number": "INV-202307-D4E5F6",
"total_amount": 200.0
}
]
```
### Status Filtering
The API supports filtering invoices by their status (PENDING, PAID, CANCELLED).
#### How to Use Status Filtering:
1. Add a `status` query parameter to the GET request
2. Specify one of the allowed status values: "PENDING", "PAID", or "CANCELLED"
#### Example:
To get only paid invoices:
```
GET /api/v1/invoices?status=PAID
```
To combine with other parameters:
```
GET /api/v1/invoices?status=PENDING&fields=id,invoice_number,total_amount&limit=5
```
### Sorting
The API supports sorting invoices by their creation date.
#### How to Use Sorting:
1. Add a `sort_order` query parameter to the GET request
2. Specify one of the allowed values:
- `asc`: Ascending order (oldest invoices first)
- `desc`: Descending order (newest invoices first, this is the default)
#### Example:
To get invoices in chronological order (oldest first):
```
GET /api/v1/invoices?sort_order=asc
```
To combine sorting with other parameters:
```
GET /api/v1/invoices?sort_order=desc&status=PENDING&limit=10
```
### 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)