import Link from 'next/link' import { ArrowRight, Banknote, FileDown, Landmark, Plus, Repeat, Upload } from 'lucide-react' import { Alert, AlertDescription } from '@/components/ui/alert' import { Button } from '@/components/ui/button' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' import { SeitenKopf, Leerzustand } from '@/components/seiten-kopf' import { Rechtshinweis } from '@/components/rechtshinweis' import { Belegzeichen, Betrag, Hinweisliste, Kennzahl, Vermischungswarnung, } from '@/components/finanzen/bausteine' import { centZuZahl } from '@/lib/db' import { formatCent, formatDatum } from '@/lib/utils' import { finanzKontext } from '@/lib/finanzen/seite' import { heute, monatePlus, tagePlus } from '@/lib/finanzen/datum' import { belegDurchVertrag, betragPruefen, kennzahlen, vermischungsWarnung } from '@/lib/finanzen/kassenbuch' import { KATEGORIE_BESCHRIFTUNG } from '@/lib/finanzen/kategorien' import { laufendesBetreuungsjahr } from '@/lib/finanzen/betreuungsjahr' import { buchungenLaden, kontenLaden, kontostaendeZumStichtag, vermoegenLaden } from '@/lib/berichte/gemeinsam' import { offeneZahlungsgruppen } from '@/lib/finanzen/wiederkehrend-laden' export const metadata = { title: 'Vermögen & Kasse' } /** * Übersichtsseite des Finanzmoduls. * * Sie beantwortet die vier Fragen, die man sich beim Öffnen stellt: * Was ist da? Wo liegt es? Was ist zuletzt passiert? Und: Wo fehlt noch * ein Beleg? */ export default async function FinanzenSeite() { const { betreute, darfSchreiben } = await finanzKontext() const schreiben = darfSchreiben('FINANZEN') const stichtag = heute() const [konten, buchungen, vermoegen] = await Promise.all([ kontenLaden(betreute.id), buchungenLaden(betreute.id), vermoegenLaden(betreute.id, stichtag), ]) const eigeneKonten = konten.filter((k) => !k.istBetreuerkonto) const staende = kontostaendeZumStichtag(eigeneKonten, stichtag) const summeKontenCent = staende.reduce((s, z) => s + (z.betragCent ?? 0n), 0n) const zwoelfMonate = tagePlus(monatePlus(stichtag, -12), 1) const letzteZwoelf = buchungen.filter((b) => b.datum >= zwoelfMonate) const zahlen = kennzahlen(letzteZwoelf) const offeneGruppen = await offeneZahlungsgruppen(betreute.id) const letzte = [...buchungen].sort((a, b) => b.datum.getTime() - a.datum.getTime()).slice(0, 8) const jahr = betreute.bestellungAm ? laufendesBetreuungsjahr(betreute.bestellungAm) : null const hinweise: string[] = [] for (const stand of staende) { if (stand.betragCent === null) { hinweise.push(`Für „${stand.bezeichnung}“ ist noch kein Kontostand erfasst.`) } else if (stand.stichtag && stand.stichtag < monatePlus(stichtag, -3)) { hinweise.push( `Der Stand von „${stand.bezeichnung}“ ist vom ${formatDatum(stand.stichtag)} und damit ` + 'älter als drei Monate.', ) } } if (!betreute.bestellungAm) { hinweise.push( 'In den Stammdaten fehlt das Datum der Bestellung. Ohne dieses Datum lässt sich das ' + 'Betreuungsjahr nicht bestimmen – und damit auch keine Rechnungslegung erzeugen.', ) } return (