employees.email ist die private Adresse (20260811140000). Sie taugt nicht als Dienstadresse und darf auch nicht als solche benutzt werden: der Honestly-Export geht an einen fremden Anbieter, der damit im Namen des Arbeitgebers einlaedt. Die Spalte "Email" stand dort deshalb seit jeher leer, mit einem Vermerk in lib/honestly.ts, dass die Firmenadresse im Datenmodell fehlt. Jetzt gibt es sie, und die Spalte fuellt sich. Eindeutig, aber freiwillig -- mehrere Personen ohne Adresse stoeren den Index nicht, weil null nie gleich null ist. Geschrieben wird ueber `case when ? then nullif` statt `coalesce`: eine Dienstadresse muss sich auch wieder entfernen lassen. Vier SQL-Funktionen mussten mit, weil `create or replace` die ganze Fassung ersetzt und ein ausgelassenes Feld dort still verschwindet: hire_employee und rehire_employee (beide teilen sich den Schritt "Person" -- das Formular haette das Feld gezeigt und den Wert weggeworfen), change_employee_data (sonst nicht aenderbar), apply_due_pending_changes (sonst verfiele eine auf spaeter datierte Aenderung) und die Feldkarte (sonst waere der Eintrag in der Historie nicht korrigierbar). Die Selbstpruefung am Ende prueft jede einzeln.
93 lines
4.6 KiB
TypeScript
93 lines
4.6 KiB
TypeScript
import type { HireDraftData } from "@/components/hire/types";
|
|
import { MITARBEITERART_STANDARD } from "./mitarbeiterart";
|
|
import type { Database } from "./types";
|
|
|
|
type EmployeeRow = Database["public"]["Tables"]["employees"]["Row"];
|
|
|
|
// Eine bestehende Person als Vorbelegung für den Wiedereintritt.
|
|
//
|
|
// Der Kunde wollte für die Wiedereinstellung denselben Assistenten wie für
|
|
// eine Neueinstellung, „bereits mit den hier festgelegten Daten
|
|
// prepopulated". Diese Abbildung ist genau das: die Zeile der Person in die
|
|
// Form, die der Assistent führt.
|
|
//
|
|
// ── Warum genau die Felder des Assistenten und keines mehr ──────────
|
|
//
|
|
// Der Rückgabetyp ist `Partial<HireDraftData>` und nicht ein eigener. Damit
|
|
// lässt sich hier nur eintragen, was der Assistent auch zeigt — und das ist
|
|
// die Bedingung dafür, dass er nichts verschickt, was niemand gesehen hat.
|
|
//
|
|
// Konkret fehlen Anschrift, Staatsbürgerschaft und Aufenthaltstitel: der
|
|
// Assistent fragt sie auch bei einer Neueinstellung nicht (sie werden später
|
|
// über „Daten ändern" gepflegt). `rehire_employee` lässt jedes nicht
|
|
// übermittelte Feld unangetastet stehen, sie bleiben also, wie sie sind.
|
|
//
|
|
// ── Was bewusst NICHT übernommen wird ───────────────────────────────
|
|
//
|
|
// * **Die Planstelle.** Sie ist beim Wiedereintritt immer neu zu wählen:
|
|
// die alte kann besetzt, ausgelaufen oder ganz entfallen sein. Ein
|
|
// vorbelegter Platz, den es so nicht mehr gibt, wäre schlimmer als ein
|
|
// leeres Feld — er sieht nach einer Antwort aus.
|
|
// * **Das Eintrittsdatum.** Der alte Eintritt ist Geschichte; das neue
|
|
// Datum ist die eigentliche Angabe dieses Vorgangs.
|
|
// * **Der Austritt.** Datum, Grund und Austrittsart räumt
|
|
// `rehire_employee` weg.
|
|
// * **Die Angehörigen.** Sie stehen schon in der Akte; der Assistent würde
|
|
// sie ein zweites Mal anlegen.
|
|
//
|
|
// Die Personalnummer kommt mit, aber nur zur Anzeige: es ist dieselbe Person,
|
|
// und `rehire_employee` fasst die Spalte nicht an.
|
|
|
|
export function vorbelegungAus(employee: EmployeeRow): Partial<HireDraftData> {
|
|
return {
|
|
personnelNumber: String(employee.personnel_number),
|
|
firstName: employee.first_name,
|
|
lastName: employee.last_name,
|
|
titlePrefix: employee.title_prefix ?? [],
|
|
titleSuffix: employee.title_suffix ?? [],
|
|
gender: employee.gender,
|
|
birthDate: employee.birth_date,
|
|
svNummer: employee.sv_nummer ?? "",
|
|
email: employee.email ?? "",
|
|
// Vorbelegt wie die private Adresse, obwohl eine Dienstadresse beim
|
|
// Austritt meist abgedreht wird: der Assistent schickt das Feld in jedem
|
|
// Fall mit, und leer geliefert löschte es die gespeicherte Adresse
|
|
// stillschweigend. Sichtbar vorbelegt lässt sie sich bewusst ersetzen
|
|
// oder leeren.
|
|
companyEmail: employee.company_email ?? "",
|
|
phone: employee.phone ?? "",
|
|
locationId: employee.location_id,
|
|
besetzung: employee.source,
|
|
contractType: employee.contract_type,
|
|
contractEndDate: employee.contract_end_date ?? "",
|
|
employmentType: employee.employment_type,
|
|
// Als Text, weil das Feld im Assistenten eines ist: ein leeres Zahlenfeld
|
|
// landete sonst als 0 im Entwurf.
|
|
weeklyHours: String(employee.weekly_hours),
|
|
paygrade: employee.paygrade,
|
|
workerType: employee.worker_type,
|
|
mitarbeiterart: employee.mitarbeiterart ?? MITARBEITERART_STANDARD,
|
|
collectiveAgreement: employee.collective_agreement,
|
|
workDays: employee.work_days,
|
|
isBetriebsrat: employee.is_betriebsrat,
|
|
hasDienstwagen: employee.has_dienstwagen,
|
|
// Die Antriebsart steht auf null, sobald kein Wagen da ist. Der Assistent
|
|
// führt sie trotzdem mit, damit sie beim Anhaken wieder da ist —
|
|
// „Verbrenner" ist dabei die Vorgabe, nicht eine Behauptung.
|
|
dienstwagenArt: employee.dienstwagen_art ?? "Verbrenner",
|
|
isLateraleFuehrung: employee.is_laterale_fuehrung,
|
|
isCLevel: employee.is_c_level,
|
|
emergencyContactName: employee.emergency_contact_name ?? "",
|
|
emergencyContactPhone: employee.emergency_contact_phone ?? "",
|
|
emergencyContactRelation: employee.emergency_contact_relation ?? "",
|
|
hasKuendigungsschutz: employee.has_kuendigungsschutz,
|
|
kuendigungsschutzGrund: employee.kuendigungsschutz_grund ?? "",
|
|
kuendigungsschutzAb: employee.kuendigungsschutz_ab ?? "",
|
|
kuendigungsschutzBis: employee.kuendigungsschutz_bis ?? "",
|
|
istBeguenstigtBehindert: employee.ist_beguenstigt_behindert,
|
|
behinderungGrad: employee.behinderung_grad === null ? "" : String(employee.behinderung_grad),
|
|
behinderungAb: employee.behinderung_ab ?? "",
|
|
behinderungBis: employee.behinderung_bis ?? "",
|
|
};
|
|
}
|