Files
admin 1e221a3c2c Vertriebsunterstützung an Reisezeit koppeln
- Reisezeit 0 -> Vertriebsunterstützung 0
- Reisezeit < 2h -> Vertriebsunterstützung = Reisezeit (Feld gesperrt)
- Reisezeit >= 2h -> Vertriebsunterstützung 2h, aber editierbar
- Regel zentral in lib/calc.ts (applyVertriebsregel), im Formular interaktiv
  und in der API-Validierung erzwungen

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 10:23:07 +02:00

79 lines
2.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Reine Hilfsfunktionen für Datum-/Zeit-Berechnungen (ohne DB-Zugriff).
const WOCHENTAGE = [
'Sonntag',
'Montag',
'Dienstag',
'Mittwoch',
'Donnerstag',
'Freitag',
'Samstag',
];
/** "HH:MM" → Minuten seit Mitternacht, oder null bei ungültiger Eingabe. */
export function parseHM(hm: string): number | null {
const m = /^(\d{1,2}):(\d{2})$/.exec(hm ?? '');
if (!m) return null;
const h = Number(m[1]);
const min = Number(m[2]);
if (h < 0 || h > 23 || min < 0 || min > 59) return null;
return h * 60 + min;
}
/**
* Differenz zwischen Beginn und Ende in dezimalen Stunden.
* Gibt 0 zurück, wenn eine Zeit ungültig ist. Ende vor Beginn ⇒ 0.
*/
export function toDecimalHours(beginn: string, ende: string): number {
const b = parseHM(beginn);
const e = parseHM(ende);
if (b === null || e === null) return 0;
const diff = e - b;
if (diff <= 0) return 0;
return diff / 60;
}
/** Mehrarbeit = Arbeitszeit 8 Stunden Pause (kann negativ sein). */
export function mehrarbeit(arbeitszeitStd: number, pauseStd: number): number {
return arbeitszeitStd - 8 - pauseStd;
}
/** True, wenn sowohl Beginn als auch Ende gültige Uhrzeiten sind (beide angegeben). */
export function hatZeiten(beginn: string, ende: string): boolean {
return parseHM(beginn) !== null && parseHM(ende) !== null;
}
/** True, wenn die Vertriebsunterstützung bei dieser Reisezeit frei änderbar ist (Reisezeit ≥ 2h). */
export function vertriebEditierbar(reisezeit: number): boolean {
return reisezeit >= 2;
}
/**
* Vertriebsunterstützung an die Reisezeit koppeln:
* Reisezeit = 0 → 0
* 0 < Reisezeit < 2 → = Reisezeit
* Reisezeit ≥ 2 → vorhandener Wert (änderbar), Standard 2
*/
export function applyVertriebsregel(reisezeit: number, vorhanden: number): number {
if (reisezeit <= 0) return 0;
if (reisezeit < 2) return reisezeit;
return vorhanden;
}
/** Deutscher Wochentagsname für ein "YYYY-MM-DD"-Datum, oder "" bei ungültig. */
export function weekdayName(datum: string): string {
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(datum ?? '');
if (!m) return '';
const d = new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
if (isNaN(d.getTime())) return '';
return WOCHENTAGE[d.getDay()];
}
/** Dezimalstunden deutsch formatieren, z.B. 0.5 → "0,5". */
export function formatHours(value: number): string {
return value.toLocaleString('de-DE', {
minimumFractionDigits: 1,
maximumFractionDigits: 2,
});
}