This commit is contained in:
2026-02-19 22:02:22 -06:00
parent 49aeff8cb6
commit 410faee6d1
4 changed files with 142 additions and 149 deletions

View File

@@ -167,13 +167,14 @@ function renderInvoiceRow(invoice) {
// --- BUTTONS (Edit | QBO | PDF HTML | Payment | Del) ---
const editBtn = `<button onclick="window.invoiceView.edit(${invoice.id})" class="text-blue-600 hover:text-blue-900">Edit</button>`;
// QBO Button — nur aktiv wenn Kunde eine qbo_id hat
// QBO Button — Export oder Sync
const customerHasQbo = !!invoice.customer_qbo_id;
let qboBtn;
if (hasQbo) {
qboBtn = `<span class="text-gray-400 text-xs cursor-pointer" title="In QBO (ID: ${invoice.qbo_id}) — Click to reset" onclick="window.invoiceView.resetQbo(${invoice.id})">✓ QBO</span>`;
// Already in QBO — show sync button + reset option
qboBtn = `<button onclick="window.invoiceView.syncToQBO(${invoice.id})" class="text-purple-600 hover:text-purple-900" title="Sync changes to QBO (ID: ${invoice.qbo_id})">⟳ QBO Sync</button>`;
} else if (!customerHasQbo) {
qboBtn = `<span class="text-gray-300 text-xs cursor-not-allowed" title="Kunde muss erst nach QBO exportiert werden">QBO ⚠</span>`;
qboBtn = `<span class="text-gray-300 text-xs cursor-not-allowed" title="Customer must be exported to QBO first">QBO ⚠</span>`;
} else {
qboBtn = `<button onclick="window.invoiceView.exportToQBO(${invoice.id})" class="text-orange-600 hover:text-orange-900" title="Export to QuickBooks">QBO Export</button>`;
}
@@ -349,6 +350,18 @@ export async function exportToQBO(id) {
finally { if (typeof hideSpinner === 'function') hideSpinner(); }
}
export async function syncToQBO(id) {
if (!confirm('Sync changes to QuickBooks Online?')) return;
if (typeof showSpinner === 'function') showSpinner('Syncing invoice to QBO...');
try {
const r = await fetch(`/api/invoices/${id}/update-qbo`, { method: 'POST' });
const d = await r.json();
if (r.ok) { alert(`${d.message}`); loadInvoices(); }
else alert(`${d.error}`);
} catch (e) { alert('Network error.'); }
finally { if (typeof hideSpinner === 'function') hideSpinner(); }
}
export async function resetQbo(id) {
if (!confirm('QBO-Verknüpfung zurücksetzen?\nRechnung muss zuerst in QBO gelöscht sein!')) return;
try {
@@ -385,6 +398,6 @@ export async function remove(id) {
// ============================================================
window.invoiceView = {
viewPDF, viewHTML, exportToQBO, resetQbo, markPaid, markUnpaid, edit, remove,
viewPDF, viewHTML, exportToQBO, syncToQBO, resetQbo, markPaid, markUnpaid, edit, remove,
loadInvoices, renderInvoiceView, setStatus
};