feat: Immobilie, Versicherungen und Heim mit COPD-Verlauf
Etappe 6. Das leerstehende Haus, die Vertraege und der Gesundheitsverlauf - die drei Bereiche, in denen fuer diesen Fall das meiste Geld und das meiste Risiko liegt. Leerstands-Checkliste mit zehn Punkten, jeder mit Begruendung. Der wichtigste: den Gebaeudeversicherer ueber den Leerstand informieren - sonst droht Leistungsfreiheit, und zwar genau dann, wenn es brennt oder eine Leitung platzt. Dazu Verkehrssicherungspflicht, Frostschutz zum Oktober, Kontrollgaenge, Zaehlerstaende, Schluesselverzeichnis. Der Kuendigungsrechner nennt den spaetesten ABSENDETAG, nicht den Fristablauf: eine Kuendigung wirkt mit dem Zugang, nicht mit dem Abschicken. Drei Tage Postlaufpuffer sind einkalkuliert. Der Kuendigungs-Assistent beantwortet die Genehmigungsfrage nach § 1850 BGB nicht - er stellt sie und verlangt den Gang zum Rechtspfleger. Der Versandnachweis ist Pflichtfeld: ohne ihn kommt die Kuendigung nicht durch die Pruefung. Leistungszuschlag nach § 43c SGB XI mit Stand 01.01.2024 (15/30/50/75 Prozent nach Verweildauer, erst ab Pflegegrad 2). Die Oberflaeche zeigt, ab wann die naechste Stufe greift - das ist bares Geld und wird regelmaessig uebersehen. COPD-Schnellerfassung fuer Exazerbation, Sauerstoff, Sturz, Krankenhaus, Hilfsmittel und Impfungen, mit STIKO-Plan fuer COPD. Beschreibungen verschluesselt. Die Jahresauswertung ueber Exazerbationen und Krankenhaustage wandert in den Jahresbericht und begruendet eine Hoeherstufung. 74 Tests. Etappe: 6 Phase: Substanz
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
'use client'
|
||||
|
||||
import { useActionState, useState } from 'react'
|
||||
import { Coins, Mail, Plus } from 'lucide-react'
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Select } from '@/components/ui/select'
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { Feld } from '@/components/feld'
|
||||
import { Leerzustand } from '@/components/seiten-kopf'
|
||||
import { Absendeknopf, Textbaustein, Zustandsmeldung } from '@/components/substanz-formular'
|
||||
import { WERTQUELLEN_VERTRAG } from '@/lib/vertraege/konstanten'
|
||||
import { rueckkaufswertAnfordern, rueckkaufswertErfassen } from '@/server/actions/vertraege'
|
||||
import { formatCent, formatDatum } from '@/lib/utils'
|
||||
import type { Formularzustand } from '@/lib/validierung/substanz'
|
||||
|
||||
export type RueckkaufswertZeile = {
|
||||
id: string
|
||||
stichtag: string
|
||||
wertCent: number
|
||||
wertquelle: string
|
||||
bemerkung: string | null
|
||||
}
|
||||
|
||||
export function Rueckkaufswert({
|
||||
betreuteId,
|
||||
vertragId,
|
||||
werte,
|
||||
angefragtAm,
|
||||
erinnerungFaellig,
|
||||
tageSeitAnfrage,
|
||||
anschreiben,
|
||||
stichtagVorschlag,
|
||||
darfSchreiben,
|
||||
}: {
|
||||
betreuteId: string
|
||||
vertragId: string
|
||||
werte: RueckkaufswertZeile[]
|
||||
angefragtAm: string | null
|
||||
erinnerungFaellig: boolean
|
||||
tageSeitAnfrage: number | null
|
||||
anschreiben: string
|
||||
stichtagVorschlag: string
|
||||
darfSchreiben: boolean
|
||||
}) {
|
||||
const [erfassen, erfassenAktion] = useActionState<Formularzustand, FormData>(
|
||||
rueckkaufswertErfassen,
|
||||
{},
|
||||
)
|
||||
const [anfrage, anfrageAktion] = useActionState<Formularzustand, FormData>(
|
||||
rueckkaufswertAnfordern,
|
||||
{},
|
||||
)
|
||||
const [briefOffen, setBriefOffen] = useState(false)
|
||||
const [erfassenOffen, setErfassenOffen] = useState(false)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<Coins className="size-5" aria-hidden="true" />
|
||||
Rückkaufswert
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Der Bezirk verlangt zu jedem Versicherungsvertrag den Rückkaufswert zu einem
|
||||
Stichtag — schriftlich von der Gesellschaft, nicht geschätzt. Die Antwort dauert
|
||||
erfahrungsgemäß drei bis sechs Wochen.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="space-y-5">
|
||||
{angefragtAm && (
|
||||
<Alert variant={erinnerungFaellig ? 'warnung' : 'hinweis'}>
|
||||
<Mail aria-hidden="true" />
|
||||
<AlertTitle>
|
||||
Angefragt am {formatDatum(angefragtAm)}
|
||||
{tageSeitAnfrage !== null && ` — vor ${tageSeitAnfrage} Tagen`}
|
||||
</AlertTitle>
|
||||
<AlertDescription>
|
||||
{erinnerungFaellig
|
||||
? 'Die vier Wochen sind um. Ruf an und halte das Gespräch im Kontaktprotokoll fest — schriftlich nachfassen dauert wieder vier Wochen.'
|
||||
: 'Die Wiedervorlage steht in den Fristen. Kommt die Antwort früher, hak die Frist dort ab.'}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{werte.length === 0 ? (
|
||||
<Leerzustand
|
||||
titel="Noch kein Rückkaufswert erfasst"
|
||||
beschreibung="Fordere ihn bei der Gesellschaft an. Frag im selben Schreiben nach der beitragsfreien Versicherungssumme — sonst musst du für den Vergleich ein zweites Mal schreiben."
|
||||
icon={Coins}
|
||||
aktion={
|
||||
darfSchreiben && (
|
||||
<Button type="button" onClick={() => setBriefOffen(true)}>
|
||||
<Mail aria-hidden="true" />
|
||||
Anschreiben erzeugen
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Stichtag</TableHead>
|
||||
<TableHead className="text-right">Rückkaufswert</TableHead>
|
||||
<TableHead>Quelle</TableHead>
|
||||
<TableHead>Bemerkung</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{werte.map((zeile) => (
|
||||
<TableRow key={zeile.id}>
|
||||
<TableCell className="whitespace-nowrap">{formatDatum(zeile.stichtag)}</TableCell>
|
||||
<TableCell className="text-right font-medium tabular-nums">
|
||||
{formatCent(zeile.wertCent)}
|
||||
</TableCell>
|
||||
<TableCell>{zeile.wertquelle}</TableCell>
|
||||
<TableCell className="text-sm text-muted-foreground">
|
||||
{zeile.bemerkung ?? '–'}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
|
||||
{darfSchreiben && (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Button type="button" variant="outline" onClick={() => setBriefOffen((o) => !o)}>
|
||||
<Mail aria-hidden="true" />
|
||||
{briefOffen ? 'Anschreiben schließen' : 'Rückkaufswert anfordern'}
|
||||
</Button>
|
||||
<Button type="button" variant="outline" onClick={() => setErfassenOffen((o) => !o)}>
|
||||
<Plus aria-hidden="true" />
|
||||
{erfassenOffen ? 'Eingabe schließen' : 'Mitgeteilten Wert eintragen'}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{darfSchreiben && briefOffen && (
|
||||
<div className="space-y-4 rounded-md border p-4">
|
||||
<Textbaustein
|
||||
text={anschreiben}
|
||||
beschriftung="Anschreiben an die Gesellschaft"
|
||||
hoehe="min-h-[32rem]"
|
||||
/>
|
||||
|
||||
<form action={anfrageAktion} className="space-y-4" noValidate>
|
||||
<input type="hidden" name="betreuteId" value={betreuteId} />
|
||||
<input type="hidden" name="vertragId" value={vertragId} />
|
||||
|
||||
<Zustandsmeldung zustand={anfrage} />
|
||||
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
<Feld
|
||||
id="anfrage-stichtag"
|
||||
beschriftung="Stichtag der Anfrage"
|
||||
erklaerung="Der Tag, zu dem der Wert mitgeteilt werden soll. Für die Sozialhilfe meist der Tag der Antragstellung."
|
||||
fehler={anfrage.felder?.stichtag}
|
||||
pflicht
|
||||
>
|
||||
<Input
|
||||
name="stichtag"
|
||||
type="date"
|
||||
defaultValue={stichtagVorschlag}
|
||||
required
|
||||
/>
|
||||
</Feld>
|
||||
</div>
|
||||
|
||||
<Absendeknopf>Anfrage vermerken und Wiedervorlage anlegen</Absendeknopf>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Setzt das Datum der Anfrage am Vertrag und legt eine Wiedervorlage in vier
|
||||
Wochen an. Den Brief selbst schickst du von Hand ab — die App verschickt nichts.
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{darfSchreiben && erfassenOffen && (
|
||||
<form action={erfassenAktion} className="space-y-4 rounded-md border p-4" noValidate>
|
||||
<input type="hidden" name="betreuteId" value={betreuteId} />
|
||||
<input type="hidden" name="vertragId" value={vertragId} />
|
||||
|
||||
<Zustandsmeldung zustand={erfassen} />
|
||||
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
<Feld
|
||||
id="rkw-stichtag"
|
||||
beschriftung="Stichtag"
|
||||
fehler={erfassen.felder?.stichtag}
|
||||
pflicht
|
||||
>
|
||||
<Input name="stichtag" type="date" required />
|
||||
</Feld>
|
||||
|
||||
<Feld
|
||||
id="rkw-wert"
|
||||
beschriftung="Rückkaufswert"
|
||||
fehler={erfassen.felder?.wert}
|
||||
pflicht
|
||||
>
|
||||
<Input name="wert" inputMode="decimal" placeholder="4.812,55" required />
|
||||
</Feld>
|
||||
|
||||
<Feld
|
||||
id="rkw-quelle"
|
||||
beschriftung="Quelle"
|
||||
erklaerung="Woher stammt die Zahl? Eine telefonische Auskunft ist besser als nichts, aber kein Nachweis."
|
||||
fehler={erfassen.felder?.wertquelle}
|
||||
pflicht
|
||||
className="sm:col-span-2"
|
||||
>
|
||||
<Select name="wertquelle" defaultValue={WERTQUELLEN_VERTRAG[0]}>
|
||||
{WERTQUELLEN_VERTRAG.map((q) => (
|
||||
<option key={q} value={q}>
|
||||
{q}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
</Feld>
|
||||
</div>
|
||||
|
||||
<Feld
|
||||
id="rkw-bemerkung"
|
||||
beschriftung="Bemerkung"
|
||||
erklaerung="z. B. die beitragsfreie Versicherungssumme, wenn sie mitgeteilt wurde."
|
||||
fehler={erfassen.felder?.bemerkung}
|
||||
>
|
||||
<Textarea name="bemerkung" rows={2} maxLength={1000} />
|
||||
</Feld>
|
||||
|
||||
<Absendeknopf>Wert aufnehmen</Absendeknopf>
|
||||
</form>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user