#!/usr/bin/env python3 """ VOLLSTÄNDIGER NEU-IMPORT: Niki Kredit Löscht alles und importiert korrekt neu """ import psycopg2 import pandas as pd from datetime import datetime from decimal import Decimal # Datenbank-Verbindung conn = psycopg2.connect( host="localhost", port=5432, database="buchhaltung", user="postgres", password="postgres" ) cursor = conn.cursor() print("="*60) print("SCHRITT 1: Alten Kredit 'Niki' löschen") print("="*60) # Finde und lösche Kredit "Niki" cursor.execute("SELECT id, name FROM kredite WHERE name ILIKE '%niki%'") niki_kredite = cursor.fetchall() if niki_kredite: for kredit_id, name in niki_kredite: print(f"Lösche Kredit: {name} (ID: {kredit_id})") # Lösche zuerst alle Zahlungen/Buchungen cursor.execute("DELETE FROM kredit_zahlungen WHERE kredit_id = %s", (kredit_id,)) cursor.execute("DELETE FROM kredit_buchungen WHERE kredit_id = %s", (kredit_id,)) # Dann den Kredit cursor.execute("DELETE FROM kredite WHERE id = %s", (kredit_id,)) print(f" -> Gelöscht: Zahlungen und Kredit") else: print("Kein Kredit 'Niki' gefunden") conn.commit() print("\n" + "="*60) print("SCHRITT 2: Excel analysieren") print("="*60) # Excel-Datei lesen df = pd.read_excel('Schulden Niki.xlsx', sheet_name='Tabelle1', header=None) # Header ist in Zeile 5 (0-basiert: 5) # Daten ab Zeile 6 header_row = 5 data_start = 6 # Nur relevante Spalten: 2=Datum, 3=Restschuld, 4=Zinsen, 5=Abgezahlt, 6=Neue Kosten, 7=Für was print(f"Excel hat {len(df)} Zeilen") print(f"Header in Zeile {header_row}: {df.iloc[header_row, 2:8].tolist()}") # Extrahiere alle Datensätze mit Zahlungen oder neuen Kosten zahlungen = [] for idx in range(data_start, len(df)): row = df.iloc[idx] datum = row[2] restschuld = row[3] zinsen = row[4] abgezahlt = row[5] neue_kosten = row[6] fuer_was = row[7] # Überspringe leere Zeilen if pd.isna(datum): continue # Konvertiere Datum if isinstance(datum, pd.Timestamp): datum_str = datum.strftime('%Y-%m-%d') else: datum_str = str(datum) # Zahlung (Abgezahlt > 0) if not pd.isna(abgezahlt) and abgezahlt > 0: zahlungen.append({ 'datum': datum_str, 'typ': 'zahlung', 'betrag': float(abgezahlt), 'notiz': f"Rate gezahlt" if pd.isna(fuer_was) else str(fuer_was) }) # Neue Kosten (Neue Kosten > 0) -> negative Auslage if not pd.isna(neue_kosten) and neue_kosten > 0: zahlungen.append({ 'datum': datum_str, 'typ': 'auslage', 'betrag': -float(neue_kosten), 'notiz': str(fuer_was) if not pd.isna(fuer_was) else "Neue Kosten" }) print(f"\nGefunden:") print(f"- {len([z for z in zahlungen if z['typ'] == 'zahlung'])} Zahlungen") print(f"- {len([z for z in zahlungen if z['typ'] == 'auslage'])} Auslagen") print(f"\nZahlungen/Auslagen:") for z in zahlungen: print(f" {z['datum']} | {z['typ']:10} | {z['betrag']:8.2f} € | {z['notiz']}") print("\n" + "="*60) print("SCHRITT 3: Kredit anlegen") print("="*60) # Kredit-Daten kredit_name = "Niki Schulden" kredit_betrag = 7000.0 # Ursprungsschuld zinssatz = 10.0 start_datum = "2023-07-01" monatsrate = 500.0 # Hauptzahlung (meist 500€) richtung = "eingehend" # Forderung # Berechne Summe der Zahlungen summe_zahlungen = sum(z['betrag'] for z in zahlungen if z['typ'] == 'zahlung') summe_auslagen = sum(z['betrag'] for z in zahlungen if z['typ'] == 'auslage') print(f"Kredit: {kredit_name}") print(f" Ursprungsschuld: {kredit_betrag:.2f} €") print(f" Zinssatz: {zinssatz}%") print(f" Start: {start_datum}") print(f" Richtung: {richtung}") print(f" Summe Zahlungen: {summe_zahlungen:.2f} €") print(f" Summe Auslagen: {summe_auslagen:.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, "Niki", # kreditgeber "Niki", # person kredit_betrag, kredit_betrag - summe_zahlungen + abs(summe_auslagen), # restschuld nach Zahlungen monatsrate, zinssatz, start_datum, "Importiert aus Excel 'Schulden Niki.xlsx'", richtung, "aktiv" )) kredit_id = cursor.fetchone()[0] conn.commit() print(f"\nKredit angelegt mit ID: {kredit_id}") print("\n" + "="*60) print("SCHRITT 4: 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'], z['typ'], z['notiz'] )) print(f" Importiert: {z['datum']} | {z['typ']} | {z['betrag']:.2f} € | {z['notiz']}") conn.commit() print("\n" + "="*60) print("SCHRITT 5: 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: {kredit[4]:.2f} €") print(f" Restschuld: {kredit[5]:.2f} €") print(f" Richtung: {kredit[12]}") # 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: print(f" {z[2]} | {z[4]:10} | {z[3]:8.2f} € | {z[5]}") # Summen prüfen sum_zahlungen_db = sum(z[3] for z in imported_zahlungen if z[4] == 'zahlung') sum_auslagen_db = sum(z[3] for z in imported_zahlungen if z[4] == 'auslage') print(f"\nSummen DB:") print(f" Zahlungen: {sum_zahlungen_db:.2f} €") print(f" Auslagen: {sum_auslagen_db:.2f} €") print(f" Netto: {sum_zahlungen_db + sum_auslagen_db:.2f} €") # Vergleich mit Excel print(f"\nVergleich:") print(f" Excel Zahlungen: {summe_zahlungen:.2f} €") print(f" Excel Auslagen: {summe_auslagen:.2f} €") print(f" DB Zahlungen: {sum_zahlungen_db:.2f} €") print(f" DB Auslagen: {sum_auslagen_db:.2f} €") if abs(summe_zahlungen - sum_zahlungen_db) < 0.01 and abs(summe_auslagen - sum_auslagen_db) < 0.01: print(f"\n✅ VERIFIKATION ERFOLGREICH: Alle Daten stimmen überein!") else: print(f"\n❌ WARNUNG: Unterschiede gefunden!") cursor.close() conn.close() print("\n" + "="*60) print("IMPORT ABGESCHLOSSEN") print("="*60) print(f"Kredit 'Niki Schulden' ist jetzt korrekt in der Datenbank.") print(f"Alle Zahlungen und Auslagen sind importiert.")