Uebernahme: extern auf intern ist ein eigenes Ereignis

Aus dem Gespraech vom 17.09.2026. Migrationen 20260917110000 (Enum-Wert)
und 20260917120000 (Logik) — getrennt, weil ein in derselben Transaktion
angelegter Enum-Wert dort noch nicht benutzt werden darf.

Die Besetzungsart (extern/intern) wurde bisher nur bei der Neueinstellung
gesetzt und war danach unerreichbar. Eine Angabe, die mit dem ersten Tag
erstarrt, obwohl gerade ihr Wechsel der Vorgang ist, um den es geht. Sie
steht jetzt in "Daten aendern".

Wechselt sie von Extern auf Intern, entsteht das Ereignis "Uebernahme" — in
der Personalakte und im Protokoll, und im Berichtemanager als Ereignistyp
auswertbar. Der umgekehrte Weg bekommt ausdruecklich keines: eine Uebernahme
zurueckzunehmen gibt es fachlich nicht.

Zwei Eintraege und nicht einer: die Vertragsaenderung haelt fest, dass ein
Feld sich geaendert hat und worauf (und laesst sich darueber zuruecknehmen),
das Ereignis, dass dieser Wechsel eine Uebernahme war. Nur das zweite laesst
sich zaehlen.

Eine auf spaeter datierte Uebernahme erzeugt das Ereignis sofort mit
pending_id, wie die Vertragsaenderung daneben; der Nachtlauf schreibt am
Stichtag nur noch die Spalte. Die Selbstpruefung haelt fest, dass er kein
zweites Ereignis schreibt — sonst staende die Uebernahme doppelt in der Akte
und jede Auswertung zaehlte sie zweimal.

Im Assistenten erscheint das Feld nicht: dort steht die Besetzungsart im
Schritt "Position", und zweimal danach zu fragen waere eine Einladung, zwei
verschiedene Antworten zu geben.
This commit is contained in:
2026-09-17 12:10:50 +02:00
parent 9ded472d25
commit 6ab78d4b27
9 changed files with 676 additions and 3 deletions

View File

@@ -8,7 +8,7 @@ import {
} from "@/lib/kuendigungsschutz";
import { MITARBEITERARTEN } from "@/lib/mitarbeiterart";
import { sortiereWochentage, WOCHENTAGE } from "@/lib/wochentage";
import type { CollectiveAgreement, DienstwagenArt, Mitarbeiterart, Weekday, WorkerType } from "@/lib/types";
import type { CollectiveAgreement, DienstwagenArt, Mitarbeiterart, SourceType, Weekday, WorkerType } from "@/lib/types";
export type RoleEmploymentValue = {
@@ -19,6 +19,21 @@ export type RoleEmploymentValue = {
* von beidem sagen.
*/
mitarbeiterart: Mitarbeiterart;
/**
* Extern oder intern besetzt.
*
* Wurde bisher nur bei der Neueinstellung gesetzt und war danach
* unerreichbar — eine Angabe, die mit dem ersten Tag erstarrt, obwohl
* gerade ihr Wechsel der Vorgang ist, um den es geht: von extern auf
* intern ist eine **Übernahme** und wird als eigenes Ereignis protokolliert
* (Migration 20260917120000).
*
* Nicht gesetzt heisst: dieses Formular fragt die Besetzungsart nicht. So
* ist es im Einstellungsassistenten — dort steht sie im Schritt „Position",
* wo sie hingehört, und zweimal danach zu fragen wäre eine Einladung, zwei
* verschiedene Antworten zu geben.
*/
source?: SourceType;
collectiveAgreement: CollectiveAgreement;
workDays: Weekday[];
isBetriebsrat: boolean;
@@ -110,6 +125,23 @@ export function RoleEmploymentFields({ value, onChange }: { value: RoleEmploymen
onChange={(v) => onChange({ mitarbeiterart: v as Mitarbeiterart })}
options={MITARBEITERARTEN.map((a) => ({ value: a, label: a }))}
/>
{/* Der Wechsel von extern auf intern ist eine Übernahme und wird als
eigenes Ereignis protokolliert — der Hinweis steht am Feld, damit
niemand ihn erst im Protokoll entdeckt. Der umgekehrte Weg
erzeugt nichts; das ist Absicht und keine Lücke. */}
{value.source !== undefined && (
<SelectField
label="Besetzungsart"
dense
value={value.source}
onChange={(v) => onChange({ source: v as SourceType })}
options={[
{ value: "Extern", label: "Extern" },
{ value: "Intern", label: "Intern" },
]}
hint={value.source === "Extern" ? "Ein Wechsel auf „Intern“ wird als Übernahme protokolliert." : undefined}
/>
)}
<SelectField
label="Kollektivvertrag"
dense