#!/usr/bin/env python3 """ KORRIGIERTER IMPORT fuer "Schulden Niki.xlsx" WICHTIG: Das ist eine FORDERUNG (eingehend) - Geld was Rene BEKOMMT! - Richtung: 'eingehend' - Restschuld STEIGT wenn Zahlung kommt (weil er mehr bekommt) - Farbe: Grün (Einnahme) """ import openpyxl import uuid import json import urllib.request import urllib.error from datetime import datetime # API Konfiguration API_BASE = "http://localhost:3001/api" def read_excel_data(filepath): """Liest die Excel-Daten ein""" wb = openpyxl.load_workbook(filepath, data_only=True) ws = wb['Tabelle1'] data = [] headers = {} # Zeile 6: Headers for col_idx in range(1, 9): cell = ws.cell(row=6, column=col_idx) if cell.value: headers[cell.value] = col_idx print(f"Gefundene Spalten: {headers}") # Zeile 7+: Daten for row_idx in range(7, ws.max_row + 1): row_data = {} for header, col_idx in headers.items(): row_data[header] = ws.cell(row=row_idx, column=col_idx).value if row_data.get('Datum'): data.append(row_data) return data def api_call(endpoint, method='GET', data=None): """Fuehrt einen API-Call aus""" url = f"{API_BASE}{endpoint}" headers = {'Content-Type': 'application/json'} req = urllib.request.Request( url, data=json.dumps(data).encode() if data else None, headers=headers, method=method ) try: with urllib.request.urlopen(req, timeout=30) as response: return json.loads(response.read().decode()) except urllib.error.HTTPError as e: print(f"HTTP Error {e.code}: {e.read().decode()}") return None except Exception as e: print(f"Error: {e}") return None def get_monthly_rate(data): """Ermittelt die monatliche Rate aus den Daten""" rates = [] for row in data: abgezahlt = row.get('Abgezahlt') neue_kosten = row.get('Neue Kosten') if abgezahlt and abgezahlt > 0 and (not neue_kosten or neue_kosten == 0): rates.append(abgezahlt) if rates: from collections import Counter return Counter(rates).most_common(1)[0][0] return 0 def import_niki_schulden(): """Hauptimport-Funktion - KORRIGIERT fuer Forderungen""" print("=" * 60) print("IMPORT: Niki Schulden (KORRIGIERT)") print("=" * 60) print("\nHINWEIS: Das ist eine FORDERUNG (Geld was Rene BEKOMMT)") print(" Richtung: eingehend (grün)") print("=" * 60) # 1. Excel-Daten lesen print("\n1. Lese Excel-Daten...") EXCEL_FILE = r'C:\Users\renet\.openclaw\workspace\buchhaltungs-app\Schulden Niki.xlsx' data = read_excel_data(EXCEL_FILE) print(f" {len(data)} Datensaetze gefunden") if not data: print(" KEINE DATEN GEFUNDEN!") return False first_row = data[0] start_datum = first_row.get('Datum') restschuld_start = abs(first_row.get('Restschuld', 0)) print(f" Startdatum: {start_datum}") print(f" Ursprungsschuld (Forderung): {restschuld_start}") monatsrate = get_monthly_rate(data) print(f" Erkannte Monatsrate: {monatsrate}") # 2. Kredit erstellen - ALS FORDERUNG (eingehend) print("\n2. Erstelle Forderung (Kredit mit richtung=eingehend)...") last_row = data[-1] restschuld_aktuell = abs(last_row.get('Restschuld', 0)) kredit_data = { 'name': 'Niki Schulden (Forderung)', 'kreditgeber': 'Niki', # Niki ist der Schuldner 'person': 'Niki', 'ursprungsschuld': float(restschuld_start), 'restschuld': float(restschuld_aktuell), 'monatsrate': float(monatsrate) if monatsrate > 0 else 0, 'zinssatz': 10.0, 'start_datum': start_datum.strftime('%Y-%m-%d') if hasattr(start_datum, 'strftime') else str(start_datum)[:10], 'status': 'aktiv', 'richtung': 'eingehend' # WICHTIG: Das ist eine Forderung! } print(f" Kredit-Daten: {json.dumps(kredit_data, indent=2)}") result = api_call('/kredite', method='POST', data=kredit_data) if not result: print(" [ERR] Fehler beim Erstellen der Forderung") return False kredit_id = result.get('id') print(f" [OK] Forderung erstellt mit ID: {kredit_id}") # 3. Zahlungen importieren print("\n3. Importiere Zahlungen...") zahlungen_count = 0 for idx, row in enumerate(data): datum = row.get('Datum') abgezahlt = row.get('Abgezahlt') or 0 neue_kosten = row.get('Neue Kosten') or 0 fuer_was = row.get('Fuer was', '') or row.get('Für was', '') # Abgezahlt = Zahlung die Niki an Rene macht -> Erhöht die Forderung if abgezahlt and abgezahlt > 0: zahlung_data = { 'betrag': float(abgezahlt), 'datum': datum.strftime('%Y-%m-%d') if hasattr(datum, 'strftime') else str(datum)[:10], 'typ': 'zahlung_eingang', # Niki zahlt -> Rene bekommt Geld 'notiz': fuer_was if fuer_was else 'Zahlung von Niki' } result = api_call(f'/kredite/{kredit_id}/zahlungen', method='POST', data=zahlung_data) if result: zahlungen_count += 1 else: print(f" [ERR] Fehler bei Zahlung {idx + 1}") # Neue Kosten = Rene gibt Niki Geld -> Vermindert die Forderung if neue_kosten and neue_kosten < 0: zahlung_data = { 'betrag': float(abs(neue_kosten)), 'datum': datum.strftime('%Y-%m-%d') if hasattr(datum, 'strftime') else str(datum)[:10], 'typ': 'auslage', # Rene gibt Geld aus -> Forderung sinkt 'notiz': fuer_was if fuer_was else 'Neue Auslage' } result = api_call(f'/kredite/{kredit_id}/zahlungen', method='POST', data=zahlung_data) if result: zahlungen_count += 1 else: print(f" [ERR] Fehler bei Auslage {idx + 1}") print(f" [OK] {zahlungen_count} Zahlungen importiert") # 4. Verifikation print("\n4. Verifikation:") result = api_call(f'/kredite/{kredit_id}/zahlungen') if result: print(f" Zahlungen in API: {len(result)}") result = api_call(f'/kredite/{kredit_id}') if result: db_restschuld = result.get('restschuld') print(f" Restforderung in DB: {db_restschuld}") print(f" Erwartet (aus Excel): {restschuld_aktuell}") if abs(float(db_restschuld) - float(restschuld_aktuell)) < 0.01: print(" [OK] Restforderung stimmt ueberein!") else: print(" [WARN] Restforderung weicht ab!") print("\n" + "=" * 60) print("IMPORT ABGESCHLOSSEN") print("=" * 60) print("\nHinweis: Diese Forderung wird als 'eingehend' markiert") print(" und in der UI in GRUEN angezeigt.") return True if __name__ == '__main__': success = import_niki_schulden() exit(0 if success else 1)