#!/usr/bin/env python3 """ KERSTIN KREDIT IMPORT - FINAL (Korrigiert) Direkter DB-Zugriff uber Docker """ import psycopg2 import pandas as pd from datetime import datetime print("="*60) print("KERSTIN IMPORT - FINAL (Korrigiert)") print("="*60) print("Startbetrag: 34.036,98 EUR") print("Startdatum: 01.01.2018") print("Zinssatz: 0%") print("="*60) # Verbindung zur PostgreSQL in Docker conn = psycopg2.connect( host="localhost", port=5432, database="buchhaltung", user="postgres", password="postgres" ) cursor = conn.cursor() print("\n" + "="*60) print("SCHRITT 1: Alten Kredit 'Kerstin' loeschen") print("="*60) cursor.execute("SELECT id, name FROM kredite WHERE name ILIKE '%kerstin%'") kerstin_kredite = cursor.fetchall() for kredit_id, name in kerstin_kredite: print(f"Loesche 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" -> Geloescht") if not kerstin_kredite: print("Kein Kredit 'Kerstin' gefunden") conn.commit() print("\n" + "="*60) print("SCHRITT 2: Excel Tabelle2 laden (Zahlungen/Auslagen)") print("="*60) # Excel-Datei lesen - Tabelle2 df = pd.read_excel('Schulden Kerstin.xlsx', sheet_name='Tabelle2', header=0) print(f"Excel Tabelle2 hat {len(df)} Zeilen") print(f"Spalten: {df.columns.tolist()}") # Extrahiere Zahlungen - NUR mit gueltigem Datum ab 01.01.2018 zahlungen = [] uebersprungen = 0 for idx, row in df.iterrows(): datum = row.iloc[0] if len(row) > 0 else None beschreibung = row.iloc[1] if len(row) > 1 else None betrag = row.iloc[2] if len(row) > 2 else None if pd.isna(betrag): continue try: betrag_val = float(betrag) except: continue # Datum konvertieren datum_str = None if isinstance(datum, pd.Timestamp): datum_str = datum.strftime('%Y-%m-%d') elif isinstance(datum, datetime): datum_str = datum.strftime('%Y-%m-%d') elif isinstance(datum, str): # Versuche verschiedene Datumsformate datum_clean = datum.strip() # Format: DD.MM.YYYY parts = datum_clean.split('.') if len(parts) == 3: try: day, month, year = parts datum_str = f"{year}-{month.zfill(2)}-{day.zfill(2)}" except: datum_str = None elif len(datum_clean) >= 10 and datum_clean[4] == '-': # Bereits im Format YYYY-MM-DD datum_str = datum_clean[:10] # Ueberspringe Eintraege OHNE gueltiges Datum if not datum_str: uebersprungen += 1 continue # Ueberspringe Eintraege VOR 01.01.2018 (bereits im Startbetrag enthalten) if datum_str < '2018-01-01': uebersprungen += 1 continue # Typ bestimmen if betrag_val < 0: zahlungen.append({ 'datum': datum_str, 'typ': 'monatsrate', 'betrag': abs(betrag_val), 'roh_betrag': betrag_val, 'notiz': str(beschreibung) if not pd.isna(beschreibung) else "Rate gezahlt" }) else: zahlungen.append({ 'datum': datum_str, 'typ': 'auslage', 'betrag': betrag_val, 'roh_betrag': betrag_val, 'notiz': str(beschreibung) if not pd.isna(beschreibung) else "Auslage" }) print(f"\nGefunden: {len(zahlungen)} Zahlungen/Auslagen (ab 01.01.2018)") print(f"Uebersprungen: {uebersprungen} Eintraege (ohne Datum oder vor 2018)") for i, z in enumerate(zahlungen[:20]): print(f" {z['datum']} | {z['typ']:12} | {z['roh_betrag']:10.2f} EUR | {str(z['notiz'])[:35]}") if len(zahlungen) > 20: print(f" ... und {len(zahlungen)-20} 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 (ab 01.01.2018):") print(f" Zahlungen/Raten (negativ): {summe_raten:.2f} EUR") print(f" Auslagen (positiv): {summe_auslagen:.2f} EUR") print(f" Netto gezahlt: {summe_raten + summe_auslagen:.2f} EUR") print("\n" + "="*60) print("SCHRITT 3: Kredit anlegen") print("="*60) # Feste Werte aus Update kredit_name = "Kerstin Schulden" start_betrag = 34036.98 zinssatz = 0.0 start_datum = '2018-01-01' monatsrate = 350.0 richtung = 'ausgehend' # Restschuld berechnen: Start + Raten (negativ) + Auslagen (positiv) restschuld = start_betrag + summe_raten + summe_auslagen print(f"Kredit: {kredit_name}") print(f" Startbetrag: {start_betrag:.2f} EUR") print(f" Zinssatz: {zinssatz}%") print(f" Start: {start_datum}") print(f" Rate: {monatsrate} EUR/Monat") print(f" Richtung: {richtung}") print(f" Berechnete Restschuld: {restschuld:.2f} EUR") 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", start_betrag, restschuld, monatsrate, zinssatz, start_datum, "Importiert aus Excel - Start 01.01.2018, 0% Zinsen, Startbetrag 34.036,98 EUR", richtung, "aktiv" if restschuld > 0 else "abgeschlossen" )) kredit_id = cursor.fetchone()[0] conn.commit() print(f"\n[OK] Kredit angelegt mit ID: {kredit_id}") print("\n" + "="*60) print("SCHRITT 4: Zahlungen importieren") print("="*60) imported_count = 0 for z in zahlungen: cursor.execute(""" INSERT INTO kredit_zahlungen (kredit_id, datum, betrag, typ, notiz) VALUES (%s, %s, %s, %s, %s) """, ( kredit_id, z['datum'], z['betrag'], z['typ'], str(z['notiz'])[:200] if z['notiz'] else "" )) imported_count += 1 print(f" {z['datum']} | {z['typ']:12} | {z['roh_betrag']:10.2f} EUR | {str(z['notiz'])[:40]}") conn.commit() print(f"\n[OK] {imported_count} Zahlungen importiert") print("\n" + "="*60) print("SCHRITT 5: Verifikation") print("="*60) 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" Startbetrag: {float(kredit[4]):.2f} EUR") print(f" Restschuld: {float(kredit[5]):.2f} EUR") print(f" Zinssatz: {float(kredit[7]):.2f}%") print(f" Richtung: {kredit[12]}") print(f" Status: {kredit[13]}") 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 i, z in enumerate(imported_zahlungen[:15]): datum_str = str(z[2])[:10] if z[2] else '----------' betrag = float(z[3]) typ = z[4] notiz = str(z[5])[:40] if z[5] else '' print(f" {datum_str} | {typ:12} | {betrag:10.2f} EUR | {notiz}") if len(imported_zahlungen) > 15: print(f" ... und {len(imported_zahlungen)-15} weitere") 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 FROM kredit_zahlungen WHERE kredit_id = %s """, (kredit_id,)) result = cursor.fetchone() sum_raten_db = float(result[0]) sum_auslagen_db = float(result[1]) print(f"\nSummen:") print(f" Zahlungen/Raten: {sum_raten_db:.2f} EUR (Excel: {abs(summe_raten):.2f} EUR)") print(f" Auslagen: {sum_auslagen_db:.2f} EUR (Excel: {summe_auslagen:.2f} EUR)") expected_restschuld = start_betrag - sum_raten_db + sum_auslagen_db print(f"\nRestschuld-Check:") print(f" Erwartet: {expected_restschuld:.2f} EUR") print(f" In DB: {float(kredit[5]):.2f} EUR") if abs(expected_restschuld - float(kredit[5])) < 0.01 and \ abs(abs(summe_raten) - sum_raten_db) < 0.01 and \ abs(summe_auslagen - sum_auslagen_db) < 0.01: print(f"\n[OK] VERIFIKATION ERFOLGREICH!") else: print(f"\n[Hinweis] Differenzen erkannt - bitte pruefen") cursor.close() conn.close() print("\n" + "="*60) print("IMPORT ABGESCHLOSSEN") print("="*60) print(f"Kredit '{kredit_name}' ist jetzt in der Datenbank.") print(f"Dashboard zeigt 'Meine Schulden' (rot) mit {restschuld:.2f} EUR Restschuld.")