/** * VOLLSTÄNDIGER NEU-IMPORT: Niki Kredit via API * Keine externen Abhängigkeiten - direkter HTTP-Call */ const http = require('http'); const API_BASE = 'http://localhost:3001'; // EXTRahierte Daten aus der Excel-Analyse // Format: [datum, abgezahlt, neue_kosten, fuer_was] const EXCEL_DATA = [ ['2024-04-01', 500, null, null], ['2024-05-01', 500, null, null], ['2024-06-01', 150, 90, 'Kameras'], ['2024-07-01', 450, 45, 'Kameras'], ['2024-08-01', 500, null, null], ['2024-09-01', 300, null, null], ['2024-10-01', 300, 110, 'Videorekorder + Zubehör'], ['2025-02-01', 200, null, null], ['2025-06-01', 500, 260, 'Handyvertag'] ]; // Hilfsfunktion für API-Calls function apiCall(method, endpoint, data = null) { return new Promise((resolve, reject) => { const options = { hostname: 'localhost', port: 3001, path: `/api${endpoint}`, method: method, headers: { 'Content-Type': 'application/json' } }; const req = http.request(options, (res) => { let responseData = ''; res.on('data', (chunk) => responseData += chunk); res.on('end', () => { try { const parsed = JSON.parse(responseData); resolve(parsed); } catch (e) { resolve(responseData); } }); }); req.on('error', reject); if (data) req.write(JSON.stringify(data)); req.end(); }); } async function main() { console.log('='.repeat(60)); console.log('NIKI KREDIT - VOLLSTÄNDIGER NEU-IMPORT'); console.log('='.repeat(60)); console.log('\n' + '='.repeat(60)); console.log('SCHRITT 1: Alten Kredit "Niki" löschen'); console.log('='.repeat(60)); // Alle Kredite holen let kredite; try { kredite = await apiCall('GET', '/kredite'); } catch (err) { console.error('Fehler beim Abrufen der Kredite:', err.message); console.log('Stelle sicher, dass das Backend läuft (docker-compose up -d)'); process.exit(1); } const nikiKredite = kredite.filter(k => k.name?.toLowerCase().includes('niki')); for (const kredit of nikiKredite) { console.log(`Lösche Kredit: ${kredit.name} (${kredit.id})`); try { await apiCall('DELETE', `/kredite/${kredit.id}`); console.log(' -> Gelöscht'); } catch (err) { console.log(' -> Fehler beim Löschen:', err.message); } } if (nikiKredite.length === 0) { console.log('Kein Kredit "Niki" gefunden'); } console.log('\n' + '='.repeat(60)); console.log('SCHRITT 2: Excel-Daten verarbeiten'); console.log('='.repeat(60)); // Extrahiere Zahlungen const zahlungen = []; for (const row of EXCEL_DATA) { const [datum, abgezahlt, neueKosten, fuerWas] = row; // Zahlung (Abgezahlt > 0) if (abgezahlt && abgezahlt > 0) { zahlungen.push({ datum: datum, typ: 'zahlung', betrag: abgezahlt, notiz: fuerWas || 'Rate gezahlt' }); } // Neue Kosten (negative Auslage) if (neueKosten && neueKosten > 0) { zahlungen.push({ datum: datum, typ: 'auslage', betrag: -neueKosten, notiz: fuerWas || 'Neue Kosten' }); } } console.log(`Gefunden:`); console.log(`- ${zahlungen.filter(z => z.typ === 'zahlung').length} Zahlungen`); console.log(`- ${zahlungen.filter(z => z.typ === 'auslage').length} Auslagen`); console.log('\nAlle Transaktionen:'); for (const z of zahlungen) { console.log(` ${z.datum} | ${z.typ.padEnd(10)} | ${z.betrag.toFixed(2).padStart(8)} € | ${z.notiz}`); } const summeZahlungen = zahlungen .filter(z => z.typ === 'zahlung') .reduce((sum, z) => sum + z.betrag, 0); const summeAuslagen = zahlungen .filter(z => z.typ === 'auslage') .reduce((sum, z) => sum + z.betrag, 0); console.log('\n' + '='.repeat(60)); console.log('SCHRITT 3: Neuen Kredit anlegen'); console.log('='.repeat(60)); const kreditData = { name: 'Niki Schulden', kreditgeber: 'Niki', person: 'Niki', ursprungsschuld: 7000, restschuld: 7000 - summeZahlungen + Math.abs(summeAuslagen), monatsrate: 500, zinssatz: 10, start_datum: '2023-07-01', richtung: 'eingehend', status: 'aktiv', notizen: 'Importiert aus Excel (Schulden Niki.xlsx)' }; console.log('Kredit-Daten:'); console.log(` Name: ${kreditData.name}`); console.log(` Ursprungsschuld: ${kreditData.ursprungsschuld} €`); console.log(` Restschuld nach Import: ${kreditData.restschuld.toFixed(2)} €`); console.log(` Zinssatz: ${kreditData.zinssatz}%`); console.log(` Start: ${kreditData.start_datum}`); console.log(` Richtung: ${kreditData.richtung}`); console.log(` Summe Zahlungen: ${summeZahlungen.toFixed(2)} €`); console.log(` Summe Auslagen: ${summeAuslagen.toFixed(2)} €`); let neuerKredit; try { neuerKredit = await apiCall('POST', '/kredite', kreditData); console.log(`\n✅ Kredit angelegt mit ID: ${neuerKredit.id}`); } catch (err) { console.error('\n❌ Fehler beim Anlegen des Kredits:', err.message); process.exit(1); } console.log('\n' + '='.repeat(60)); console.log('SCHRITT 4: Zahlungen importieren'); console.log('='.repeat(60)); for (const z of zahlungen) { try { await apiCall('POST', `/kredite/${neuerKredit.id}/zahlungen`, { datum: z.datum, betrag: z.betrag, typ: z.typ, notizen: z.notiz }); console.log(` ✅ ${z.datum} | ${z.typ.padEnd(10)} | ${z.betrag.toFixed(2).padStart(8)} € | ${z.notiz}`); } catch (err) { console.log(` ❌ ${z.datum} | FEHLER: ${err.message}`); } } console.log('\n' + '='.repeat(60)); console.log('SCHRITT 5: Verifikation'); console.log('='.repeat(60)); // Kredit prüfen let alleKredite; try { alleKredite = await apiCall('GET', '/kredite'); } catch (err) { console.error('Fehler beim Abrufen:', err.message); process.exit(1); } const nikiKredit = alleKredite.find(k => k.id === neuerKredit.id); if (!nikiKredit) { console.log('❌ Kredit nicht gefunden!'); process.exit(1); } console.log('\nKredit in DB:'); console.log(` ID: ${nikiKredit.id}`); console.log(` Name: ${nikiKredit.name}`); console.log(` Ursprungsschuld: ${parseFloat(nikiKredit.ursprungsschuld).toFixed(2)} €`); console.log(` Restschuld: ${parseFloat(nikiKredit.restschuld).toFixed(2)} €`); console.log(` Zinssatz: ${nikiKredit.zinssatz}%`); console.log(` Richtung: ${nikiKredit.richtung}`); // Zahlungen prüfen let zahlungenDB; try { zahlungenDB = await apiCall('GET', `/kredite/${neuerKredit.id}/zahlungen`); } catch (err) { console.log('Zahlungen-Endpoint nicht verfügbar (kann normal sein)'); zahlungenDB = []; } console.log(`\nZahlungen in DB: ${zahlungenDB.length}`); let sumZahlungenDB = 0; let sumAuslagenDB = 0; for (const z of zahlungenDB) { const betrag = parseFloat(z.betrag); const typ = z.typ || 'zahlung'; console.log(` ${z.datum} | ${typ.padEnd(10)} | ${betrag.toFixed(2).padStart(8)} € | ${z.notizen || ''}`); if (typ === 'zahlung') sumZahlungenDB += betrag; if (typ === 'auslage') sumAuslagenDB += betrag; } console.log('\n' + '='.repeat(60)); console.log('SUMMEN-VERGLEICH'); console.log('='.repeat(60)); console.log(` Excel Zahlungen: ${summeZahlungen.toFixed(2).padStart(8)} €`); console.log(` DB Zahlungen: ${sumZahlungenDB.toFixed(2).padStart(8)} €`); console.log(` Excel Auslagen: ${summeAuslagen.toFixed(2).padStart(8)} €`); console.log(` DB Auslagen: ${sumAuslagenDB.toFixed(2).padStart(8)} €`); const zahlungDiff = Math.abs(summeZahlungen - sumZahlungenDB); const auslageDiff = Math.abs(summeAuslagen - sumAuslagenDB); if (zahlungDiff < 0.01 && auslageDiff < 0.01) { console.log('\n✅ VERIFIKATION ERFOLGREICH: Alle Daten stimmen überein!'); console.log(` - ${zahlungenDB.length} Zahlungen korrekt importiert`); console.log(` - Restschuld korrekt berechnet`); console.log(` - Verlauf ist abrufbar`); } else { console.log('\n❌ WARNUNG: Unterschiede gefunden!'); if (zahlungDiff >= 0.01) console.log(` Zahlungsdifferenz: ${zahlungDiff.toFixed(2)} €`); if (auslageDiff >= 0.01) console.log(` Auslagendifferenz: ${auslageDiff.toFixed(2)} €`); } console.log('\n' + '='.repeat(60)); console.log('IMPORT ABGESCHLOSSEN'); console.log('='.repeat(60)); console.log(`✅ Kredit 'Niki Schulden' ist jetzt korrekt in der Datenbank.`); console.log(`✅ Alle Zahlungen und Auslagen sind importiert.`); console.log(`✅ Kann als Template für Kerstin verwendet werden.`); } main().catch(err => { console.error('Fehler:', err); process.exit(1); });