'use client' import * as React from 'react' import { useActionState } from 'react' import { AlertCircle, CheckCircle2 } from 'lucide-react' import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' import { Checkbox } from '@/components/ui/checkbox' import { Input } from '@/components/ui/input' import { Select } from '@/components/ui/select' import { Textarea } from '@/components/ui/textarea' import { Feld } from '@/components/feld' import { Absendeknopf, Betragseingabe } from '@/components/finanzen/eingaben' import { Vermischungswarnung } from '@/components/finanzen/bausteine' import { ALLE_KATEGORIEN, BUCHUNG_RICHTUNGEN, KATEGORIE_BESCHRIFTUNG, RICHTUNG_BESCHRIFTUNG, kategorienFuerRichtung, standardKategorie, } from '@/lib/finanzen/kategorien' import { buchungSpeichern, type Formularzustand } from '@/server/actions/finanzen' import type { BuchungKategorie, BuchungRichtung } from '@prisma/client' export type KontoAuswahl = { id: string bezeichnung: string istBetreuerkonto: boolean } export type BelegAuswahl = { id: string titel: string } export type BuchungWerte = { id: string kontoId: string | null datum: string wertstellung: string | null betrag: string richtung: BuchungRichtung kategorie: BuchungKategorie gegenstelle: string | null verwendungszweck: string | null belegId: string | null belegFehltBegruendung: string | null betrifftBetreute: boolean vermoegenswirksam: boolean } /** * Buchung erfassen oder ändern. * * Drei Dinge macht dieses Formular anders als eine Haushaltsbuch-App: * * 1. Es warnt sichtbar, wenn eine Buchung auf einem Konto des Betreuers * läuft und trotzdem als Vermögen der Betreuten gilt. * 2. Es lässt eine Buchung ohne Beleg zu – verlangt dann aber eine * Begründung, weil genau danach gefragt wird. * 3. Es trennt laufende Vorgänge von vermögenswirksamen. Ein * Verkaufserlös ist keine Einnahme im Sinne der Rechnungslegung. */ export function Buchungsformular({ betreuteId, konten, belege, buchung, standardDatum, schnellerfassung = false, }: { betreuteId: string konten: KontoAuswahl[] belege: BelegAuswahl[] buchung?: BuchungWerte /** Vorbelegung des Datumsfeldes bei einer neuen Buchung. */ standardDatum?: string /** Nach dem Speichern bleibt das Formular für die nächste Buchung offen. */ schnellerfassung?: boolean }) { const [zustand, absenden] = useActionState(buchungSpeichern, {}) const [kontoId, setKontoId] = React.useState(buchung?.kontoId ?? konten[0]?.id ?? '') const [richtung, setRichtung] = React.useState(buchung?.richtung ?? 'AUSGABE') const [kategorie, setKategorie] = React.useState( buchung?.kategorie ?? 'SONSTIGE_AUSGABE', ) const [betrifftBetreute, setBetrifftBetreute] = React.useState(buchung?.betrifftBetreute ?? true) const [belegId, setBelegId] = React.useState(buchung?.belegId ?? '') const konto = konten.find((k) => k.id === kontoId) const vermischt = Boolean(konto?.istBetreuerkonto) && betrifftBetreute const vorschlaege = kategorienFuerRichtung(richtung) function richtungWechseln(neu: BuchungRichtung) { setRichtung(neu) // Die Kategorie folgt der Richtung, solange sie nicht dazu passt - // sonst steht "Heimkosten" unter den Einnahmen. if (!kategorienFuerRichtung(neu).includes(kategorie)) { setKategorie(standardKategorie(neu)) } } return (
{buchung && } {schnellerfassung && !buchung && } {zustand.fehler && ( )} {zustand.erfolg && ( )}