From 451f6f66c1ea60a30ddf16f35168ae02537e6c40 Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Thu, 19 Feb 2026 22:18:15 -0600 Subject: [PATCH] Korrektur zur Nummer ermittlung --- server.js | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/server.js b/server.js index e18b532..e2cd58a 100644 --- a/server.js +++ b/server.js @@ -1170,37 +1170,43 @@ app.post('/api/invoices/:id/export', async (req, res) => { ? 'https://quickbooks.api.intuit.com' : 'https://sandbox-quickbooks.api.intuit.com'; + + // ------------------------------------------- // --- SCHRITT 3a: NÄCHSTE NUMMER ERMITTELN --- - console.log("🔍 Frage QBO nach der letzten Rechnungsnummer..."); - - // Wir suchen die ZULETZT ERSTELLTE Rechnung - const lastNumQuery = "SELECT DocNumber FROM Invoice ORDERBY MetaData.CreateTime DESC MAXRESULTS 1"; + console.log("🔍 Frage QBO nach der höchsten Rechnungsnummer..."); + + // Alle Rechnungen laden (nur DocNumber Feld), nach DocNumber absteigend + // QBO unterstützt leider kein MAX() oder CAST, daher holen wir die letzten 100 + // und ermitteln die höchste rein numerische Nummer clientseitig. + const numQuery = "SELECT DocNumber FROM Invoice ORDERBY DocNumber DESC MAXRESULTS 100"; const lastNumResponse = await makeQboApiCall({ - url: `${baseUrl}/v3/company/${companyId}/query?query=${encodeURI(lastNumQuery)}`, + url: `${baseUrl}/v3/company/${companyId}/query?query=${encodeURI(numQuery)}`, method: 'GET' }); - + const lastNumData = lastNumResponse.getJson ? lastNumResponse.getJson() : lastNumResponse.json; let nextDocNumber = null; - if (lastNumData.QueryResponse && lastNumData.QueryResponse.Invoice && lastNumData.QueryResponse.Invoice.length > 0) { - const lastDocNumberStr = lastNumData.QueryResponse.Invoice[0].DocNumber; - // Versuchen, die Nummer zu parsen (Entfernt Buchstaben, behält Zahlen) - const lastNum = parseInt(lastDocNumberStr.replace(/[^0-9]/g, ''), 10); - - if (!isNaN(lastNum)) { - nextDocNumber = (lastNum + 1).toString(); - console.log(`✅ Letzte Nummer war ${lastDocNumberStr}. Neue Nummer wird: ${nextDocNumber}`); + if (lastNumData.QueryResponse?.Invoice?.length > 0) { + // Nur rein numerische DocNumbers betrachten (keine "110444-A" etc.) + const numericDocs = lastNumData.QueryResponse.Invoice + .map(inv => inv.DocNumber) + .filter(dn => /^\d+$/.test(dn)) + .map(dn => parseInt(dn, 10)) + .sort((a, b) => b - a); // Absteigend + + if (numericDocs.length > 0) { + const highest = numericDocs[0]; + nextDocNumber = (highest + 1).toString(); + console.log(`✅ Höchste numerische Nummer: ${highest}. Neue Nummer: ${nextDocNumber}`); } } - // Fallback: Wenn QBO leer ist oder Parsing fehlschlägt, nimm die lokale Nummer + // Fallback if (!nextDocNumber) { console.log("⚠️ Konnte keine Nummer aus QBO ermitteln. Verwende lokale Nummer."); nextDocNumber = invoice.invoice_number; } - // ------------------------------------------- - // 4. QBO JSON bauen const lineItems = items.map(item => {