From 2d5be21bf28ce6fdaacdbe078df1eb4db14b59c5 Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Tue, 17 Feb 2026 16:51:30 -0600 Subject: [PATCH] update --- public/app.js | 70 ++--- public/index.html | 6 +- public/invoice-view-init.js | 25 ++ public/invoice-view.js | 503 ++++++++++++++++++++++++++++++++ server.js | 49 ++++ templates/invoice-template.html | 46 +-- 6 files changed, 633 insertions(+), 66 deletions(-) create mode 100644 public/invoice-view-init.js create mode 100644 public/invoice-view.js diff --git a/public/app.js b/public/app.js index 15e0edc..4bac4e7 100644 --- a/public/app.js +++ b/public/app.js @@ -78,7 +78,7 @@ window.customerSearch = customerSearch; document.addEventListener('DOMContentLoaded', () => { loadCustomers(); loadQuotes(); - loadInvoices(); + //loadInvoices(); setDefaultDate(); checkCurrentLogo(); @@ -755,33 +755,37 @@ async function fetchNextInvoiceNumber() { } async function loadInvoices() { + // Wird vom invoice-view.js Modul überschrieben (window.loadInvoices) + // Dieser Fallback lädt die Daten falls das Modul noch nicht geladen ist try { const response = await fetch('/api/invoices'); invoices = await response.json(); - renderInvoices(); + // Falls das Modul geladen ist, nutze dessen Renderer + if (window.invoiceView) { + window.invoiceView.renderInvoiceView(); + } else { + renderInvoices(); + } } catch (error) { console.error('Error loading invoices:', error); - alert('Error loading invoices'); } } function renderInvoices() { + if (window.invoiceView) { + window.invoiceView.renderInvoiceView(); + return; + } + // Minimaler Fallback falls Modul nicht geladen const tbody = document.getElementById('invoices-list'); tbody.innerHTML = invoices.map(invoice => ` - ${invoice.invoice_number} + ${invoice.invoice_number} ${invoice.customer_name || 'N/A'} - ${formatDate(invoice.invoice_date)} - ${invoice.terms} - $${parseFloat(invoice.total).toFixed(2)} - - - - - - + ${formatDate(invoice.invoice_date)} + ${invoice.terms} + $${parseFloat(invoice.total).toFixed(2)} + Loading module... `).join(''); } @@ -1125,38 +1129,13 @@ async function deleteInvoice(id) { } function viewInvoicePDF(id) { - window.open(`/api/invoices/${id}/pdf`, '_blank'); -} - -// *** FIX 2: Verbesserte Erfolgsmeldung mit QBO DocNumber *** -async function exportToQBO(id) { - if (!confirm('Rechnung wirklich an QuickBooks Online senden?')) return; - - // UI Feedback (einfach, aber wirksam) - const btn = event.target; // Der geklickte Button - const originalText = btn.textContent; - btn.textContent = "⏳..."; - btn.disabled = true; - - try { - const response = await fetch(`/api/invoices/${id}/export`, { method: 'POST' }); - const result = await response.json(); - - if (response.ok) { - alert(`✅ Erfolg! QBO ID: ${result.qbo_id}, Rechnungsnr: ${result.qbo_doc_number}`); - // Liste neu laden um aktualisierte invoice_number anzuzeigen - loadInvoices(); - } else { - alert(`❌ Fehler: ${result.error}`); - } - } catch (error) { - console.error(error); - alert('Netzwerkfehler beim Export.'); - } finally { - btn.textContent = originalText; - btn.disabled = false; + if (window.invoiceView) { + window.invoiceView.viewPDF(id); + } else { + window.open(`/api/invoices/${id}/pdf`, '_blank'); } } + async function checkQboOverdue() { const btn = document.querySelector('button[onclick="checkQboOverdue()"]'); const resultDiv = document.getElementById('qbo-result'); @@ -1263,3 +1242,4 @@ async function importFromQBO() { btn.disabled = false; } } +window.openInvoiceModal = openInvoiceModal; \ No newline at end of file diff --git a/public/index.html b/public/index.html index af86a9b..d13275b 100644 --- a/public/index.html +++ b/public/index.html @@ -67,13 +67,16 @@