invoice-system/CHANGELOG.md

213 lines
5.8 KiB
Markdown

# Changelog
## Version 2.0.0 - Invoice System Implementation (2026-01-31)
### Major New Features
#### Invoice Management
- ✅ Full invoice creation and editing
- ✅ Invoice listing with customer names
- ✅ Invoice PDF generation with professional formatting
- ✅ Terms field (default: "Net 30")
- ✅ Authorization/P.O. field for purchase orders or authorization codes
- ✅ Automatic invoice numbering (YYYY-NNN format)
- ✅ Convert quotes to invoices with one click
#### Quote to Invoice Conversion
- ✅ "→ Invoice" button on quote list
- ✅ Automatic validation (no TBD items allowed)
- ✅ One-click conversion preserving all quote data
- ✅ Automatic current date assignment
- ✅ Default terms applied ("Net 30")
- ✅ Links invoice to original quote
#### PDF Differences
**Quotes:**
- Label: "Quote For:"
- Email: support@bayarea-cc.com
- Header info: Quote #, Account #, Date
- Allows TBD items with asterisk notation
**Invoices:**
- Label: "Bill To:"
- Email: accounting@bayarea-cc.com
- Header info: Invoice #, Account #, Date, Terms
- No TBD items allowed
- Optional authorization field displayed
### Database Changes
#### New Tables
- `invoices` - Main invoice table
- `invoice_items` - Invoice line items
#### New Columns in Invoices
- `invoice_number` - Unique invoice identifier
- `terms` - Payment terms (e.g., "Net 30")
- `authorization` - P.O. number or authorization code
- `created_from_quote_id` - Reference to original quote (if converted)
#### Indexes Added
- `idx_invoices_invoice_number`
- `idx_invoices_customer_id`
- `idx_invoice_items_invoice_id`
- `idx_invoices_created_from_quote`
### API Endpoints Added
#### Invoice Endpoints
- `GET /api/invoices` - List all invoices
- `GET /api/invoices/:id` - Get invoice details
- `POST /api/invoices` - Create new invoice
- `PUT /api/invoices/:id` - Update invoice
- `DELETE /api/invoices/:id` - Delete invoice
- `GET /api/invoices/:id/pdf` - Generate invoice PDF
#### Conversion Endpoint
- `POST /api/quotes/:id/convert-to-invoice` - Convert quote to invoice
### UI Changes
#### New Tab
- Added "Invoices" tab to navigation
- Invoice list view with all invoice details
- Terms column in invoice list
#### New Modal
- Invoice creation/editing modal
- Terms input field
- Authorization input field
- Tax exempt checkbox
- Rich text description editor (Quill.js)
#### Quote List Enhancement
- Added "→ Invoice" button to convert quotes
- Clear visual separation between quotes and invoices
### Business Logic
#### Validation Rules
- Quotes can have TBD items
- Invoices CANNOT have TBD items
- Conversion blocked if quote contains TBD items
- User receives clear error message for TBD conversion attempts
#### Calculations
- Same tax rate (8.25%) for both quotes and invoices
- Tax exempt option available for both
- Automatic subtotal, tax, and total calculations
#### Numbering
- Separate number sequences for quotes and invoices
- Both use YYYY-NNN format
- Auto-increment within calendar year
- Reset to 001 each January 1st
### Files Modified
- `server.js` - Added invoice routes and PDF generation
- `public/app.js` - Added invoice management functions
- `public/index.html` - Added invoice tab and modal
### Files Added
- `add_invoices.sql` - Database migration for invoices
- `INSTALLATION.md` - Detailed installation guide
- `CHANGELOG.md` - This file
- `docker-compose.yml` - Docker deployment configuration
- `Dockerfile` - Container image definition
- `.dockerignore` - Docker build exclusions
### Migration Path
For existing installations:
1. Run the invoice migration:
```sql
psql -U quoteuser -d quotes_db -f add_invoices.sql
```
2. No changes to existing quotes data
3. Invoice numbering starts fresh (2026-001)
4. All existing features remain unchanged
### Technical Details
#### Invoice Number Generation
```javascript
async function getNextInvoiceNumber() {
const year = new Date().getFullYear();
const result = await pool.query(
'SELECT invoice_number FROM invoices WHERE invoice_number LIKE $1 ORDER BY invoice_number DESC LIMIT 1',
[`${year}-%`]
);
if (result.rows.length === 0) {
return `${year}-001`;
}
const lastNumber = parseInt(result.rows[0].invoice_number.split('-')[1]);
const nextNumber = String(lastNumber + 1).padStart(3, '0');
return `${year}-${nextNumber}`;
}
```
#### Conversion Validation
```javascript
// Check for TBD items
const hasTBD = itemsResult.rows.some(item =>
item.rate.toUpperCase() === 'TBD' || item.amount.toUpperCase() === 'TBD'
);
if (hasTBD) {
return res.status(400).json({
error: 'Cannot convert quote with TBD items to invoice. Please update all TBD items first.'
});
}
```
### Backward Compatibility
- ✅ Fully backward compatible with existing quote system
- ✅ No breaking changes to quote functionality
- ✅ Existing PDFs continue to work
- ✅ Customer data unchanged
### Testing Checklist
- [x] Create new invoice manually
- [x] Edit existing invoice
- [x] Delete invoice
- [x] Generate invoice PDF
- [x] Convert quote without TBD to invoice
- [x] Block conversion of quote with TBD items
- [x] Verify "Bill To:" label on invoice PDF
- [x] Verify accounting@bayarea-cc.com on invoice PDF
- [x] Verify terms display in PDF
- [x] Verify authorization display in PDF (when present)
- [x] Test tax calculations on invoices
- [x] Test tax-exempt invoices
### Known Limitations
- None identified
### Future Enhancements (Potential)
- Invoice payment tracking
- Partial payment support
- Invoice status (Paid/Unpaid/Overdue)
- Email delivery of PDFs
- Invoice reminders
- Multi-currency support
- Custom tax rates per customer
---
## Version 1.0.0 - Initial Quote System
### Features
- Quote creation and management
- Customer management
- PDF generation
- Rich text descriptions
- TBD item support
- Tax calculations
- Company logo upload
See README.md for full documentation.