/** * Laufende Nummern je Wehr und Jahr. * * Prüfprotokolle, Einsätze und Übungen tragen dieselbe Art von Nummer: * `JJJJ-NNNN`, fortlaufend innerhalb eines Jahres, je Wehr getrennt. Sie steht * auf Papier und wird am Telefon genannt — deshalb kurz, sprechbar und ohne * Bindestrichwüste. * * Die Nummern werden nie wiederverwendet. Vergeben wird die höchste vorhandene * plus eins, nicht die Anzahl der Datensätze; sonst bekäme ein im * Aufbewahrungslauf entfernter Vorgang seine Nummer an einen neuen vererbt. * * Reine Zeichenkettenarbeit, kein Datenbankzugriff: wer die Nummer vergibt, * muss dabei selbst für eine Sperre sorgen (siehe `abschliessen` im * Prüfungs-Router und `anlegen` im Einsatz-Router). */ /** Vier Stellen reichen für 9999 Vorgänge im Jahr — mehr hat keine Wehr. */ const STELLEN = 4; /** Bildet "2026-0042". */ export function nummerBilden(jahr: number, laufend: number): string { return `${jahr}-${String(laufend).padStart(STELLEN, "0")}`; } /** Zerlegt eine Nummer wieder. Gibt null zurück, wenn sie nicht passt. */ export function nummerLesen( nummer: string | null | undefined, ): { jahr: number; laufend: number } | null { if (!nummer) return null; const treffer = /^(\d{4})-(\d{1,6})$/.exec(nummer.trim()); if (!treffer) return null; return { jahr: Number(treffer[1]), laufend: Number(treffer[2]) }; } /** * Die nächste Nummer nach der bisher höchsten. * * @param hoechste die bisher höchste Nummer des Jahres, oder null */ export function naechsteNummer(jahr: number, hoechste: string | null | undefined): string { return nummerBilden(jahr, (nummerLesen(hoechste)?.laufend ?? 0) + 1); }