Meine Konten

Gesamtsaldo 0,00 €
Einnahmen (Monat) 0,00 €
Ausgaben (Monat) 0,00 €
Bilanz (Monat) 0,00 €
Wochenbudgets Rest 0,00 €
Monatsbudgets Rest 0,00 €
Gesamt Budget Rest 0,00 €

Konten-Details

Letzte Transaktionen

Verwaltung

Konten verwalten

Konten-Anzeige auf Startseite

Ziehe die Konten per Drag & Drop in die gewünschte Reihenfolge. Mit dem Auge-Symbol kannst du Konten auf der Startseite ein-/ausblenden.

Fixkosten verwalten

Kategorien verwalten

Emotionen verwalten

Verwalte die Emotionen, die bei Buchungen ausgewählt werden können.

Benutzer-Einstellungen

Profil

Standard-Konten

Diese Konten werden automatisch bei neuen Transaktionen vorausgewählt.

Standard-Kategorien

Diese Kategorien werden vorausgewählt, wenn keine automatisch erkannt wird.

Passwort ändern

Gefahrenbereich

Das Löschen Ihres Accounts kann nicht rückgängig gemacht werden.

Wartungsmodus

Status wird geladen...

Hinweis

Im Wartungsmodus können sich nur Administratoren anmelden. Alle anderen Benutzer sehen eine Wartungsseite.

Benutzerverwaltung

Händler-Verwaltung

Verwalte System-Händler die beim Bank-Import für alle Benutzer automatisch erkannt werden.

Neuen System-Händler anlegen

Texte die im Kontoauszug vorkommen (Großschreibung wird ignoriert)

System-Händler (0)

Benutzer-definierte Händler

Von einzelnen Benutzern angelegte Händler (nur sichtbar für den jeweiligen Benutzer)

Google Sheets Export

Einrichtung

Um den Export zu nutzen, muss einmalig ein Google Apps Script im Ziel-Sheet eingerichtet werden.

Anleitung zur Einrichtung anzeigen
  1. Öffne das Google Sheet
  2. Gehe zu Erweiterungen → Apps Script
  3. Lösche den vorhandenen Code und füge den Code von unten ein
  4. Speichere das Projekt (Strg+S)
  5. Klicke auf Bereitstellen → Neue Bereitstellung
  6. Wähle Typ: Web-App
  7. Ausführen als: Ich
  8. Zugriff: Jeder
  9. Klicke auf Bereitstellen und kopiere die URL
  10. Füge die URL unten in das Feld ein
function doPost(e) {
  try {
    const data = JSON.parse(e.postData.contents);
    const ss = SpreadsheetApp.getActiveSpreadsheet();
    
    // Buchungen-Sheet
    let transSheet = ss.getSheetByName('Buchungen');
    if (!transSheet) {
      transSheet = ss.insertSheet('Buchungen');
    }
    transSheet.clear();
    
    // Header für Buchungen
    const transHeaders = ['ID', 'Datum', 'Typ', 'Betrag', 'Konto', 'Kategorie', 'Beschreibung', 'Emotion', 'Getätigt von', 'Erstellt von', 'Bearbeitet von', 'Erstellt am'];
    transSheet.getRange(1, 1, 1, transHeaders.length).setValues([transHeaders]);
    transSheet.getRange(1, 1, 1, transHeaders.length).setFontWeight('bold').setBackground('#4285f4').setFontColor('white');
    
    // Buchungen einfügen
    if (data.transactions && data.transactions.length > 0) {
      const transData = data.transactions.map(t => [
        t.id,
        t.transaction_date,
        t.type === 'income' ? 'Einnahme' : 'Ausgabe',
        parseFloat(t.amount),
        t.account_name || '',
        t.category_name || '',
        t.description || '',
        t.emotion_name || '',
        t.spent_by_username || '',
        t.created_by_username || '',
        t.updated_by_username || '',
        t.created_at
      ]);
      transSheet.getRange(2, 1, transData.length, transHeaders.length).setValues(transData);
    }
    
    // Konten-Sheet
    let accSheet = ss.getSheetByName('Konten');
    if (!accSheet) {
      accSheet = ss.insertSheet('Konten');
    }
    accSheet.clear();
    
    // Header für Konten
    const accHeaders = ['ID', 'Name', 'Typ', 'Kontostand', 'Beschreibung', 'Im Dashboard', 'Aktiv'];
    accSheet.getRange(1, 1, 1, accHeaders.length).setValues([accHeaders]);
    accSheet.getRange(1, 1, 1, accHeaders.length).setFontWeight('bold').setBackground('#34a853').setFontColor('white');
    
    // Konten einfügen
    if (data.accounts && data.accounts.length > 0) {
      const accData = data.accounts.map(a => [
        a.id,
        a.name,
        a.type_name || '',
        parseFloat(a.balance),
        a.description || '',
        a.show_in_dashboard ? 'Ja' : 'Nein',
        a.is_active ? 'Ja' : 'Nein'
      ]);
      accSheet.getRange(2, 1, accData.length, accHeaders.length).setValues(accData);
    }
    
    // Spaltenbreiten anpassen
    transSheet.autoResizeColumns(1, transHeaders.length);
    accSheet.autoResizeColumns(1, accHeaders.length);
    
    return ContentService.createTextOutput(JSON.stringify({success: true, message: 'Export erfolgreich!'}))
      .setMimeType(ContentService.MimeType.JSON);
  } catch (error) {
    return ContentService.createTextOutput(JSON.stringify({success: false, message: error.toString()}))
      .setMimeType(ContentService.MimeType.JSON);
  }
}

function doGet(e) {
  try {
    const action = e.parameter.action || 'status';
    
    if (action === 'export') {
      // Buchungen aus Sheet lesen und zurückgeben
      const ss = SpreadsheetApp.getActiveSpreadsheet();
      const transSheet = ss.getSheetByName('Buchungen');
      
      if (!transSheet) {
        return ContentService.createTextOutput(JSON.stringify({
          success: false, 
          message: 'Blatt "Buchungen" nicht gefunden'
        })).setMimeType(ContentService.MimeType.JSON);
      }
      
      const data = transSheet.getDataRange().getValues();
      const headers = data[0];
      const transactions = [];
      
      for (let i = 1; i < data.length; i++) {
        const row = data[i];
        if (!row[1]) continue; // Überspringe leere Zeilen (kein Datum)
        
        transactions.push({
          id: row[0] || null,
          transaction_date: row[1] ? Utilities.formatDate(new Date(row[1]), 'Europe/Vienna', 'yyyy-MM-dd') : null,
          type: row[2] === 'Einnahme' ? 'income' : 'expense',
          amount: parseFloat(row[3]) || 0,
          account_name: row[4] || '',
          category_name: row[5] || '',
          description: row[6] || '',
          emotion_name: row[7] || '',
          spent_by_username: row[8] || ''
        });
      }
      
      return ContentService.createTextOutput(JSON.stringify({
        success: true,
        transactions: transactions
      })).setMimeType(ContentService.MimeType.JSON);
    }
    
    return ContentService.createTextOutput(JSON.stringify({
      success: true, 
      message: 'Export-API bereit'
    })).setMimeType(ContentService.MimeType.JSON);
  } catch (error) {
    return ContentService.createTextOutput(JSON.stringify({
      success: false, 
      message: error.toString()
    })).setMimeType(ContentService.MimeType.JSON);
  }
}

Web-App URL

Die URL der bereitgestellten Google Apps Script Web-App

Daten exportieren

Exportiert alle Buchungen und Konten in das Google Sheet. Das Sheet wird dabei komplett überschrieben.

Daten importieren

Importiert Buchungen aus dem Google Sheet. Bestehende Buchungen werden anhand der ID abgeglichen und aktualisiert. Buchungen ohne ID werden als neue Buchungen angelegt.

KI-Assistent (Gemini)

Exportiere Buchungen als JSON, lass sie von Gemini bearbeiten (z.B. auf andere Konten umbuchen), und importiere die Änderungen.

Anleitung für Gemini anzeigen

Kopiere diese Anleitung zusammen mit dem JSON zu Gemini:

Ich habe hier Buchungen aus meinem Haushaltsbudget-System als JSON. 
Bitte hilf mir, diese zu bearbeiten.

WICHTIGE REGELN:
1. Die "id" MUSS unverändert bleiben (sonst wird eine neue Buchung erstellt statt aktualisiert)
2. Ändere NUR die Felder, die ich explizit nenne
3. Gib mir am Ende das komplette JSON zurück im gleichen Format

VERFÜGBARE KONTEN:
- Girokonto (Hauptkonto)
- Wochenkonto (wöchentliche Ausgaben)
- Bargeld
- Sparkonto
- [weitere Konten aus deinem System]

VERFÜGBARE KATEGORIEN:
- Lebensmittel
- Haushalt
- Transport
- Freizeit
- Restaurant
- Shopping
- Fixkosten
- [weitere Kategorien aus deinem System]

MEINE ANFRAGE:
[Beschreibe hier was du ändern möchtest, z.B.:]
- "Buche alle Transaktionen mit 'BILLA' im Beschreibungsfeld auf das Konto 'Wochenkonto' um"
- "Ändere die Kategorie aller Transaktionen über 100€ auf 'Fixkosten'"
- "Korrigiere alle Transaktionen vom 15.01. auf das Datum 16.01."

HIER SIND MEINE BUCHUNGEN:
1
JSON exportieren

Klicke um die Buchungen als JSON zu laden:

2
An Gemini senden

Kopiere Anleitung + JSON und füge es in Gemini ein:

3
Bearbeitetes JSON importieren

Füge das von Gemini bearbeitete JSON hier ein:

Datenbank-Synchronisation

Umgebungs-Info

Aktuelle Umgebung Wird ermittelt...
Lokal localhost / haushaltsbudget
Produktiv budget.jackydoo.at

Lokal → Produktiv

Überschreibt die Produktiv-Datenbank mit den Daten aus der lokalen Entwicklungsumgebung.
⚠️ Alle Produktiv-Daten werden dabei gelöscht!

Produktiv → Lokal

Überschreibt die lokale Datenbank mit den Daten aus der Produktivumgebung.
⚠️ Alle lokalen Daten werden dabei gelöscht!

Daten zurücksetzen

Gefahrenzone

⚠️ Achtung: Die folgenden Aktionen können nicht rückgängig gemacht werden!

Alle Buchungsdaten löschen

Löscht alle Konten, Transaktionen, Umbuchungen und Fixkosten.

Behält: Benutzer, Kategorien, Händler

Konten -
Transaktionen -
Umbuchungen -
Fixkosten -

Was wird gelöscht?

Alle Konten (Giro, Ausgabe, Spar)
Alle Transaktionen (Ein- & Ausgaben)
Alle Umbuchungen zwischen Konten
Alle wiederkehrenden Buchungen
Alle Budget-Allokationen
Benutzer (bleiben erhalten)
Kategorien (bleiben erhalten)
Händler (bleiben erhalten)

System-Informationen

Datenbank

Wird geladen...

Applikation

Version 1.0.0
Umgebung Lokal

Aktionen