update sync endpoint

This commit is contained in:
Andreas Knuth 2026-02-20 12:16:34 -06:00
parent 4e6429e9ac
commit c44fc7f63e
1 changed files with 34 additions and 32 deletions

View File

@ -2062,13 +2062,13 @@ app.get('/api/qbo/labor-rate', async (req, res) => {
app.post('/api/qbo/sync-payments', async (req, res) => {
const dbClient = await pool.connect();
try {
// Alle lokalen Invoices die in QBO sind aber noch nicht voll bezahlt
// Alle lokalen Invoices die in QBO sind und noch aktualisiert werden könnten
// Auch bereits bezahlte prüfen um payment_status zu korrigieren (Paid↔Deposited)
const openResult = await dbClient.query(`
SELECT i.id, i.qbo_id, i.invoice_number, i.total, i.paid_date, i.payment_status,
COALESCE((SELECT SUM(pi.amount) FROM payment_invoices pi WHERE pi.invoice_id = i.id), 0) as local_paid
FROM invoices i
WHERE i.qbo_id IS NOT NULL
AND (i.paid_date IS NULL OR i.payment_status IS NULL OR i.payment_status != 'Deposited')
`);
const openInvoices = openResult.rows;
@ -2119,9 +2119,8 @@ app.post('/api/qbo/sync-payments', async (req, res) => {
// Prüfe ob in QBO bezahlt/teilweise bezahlt
if (qboBalance === 0 && qboTotal > 0) {
// Voll bezahlt in QBO
// Prüfe ob "Deposited" — DepositToAccountRef != Undeposited Funds (221)
let status = 'Paid';
const UNDEPOSITED_FUNDS_ID = '221';
let status = 'Paid';
if (qboInv.LinkedTxn) {
for (const txn of qboInv.LinkedTxn) {
@ -2142,27 +2141,27 @@ app.post('/api/qbo/sync-payments', async (req, res) => {
}
}
// paid_date setzen falls noch nicht
if (!localInv.paid_date) {
// Update wenn sich etwas geändert hat
const needsUpdate = !localInv.paid_date || localInv.payment_status !== status;
if (needsUpdate) {
await dbClient.query(
'UPDATE invoices SET paid_date = CURRENT_DATE, payment_status = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2',
[status, localInv.id]
);
} else {
await dbClient.query(
'UPDATE invoices SET payment_status = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2',
`UPDATE invoices SET
paid_date = COALESCE(paid_date, CURRENT_DATE),
payment_status = $1,
updated_at = CURRENT_TIMESTAMP
WHERE id = $2`,
[status, localInv.id]
);
updated++;
console.log(` ✅ #${localInv.invoice_number}: ${status}`);
}
// Fehlenden lokalen Payment-Eintrag erstellen wenn nötig
const qboPaid = qboTotal;
if (qboPaid > localPaid) {
const diff = qboPaid - localPaid;
// Einen generischen Payment-Eintrag für den Differenzbetrag
// Fehlenden Payment-Eintrag NUR erstellen wenn Differenz > $0.01
const diff = qboTotal - localPaid;
if (diff > 0.01) {
const payResult = await dbClient.query(
`INSERT INTO payments (payment_date, payment_method, total_amount, customer_id, notes, created_at)
VALUES (CURRENT_DATE, 'Synced from QBO', $1, (SELECT customer_id FROM invoices WHERE id = $2), 'Auto-synced from QBO', CURRENT_TIMESTAMP)
VALUES (CURRENT_DATE, 'Synced from QBO', $1, (SELECT customer_id FROM invoices WHERE id = $2), 'Synced from QBO', CURRENT_TIMESTAMP)
RETURNING id`,
[diff, localInv.id]
);
@ -2171,19 +2170,28 @@ app.post('/api/qbo/sync-payments', async (req, res) => {
[payResult.rows[0].id, localInv.id, diff]
);
newPayments++;
console.log(` 💰 #${localInv.invoice_number}: +$${diff.toFixed(2)} payment synced`);
}
console.log(` ✅ #${localInv.invoice_number}: ${status} (QBO Balance: $${qboBalance})`);
updated++;
} else if (qboBalance > 0 && qboBalance < qboTotal) {
// Teilweise bezahlt in QBO
const qboPaid = qboTotal - qboBalance;
if (qboPaid > localPaid) {
const diff = qboPaid - localPaid;
const diff = qboPaid - localPaid;
const needsUpdate = localInv.payment_status !== 'Partial';
if (needsUpdate) {
await dbClient.query(
'UPDATE invoices SET payment_status = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2',
['Partial', localInv.id]
);
updated++;
}
// Payment nur erstellen wenn echte Differenz > $0.01
if (diff > 0.01) {
const payResult = await dbClient.query(
`INSERT INTO payments (payment_date, payment_method, total_amount, customer_id, notes, created_at)
VALUES (CURRENT_DATE, 'Synced from QBO', $1, (SELECT customer_id FROM invoices WHERE id = $2), 'Auto-synced partial from QBO', CURRENT_TIMESTAMP)
VALUES (CURRENT_DATE, 'Synced from QBO', $1, (SELECT customer_id FROM invoices WHERE id = $2), 'Synced from QBO', CURRENT_TIMESTAMP)
RETURNING id`,
[diff, localInv.id]
);
@ -2191,15 +2199,8 @@ app.post('/api/qbo/sync-payments', async (req, res) => {
'INSERT INTO payment_invoices (payment_id, invoice_id, amount) VALUES ($1, $2, $3)',
[payResult.rows[0].id, localInv.id, diff]
);
await dbClient.query(
'UPDATE invoices SET payment_status = $1, updated_at = CURRENT_TIMESTAMP WHERE id = $2',
['Partial', localInv.id]
);
console.log(` 📎 #${localInv.invoice_number}: Partial ($${qboPaid.toFixed(2)} of $${qboTotal.toFixed(2)})`);
updated++;
newPayments++;
console.log(` 📎 #${localInv.invoice_number}: Partial +$${diff.toFixed(2)} ($${qboPaid.toFixed(2)} of $${qboTotal.toFixed(2)})`);
}
}
}
@ -2241,6 +2242,7 @@ app.get('/api/qbo/last-sync', async (req, res) => {
});
// Start server and browser
async function startServer() {
await initBrowser();