import type { Project, Uebergabezeitpunkt } from "@prisma/client"; export const UEBERGABE_LABEL: Record = { INBETRIEBNAHME: "zur Inbetriebnahme", BAUAKTE_II_IBN: "Bauakte Teil II (IBN-Akte)", IBN_PLUS_3M: "3 Monate nach IBN", IBN_PLUS_6M: "6 Monate nach IBN", BAUAKTE_I_BAUENDE_6M: "Bauakte Teil I – 6 Monate nach Bauende", PROJEKTABSCHLUSS: "zum Projektabschluss", }; function plusMonths(d: Date, m: number) { const x = new Date(d); x.setMonth(x.getMonth() + m); return x; } /** * Rechnet den Übergabezeitpunkt aus der Ablagestruktur gegen die * Projekttermine und liefert die konkrete Frist. * Es gilt die früheste erreichbare Frist – so entsteht kein Stau am Projektende. */ export function berechneFrist( uebergabe: Uebergabezeitpunkt[], projekt: Pick, ): Date | null { const kandidaten: Date[] = []; for (const u of uebergabe) { switch (u) { case "INBETRIEBNAHME": case "BAUAKTE_II_IBN": if (projekt.inbetriebnahme) kandidaten.push(projekt.inbetriebnahme); break; case "IBN_PLUS_3M": if (projekt.inbetriebnahme) kandidaten.push(plusMonths(projekt.inbetriebnahme, 3)); break; case "IBN_PLUS_6M": if (projekt.inbetriebnahme) kandidaten.push(plusMonths(projekt.inbetriebnahme, 6)); break; case "BAUAKTE_I_BAUENDE_6M": if (projekt.bauende) kandidaten.push(plusMonths(projekt.bauende, 6)); break; case "PROJEKTABSCHLUSS": if (projekt.projektabschluss) kandidaten.push(projekt.projektabschluss); break; } } if (kandidaten.length === 0) return null; return new Date(Math.min(...kandidaten.map((d) => d.getTime()))); } /** Aufbewahrungsende gemäß Ablagestruktur (Jahre nach Bauschlussmeldung). */ export function berechneAufbewahrung( jahre: string | null, nutzungsdauer: boolean, bauschlussmeldung: Date | null, ): { bis: Date | null; hinweis: string } { if (nutzungsdauer) return { bis: null, hinweis: "Nutzungsdauer der Anlage" }; if (!jahre) return { bis: null, hinweis: "nicht festgelegt" }; const m = jahre.match(/(\d+)/); if (!m) return { bis: null, hinweis: jahre }; const n = parseInt(m[1], 10); if (!bauschlussmeldung) return { bis: null, hinweis: `${n} Jahre nach Bauschlussmeldung` }; const bis = new Date(bauschlussmeldung); bis.setFullYear(bis.getFullYear() + n); return { bis, hinweis: `${n} Jahre nach Bauschlussmeldung` }; } export type Ampel = "GRUEN" | "GELB" | "ROT" | "GRAU"; export function fristAmpel(frist: Date | null, erledigt: boolean, heute = new Date()): Ampel { if (erledigt) return "GRUEN"; if (!frist) return "GRAU"; const tage = Math.floor((frist.getTime() - heute.getTime()) / 864e5); if (tage < 0) return "ROT"; if (tage <= 30) return "GELB"; return "GRUEN"; } export const FACHBEREICHE_NETZ = [ "Oberbau", "Tiefbau", "Konstruktiver Ingenieurbau", "Hochbau", "Elektrotechnik 50 Hz", "LST", "Tk (inkl. HOA, FBOA)", "Oberleitung 16,7 Hz", "Maschinentechnik", ]; export const FACHBEREICHE_BAHNHOF = [ "Hoch-, Tief- und Ingenieurbau/Verkehrsanlagen inkl. baulichem Brandschutz", "HLS (KG 410/420/430/435)", "Starkstromanlagen 50 Hz, Erdung (KG 440)", "Blitzschutz (KG 446)", "TK-Anlagen (KG 450)", "Fördertechnik (KG 460)", "Gebäudeautomation (KG 480)", ];