Vor Vermoegensverzeichnis und Jahresbericht braucht es von jeder Lebens- und Rentenversicherung den Rueckkaufswert zum Stichtag - jedes Mal dieselben fuenf bis zehn Briefe. Neu unter Vertraege: Stichtag waehlen, Liste pruefen, ein Klick. Heraus kommt ein ZIP mit einer Word-Datei je Gesellschaft plus Begleitblatt; je Vertrag entstehen nebenbei die PDF-Fassung in der Akte, die Wiedervorlage nach 28 Tagen und der Anfragevermerk. Aufbau: - Auswahllogik als reine Funktionen in vertraege/serienabfrage.ts: Vorauswahl, Hindernisse mit Begruendung statt stummem Ausblenden, 28-Tage-Sperre im Gleichschritt mit der Wiedervorlage. - Der Lauf in vertraege/serienlauf.ts: je Vertrag das volle Paket aus Issue #4, aber in einem Durchgang. Kein Alles-oder-nichts - ein gescheiterter Vertrag steht mit Grund im Begleitblatt, die uebrigen laufen durch. Eine Transaktion ueber alle waere die falsche Zusage. - Dublettenschutz tagesgenau: Der Doppelklick erzeugt nichts Doppeltes, die bewusste zweite Anfrage nach einer Woche bleibt moeglich. - Die Anzahl steht vor dem Klick auf dem Knopf. Gekuendigte Vertraege bleiben anfragbar: Bis zum Wirksamwerden besteht der Vertrag, und genau dann will der Sozialhilfetraeger den Wert sehen. Geprueft: zwoelf Einheitstests, drei End-to-End-Tests inklusive der Nebenwirkungen in der Datenbank und des Dublettenschutzes. 602 Unit-Tests, 87 e2e, null Typfehler. Refs #6
93 lines
3.3 KiB
TypeScript
93 lines
3.3 KiB
TypeScript
import type { Metadata } from 'next'
|
|
import { redirect } from 'next/navigation'
|
|
import { Scale } from 'lucide-react'
|
|
import { Alert, AlertDescription } from '@/components/ui/alert'
|
|
import { SeitenKopf } from '@/components/seiten-kopf'
|
|
import {
|
|
SerienabfrageFormular,
|
|
type SerienZeile,
|
|
} from '@/components/vertraege/serienabfrage-formular'
|
|
import { aktiveBetreute, erfordereBenutzer, erfordereZugang } from '@/lib/auth/sitzung'
|
|
import { db, nichtGeloescht } from '@/lib/db'
|
|
import { kandidatenBewerten } from '@/lib/vertraege/serienabfrage'
|
|
import { VERTRAG_ART_BESCHRIFTUNG } from '@/lib/vertraege/konstanten'
|
|
import { heuteAlsTag } from '@/lib/fristen/datum'
|
|
|
|
export const metadata: Metadata = { title: 'Rückkaufswerte anfragen' }
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
/**
|
|
* Die Serienabfrage: alle Rückkaufswerte in einem Zug.
|
|
*
|
|
* Liegt unter /vertraege/serienabfrage/seite, weil /vertraege/serienabfrage
|
|
* die POST-Route ist, die das ZIP liefert. Die Trennung ist Absicht: Die
|
|
* Route hat Nebenwirkungen und gehört nicht hinter einen GET.
|
|
*/
|
|
export default async function SerienabfrageSeite() {
|
|
const benutzer = await erfordereBenutzer('/vertraege/serienabfrage/seite')
|
|
const aktive = await aktiveBetreute(benutzer)
|
|
if (!aktive) redirect('/ersteinrichtung')
|
|
|
|
const { darfSchreiben } = await erfordereZugang(aktive.id, 'VERTRAEGE', 'lesen')
|
|
if (!darfSchreiben('VERTRAEGE')) redirect('/vertraege')
|
|
|
|
const vertraege = await db.vertrag.findMany({
|
|
where: { betreuteId: aktive.id, ...nichtGeloescht },
|
|
select: {
|
|
id: true,
|
|
bezeichnung: true,
|
|
gesellschaft: true,
|
|
art: true,
|
|
status: true,
|
|
rueckkaufswertAngefragtAm: true,
|
|
},
|
|
})
|
|
|
|
const bewertet = kandidatenBewerten(vertraege)
|
|
|
|
// Vertraege ohne jede Aussicht auf einen Rueckkaufswert (Strom, Telefon,
|
|
// Rundfunk) wuerden die Liste nur verlaengern - sie bleiben draussen.
|
|
// Alles andere steht drin, notfalls mit Hindernis.
|
|
const zeilen: SerienZeile[] = bewertet
|
|
.filter(
|
|
(k) => k.moeglich || k.hindernis !== 'Diese Vertragsart bildet keinen Rückkaufswert.',
|
|
)
|
|
.map((k) => ({
|
|
vertragId: k.vertrag.id,
|
|
bezeichnung: k.vertrag.bezeichnung,
|
|
gesellschaft: k.vertrag.gesellschaft,
|
|
artBeschriftung: VERTRAG_ART_BESCHRIFTUNG[k.vertrag.art],
|
|
moeglich: k.moeglich,
|
|
hindernis: k.hindernis,
|
|
vorausgewaehlt: k.vorausgewaehlt,
|
|
}))
|
|
|
|
return (
|
|
<div className="max-w-3xl space-y-6">
|
|
<SeitenKopf
|
|
titel="Rückkaufswerte anfragen"
|
|
beschreibung="Alle Lebens- und Rentenversicherungen in einem Zug — ein ZIP mit einem Schreiben je Gesellschaft, die Nachweise in der Akte, die Wiedervorlagen gesetzt."
|
|
pfad={[
|
|
{ titel: 'Verträge', href: '/vertraege' },
|
|
{ titel: 'Rückkaufswerte anfragen' },
|
|
]}
|
|
/>
|
|
|
|
<SerienabfrageFormular
|
|
betreuteId={aktive.id}
|
|
zeilen={zeilen}
|
|
stichtagVorschlag={heuteAlsTag().toISOString().slice(0, 10)}
|
|
/>
|
|
|
|
<Alert variant="hinweis">
|
|
<Scale aria-hidden="true" />
|
|
<AlertDescription>
|
|
Die Schreiben sind Entwürfe zum Ausdrucken und Unterschreiben — versendet wird nichts
|
|
automatisch. Keine Rechtsberatung; bei Fragen zur Verwertungspflicht entscheidet der
|
|
Sozialhilfeträger.
|
|
</AlertDescription>
|
|
</Alert>
|
|
</div>
|
|
)
|
|
}
|