import Link from 'next/link' import { SeitenKopf } from '@/components/seiten-kopf' import { Rechtshinweis } from '@/components/rechtshinweis' import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { HeimkostenFormular } from '@/components/sozialhilfe/heimkosten-formular' import { HeimkostenTabelle, type MonatsZeile } from '@/components/sozialhilfe/heimkosten-tabelle' import { betragFormatieren } from '@/lib/finanzen/betrag' import { db } from '@/lib/db' import { heuteAlsTag } from '@/lib/fristen/datum' import { BARBETRAG_CENT, BEKLEIDUNGSPAUSCHALE_HINWEIS, KONSTANTEN_NAECHSTE_PRUEFUNG, KONSTANTEN_STAND, } from '@/lib/sozialhilfe/konstanten' import { heimkostenAuswerten, jahresverlaufBilden, KOSTENLESART_BESCHRIFTUNG, KOSTENLESART_ERKLAERUNG, KOSTENLESART_STANDARD, leistungszuschlagProzent, leistungszuschlagStufe, monatsname, pflegekassePauschaleCent, pflegekasseRechtsgrundlage, verweildauerMonate, } from '@/lib/sozialhilfe/heimkosten' import { sozialhilfeKontext } from '@/lib/sozialhilfe/zugang' import { formatCent } from '@/lib/utils' import { Info, TrendingDown } from 'lucide-react' export const dynamic = 'force-dynamic' /** * Heimkosten-Gegenüberstellung. * * Die eine Zahl, um die es geht, ist die Deckungslücke: Was bleibt übrig, * nachdem Pflegekasse, Rente und Sozialhilfe gezahlt haben? Sie steht je * Monat und als Jahressumme da - denn eine Lücke von 180 Euro im Monat * sind über ein Jahr mehr als zweitausend. */ export default async function HeimkostenSeite({ searchParams, }: { searchParams: Promise<{ jahr?: string }> }) { const { betreuteId, betreute } = await sozialhilfeKontext() const parameter = await searchParams const heute = heuteAlsTag() const gewaehltesJahr = Number.parseInt(parameter.jahr ?? '', 10) const jahr = Number.isFinite(gewaehltesJahr) ? gewaehltesJahr : heute.getUTCFullYear() const [monate, heimvertrag] = await Promise.all([ db.heimkostenmonat.findMany({ where: { betreuteId, jahr }, orderBy: { monat: 'asc' }, }), db.heimvertrag.findUnique({ where: { betreuteId } }), ]) const ergebnisse = monate.map((m) => heimkostenAuswerten({ jahr: m.jahr, monat: m.monat, pflegeEigenanteilCent: m.pflegeEigenanteilCent, unterkunftVerpflegungCent: m.unterkunftVerpflegungCent, investitionskostenCent: m.investitionskostenCent, ausbildungsumlageCent: m.ausbildungsumlageCent, zusatzleistungenCent: m.zusatzleistungenCent, pflegekasseCent: m.pflegekasseCent, leistungszuschlagCent: m.leistungszuschlagCent, renteCent: m.renteCent, sonstigeEinkuenfteCent: m.sonstigeEinkuenfteCent, sozialhilfeCent: m.sozialhilfeCent, eigenmittelCent: m.eigenmittelCent, barbetragCent: m.barbetragCent, bekleidungspauschaleCent: m.bekleidungspauschaleCent, abwesenheitstage: m.abwesenheitstage, }), ) const verlauf = jahresverlaufBilden(jahr, ergebnisse) const zeilen: MonatsZeile[] = Array.from({ length: 12 }, (_, i) => { const monat = i + 1 const ergebnis = ergebnisse.find((e) => e.monat === monat) const roh = monate.find((m) => m.monat === monat) return { jahr, monat, heimkostenCent: ergebnis?.heimkostenCent ?? 0n, gesamtbedarfCent: ergebnis?.gesamtbedarfCent ?? 0n, deckungCent: ergebnis?.deckungCent ?? 0n, deckungslueckeCent: ergebnis?.deckungslueckeCent ?? 0n, ueberdeckungCent: ergebnis?.ueberdeckungCent ?? 0n, abwesenheitstage: roh?.abwesenheitstage ?? 0, erfasst: ergebnis !== undefined, } }) // Vorschläge fürs Formular: Pauschale der Pflegekasse zum Pflegegrad // und der gesetzliche Mindest-Barbetrag. const pauschale = pflegekassePauschaleCent(betreute.pflegegrad) // Bewusst nur ein Hinweis, kein Vorschlagswert zum Uebernehmen: Unter der // Lesart EIGENANTEIL_NETTO steckt die Pauschale schon im Eigenanteil. // Wer sie hier zusaetzlich eintraegt, zaehlt dasselbe Geld zweimal. const hinweisPflegekasse = pauschale ? `Pflegegrad ${betreute.pflegegrad}: ${formatCent(pauschale)} monatlich ` + `(${pflegekasseRechtsgrundlage(betreute.pflegegrad)}, Stand ${KONSTANTEN_STAND}). ` + `Dieser Betrag ist im Eigenanteil oben bereits abgezogen — lass das Feld deshalb auf 0. ` + `Es dient nur der Erinnerung, was die Pflegekasse direkt an die Einrichtung zahlt.` : 'Pauschale nach § 43 SGB XI. Sie ist im Eigenanteil bereits abgezogen — lass das Feld ' + 'auf 0. Hinterlege den Pflegegrad in den Stammdaten, dann steht hier der Betrag.' const einzug = heimvertrag?.einzugAm ?? betreute.heimEinzugAm ?? null const verweildauer = einzug ? verweildauerMonate(einzug, heute) : null const naechsterOffenerMonat = zeilen.find((z) => !z.erfasst && z.monat <= (jahr === heute.getUTCFullYear() ? heute.getUTCMonth() + 1 : 12)) ?.monat ?? (jahr === heute.getUTCFullYear() ? heute.getUTCMonth() + 1 : 1) const jahre = Array.from({ length: 6 }, (_, i) => heute.getUTCFullYear() - 3 + i) return (
{jahre.map((j) => ( {j} ))} } />

Bedarf {jahr}

{formatCent(verlauf.summeBedarfCent)}

Deckung {jahr}

{formatCent(verlauf.summeDeckungCent)}

0n ? 'border-ampel-rot/40' : undefined}>

Deckungslücke {jahr}

0n ? 'text-ampel-rot' : 'text-ampel-gruen' }`} > {formatCent(verlauf.summeDeckungslueckeCent)}

{verlauf.groessteLuecke && ( )} Was hier gegen was gerechnet wird Lesart: {KOSTENLESART_BESCHRIFTUNG[KOSTENLESART_STANDARD]}. Ohne diese Festlegung lässt sich die Rechnung nicht mit der Heimrechnung vergleichen.

{KOSTENLESART_ERKLAERUNG[KOSTENLESART_STANDARD]}

Bedarf

  • einrichtungseinheitlicher Eigenanteil (bereits netto)
  • Unterkunft und Verpflegung
  • Investitionskosten
  • Ausbildungsumlage
  • Zusatzleistungen
  • Barbetrag (§ 27b Abs. 2 SGB XII)
  • Bekleidungspauschale

Deckung

  • Leistungszuschlag (§ 43c SGB XI)
  • Rente
  • sonstige Einkünfte
  • Anteil der Sozialhilfe
  • Eigenmittel

Nicht dabei: die Pauschale der Pflegekasse nach § 43 Abs. 2 SGB XI. Sie ist im Eigenanteil schon abgezogen und würde hier ein zweites Mal zählen.

Barbetrag und Bekleidungspauschale stehen bewusst auf der Bedarfsseite: Sie müssen der betreuten Person tatsächlich verbleiben. Wer sie herauslässt, hält die Deckung für besser, als sie ist.

Jahresverlauf Gesamtbedarf ist die Heimrechnung plus Barbetrag und Bekleidungspauschale. {ergebnisse.some((e) => e.hinweise.length > 0) && ( Was auffällt
    {ergebnisse.flatMap((e) => e.hinweise.map((hinweis, i) => (
  • {monatsname(e.monat)}: {hinweis}
  • )), )}
)} {ergebnisse.some((e) => e.abwesenheit.abwesenheitstage > 0) && ( Abwesenheitstage Was die Abwesenheit voraussichtlich bringt — eine Schätzung nach dem Rahmenvertrag, nicht die Abrechnung.
    {ergebnisse .filter((e) => e.abwesenheit.abwesenheitstage > 0) .map((e) => (
  • {monatsname(e.monat)}: {e.abwesenheit.erklaerung} Geschätzte Minderung{' '} {formatCent(e.abwesenheit.geschaetzteMinderungCent)} , die Lücke sänke damit auf{' '} {formatCent(e.deckungslueckeNachAbwesenheitCent)} .
  • ))}
)}

Monat erfassen oder ändern

) } /** Cent fuer ein Eingabefeld, null wird zu leer. */ function eingabefeld(cent: bigint | null): string { return cent === null ? '' : betragFormatieren(cent) }