diff --git a/docs/schema-wuensche/sozialhilfe.md b/docs/schema-wuensche/sozialhilfe.md new file mode 100644 index 0000000..0b37977 --- /dev/null +++ b/docs/schema-wuensche/sozialhilfe.md @@ -0,0 +1,243 @@ +# Schema-Wünsche aus Etappe 5 „Behörde“ + +Das Schema wurde nicht angefasst. Was beim Bauen des Sozialhilfemoduls +gefehlt hat, steht hier — nach Dringlichkeit sortiert, jeweils mit dem +Behelf, der jetzt an seiner Stelle steht. + +--- + +## 1. `Heimkostenmonat`: Kostenseite und Deckungsseite überschneiden sich — wichtig + +Dieselbe Sache wie Punkt 1 in `docs/schema-wuensche/dashboard.md`, hier aus +Sicht des Moduls, das die Gegenüberstellung baut. + +**Das Problem.** `pflegeEigenanteilCent` heißt „einrichtungseinheitlicher +Eigenanteil". Der ist definitionsgemäß **schon um die Pauschale der +Pflegekasse nach § 43 Abs. 2 SGB XI gekürzt**. Steht in derselben Zeile +zusätzlich `pflegekasseCent` als Deckung, wird dasselbe Geld zweimal +gezählt — die Deckungslücke fällt um die Pauschale zu klein aus, bei +Pflegegrad 3 um 1.319 Euro im Monat. + +**Was ich entschieden habe.** Dieses Modul rechnet in der Lesart +`EIGENANTEIL_NETTO` (siehe Kopfkommentar in +`src/lib/sozialhilfe/heimkosten.ts`): + +``` +Bedarf = pflegeEigenanteil (netto, wie auf der Heimrechnung) + + unterkunftVerpflegung + investitionskosten + + ausbildungsumlage + zusatzleistungen + + barbetrag + bekleidungspauschale + +Deckung = leistungszuschlag + rente + sonstigeEinkuenfte + + sozialhilfe + eigenmittel + +Deckungslücke = Bedarf − Deckung +``` + +`pflegekasseCent` zählt **nicht** als Deckung. Der Wert wird als +`pflegekasseNachrichtlichCent` mitgeführt und angezeigt; ist er ungleich +null, gibt `heimkostenAuswerten()` einen Hinweis aus, der die +Doppelzählung erklärt. Das Formular belegt das Feld nicht mehr vor. + +`leistungszuschlagCent` zählt dagegen **sehr wohl** als Deckung: Der +Zuschlag nach § 43c SGB XI mindert den Eigenanteil erst danach und steht +auf der Heimrechnung als eigene Abzugsposition. + +Die Alternative — durchgängig den Bruttosatz erfassen — ist als Lesart +`PFLEGESATZ_BRUTTO` implementiert und getestet: Bei konsistenter Erfassung +kommen beide Lesarten auf dieselbe Deckungslücke. Benutzt wird sie in der +Oberfläche nicht, weil das Schema keinen Ort hat, um die Wahl zu +speichern. + +**Wunsch, in dieser Reihenfolge:** + +1. Den Kommentar am Feld schärfen, damit die Lesart im Schema steht und + nicht nur hier: + +```prisma +/// NETTO: der einrichtungseinheitliche Eigenanteil, wie er auf der +/// Heimrechnung steht - bereits um § 43 Abs. 2 SGB XI gekuerzt, noch +/// nicht um den Leistungszuschlag. pflegekasseCent zaehlt deshalb NICHT +/// als Deckung, sondern nur nachrichtlich. +pflegeEigenanteilCent BigInt @default(0) +``` + +2. Wenn beide Lesarten gebraucht werden, ein Feld dafür — sonst muss jedes + Modul raten, was in der Zeile steht: + +```prisma +enum Kostenlesart { + EIGENANTEIL_NETTO + PFLEGESATZ_BRUTTO +} + +lesart Kostenlesart @default(EIGENANTEIL_NETTO) +``` + +3. Alternativ ein `heimrechnungGesamtCent`, das schlicht den + Rechnungsbetrag trägt; die Aufteilung wäre dann nur noch informativ und + die Summe könnte gegen sie geprüft werden. + +**Verabredung bis dahin**: Wer `Heimkostenmonat` schreibt — dieses Modul, +das Dashboard, ein Import — trägt als `pflegeEigenanteilCent` den Netto- +Eigenanteil ein und lässt `pflegekasseCent` auf 0. + +--- + +## 2. `Nachforderung.checklistenSchluessel` — wichtig + +```prisma +/// Stabiler Schluessel aus src/lib/sozialhilfe/checkliste.ts. +/// Verhindert Dubletten beim erneuten Uebernehmen der Standardunterlagen. +checklistenSchluessel String? + +@@unique([antragId, checklistenSchluessel]) +``` + +**Warum**: `ausCheckliste: Boolean` merkt sich nur *dass* eine Zeile aus der +Checkliste kam, nicht *welche* Position. Um beim zweiten Aufruf des Panels +nicht dieselbe Unterlage noch einmal anzulegen, vergleicht +`nochNichtUebernommen()` derzeit über die **Bezeichnung** (kleingeschrieben, +getrimmt). Das reicht, solange niemand die Bezeichnung ändert — tut er es, +entsteht beim nächsten Übernehmen eine Dublette. + +**Behelf**: Vergleich über die Bezeichnung in +`src/lib/sozialhilfe/checkliste.ts` und in `checklisteUebernehmen()`. + +--- + +## 3. Rückkaufswert am Vertrag — wichtig + +```prisma +model Vertrag { + // ... + rueckkaufswertCent BigInt? + rueckkaufswertStichtag DateTime? @db.Date +} +``` + +**Warum**: Die Bewertungsansicht stellt Vermögensposten und Verträge +nebeneinander. Ein Vermögensposten trägt seinen Wert über `Wertstand`, +ein Vertrag hat gar kein Wertfeld — nur `beitragCent`, und das ist die +Prämie, nicht der Wert. Verträge erscheinen deshalb ohne Betrag, und die +Summe „verwertbar“ ist unvollständig, solange nicht zu jeder Versicherung +zusätzlich ein Vermögensposten angelegt wurde. + +Für das Sozialhilfeverfahren ist genau dieser Wert der entscheidende: Der +Träger fragt nach Rückkaufswerten, nicht nach Versicherungssummen. + +**Behelf**: Die Bewertungsansicht zeigt nur Verträge, die überhaupt einen +Wert haben können (`MIT_RUECKKAUFSWERT` aus +`src/lib/vertraege/konstanten.ts`), und markiert sie mit „Wert noch nicht +ermittelt“. Wer den Betrag braucht, legt zusätzlich einen +`Vermoegensposten` mit `vertragId` und einem `Wertstand` an — dann wird der +Vertrag in der Liste ausgeblendet, damit die Summe nicht doppelt zählt. + +--- + +## 4. `Bescheid.rechtsbehelfsbelehrungVorhanden` — mittel + +```prisma +/// Ausdrueckliche Einschaetzung, nicht aus der Fristlaenge abgeleitet. +rechtsbehelfsbelehrungVorhanden Boolean @default(true) +rechtsbehelfsbelehrungBemerkung String? +``` + +**Warum**: Ob die Jahresfrist des § 66 Abs. 2 SGG gilt, ist eine bewusste +Einschätzung mit Begründung („die Belehrung nennt die falsche Behörde“). +Derzeit wird sie aus `rechtsbehelfsfristMonate === 12` zurückgeschlossen — +das trägt, verliert aber die Begründung, und die bräuchte man genau dann, +wenn man sich im Widerspruchsverfahren darauf beruft. + +**Behelf**: `belehrungZuMonaten()` in +`src/lib/sozialhilfe/rechtsbehelf.ts`. Die Begründung gehört bis auf +Weiteres in `notizenVerschluesselt`. + +--- + +## 5. `Bescheid.widerspruchFristId` → `Frist` — mittel + +```prisma +widerspruchFristId String? @unique +widerspruchFrist Frist? @relation(fields: [widerspruchFristId], references: [id], onDelete: SetNull) +``` + +**Warum**: Die angelegte Frist „Widerspruch möglich bis“ wird derzeit über +`Frist.systemSchluessel = "sozialhilfe-widerspruch-"` gefunden. +Das funktioniert (`@@unique([betreuteId, systemSchluessel])` trägt es), ist +aber eine Verknüpfung über eine zusammengesetzte Zeichenkette. Ein echter +Fremdschlüssel wäre sauberer und ließe die Frist beim Löschen des Bescheids +mitziehen. Dasselbe gilt für +`"sozialhilfe-nachforderung-"`. + +**Behelf**: `systemSchluessel` mit festem Präfix, `upsert` statt `create`. + +--- + +## 6. `Heimkostenmonat` — Feld für die tatsächliche Zahlung — mittel + +```prisma +/// Was tatsaechlich vom Konto ging - fuer den Abgleich mit dem Bescheid. +gezahltCent BigInt? +gezahltAm DateTime? @db.Date +rechnungsnummer String? +``` + +**Warum**: Die Gegenüberstellung rechnet Bedarf gegen Deckung. Was +tatsächlich abgebucht wurde, steht nirgends — und genau die Differenz +zwischen „laut Bescheid“ und „tatsächlich abgebucht“ ist der Anlass, beim +Träger nachzufragen. + +**Behelf**: `bemerkung`. + +--- + +## 7. `Heimkostenmonat.abwesenheitsminderungCent` — klein + +```prisma +/// Tatsaechliche Minderung laut Heimrechnung, nicht die Schaetzung. +abwesenheitsminderungCent BigInt @default(0) +``` + +**Warum**: `abwesenheitstage` ist da, die Wirkung schätzt +`abwesenheitSchaetzen()` nach dem Rahmenvertrag (drei Karenztage, danach +25 % auf Pflegeanteil sowie Unterkunft und Verpflegung). Was die +Einrichtung wirklich abgezogen hat, steht auf der Rechnung und ließe sich +nicht festhalten. + +**Behelf**: Die Schätzung wird ausdrücklich als Schätzung ausgewiesen und +neben die erfasste Lücke gestellt, nicht in sie hineingerechnet. + +--- + +## 8. `Leistung.wiederholungsfristMonat/-tag` — klein + +```prisma +/// Fuer jaehrlich zu wiederholende Antraege: Stichtag im Jahr. +antragsschlussMonat Int? +antragsschlussTag Int? +``` + +**Warum**: `jaehrlichNeuBeantragen: Boolean` sagt, *dass* wiederholt werden +muss, nicht *bis wann*. Beim Landespflegegeld ist der 31.12. eine +Ausschlussfrist — daraus ließe sich automatisch eine Frist ableiten, +statt sie von Hand anzulegen. + +**Behelf**: `antragsschluss` als Text im Katalog +(`src/lib/sozialhilfe/leistungskatalog.ts`) und ein Hinweis in der +Oberfläche. Die Fristableitung übernimmt `pflichtfristenAbleiten()` mit +`landespflegegeld-` (siehe `docs/SCHNITTSTELLEN.md`). + +--- + +## 9. `Nachforderung.notizenVerschluesselt` — klein + +**Warum**: `erlaeuterung` und `begruendungNichtVorhanden` liegen im +Klartext. Beides ist meist harmlos („Grundbuchauszug beim Amtsgericht +angefordert“), kann aber Gesundheits- oder Vermögensangaben enthalten +(„Rückkaufswert 12.480 Euro, Police verpfändet“). Wäre mindestens die +Begründung verschlüsselt, wäre das konsequenter zum Rest des Schemas. + +**Behelf**: keiner. Die Felder werden benutzt, wie sie sind. Falls sie +verschlüsselt werden sollen, gehört `Nachforderung` in +`VERSCHLUESSELTE_FELDER` in `src/lib/crypto/feld.ts`. diff --git a/src/app/(app)/sozialhilfe/[antragId]/bescheide/[bescheidId]/page.tsx b/src/app/(app)/sozialhilfe/[antragId]/bescheide/[bescheidId]/page.tsx index a40197b..01c4ee5 100644 --- a/src/app/(app)/sozialhilfe/[antragId]/bescheide/[bescheidId]/page.tsx +++ b/src/app/(app)/sozialhilfe/[antragId]/bescheide/[bescheidId]/page.tsx @@ -1,149 +1,149 @@ -import { notFound } from 'next/navigation' -import { Trash2 } from 'lucide-react' -import { SeitenKopf } from '@/components/seiten-kopf' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { AktionMitRueckfrage } from '@/components/sozialhilfe/bausteine' -import { BescheidFormular } from '@/components/sozialhilfe/bescheid-formular' -import { BescheidPruefung } from '@/components/sozialhilfe/bescheid-pruefung' -import { oeffnen } from '@/lib/crypto/feld' -import { db, nichtGeloescht } from '@/lib/db' -import { alsIsoTag, heuteAlsTag } from '@/lib/fristen/datum' -import { BESCHEID_ART_BESCHRIFTUNG } from '@/lib/sozialhilfe/bescheide' -import { centZuEingabe } from '@/lib/sozialhilfe/betrag' -import { - fristAmpel, - rechtsbehelfsfristBerechnen, - zugangsvermutung, -} from '@/lib/sozialhilfe/rechtsbehelf' -import { sozialhilfeKontext } from '@/lib/sozialhilfe/zugang' -import { bescheidLoeschen } from '@/server/actions/sozialhilfe' -import { formatDatum } from '@/lib/utils' - -export const dynamic = 'force-dynamic' - -/** - * Bescheid-Prüfung. - * - * Der Rechenweg der Widerspruchsfrist steht ausgeschrieben da - die - * Anwendung kann sich irren, und wer eine Frist verpasst, soll sehen - * können, wo die Rechnung abgebogen ist. - */ -export default async function BescheidSeite({ - params, -}: { - params: Promise<{ antragId: string; bescheidId: string }> -}) { - const { antragId, bescheidId } = await params - const { betreuteId, darfSchreiben } = await sozialhilfeKontext() - - const bescheid = await db.bescheid.findFirst({ - where: { id: bescheidId, antragId, antrag: { betreuteId }, ...nichtGeloescht }, - include: { antrag: { select: { id: true, traeger: true, aktenzeichen: true } } }, - }) - if (!bescheid) notFound() - - const offen = oeffnen('Bescheid', bescheid) - const heute = heuteAlsTag() - - const ergebnis = rechtsbehelfsfristBerechnen({ - zugegangenAm: bescheid.zugegangenAm, - bescheidVom: bescheid.bescheidVom, - fristMonate: bescheid.rechtsbehelfsfristMonate, - heute, - }) - - const vorschlag = zugangsvermutung(bescheid.bescheidVom) - - return ( -
- - {bescheid.antrag.traeger} - {bescheid.antrag.aktenzeichen ? ` · Az. ${bescheid.antrag.aktenzeichen}` : ''} · Zugang{' '} - {formatDatum(bescheid.zugegangenAm)} - - } - pfad={[ - { titel: 'Start', href: '/heute' }, - { titel: 'Sozialhilfe', href: '/sozialhilfe' }, - { titel: 'Antragsakte', href: `/sozialhilfe/${antragId}` }, - { titel: 'Bescheid' }, - ]} - /> - - - - {offen.notizen && ( - - - Notizen - Verschlüsselt gespeichert. - - -

{offen.notizen}

-
-
- )} - - {darfSchreiben && ( -
-

Bescheid bearbeiten

- - -
- - -
-
- )} -
- ) -} +import { notFound } from 'next/navigation' +import { Trash2 } from 'lucide-react' +import { SeitenKopf } from '@/components/seiten-kopf' +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' +import { AktionMitRueckfrage } from '@/components/sozialhilfe/bausteine' +import { BescheidFormular } from '@/components/sozialhilfe/bescheid-formular' +import { BescheidPruefung } from '@/components/sozialhilfe/bescheid-pruefung' +import { oeffnen } from '@/lib/crypto/feld' +import { db, nichtGeloescht } from '@/lib/db' +import { alsIsoTag, heuteAlsTag } from '@/lib/fristen/datum' +import { BESCHEID_ART_BESCHRIFTUNG } from '@/lib/sozialhilfe/bescheide' +import { betragFormatieren } from '@/lib/finanzen/betrag' +import { + fristAmpel, + rechtsbehelfsfristBerechnen, + zugangsvermutung, +} from '@/lib/sozialhilfe/rechtsbehelf' +import { sozialhilfeKontext } from '@/lib/sozialhilfe/zugang' +import { bescheidLoeschen } from '@/server/actions/sozialhilfe' +import { formatDatum } from '@/lib/utils' + +export const dynamic = 'force-dynamic' + +/** + * Bescheid-Prüfung. + * + * Der Rechenweg der Widerspruchsfrist steht ausgeschrieben da - die + * Anwendung kann sich irren, und wer eine Frist verpasst, soll sehen + * können, wo die Rechnung abgebogen ist. + */ +export default async function BescheidSeite({ + params, +}: { + params: Promise<{ antragId: string; bescheidId: string }> +}) { + const { antragId, bescheidId } = await params + const { betreuteId, darfSchreiben } = await sozialhilfeKontext() + + const bescheid = await db.bescheid.findFirst({ + where: { id: bescheidId, antragId, antrag: { betreuteId }, ...nichtGeloescht }, + include: { antrag: { select: { id: true, traeger: true, aktenzeichen: true } } }, + }) + if (!bescheid) notFound() + + const offen = oeffnen('Bescheid', bescheid) + const heute = heuteAlsTag() + + const ergebnis = rechtsbehelfsfristBerechnen({ + zugegangenAm: bescheid.zugegangenAm, + bescheidVom: bescheid.bescheidVom, + fristMonate: bescheid.rechtsbehelfsfristMonate, + heute, + }) + + const vorschlag = zugangsvermutung(bescheid.bescheidVom) + + return ( +
+ + {bescheid.antrag.traeger} + {bescheid.antrag.aktenzeichen ? ` · Az. ${bescheid.antrag.aktenzeichen}` : ''} · Zugang{' '} + {formatDatum(bescheid.zugegangenAm)} + + } + pfad={[ + { titel: 'Start', href: '/heute' }, + { titel: 'Sozialhilfe', href: '/sozialhilfe' }, + { titel: 'Antragsakte', href: `/sozialhilfe/${antragId}` }, + { titel: 'Bescheid' }, + ]} + /> + + + + {offen.notizen && ( + + + Notizen + Verschlüsselt gespeichert. + + +

{offen.notizen}

+
+
+ )} + + {darfSchreiben && ( +
+

Bescheid bearbeiten

+ + +
+ + +
+
+ )} +
+ ) +} diff --git a/src/app/(app)/sozialhilfe/heimkosten/page.tsx b/src/app/(app)/sozialhilfe/heimkosten/page.tsx index 256b71f..0ef689c 100644 --- a/src/app/(app)/sozialhilfe/heimkosten/page.tsx +++ b/src/app/(app)/sozialhilfe/heimkosten/page.tsx @@ -1,318 +1,383 @@ -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 { centZuEingabe } from '@/lib/sozialhilfe/betrag' -import { db, nichtGeloescht } 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, - 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) - const vorschlagPflegekasse = pauschale - ? { - betrag: centZuEingabe(pauschale), - text: `Pflegegrad ${betreute.pflegegrad}: ${formatCent(pauschale)} monatlich (${pflegekasseRechtsgrundlage(betreute.pflegegrad)}, Stand ${KONSTANTEN_STAND}).`, - } - : null - - 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 && ( - - - )} - - - - 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

- -
- - -
- ) -} +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, nichtGeloescht } 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) +} diff --git a/src/app/(app)/sozialhilfe/vermoegen/page.tsx b/src/app/(app)/sozialhilfe/vermoegen/page.tsx index 1ae9ecd..46926df 100644 --- a/src/app/(app)/sozialhilfe/vermoegen/page.tsx +++ b/src/app/(app)/sozialhilfe/vermoegen/page.tsx @@ -1,229 +1,232 @@ -import { SeitenKopf } from '@/components/seiten-kopf' -import { Rechtshinweis } from '@/components/rechtshinweis' -import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' -import { Card, CardContent } from '@/components/ui/card' -import { Vermoegensliste, type ListenPosten } from '@/components/sozialhilfe/vermoegensliste' -import { oeffnen } from '@/lib/crypto/feld' -import { centZuZahl, db, nichtGeloescht } from '@/lib/db' -import { alsIsoTag } from '@/lib/fristen/datum' -import { VERMOEGENSART_BESCHRIFTUNG, VERMOEGENSRELEVANTE_VERTRAGSARTEN, VERTRAGSART_BESCHRIFTUNG } from '@/lib/sozialhilfe/arten' -import { BEWERTUNG_BESCHRIFTUNG } from '@/lib/sozialhilfe/schonvermoegen' -import { freibetragVergleichen, uebersichtBilden } from '@/lib/sozialhilfe/vermoegensuebersicht' -import { sozialhilfeKontext } from '@/lib/sozialhilfe/zugang' -import { formatCent } from '@/lib/utils' -import { AlertCircle } from 'lucide-react' - -export const dynamic = 'force-dynamic' - -/** - * Vermögens-Bewertungsansicht. - * - * Sie zählt zusammen und stellt gegenüber - sie entscheidet nichts. Was - * geschützt ist, sagt der Träger; bleibt man uneins, das Sozialgericht. - * Deshalb heißt die Spalte "Einschätzung" und nicht "Bewertung". - */ -export default async function VermoegensbewertungSeite() { - const { betreuteId, darfSchreiben } = await sozialhilfeKontext() - - const [posten, vertraege] = await Promise.all([ - db.vermoegensposten.findMany({ - where: { betreuteId, ...nichtGeloescht }, - include: { wertstaende: { orderBy: { stichtag: 'desc' }, take: 1 } }, - orderBy: { bezeichnung: 'asc' }, - }), - db.vertrag.findMany({ - where: { - betreuteId, - art: { in: [...VERMOEGENSRELEVANTE_VERTRAGSARTEN] }, - ...nichtGeloescht, - }, - orderBy: { bezeichnung: 'asc' }, - }), - ]) - - // Verträge, die schon als Vermögensposten geführt werden, nicht doppelt - // zeigen - sonst wäre die Summe zweimal drin. - const bereitsAlsPosten = new Set( - posten.map((p) => p.vertragId).filter((id): id is string => id !== null), - ) - - const zeilen: ListenPosten[] = [ - ...posten.map((p) => { - const geoeffnet = oeffnen('Vermoegensposten', p) - const stand = p.wertstaende[0] - return { - id: p.id, - bezeichnung: p.bezeichnung, - herkunft: 'VERMOEGEN' as const, - art: p.art, - artBeschriftung: VERMOEGENSART_BESCHRIFTUNG[p.art], - bewertung: p.bewertungSozialhilfe, - wertCent: stand ? centZuZahl(stand.wertCent) : null, - wertStichtag: stand ? alsIsoTag(stand.stichtag) : null, - begruendung: geoeffnet.bewertungBegruendung ?? '', - zusatz: stand ? stand.wertquelle : null, - } - }), - ...vertraege - .filter((v) => !bereitsAlsPosten.has(v.id)) - .map((v) => { - const geoeffnet = oeffnen('Vertrag', v) - return { - id: v.id, - bezeichnung: v.bezeichnung, - herkunft: 'VERTRAG' as const, - art: v.art, - artBeschriftung: VERTRAGSART_BESCHRIFTUNG[v.art], - bewertung: v.bewertungSozialhilfe, - // Der Rückkaufswert steht am Vertrag nicht als Betrag; er wird - // als Vermögensposten mit Wertstand geführt. Bis dahin: offen. - wertCent: null, - wertStichtag: null, - begruendung: geoeffnet.bewertungBegruendung ?? '', - zusatz: v.gesellschaft, - } - }), - ] - - const uebersicht = uebersichtBilden( - zeilen.map((z) => ({ - id: z.id, - bezeichnung: z.bezeichnung, - herkunft: z.herkunft, - artBeschriftung: z.artBeschriftung, - bewertung: z.bewertung, - wertCent: z.wertCent === null ? null : BigInt(z.wertCent), - wertStichtag: null, - begruendung: z.begruendung, - href: '#', - })), - ) - - const vergleich = freibetragVergleichen(uebersicht.jeBewertung.VERWERTBAR.summeCent) - - return ( -
- - -
- - - - -
- - - -
- - Vermögensfreibetrag (§ 90 Abs. 2 Nr. 9 SGB XII) - - - {formatCent(vergleich.freibetragCent)} - -
-
- Über dem Freibetrag - - {formatCent(vergleich.ueberFreibetragCent)} - -
-

{vergleich.hinweis}

- -
-
- - {uebersicht.ungeprueft.length > 0 && ( - - - )} - - {uebersicht.ohneBegruendung.length > 0 && ( - - - )} - - - - -
- ) -} - -function Summenkachel({ - titel, - betrag, - anzahl, - ohneWert, - farbe, -}: { - titel: string - betrag: bigint - anzahl: number - ohneWert: number - farbe: string -}) { - return ( - - -

{titel}

-

{formatCent(betrag)}

-

- {anzahl} {anzahl === 1 ? 'Posten' : 'Posten'} - {ohneWert > 0 && `, davon ${ohneWert} ohne Wert`} -

-
-
- ) -} +import { SeitenKopf } from '@/components/seiten-kopf' +import { Rechtshinweis } from '@/components/rechtshinweis' +import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' +import { Card, CardContent } from '@/components/ui/card' +import { Vermoegensliste, type ListenPosten } from '@/components/sozialhilfe/vermoegensliste' +import { oeffnen } from '@/lib/crypto/feld' +import { centZuZahl, db, nichtGeloescht } from '@/lib/db' +import { alsIsoTag } from '@/lib/fristen/datum' +import { VERMOEGENS_ART_BESCHRIFTUNG } from '@/lib/finanzen/kategorien' +import { MIT_RUECKKAUFSWERT, VERTRAG_ART_BESCHRIFTUNG } from '@/lib/vertraege/konstanten' +import { BEWERTUNG_BESCHRIFTUNG } from '@/lib/sozialhilfe/schonvermoegen' +import { freibetragVergleichen, uebersichtBilden } from '@/lib/sozialhilfe/vermoegensuebersicht' +import { sozialhilfeKontext } from '@/lib/sozialhilfe/zugang' +import { formatCent } from '@/lib/utils' +import { AlertCircle } from 'lucide-react' + +export const dynamic = 'force-dynamic' + +/** + * Vermögens-Bewertungsansicht. + * + * Sie zählt zusammen und stellt gegenüber - sie entscheidet nichts. Was + * geschützt ist, sagt der Träger; bleibt man uneins, das Sozialgericht. + * Deshalb heißt die Spalte "Einschätzung" und nicht "Bewertung". + */ +export default async function VermoegensbewertungSeite() { + const { betreuteId, darfSchreiben } = await sozialhilfeKontext() + + const [posten, vertraege] = await Promise.all([ + db.vermoegensposten.findMany({ + where: { betreuteId, ...nichtGeloescht }, + include: { wertstaende: { orderBy: { stichtag: 'desc' }, take: 1 } }, + orderBy: { bezeichnung: 'asc' }, + }), + db.vertrag.findMany({ + where: { + betreuteId, + // Nur Vertraege, die ueberhaupt einen Wert darstellen koennen. Ein + // Stromvertrag hat keinen Rueckkaufswert und wuerde die Liste zumuellen. + art: { in: [...MIT_RUECKKAUFSWERT] }, + ...nichtGeloescht, + }, + orderBy: { bezeichnung: 'asc' }, + }), + ]) + + // Verträge, die schon als Vermögensposten geführt werden, nicht doppelt + // zeigen - sonst wäre die Summe zweimal drin. + const bereitsAlsPosten = new Set( + posten.map((p) => p.vertragId).filter((id): id is string => id !== null), + ) + + const zeilen: ListenPosten[] = [ + ...posten.map((p) => { + const geoeffnet = oeffnen('Vermoegensposten', p) + const stand = p.wertstaende[0] + return { + id: p.id, + bezeichnung: p.bezeichnung, + herkunft: 'VERMOEGEN' as const, + art: p.art, + artBeschriftung: VERMOEGENS_ART_BESCHRIFTUNG[p.art], + bewertung: p.bewertungSozialhilfe, + wertCent: stand ? centZuZahl(stand.wertCent) : null, + wertStichtag: stand ? alsIsoTag(stand.stichtag) : null, + begruendung: geoeffnet.bewertungBegruendung ?? '', + zusatz: stand ? stand.wertquelle : null, + } + }), + ...vertraege + .filter((v) => !bereitsAlsPosten.has(v.id)) + .map((v) => { + const geoeffnet = oeffnen('Vertrag', v) + return { + id: v.id, + bezeichnung: v.bezeichnung, + herkunft: 'VERTRAG' as const, + art: v.art, + artBeschriftung: VERTRAG_ART_BESCHRIFTUNG[v.art], + bewertung: v.bewertungSozialhilfe, + // Der Rückkaufswert steht am Vertrag nicht als Betrag; er wird + // als Vermögensposten mit Wertstand geführt. Bis dahin: offen. + wertCent: null, + wertStichtag: null, + begruendung: geoeffnet.bewertungBegruendung ?? '', + zusatz: v.gesellschaft, + } + }), + ] + + const uebersicht = uebersichtBilden( + zeilen.map((z) => ({ + id: z.id, + bezeichnung: z.bezeichnung, + herkunft: z.herkunft, + artBeschriftung: z.artBeschriftung, + bewertung: z.bewertung, + wertCent: z.wertCent === null ? null : BigInt(z.wertCent), + wertStichtag: null, + begruendung: z.begruendung, + href: '#', + })), + ) + + const vergleich = freibetragVergleichen(uebersicht.jeBewertung.VERWERTBAR.summeCent) + + return ( +
+ + +
+ + + + +
+ + + +
+ + Vermögensfreibetrag (§ 90 Abs. 2 Nr. 9 SGB XII) + + + {formatCent(vergleich.freibetragCent)} + +
+
+ Über dem Freibetrag + + {formatCent(vergleich.ueberFreibetragCent)} + +
+

{vergleich.hinweis}

+ +
+
+ + {uebersicht.ungeprueft.length > 0 && ( + + + )} + + {uebersicht.ohneBegruendung.length > 0 && ( + + + )} + + + + +
+ ) +} + +function Summenkachel({ + titel, + betrag, + anzahl, + ohneWert, + farbe, +}: { + titel: string + betrag: bigint + anzahl: number + ohneWert: number + farbe: string +}) { + return ( + + +

{titel}

+

{formatCent(betrag)}

+

+ {anzahl} {anzahl === 1 ? 'Posten' : 'Posten'} + {ohneWert > 0 && `, davon ${ohneWert} ohne Wert`} +

+
+
+ ) +} diff --git a/src/components/sozialhilfe/heimkosten-formular.tsx b/src/components/sozialhilfe/heimkosten-formular.tsx index 7a2c822..ab2e008 100644 --- a/src/components/sozialhilfe/heimkosten-formular.tsx +++ b/src/components/sozialhilfe/heimkosten-formular.tsx @@ -1,326 +1,310 @@ -'use client' - -import { useActionState, useState } from 'react' -import { Feld, Feldgruppe } from '@/components/feld' -import { Rechtshinweis } from '@/components/rechtshinweis' -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' -import { Input } from '@/components/ui/input' -import { Select } from '@/components/ui/select' -import { Textarea } from '@/components/ui/textarea' -import { Absenden, Meldung } from '@/components/sozialhilfe/bausteine' -import { MONATSNAMEN } from '@/lib/sozialhilfe/heimkosten' -import { heimkostenSpeichern, type Formularzustand } from '@/server/actions/sozialhilfe' - -export type HeimkostenWerte = { - jahr: number - monat: number - pflegeEigenanteil: string - unterkunftVerpflegung: string - investitionskosten: string - ausbildungsumlage: string - zusatzleistungen: string - pflegekasse: string - leistungszuschlagProzent: number - leistungszuschlag: string - rente: string - sonstigeEinkuenfte: string - sozialhilfe: string - eigenmittel: string - barbetrag: string - bekleidungspauschale: string - abwesenheitstage: number - bemerkung: string -} - -/** - * Ein Monat der Gegenüberstellung. - * - * Die Reihenfolge folgt der Heimrechnung: erst die vier Bausteine der - * Kosten, dann die Deckungsquellen, dann das, was der betreuten Person - * verbleiben muss. Wer von oben nach unten abtippt, findet alles an der - * Stelle, an der es auf der Rechnung steht. - */ -export function HeimkostenFormular({ - werte, - jahre, - vorschlagPflegekasse, - vorschlagBarbetrag, -}: { - werte: HeimkostenWerte - jahre: number[] - /** Pauschale der Pflegekasse zum hinterlegten Pflegegrad, als "1319,00". */ - vorschlagPflegekasse: { betrag: string; text: string } | null - vorschlagBarbetrag: { betrag: string; text: string } -}) { - const [zustand, aktion] = useActionState(heimkostenSpeichern, {}) - const [pflegekasse, setPflegekasse] = useState(werte.pflegekasse) - const [barbetrag, setBarbetrag] = useState(werte.barbetrag) - - return ( -
- - - - - Monat erfassen - - Beträge wie auf der Heimrechnung, z.B. 1.234,56. Ein bereits erfasster Monat wird - überschrieben. - - - - -
- - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - {vorschlagPflegekasse.text}{' '} - - - ) : ( - 'Pauschale nach § 43 SGB XI. Hinterlege den Pflegegrad in den Stammdaten, dann steht hier ein Vorschlag.' - ) - } - > - setPflegekasse(e.target.value)} - /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {vorschlagBarbetrag.text}{' '} - - - } - > - setBarbetrag(e.target.value)} - /> - - - - - - - - - - - - -