removed
This commit is contained in:
parent
2d5be21bf2
commit
84b0836234
212
CHANGELOG.md
212
CHANGELOG.md
|
|
@ -1,212 +0,0 @@
|
||||||
# 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.
|
|
||||||
|
|
@ -1,294 +0,0 @@
|
||||||
# Invoice System Implementation Summary
|
|
||||||
|
|
||||||
## Übersicht / Overview
|
|
||||||
|
|
||||||
Dieses Dokument fasst die komplette Invoice-System-Implementierung für Bay Area Affiliates zusammen.
|
|
||||||
|
|
||||||
This document summarizes the complete Invoice System implementation for Bay Area Affiliates.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Was wurde implementiert / What Was Implemented
|
|
||||||
|
|
||||||
### 1. Datenbank / Database ✅
|
|
||||||
- **Neue Tabellen:** `invoices`, `invoice_items`
|
|
||||||
- **Neue Indizes:** Für Performance-Optimierung
|
|
||||||
- **Migration Script:** `add_invoices.sql`
|
|
||||||
- **Rückwärtskompatibel:** Keine Änderungen an bestehenden Quotes
|
|
||||||
|
|
||||||
### 2. Backend (server.js) ✅
|
|
||||||
- **Invoice CRUD Operationen:**
|
|
||||||
- GET /api/invoices - Liste aller Invoices
|
|
||||||
- GET /api/invoices/:id - Invoice Details
|
|
||||||
- POST /api/invoices - Neue Invoice erstellen
|
|
||||||
- PUT /api/invoices/:id - Invoice bearbeiten
|
|
||||||
- DELETE /api/invoices/:id - Invoice löschen
|
|
||||||
|
|
||||||
- **PDF Generierung:**
|
|
||||||
- GET /api/invoices/:id/pdf - Invoice PDF
|
|
||||||
- "Bill To:" statt "Quote For:"
|
|
||||||
- accounting@bayarea-cc.com statt support@
|
|
||||||
- Terms-Feld in Header-Tabelle
|
|
||||||
- Authorization-Feld (optional)
|
|
||||||
|
|
||||||
- **Quote-zu-Invoice Konvertierung:**
|
|
||||||
- POST /api/quotes/:id/convert-to-invoice
|
|
||||||
- Validierung: Keine TBD-Items erlaubt
|
|
||||||
- Automatische Nummer-Generierung
|
|
||||||
- Verknüpfung mit Original-Quote
|
|
||||||
|
|
||||||
### 3. Frontend (app.js) ✅
|
|
||||||
- **Invoice Management:**
|
|
||||||
- loadInvoices() - Invoices laden
|
|
||||||
- renderInvoices() - Invoices anzeigen
|
|
||||||
- openInvoiceModal() - Modal für Create/Edit
|
|
||||||
- handleInvoiceSubmit() - Formular speichern
|
|
||||||
- addInvoiceItem() - Line Items hinzufügen
|
|
||||||
- updateInvoiceTotals() - Berechnungen
|
|
||||||
|
|
||||||
- **Conversion Feature:**
|
|
||||||
- convertQuoteToInvoice() - Quote konvertieren
|
|
||||||
- Fehlerbehandlung für TBD-Items
|
|
||||||
|
|
||||||
### 4. UI (index.html) ✅
|
|
||||||
- **Neuer Tab:** "Invoices" in Navigation
|
|
||||||
- **Invoice-Liste:** Tabelle mit allen Invoices
|
|
||||||
- **Invoice Modal:**
|
|
||||||
- Customer Selection
|
|
||||||
- Date Picker
|
|
||||||
- Terms Input (default: "Net 30")
|
|
||||||
- Authorization Input (optional)
|
|
||||||
- Tax Exempt Checkbox
|
|
||||||
- Items mit Quill Rich Text Editor
|
|
||||||
- Totals Berechnung
|
|
||||||
|
|
||||||
- **Quote-Liste Enhancement:**
|
|
||||||
- "→ Invoice" Button für Konvertierung
|
|
||||||
|
|
||||||
### 5. Dokumentation ✅
|
|
||||||
- **README.md:** Komplette Dokumentation
|
|
||||||
- **INSTALLATION.md:** Installations-Anleitung (DE/EN)
|
|
||||||
- **CHANGELOG.md:** Änderungsprotokoll
|
|
||||||
- **setup.sh:** Automatisches Setup-Script
|
|
||||||
|
|
||||||
### 6. Deployment ✅
|
|
||||||
- **Docker Support:**
|
|
||||||
- Dockerfile
|
|
||||||
- docker-compose.yml
|
|
||||||
- .dockerignore
|
|
||||||
|
|
||||||
- **Environment:**
|
|
||||||
- .env.example
|
|
||||||
- Konfigurierbare Settings
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Key Unterschiede: Quotes vs Invoices
|
|
||||||
|
|
||||||
| Feature | Quotes | Invoices |
|
|
||||||
|---------|--------|----------|
|
|
||||||
| **TBD Items** | ✅ Erlaubt | ❌ Nicht erlaubt |
|
|
||||||
| **Email** | support@bayarea-cc.com | accounting@bayarea-cc.com |
|
|
||||||
| **Label** | "Quote For:" | "Bill To:" |
|
|
||||||
| **Terms** | Nein | Ja (z.B. "Net 30") |
|
|
||||||
| **Authorization** | Nein | Ja (optional, P.O. etc.) |
|
|
||||||
| **Header Info** | Quote #, Account #, Date | Invoice #, Account #, Date, Terms |
|
|
||||||
| **Konvertierung** | → zu Invoice | - |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Dateistruktur / File Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
invoice-system/
|
|
||||||
├── server.js # Express Backend mit allen Routes
|
|
||||||
├── public/
|
|
||||||
│ ├── index.html # UI mit Tabs (Quotes/Invoices/Customers/Settings)
|
|
||||||
│ ├── app.js # Frontend JavaScript
|
|
||||||
│ └── uploads/ # Logo-Speicher
|
|
||||||
├── package.json # Dependencies
|
|
||||||
├── init.sql # Initial DB Schema (Customers, Quotes)
|
|
||||||
├── add_invoices.sql # Invoice Tables Migration
|
|
||||||
├── setup.sh # Auto-Installations-Script
|
|
||||||
├── .env.example # Environment Template
|
|
||||||
├── docker-compose.yml # Docker Deployment
|
|
||||||
├── Dockerfile # Container Image
|
|
||||||
├── README.md # Haupt-Dokumentation
|
|
||||||
├── INSTALLATION.md # Setup-Anleitung (DE/EN)
|
|
||||||
└── CHANGELOG.md # Versions-Historie
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Installation / Setup
|
|
||||||
|
|
||||||
### Schnellstart / Quick Start
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Dateien entpacken
|
|
||||||
cd /installation/directory
|
|
||||||
|
|
||||||
# 2. Setup ausführen
|
|
||||||
chmod +x setup.sh
|
|
||||||
./setup.sh
|
|
||||||
|
|
||||||
# 3. Server starten
|
|
||||||
npm start
|
|
||||||
|
|
||||||
# 4. Browser öffnen
|
|
||||||
# http://localhost:3000
|
|
||||||
```
|
|
||||||
|
|
||||||
### Docker Deployment
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build und Start
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# Logs ansehen
|
|
||||||
docker-compose logs -f
|
|
||||||
|
|
||||||
# Stoppen
|
|
||||||
docker-compose down
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Validierungs-Regeln / Validation Rules
|
|
||||||
|
|
||||||
### Quote zu Invoice Konvertierung
|
|
||||||
|
|
||||||
**ERLAUBT / ALLOWED:**
|
|
||||||
```javascript
|
|
||||||
Quote Item: { qty: "2", rate: "125.00/hr", amount: "250.00" }
|
|
||||||
→ Kann konvertiert werden ✅
|
|
||||||
```
|
|
||||||
|
|
||||||
**NICHT ERLAUBT / NOT ALLOWED:**
|
|
||||||
```javascript
|
|
||||||
Quote Item: { qty: "2", rate: "TBD", amount: "TBD" }
|
|
||||||
→ Fehler: "Cannot convert quote with TBD items to invoice" ❌
|
|
||||||
```
|
|
||||||
|
|
||||||
**Lösung / Solution:**
|
|
||||||
1. Quote bearbeiten
|
|
||||||
2. TBD durch tatsächliche Werte ersetzen
|
|
||||||
3. Quote speichern
|
|
||||||
4. Dann konvertieren
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## API Beispiele / API Examples
|
|
||||||
|
|
||||||
### Invoice erstellen / Create Invoice
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
POST /api/invoices
|
|
||||||
{
|
|
||||||
"customer_id": 1,
|
|
||||||
"invoice_date": "2026-01-31",
|
|
||||||
"terms": "Net 30",
|
|
||||||
"authorization": "P.O. #12345",
|
|
||||||
"tax_exempt": false,
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"quantity": "2",
|
|
||||||
"description": "<p>Email Hosting - Monthly</p>",
|
|
||||||
"rate": "25.00",
|
|
||||||
"amount": "50.00"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Quote zu Invoice / Quote to Invoice
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
POST /api/quotes/5/convert-to-invoice
|
|
||||||
// Response bei Erfolg:
|
|
||||||
{
|
|
||||||
"id": 1,
|
|
||||||
"invoice_number": "2026-001",
|
|
||||||
"customer_id": 1,
|
|
||||||
"total": 54.13,
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response bei TBD-Items:
|
|
||||||
{
|
|
||||||
"error": "Cannot convert quote with TBD items to invoice. Please update all TBD items first."
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Testing Checklist ✅
|
|
||||||
|
|
||||||
- [x] Invoice erstellen
|
|
||||||
- [x] Invoice bearbeiten
|
|
||||||
- [x] Invoice löschen
|
|
||||||
- [x] Invoice PDF generieren
|
|
||||||
- [x] Quote ohne TBD zu Invoice konvertieren
|
|
||||||
- [x] Quote mit TBD Konvertierung blockieren
|
|
||||||
- [x] "Bill To:" Label im PDF
|
|
||||||
- [x] accounting@bayarea-cc.com im PDF
|
|
||||||
- [x] Terms im PDF Header
|
|
||||||
- [x] Authorization im PDF (wenn vorhanden)
|
|
||||||
- [x] Tax Berechnungen
|
|
||||||
- [x] Tax-Exempt Invoices
|
|
||||||
- [x] Customer Dropdown funktioniert
|
|
||||||
- [x] Auto-Numbering (2026-001, 2026-002, etc.)
|
|
||||||
- [x] Rich Text Editor in Items
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Nächste Schritte / Next Steps
|
|
||||||
|
|
||||||
### Deployment auf deinem Server
|
|
||||||
1. Dateien hochladen
|
|
||||||
2. `setup.sh` ausführen
|
|
||||||
3. Logo hochladen (Settings Tab)
|
|
||||||
4. Ersten Customer erstellen
|
|
||||||
5. Test-Quote erstellen
|
|
||||||
6. Quote zu Invoice konvertieren
|
|
||||||
7. PDFs testen
|
|
||||||
|
|
||||||
### Optional: Docker
|
|
||||||
```bash
|
|
||||||
docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Backup einrichten
|
|
||||||
```bash
|
|
||||||
# Cronjob für tägliches Backup
|
|
||||||
0 2 * * * pg_dump -U quoteuser quotes_db > /backups/quotes_$(date +\%Y\%m\%d).sql
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Support & Hilfe
|
|
||||||
|
|
||||||
- **Dokumentation:** README.md
|
|
||||||
- **Installation:** INSTALLATION.md
|
|
||||||
- **Änderungen:** CHANGELOG.md
|
|
||||||
- **Logs:** `journalctl -u quote-system -f` (systemd)
|
|
||||||
- **Docker Logs:** `docker-compose logs -f`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Zusammenfassung / Summary
|
|
||||||
|
|
||||||
**Vollständiges Invoice-System implementiert mit:**
|
|
||||||
- ✅ Separate Invoice-Verwaltung
|
|
||||||
- ✅ Quote-zu-Invoice Konvertierung
|
|
||||||
- ✅ TBD-Validierung
|
|
||||||
- ✅ Professionelle PDFs
|
|
||||||
- ✅ Unterschiedliche Email-Adressen
|
|
||||||
- ✅ Terms & Authorization Felder
|
|
||||||
- ✅ Automatische Nummerierung
|
|
||||||
- ✅ Vollständige Dokumentation
|
|
||||||
- ✅ Docker Support
|
|
||||||
- ✅ Auto-Setup Script
|
|
||||||
- ✅ Rückwärtskompatibel
|
|
||||||
|
|
||||||
**Bereit für Produktion!** 🚀
|
|
||||||
264
INSTALLATION.md
264
INSTALLATION.md
|
|
@ -1,264 +0,0 @@
|
||||||
# Installation Guide / Installationsanleitung
|
|
||||||
|
|
||||||
## English Version
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
- Node.js 18 or higher
|
|
||||||
- PostgreSQL 12 or higher
|
|
||||||
- npm (comes with Node.js)
|
|
||||||
|
|
||||||
### Quick Installation
|
|
||||||
|
|
||||||
1. **Extract files to your server**
|
|
||||||
```bash
|
|
||||||
cd /your/installation/directory
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Run the setup script**
|
|
||||||
```bash
|
|
||||||
chmod +x setup.sh
|
|
||||||
./setup.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
The script will:
|
|
||||||
- Create the PostgreSQL database and user
|
|
||||||
- Set up environment variables
|
|
||||||
- Run database migrations
|
|
||||||
- Install Node.js dependencies
|
|
||||||
- Create necessary directories
|
|
||||||
|
|
||||||
3. **Start the server**
|
|
||||||
```bash
|
|
||||||
npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Access the application**
|
|
||||||
Open your browser to: http://localhost:3000
|
|
||||||
|
|
||||||
### Manual Installation
|
|
||||||
|
|
||||||
If you prefer to install manually:
|
|
||||||
|
|
||||||
1. **Create PostgreSQL database**
|
|
||||||
```bash
|
|
||||||
sudo -u postgres psql
|
|
||||||
CREATE DATABASE quotes_db;
|
|
||||||
CREATE USER quoteuser WITH PASSWORD 'your_password';
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE quotes_db TO quoteuser;
|
|
||||||
\q
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Run database migrations**
|
|
||||||
```bash
|
|
||||||
psql -U quoteuser -d quotes_db -f init.sql
|
|
||||||
psql -U quoteuser -d quotes_db -f add_invoices.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Install dependencies**
|
|
||||||
```bash
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Configure environment**
|
|
||||||
```bash
|
|
||||||
cp .env.example .env
|
|
||||||
# Edit .env with your settings
|
|
||||||
```
|
|
||||||
|
|
||||||
5. **Create directories**
|
|
||||||
```bash
|
|
||||||
mkdir -p public/uploads
|
|
||||||
```
|
|
||||||
|
|
||||||
6. **Start the server**
|
|
||||||
```bash
|
|
||||||
npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Deutsche Version
|
|
||||||
|
|
||||||
### Voraussetzungen
|
|
||||||
- Node.js 18 oder höher
|
|
||||||
- PostgreSQL 12 oder höher
|
|
||||||
- npm (kommt mit Node.js)
|
|
||||||
|
|
||||||
### Schnell-Installation
|
|
||||||
|
|
||||||
1. **Dateien auf deinen Server entpacken**
|
|
||||||
```bash
|
|
||||||
cd /dein/installations/verzeichnis
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Setup-Script ausführen**
|
|
||||||
```bash
|
|
||||||
chmod +x setup.sh
|
|
||||||
./setup.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Das Script wird:
|
|
||||||
- PostgreSQL-Datenbank und Benutzer erstellen
|
|
||||||
- Umgebungsvariablen einrichten
|
|
||||||
- Datenbank-Migrationen ausführen
|
|
||||||
- Node.js-Abhängigkeiten installieren
|
|
||||||
- Notwendige Verzeichnisse erstellen
|
|
||||||
|
|
||||||
3. **Server starten**
|
|
||||||
```bash
|
|
||||||
npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Anwendung öffnen**
|
|
||||||
Browser öffnen: http://localhost:3000
|
|
||||||
|
|
||||||
### Manuelle Installation
|
|
||||||
|
|
||||||
Falls du lieber manuell installieren möchtest:
|
|
||||||
|
|
||||||
1. **PostgreSQL-Datenbank erstellen**
|
|
||||||
```bash
|
|
||||||
sudo -u postgres psql
|
|
||||||
CREATE DATABASE quotes_db;
|
|
||||||
CREATE USER quoteuser WITH PASSWORD 'dein_passwort';
|
|
||||||
GRANT ALL PRIVILEGES ON DATABASE quotes_db TO quoteuser;
|
|
||||||
\q
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Datenbank-Migrationen ausführen**
|
|
||||||
```bash
|
|
||||||
psql -U quoteuser -d quotes_db -f init.sql
|
|
||||||
psql -U quoteuser -d quotes_db -f add_invoices.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Abhängigkeiten installieren**
|
|
||||||
```bash
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Umgebung konfigurieren**
|
|
||||||
```bash
|
|
||||||
cp .env.example .env
|
|
||||||
# .env mit deinen Einstellungen bearbeiten
|
|
||||||
```
|
|
||||||
|
|
||||||
5. **Verzeichnisse erstellen**
|
|
||||||
```bash
|
|
||||||
mkdir -p public/uploads
|
|
||||||
```
|
|
||||||
|
|
||||||
6. **Server starten**
|
|
||||||
```bash
|
|
||||||
npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## File Structure / Dateistruktur
|
|
||||||
|
|
||||||
```
|
|
||||||
quote-invoice-system/
|
|
||||||
├── server.js # Express server / Backend-Server
|
|
||||||
├── public/
|
|
||||||
│ ├── index.html # Main UI / Hauptoberfläche
|
|
||||||
│ ├── app.js # Frontend JavaScript
|
|
||||||
│ └── uploads/ # Logo storage / Logo-Speicher
|
|
||||||
├── package.json # Dependencies / Abhängigkeiten
|
|
||||||
├── init.sql # Initial DB schema / Initiales DB-Schema
|
|
||||||
├── add_invoices.sql # Invoice tables / Rechnungs-Tabellen
|
|
||||||
├── setup.sh # Auto-installation / Auto-Installation
|
|
||||||
├── .env.example # Environment template / Umgebungs-Vorlage
|
|
||||||
└── README.md # Documentation / Dokumentation
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting / Fehlerbehebung
|
|
||||||
|
|
||||||
### Database connection fails / Datenbankverbindung fehlgeschlagen
|
|
||||||
- Check PostgreSQL is running: `sudo systemctl status postgresql`
|
|
||||||
- Verify credentials in `.env` file
|
|
||||||
- Ensure user has permissions: `GRANT ALL ON SCHEMA public TO quoteuser;`
|
|
||||||
|
|
||||||
### Port 3000 already in use / Port 3000 bereits belegt
|
|
||||||
- Change `PORT` in `.env` file
|
|
||||||
- Or stop the service using port 3000
|
|
||||||
|
|
||||||
### PDF generation fails / PDF-Generierung fehlgeschlagen
|
|
||||||
- Puppeteer requires Chromium
|
|
||||||
- On Ubuntu/Debian: `sudo apt-get install chromium-browser`
|
|
||||||
- On Alpine/Docker: Already configured in Dockerfile
|
|
||||||
|
|
||||||
### Permission errors / Berechtigungsfehler
|
|
||||||
- Ensure `public/uploads` directory exists and is writable
|
|
||||||
- Run: `chmod 755 public/uploads`
|
|
||||||
|
|
||||||
## Production Deployment / Produktions-Deployment
|
|
||||||
|
|
||||||
### Using PM2 (Recommended / Empfohlen)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install PM2
|
|
||||||
npm install -g pm2
|
|
||||||
|
|
||||||
# Start application
|
|
||||||
pm2 start server.js --name quote-system
|
|
||||||
|
|
||||||
# Save PM2 configuration
|
|
||||||
pm2 save
|
|
||||||
|
|
||||||
# Auto-start on boot
|
|
||||||
pm2 startup
|
|
||||||
```
|
|
||||||
|
|
||||||
### Using systemd
|
|
||||||
|
|
||||||
Create `/etc/systemd/system/quote-system.service`:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[Unit]
|
|
||||||
Description=Quote & Invoice System
|
|
||||||
After=network.target postgresql.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
User=your_user
|
|
||||||
WorkingDirectory=/path/to/quote-invoice-system
|
|
||||||
Environment="NODE_ENV=production"
|
|
||||||
ExecStart=/usr/bin/node server.js
|
|
||||||
Restart=on-failure
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
```
|
|
||||||
|
|
||||||
Then:
|
|
||||||
```bash
|
|
||||||
sudo systemctl enable quote-system
|
|
||||||
sudo systemctl start quote-system
|
|
||||||
```
|
|
||||||
|
|
||||||
## Security Recommendations / Sicherheitsempfehlungen
|
|
||||||
|
|
||||||
1. **Use strong database passwords / Starke Datenbank-Passwörter verwenden**
|
|
||||||
2. **Run behind reverse proxy (nginx) / Hinter Reverse-Proxy betreiben**
|
|
||||||
3. **Enable HTTPS / HTTPS aktivieren**
|
|
||||||
4. **Regular backups / Regelmäßige Backups**
|
|
||||||
5. **Keep dependencies updated / Abhängigkeiten aktuell halten**
|
|
||||||
|
|
||||||
## Backup / Sicherung
|
|
||||||
|
|
||||||
### Database Backup / Datenbank-Backup
|
|
||||||
```bash
|
|
||||||
pg_dump -U quoteuser quotes_db > backup_$(date +%Y%m%d).sql
|
|
||||||
```
|
|
||||||
|
|
||||||
### Restore / Wiederherstellen
|
|
||||||
```bash
|
|
||||||
psql -U quoteuser quotes_db < backup_20260131.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
For technical support / Für technischen Support:
|
|
||||||
- Check README.md for usage instructions
|
|
||||||
- Review error logs: `journalctl -u quote-system -f`
|
|
||||||
- Contact Bay Area Affiliates, Inc.
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
-- Migration to add Invoice functionality
|
|
||||||
-- Run this on your existing database
|
|
||||||
|
|
||||||
-- Create invoices table
|
|
||||||
CREATE TABLE IF NOT EXISTS invoices (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
invoice_number VARCHAR(50) UNIQUE NOT NULL,
|
|
||||||
customer_id INTEGER REFERENCES customers(id),
|
|
||||||
invoice_date DATE NOT NULL,
|
|
||||||
terms VARCHAR(100) DEFAULT 'Net 30',
|
|
||||||
auth_code VARCHAR(255),
|
|
||||||
tax_exempt BOOLEAN DEFAULT FALSE,
|
|
||||||
tax_rate DECIMAL(5,2) DEFAULT 8.25,
|
|
||||||
subtotal DECIMAL(10,2) DEFAULT 0,
|
|
||||||
tax_amount DECIMAL(10,2) DEFAULT 0,
|
|
||||||
total DECIMAL(10,2) DEFAULT 0,
|
|
||||||
created_from_quote_id INTEGER REFERENCES quotes(id),
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Create invoice_items table
|
|
||||||
CREATE TABLE IF NOT EXISTS invoice_items (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
invoice_id INTEGER REFERENCES invoices(id) ON DELETE CASCADE,
|
|
||||||
quantity VARCHAR(20) NOT NULL,
|
|
||||||
description TEXT NOT NULL,
|
|
||||||
rate VARCHAR(50) NOT NULL,
|
|
||||||
amount VARCHAR(50) NOT NULL,
|
|
||||||
item_order INTEGER NOT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Create indexes
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_invoices_invoice_number ON invoices(invoice_number);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_invoices_customer_id ON invoices(customer_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_invoice_items_invoice_id ON invoice_items(invoice_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_invoices_created_from_quote ON invoices(created_from_quote_id);
|
|
||||||
53
init.sql
53
init.sql
|
|
@ -1,53 +0,0 @@
|
||||||
-- Initial Database Setup for Quote & Invoice System
|
|
||||||
-- Run this first to create the basic tables
|
|
||||||
|
|
||||||
-- Create customers table
|
|
||||||
CREATE TABLE IF NOT EXISTS customers (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
name VARCHAR(255) NOT NULL,
|
|
||||||
street VARCHAR(255) NOT NULL,
|
|
||||||
city VARCHAR(100) NOT NULL,
|
|
||||||
state VARCHAR(2) NOT NULL,
|
|
||||||
zip_code VARCHAR(10) NOT NULL,
|
|
||||||
account_number VARCHAR(50),
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Create quotes table
|
|
||||||
CREATE TABLE IF NOT EXISTS quotes (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
quote_number VARCHAR(50) UNIQUE NOT NULL,
|
|
||||||
customer_id INTEGER REFERENCES customers(id),
|
|
||||||
quote_date DATE NOT NULL,
|
|
||||||
tax_exempt BOOLEAN DEFAULT FALSE,
|
|
||||||
tax_rate DECIMAL(5,2) DEFAULT 8.25,
|
|
||||||
subtotal DECIMAL(10,2) DEFAULT 0,
|
|
||||||
tax_amount DECIMAL(10,2) DEFAULT 0,
|
|
||||||
total DECIMAL(10,2) DEFAULT 0,
|
|
||||||
has_tbd BOOLEAN DEFAULT FALSE,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Create quote_items table
|
|
||||||
CREATE TABLE IF NOT EXISTS quote_items (
|
|
||||||
id SERIAL PRIMARY KEY,
|
|
||||||
quote_id INTEGER REFERENCES quotes(id) ON DELETE CASCADE,
|
|
||||||
quantity VARCHAR(20) NOT NULL,
|
|
||||||
description TEXT NOT NULL,
|
|
||||||
rate VARCHAR(50) NOT NULL,
|
|
||||||
amount VARCHAR(50) NOT NULL,
|
|
||||||
item_order INTEGER NOT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Create indexes for better performance
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_quotes_quote_number ON quotes(quote_number);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_quotes_customer_id ON quotes(customer_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_quote_items_quote_id ON quote_items(quote_id);
|
|
||||||
|
|
||||||
-- Insert sample customer
|
|
||||||
INSERT INTO customers (name, street, city, state, zip_code, account_number)
|
|
||||||
VALUES ('Braselton Development', '5337 Yorktown Blvd. Suite 10-D', 'Corpus Christi', 'TX', '78414', '3617790060')
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
Loading…
Reference in New Issue