5.8 KiB
5.8 KiB
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 tableinvoice_items- Invoice line items
New Columns in Invoices
invoice_number- Unique invoice identifierterms- Payment terms (e.g., "Net 30")authorization- P.O. number or authorization codecreated_from_quote_id- Reference to original quote (if converted)
Indexes Added
idx_invoices_invoice_numberidx_invoices_customer_ididx_invoice_items_invoice_ididx_invoices_created_from_quote
API Endpoints Added
Invoice Endpoints
GET /api/invoices- List all invoicesGET /api/invoices/:id- Get invoice detailsPOST /api/invoices- Create new invoicePUT /api/invoices/:id- Update invoiceDELETE /api/invoices/:id- Delete invoiceGET /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 generationpublic/app.js- Added invoice management functionspublic/index.html- Added invoice tab and modal
Files Added
add_invoices.sql- Database migration for invoicesINSTALLATION.md- Detailed installation guideCHANGELOG.md- This filedocker-compose.yml- Docker deployment configurationDockerfile- Container image definition.dockerignore- Docker build exclusions
Migration Path
For existing installations:
-
Run the invoice migration:
psql -U quoteuser -d quotes_db -f add_invoices.sql -
No changes to existing quotes data
-
Invoice numbering starts fresh (2026-001)
-
All existing features remain unchanged
Technical Details
Invoice Number Generation
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
// 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
- Create new invoice manually
- Edit existing invoice
- Delete invoice
- Generate invoice PDF
- Convert quote without TBD to invoice
- Block conversion of quote with TBD items
- Verify "Bill To:" label on invoice PDF
- Verify accounting@bayarea-cc.com on invoice PDF
- Verify terms display in PDF
- Verify authorization display in PDF (when present)
- Test tax calculations on invoices
- 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.