This commit is contained in:
2026-02-17 16:51:30 -06:00
parent 31f03b0d7c
commit 2d5be21bf2
6 changed files with 633 additions and 66 deletions

View File

@@ -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 => `
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${invoice.invoice_number}</td>
<td class="px-6 py-4 text-sm font-medium text-gray-900">${invoice.invoice_number}</td>
<td class="px-6 py-4 text-sm text-gray-500">${invoice.customer_name || 'N/A'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${formatDate(invoice.invoice_date)}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${invoice.terms}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 font-semibold">$${parseFloat(invoice.total).toFixed(2)}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium space-x-2">
<button onclick="viewInvoicePDF(${invoice.id})" class="text-green-600 hover:text-green-900">PDF</button>
<button onclick="exportToQBO(${invoice.id})" class="text-orange-600 hover:text-orange-900" title="Export to QuickBooks">
QBO Export
</button>
<button onclick="editInvoice(${invoice.id})" class="text-blue-600 hover:text-blue-900">Edit</button>
<button onclick="deleteInvoice(${invoice.id})" class="text-red-600 hover:text-red-900">Delete</button>
</td>
<td class="px-6 py-4 text-sm text-gray-500">${formatDate(invoice.invoice_date)}</td>
<td class="px-6 py-4 text-sm text-gray-500">${invoice.terms}</td>
<td class="px-6 py-4 text-sm font-semibold">$${parseFloat(invoice.total).toFixed(2)}</td>
<td class="px-6 py-4 text-sm">Loading module...</td>
</tr>
`).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;