Initial commit - Stand 26.04.2026
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
VOLLSTÄNDIGER NEU-IMPORT: Niki Kredit
|
||||
Löscht alles und importiert korrekt neu - läuft im Docker-Backend
|
||||
"""
|
||||
|
||||
import psycopg2
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
|
||||
# Datenbank-Verbindung - Docker intern (db statt localhost)
|
||||
conn = psycopg2.connect(
|
||||
host="db",
|
||||
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('/app/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.")
|
||||
Reference in New Issue
Block a user