import type { GesundheitsArt } from '@prisma/client' import { tag, tageZwischen, tagesdatum } from '@/lib/fristen/datum' /** * Abwesenheitstage. * * Warum das gezaehlt wird: Liegt die betreute Person im Krankenhaus, wird * der Heimplatz freigehalten, aber nicht voll berechnet. Ab einer im * Heimvertrag geregelten Zahl von Tagen mindert sich der Eigenanteil. * Die Einrichtung zieht das nicht immer von selbst ab, und der * Sozialhilfetraeger rechnet es erst recht nicht nach - wer die Tage nicht * mitzaehlt, zahlt zu viel. * * Gezaehlt werden die Tage zwischen Aufnahme und Entlassung; der * Entlassungstag zaehlt nicht mit, weil die betreute Person an diesem Tag * wieder im Heim verpflegt wird. Ob der Aufnahmetag mitzaehlt, regelt der * Heimvertrag unterschiedlich - deshalb laesst sich die Zahl an jedem * Ereignis von Hand ueberschreiben. */ export type AbwesenheitsEreignis = { datum: Date bisDatum: Date | null abwesenheitstage: number | null art: GesundheitsArt } export type Abwesenheitsjahr = { jahr: number tage: number /** Wie viele Ereignisse haben zu diesen Tagen beigetragen? */ ereignisse: number } /** * Tage eines einzelnen Ereignisses. Ist die Zahl von Hand eingetragen, * gilt sie; sonst wird aus dem Zeitraum gerechnet. */ export function tageEines(ereignis: AbwesenheitsEreignis): number { if (ereignis.abwesenheitstage !== null && ereignis.abwesenheitstage >= 0) { return ereignis.abwesenheitstage } if (!ereignis.bisDatum) return 0 return Math.max(0, tageZwischen(ereignis.datum, ereignis.bisDatum)) } /** * Summe je Kalenderjahr. * * Ein Aufenthalt ueber den Jahreswechsel wird auf beide Jahre aufgeteilt - * die Heimrechnung kommt monatlich, und der Jahresbericht braucht die Tage * dort, wo sie angefallen sind. Nur wenn die Tageszahl von Hand * eingetragen wurde, wird sie ungeteilt dem Jahr des Beginns zugeordnet: * Dann hat jemand bewusst eine Zahl gesetzt, und die soll nicht durch eine * Automatik zerlegt werden. */ export function abwesenheitstageJeJahr( ereignisse: AbwesenheitsEreignis[], ): Abwesenheitsjahr[] { const jahre = new Map() const dazu = (jahr: number, tage: number) => { if (tage <= 0) return const vorhanden = jahre.get(jahr) if (vorhanden) { vorhanden.tage += tage } else { jahre.set(jahr, { jahr, tage, ereignisse: 0 }) } } for (const ereignis of ereignisse) { const beginn = tagesdatum(ereignis.datum) const handgezaehlt = ereignis.abwesenheitstage !== null && ereignis.abwesenheitstage >= 0 if (handgezaehlt) { dazu(beginn.getUTCFullYear(), ereignis.abwesenheitstage!) zaehleEreignis(jahre, beginn.getUTCFullYear()) continue } if (!ereignis.bisDatum) continue const ende = tagesdatum(ereignis.bisDatum) if (ende.getTime() <= beginn.getTime()) continue // Jahresweise zerlegen. let abschnittVon = beginn while (abschnittVon.getTime() < ende.getTime()) { const jahr = abschnittVon.getUTCFullYear() const jahresende = tag(jahr + 1, 1, 1) const abschnittBis = jahresende.getTime() < ende.getTime() ? jahresende : ende dazu(jahr, tageZwischen(abschnittVon, abschnittBis)) zaehleEreignis(jahre, jahr) abschnittVon = abschnittBis } } return [...jahre.values()].sort((a, b) => b.jahr - a.jahr) } function zaehleEreignis(jahre: Map, jahr: number): void { const eintrag = jahre.get(jahr) if (eintrag) eintrag.ereignisse += 1 } /** Gesamtsumme ueber alle Jahre - fuer die Kachel auf der Uebersicht. */ export function abwesenheitstageGesamt(jahre: Abwesenheitsjahr[]): number { return jahre.reduce((summe, j) => summe + j.tage, 0) }