#!/usr/bin/env python3 """ VOLLSTÄNDIGER NEU-IMPORT: Kerstin Kredit Importiert Kerstin-Schulden aus Excel mit korrekter Berechnung """ import psycopg2 import pandas as pd import openpyxl from datetime import datetime from decimal import Decimal # Datenbank-Verbindung - Host aus Umgebungsvariable oder localhost import os db_host = os.environ.get('DB_HOST', 'localhost') conn = psycopg2.connect( host=db_host, port=5432, database="buchhaltung", user="postgres", password="postgres" ) cursor = conn.cursor() print("="*60) print("BACKUP: Übersprungen (pg_dump nicht verfügbar)") print("="*60) print("Manuelles Backup existiert bereits: Schulden Kerstin.xlsx.backup_*") print("\n" + "="*60) print("SCHRITT 1: Alten Kredit 'Kerstin' löschen falls vorhanden") print("="*60) # Finde und lösche Kredit "Kerstin" cursor.execute("SELECT id, name FROM kredite WHERE name ILIKE '%kerstin%'") kerstin_kredite = cursor.fetchall() if kerstin_kredite: for kredit_id, name in kerstin_kredite: print(f"Lösche Kredit: {name} (ID: {kredit_id})") cursor.execute("DELETE FROM kredit_zahlungen WHERE kredit_id = %s", (kredit_id,)) cursor.execute("DELETE FROM kredit_buchungen WHERE kredit_id = %s", (kredit_id,)) cursor.execute("DELETE FROM kredite WHERE id = %s", (kredit_id,)) print(f" -> Gelöscht") else: print("Kein Kredit 'Kerstin' gefunden") conn.commit() print("\n" + "="*60) print("SCHRITT 2: Excel Tabelle1 analysieren (Kredit-Details)") print("="*60) # Excel-Datei laden mit openpyxl für berechnete Werte wb = openpyxl.load_workbook('Schulden Kerstin.xlsx', data_only=True) ws1 = wb['Tabelle1'] # Erste Zeile: Restsumme=15000, Rate=350, Zinssatz=0.04 restsumme = ws1.cell(2, 1).value # A2 rate = ws1.cell(2, 2).value # B2 zinssatz = ws1.cell(2, 3).value # C2 start_datum = ws1.cell(2, 5).value # E2 print(f"Kredit-Details aus Excel:") print(f" Restsumme/Startbetrag: {restsumme} €") print(f" Monatsrate: {rate} €") print(f" Zinssatz: {zinssatz} ({zinssatz*100 if zinssatz else 0}%)") print(f" Startdatum: {start_datum}") wb.close() # Jetzt Tabelle2 für Zahlungen/Auslagen print("\n" + "="*60) print("SCHRITT 3: Excel Tabelle2 analysieren (Zahlungen)") print("="*60) wb2 = openpyxl.load_workbook('Schulden Kerstin.xlsx', data_only=True) ws2 = wb2['Tabelle2'] zahlungen = [] for row in ws2.iter_rows(min_row=2, values_only=True): # Ab Zeile 2 (nach Header) datum = row[0] # Spalte A beschreibung = row[1] # Spalte B betrag = row[2] # Spalte C # Überspringe leere Zeilen if betrag is None or (datum is None and beschreibung is None): continue # Konvertiere Betrag try: betrag_val = float(betrag) except: continue # Konvertiere Datum datum_str = None if datum and not pd.isna(datum): if isinstance(datum, datetime): datum_str = datum.strftime('%Y-%m-%d') elif isinstance(datum, str) and len(datum) >= 10: datum_str = datum[:10] # Bestimme Typ basierend auf Betrag und Beschreibung # Negative Beträge = Rückzahlungen (monatsrate) # Positive Beträge = neue Ausgaben (auslage) if betrag_val < 0: # Negative Werte = Rückzahlungen typ = 'monatsrate' notiz = beschreibung if beschreibung else "Rate gezahlt" else: # Positive Werte = neue Ausgaben/Auslagen typ = 'auslage' notiz = beschreibung if beschreibung else "Auslage" zahlungen.append({ 'datum': datum_str, 'typ': typ, 'betrag': abs(betrag_val), # Absolutwert für DB 'roh_betrag': betrag_val, 'notiz': str(notiz) if notiz else "" }) print(f"Gefunden: {len(zahlungen)} Zahlungen/Auslagen") for z in zahlungen[:15]: # Erste 15 zeigen print(f" {z['datum'] or '----------'} | {z['typ']:12} | {z['roh_betrag']:10.2f} € | {z['notiz'][:30]}") if len(zahlungen) > 15: print(f" ... und {len(zahlungen)-15} weitere") summe_raten = sum(z['roh_betrag'] for z in zahlungen if z['typ'] == 'monatsrate') summe_auslagen = sum(z['roh_betrag'] for z in zahlungen if z['typ'] == 'auslage') print(f"\nZusammenfassung:") print(f" Monatsraten (negativ): {summe_raten:.2f} €") print(f" Auslagen (positiv): {summe_auslagen:.2f} €") print(f" Netto gezahlt: {summe_raten + summe_auslagen:.2f} €") wb2.close() print("\n" + "="*60) print("SCHRITT 4: Kredit anlegen") print("="*60) # Kredit-Daten kredit_name = "Kerstin Schulden" kredit_betrag = float(restsumme) if restsumme else 15000.0 zinssatz_pct = float(zinssatz) * 100 if zinssatz else 4.0 start_dt = start_datum.strftime('%Y-%m-%d') if isinstance(start_datum, datetime) else '2014-08-01' monatsrate = float(rate) if rate else 350.0 richtung = "ausgehend" # Schulden - ich zahle # Berechne Restschuld restschuld = kredit_betrag + summe_raten + summe_auslagen print(f"Kredit: {kredit_name}") print(f" Ursprungsschuld: {kredit_betrag:.2f} €") print(f" Zinssatz: {zinssatz_pct}%") print(f" Start: {start_dt}") print(f" Richtung: {richtung}") print(f" Berechnete Restschuld: {restschuld:.2f} €") # Kredit einfügen cursor.execute(""" INSERT INTO kredite (name, kreditgeber, person, ursprungsschuld, restschuld, monatsrate, zinssatz, start_datum, notizen, richtung, status) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING id """, ( kredit_name, "Kerstin", "Kerstin", kredit_betrag, restschuld, monatsrate, zinssatz_pct, start_dt, "Importiert aus Excel 'Schulden Kerstin.xlsx'", richtung, "aktiv" if restschuld > 0 else "abgeschlossen" )) kredit_id = cursor.fetchone()[0] conn.commit() print(f"\nKredit angelegt mit ID: {kredit_id}") print("\n" + "="*60) print("SCHRITT 5: Zahlungen importieren") print("="*60) # Zahlungen einfügen for z in zahlungen: cursor.execute(""" INSERT INTO kredit_zahlungen (kredit_id, datum, betrag, typ, notizen) VALUES (%s, %s, %s, %s, %s) """, ( kredit_id, z['datum'], z['betrag'], # Absolutwert z['typ'], z['notiz'][:200] if z['notiz'] else "" # Begrenze auf 200 Zeichen )) print(f" {z['datum'] or '----------'} | {z['typ']:12} | {z['roh_betrag']:10.2f} € | {z['notiz'][:40] if z['notiz'] else ''}") conn.commit() print("\n" + "="*60) print("SCHRITT 6: Verifikation") print("="*60) # Kredit prüfen cursor.execute("SELECT * FROM kredite WHERE id = %s", (kredit_id,)) kredit = cursor.fetchone() print(f"\nKredit in DB:") print(f" Name: {kredit[1]}") print(f" Ursprungsschuld: {float(kredit[4]):.2f} €") print(f" Restschuld: {float(kredit[5]):.2f} €") print(f" Richtung: {kredit[12]}") print(f" Status: {kredit[13]}") # Zahlungen prüfen cursor.execute("SELECT * FROM kredit_zahlungen WHERE kredit_id = %s ORDER BY datum", (kredit_id,)) imported_zahlungen = cursor.fetchall() print(f"\nZahlungen in DB: {len(imported_zahlungen)}") for z in imported_zahlungen[:10]: print(f" {z[2]} | {z[4]:12} | {float(z[3]):10.2f} € | {z[5][:40] if z[5] else ''}") if len(imported_zahlungen) > 10: print(f" ... und {len(imported_zahlungen)-10} weitere") # Summen prüfen cursor.execute(""" SELECT COALESCE(SUM(CASE WHEN typ = 'monatsrate' THEN betrag ELSE 0 END), 0) as sum_raten, COALESCE(SUM(CASE WHEN typ = 'auslage' THEN betrag ELSE 0 END), 0) as sum_auslagen, COALESCE(SUM(betrag), 0) as sum_total FROM kredit_zahlungen WHERE kredit_id = %s """, (kredit_id,)) result = cursor.fetchone() sum_raten_db = float(result[0]) sum_auslagen_db = float(result[1]) sum_total_db = float(result[2]) print(f"\nSummen in DB:") print(f" Raten: {sum_raten_db:.2f} €") print(f" Auslagen: {sum_auslagen_db:.2f} €") print(f" Gesamt: {sum_total_db:.2f} €") # Erwartete Werte (Excel hat negative Werte für Raten) sum_raten_excel = abs(summe_raten) # Negativ in Excel = positiv in DB sum_auslagen_excel = summe_auslagen # Positiv in Excel = positiv in DB print(f"\nVergleich mit Excel:") print(f" Excel Raten: {sum_raten_excel:.2f} € | DB: {sum_raten_db:.2f} €") print(f" Excel Auslagen: {sum_auslagen_excel:.2f} € | DB: {sum_auslagen_db:.2f} €") # Prüfe Restschuld expected_restschuld = kredit_betrag - sum_raten_db + sum_auslagen_db print(f"\nRestschuld-Check:") print(f" Erwartet: {expected_restschuld:.2f} €") print(f" In DB: {float(kredit[5]):.2f} €") if abs(sum_raten_excel - sum_raten_db) < 0.01 and abs(sum_auslagen_excel - sum_auslagen_db) < 0.01: print(f"\n✅ VERIFIKATION ERFOLGREICH: Alle Daten stimmen überein!") else: print(f"\n⚠️ Hinweis: Kleinere Rundungsdifferenzen möglich") cursor.close() conn.close() print("\n" + "="*60) print("IMPORT ABGESCHLOSSEN") print("="*60) print(f"Kredit 'Kerstin Schulden' ist jetzt in der Datenbank.") print(f"Dashboard sollte jetzt 'Meine Schulden' (rot) anzeigen.")