fix doc numer increase

This commit is contained in:
2026-07-22 10:51:34 -05:00
parent 18fec009a4
commit 248affc0f9
2 changed files with 40 additions and 24 deletions

View File

@@ -197,8 +197,10 @@ async function makeQboApiCall(requestOptions) {
await doRefresh(); await doRefresh();
return await client.makeApiCall(requestOptions); return await client.makeApiCall(requestOptions);
} }
throw new Error(`QBO API Error ${qboFault.code}: ${qboFault.message}${qboFault.detail ? ' - ' + qboFault.detail : ''}`); const err = new Error(`QBO API Error ${qboFault.code}: ${qboFault.message}${qboFault.detail ? ' - ' + qboFault.detail : ''}`);
} err.qboCode = qboFault.code;
err.qboFault = qboFault;
throw err; }
// ── Kein saveTokens() hier Token hat sich nicht geändert ── // ── Kein saveTokens() hier Token hat sich nicht geändert ──
return response; return response;

View File

@@ -82,36 +82,50 @@ async function exportInvoiceToQbo(invoiceId, dbClient) { // <-- Nutzt jetzt dbCl
}; };
let qboInvoice = null; let qboInvoice = null;
const MAX_RETRIES = 20;
for (let attempt = 0; attempt < 5; attempt++) { for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
console.log(`📤 QBO Export Invoice (DocNumber: ${qboPayload.DocNumber})...`); console.log(`📤 QBO Export Invoice (DocNumber: ${qboPayload.DocNumber})...`);
const response = await makeQboApiCall({ try {
url: `${baseUrl}/v3/company/${companyId}/invoice`, const response = await makeQboApiCall({
method: 'POST', url: `${baseUrl}/v3/company/${companyId}/invoice`,
headers: { 'Content-Type': 'application/json' }, method: 'POST',
body: JSON.stringify(qboPayload) headers: { 'Content-Type': 'application/json' },
}); body: JSON.stringify(qboPayload) // innerhalb der Schleife → aktuelle DocNumber
});
const data = response.getJson ? response.getJson() : response.json; const data = response.getJson ? response.getJson() : response.json;
if (data.Fault?.Error?.[0]?.code === '6140') { // Fault-Fallback, falls makeQboApiCall doch mal nicht wirft
console.log(` ⚠️ DocNumber ${qboPayload.DocNumber} exists, retrying...`); const fault = extractQboFault(data);
qboPayload.DocNumber = (parseInt(qboPayload.DocNumber) + 1).toString(); if (fault) {
continue; const err = new Error(`QBO API Error ${fault.code}: ${fault.message}`);
err.qboCode = fault.code;
throw err;
}
qboInvoice = data.Invoice || data;
if (qboInvoice.Id) break;
throw new Error("QBO returned no ID: " + JSON.stringify(data).substring(0, 500));
} catch (err) {
if (err.qboCode === '6140') {
const oldNum = qboPayload.DocNumber;
qboPayload.DocNumber = (parseInt(oldNum) + 1).toString();
console.log(` ⚠️ DocNumber ${oldNum} belegt (evtl. voided), versuche ${qboPayload.DocNumber}...`);
qboInvoice = null;
continue;
}
console.error(`❌ QBO Export Fault:`, err.message);
throw err;
} }
if (data.Fault) {
const errMsg = data.Fault.Error?.map(e => `${e.code}: ${e.Message} - ${e.Detail}`).join('; ') || JSON.stringify(data.Fault);
console.error(`❌ QBO Export Fault:`, errMsg);
throw new Error('QBO export failed: ' + errMsg);
}
qboInvoice = data.Invoice || data;
if (qboInvoice.Id) break;
throw new Error("QBO returned no ID: " + JSON.stringify(data).substring(0, 500));
} }
if (!qboInvoice?.Id) throw new Error('Could not find free DocNumber after 5 attempts.'); if (!qboInvoice?.Id) {
throw new Error(`Keine freie DocNumber nach ${MAX_RETRIES} Versuchen (ab ${nextDocNumber}).`);
}
await dbClient.query( await dbClient.query(
'UPDATE invoices SET qbo_id = $1, qbo_sync_token = $2, qbo_doc_number = $3, invoice_number = $4 WHERE id = $5', 'UPDATE invoices SET qbo_id = $1, qbo_sync_token = $2, qbo_doc_number = $3, invoice_number = $4 WHERE id = $5',