#!/usr/bin/env python3 """ KERSTIN KREDIT IMPORT - FINAL v3 Importiert ALLE Eintraege aus Tabelle2 (auch ohne explizites Datum) """ import psycopg2 import pandas as pd from datetime import datetime import re print("="*60) print("KERSTIN IMPORT - FINAL v3") 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 ALLE gueltigen Eintraege (mit Betrag) zahlungen = [] uebersprungen = 0 for idx, row in df.iterrows(): datum_raw = 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 # Ueberspringe leere Zeilen if pd.isna(betrag): uebersprungen += 1 continue try: betrag_val = float(betrag) except: uebersprungen += 1 continue # Ueberspringe Summenzeilen ("Gesammtbetrag" etc.) if isinstance(datum_raw, str) and 'gesammt' in datum_raw.lower(): uebersprungen += 1 continue # Datum konvertieren datum_str = None if isinstance(datum_raw, pd.Timestamp): datum_str = datum_raw.strftime('%Y-%m-%d') elif isinstance(datum_raw, datetime): datum_str = datum_raw.strftime('%Y-%m-%d') elif isinstance(datum_raw, str): datum_clean = datum_raw.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] == '-': datum_str = datum_clean[:10] # Beschreibung extrahieren notiz = str(beschreibung) if not pd.isna(beschreibung) else "" if not notiz or notiz == "nan": notiz = "Auslage" if betrag_val > 0 else "Rate gezahlt" # Typ bestimmen if betrag_val < 0: zahlungen.append({ 'datum': datum_str, 'typ': 'monatsrate', 'betrag': abs(betrag_val), 'roh_betrag': betrag_val, 'notiz': notiz }) else: zahlungen.append({ 'datum': datum_str, 'typ': 'auslage', 'betrag': betrag_val, 'roh_betrag': betrag_val, 'notiz': notiz }) print(f"\nGefunden: {len(zahlungen)} Zahlungen/Auslagen") print(f"Uebersprungen: {uebersprungen} Eintraege (leer oder Summenzeilen)") print(f"\nErste 20 Eintraege:") for i, z in enumerate(zahlungen[:20]): datum_disp = z['datum'] if z['datum'] else '----------' print(f" {datum_disp} | {z['typ']:12} | {z['roh_betrag']:10.2f} EUR | {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:") 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 imported_with_date = 0 imported_without_date = 0 for z in zahlungen: # Wenn kein Datum, verwende Startdatum (01.01.2018) datum_for_db = z['datum'] if z['datum'] else start_datum cursor.execute(""" INSERT INTO kredit_zahlungen (kredit_id, datum, betrag, typ, notiz) VALUES (%s, %s, %s, %s, %s) """, ( kredit_id, datum_for_db, z['betrag'], z['typ'], z['notiz'][:200] if z['notiz'] else "" )) imported_count += 1 if z['datum']: imported_with_date += 1 else: imported_without_date += 1 datum_disp = z['datum'] if z['datum'] else f"[{start_datum}]" print(f" {datum_disp} | {z['typ']:12} | {z['roh_betrag']:10.2f} EUR | {z['notiz'][:40]}") conn.commit() print(f"\n[OK] {imported_count} Zahlungen importiert") print(f" {imported_with_date} mit Datum, {imported_without_date} ohne Datum (Startdatum verwendet)") 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 datum, betrag, typ, notiz 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[0]) if z[0] else '----------' betrag = float(z[1]) if z[1] else 0.0 typ = z[2] notiz = str(z[3])[:40] if z[3] 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: print(f"\n[OK] VERIFIKATION ERFOLGREICH!") else: print(f"\n[Hinweis] Differenzen erkannt") 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.")