267 lines
9.7 KiB
Markdown
267 lines
9.7 KiB
Markdown
# HR KPI Nachdokumentation 2026-05-13
|
|
|
|
## Nachtrag 2026-05-20 HR KPI Cockpit Ausbau
|
|
|
|
Die urspruengliche HR-KPI-Doku wurde um den produktiven Cockpit-Ausbau ergaenzt.
|
|
|
|
Neu bzw. erweitert:
|
|
|
|
- `Anleitung`-Reiter im HR KPI Cockpit.
|
|
- Datenordner fuer Rexx-/SAP-Dateien ist im Cockpit sichtbar und je Lauf anpassbar; dauerhaft ueber `HrKpi:DataFolder`.
|
|
- Dateistatus zeigt Pfad, Zeilenanzahl, letzte Aenderung, Dateialter und Frischebewertung.
|
|
- Managementsicht anonymisiert Personennamen in Detailtabellen.
|
|
- Ampel-Reiter fuer Fluktuation, Krankenquote, GLZ, Restferien und Datenqualitaet.
|
|
- Filter fuer GLZ-Ampel und Restferien-Ampel.
|
|
- Periodenvergleich fuer wichtige Kennzahlen, soweit Daten vorhanden sind.
|
|
- Datenqualitaets-Hinweise fuer fehlende/alte Dateien und auffaellige Werte.
|
|
- Austritte nach Austrittsart und Organisation.
|
|
- Absenzen nach Organisation, Top-Absenzen und Drucken/PDF.
|
|
|
|
Anwenderdoku:
|
|
|
|
- `docs/HR_KPI_ANLEITUNG_HR_2026-05-20.docx`
|
|
- `docs/hr_kpi_cockpit_preview.png`
|
|
|
|
Validierung:
|
|
|
|
- `dotnet test TrafagSalesExporter.sln --verbosity minimal`
|
|
- Ergebnis: `77/77` Tests gruen.
|
|
|
|
## Ziel
|
|
|
|
Das HR KPI Cockpit wurde als separater, fachlich entkoppelter Reiter umgesetzt. Es nutzt PowerBI-M-/DAX-Logik nicht als generischen Interpreter, sondern als fachliche Vorlage, die in nachvollziehbare C#-Logik uebertragen wurde.
|
|
|
|
Der Reiter ist vom Finance-/Management-Cockpit getrennt. Er nutzt nur gemeinsame technische Infrastruktur wie Blazor, MudBlazor, DI, ClosedXML und bestehende Programmstruktur.
|
|
|
|
## Eingebaute HR KPI Funktion
|
|
|
|
Neue Navigation:
|
|
|
|
- `HR KPI` im Hauptmenue.
|
|
- Route: `/hr-kpi`.
|
|
|
|
Neue zentrale Dateien:
|
|
|
|
- `Components/Pages/HrKpi.razor`
|
|
- `Components/HrKpi/HrKpiDashboardTabs.razor`
|
|
- `Models/HrKpiModels.cs`
|
|
- `Services/HrKpiService.cs`
|
|
- `Services/HrKpi/HrKpiDashboardBuilder.cs`
|
|
- `TrafagSalesExporter.Tests/HrKpiServiceTests.cs`
|
|
|
|
## Datenquellen
|
|
|
|
Standard-Datenordner:
|
|
|
|
```text
|
|
C:\temp
|
|
```
|
|
|
|
Konfigurierbar ueber `appsettings.json`:
|
|
|
|
```json
|
|
"HrKpi": {
|
|
"DataFolder": "C:\\temp",
|
|
"MainFile": "Saldiperstichdatum.xlsx",
|
|
"TimeFile": "Exportkommengehen.xlsx",
|
|
"SapFile": "HR_KPI_Export.xlsx",
|
|
"AbsenceFile": "Abwesenheitinstunden.xlsx",
|
|
"LeaverFile": "Personalausgeschieden.xlsx"
|
|
}
|
|
```
|
|
|
|
Verarbeitete Dateien:
|
|
|
|
- `Saldiperstichdatum.xlsx`: aktive Mitarbeitende, Saldi, Ferien, Organisation, Kostenstelle.
|
|
- `Exportkommengehen.xlsx`: Arbeitszeitmodell, Sollzeit, Geburtsdatum.
|
|
- `HR_KPI_Export.xlsx`: SAP-HR-Felder wie Beschaeftigungsgrad, Geschlecht, BU/NBU, Planstelle.
|
|
- `Abwesenheitinstunden.xlsx`: Krankheit kurz/lang in Stunden.
|
|
- `Personalausgeschieden.xlsx`: Austritte, Austrittsart, Austrittsdatum.
|
|
|
|
## Dashboard-Reiter
|
|
|
|
Das Cockpit zeigt folgende Tabs:
|
|
|
|
- `Ueberblick`
|
|
- `Fluktuation`
|
|
- `Absenzen`
|
|
- `Zeit / Ferien`
|
|
- `Mitarbeitende`
|
|
- `Datenstatus`
|
|
|
|
Im Fluktuationsbereich wurden zusaetzliche Visualisierungen ergaenzt:
|
|
|
|
- Jahres-Fluktuations-Gauge
|
|
- Austritts-Funnel
|
|
- Donut nach Ausschlussgruenden
|
|
- relevante Austritte nach Organisation
|
|
- relevante Austritte pro Monat
|
|
|
|
## Filter
|
|
|
|
Aktuell vorhandene Filter:
|
|
|
|
- Datenordner
|
|
- Austrittsjahr
|
|
- Von Austritt
|
|
- Bis Austritt
|
|
- Organisation
|
|
- Eintrittsjahr
|
|
- Suche Name / Personalnummer
|
|
- Kostenstelle
|
|
- Mitarbeitertyp
|
|
- Fluktuation
|
|
- GLZ-Ampel
|
|
- Restferien-Ampel
|
|
|
|
## Korrektur Austrittsjahr / Von-Bis
|
|
|
|
Problem:
|
|
|
|
- `Austrittsjahr` war als `int` modelliert.
|
|
- Dadurch war immer ein Jahr gesetzt.
|
|
- Leeren bzw. "alle Austrittsjahre" war nicht moeglich.
|
|
- Aus Sicht UI wirkte es so, als ob leere Auswahl nicht uebernommen wird.
|
|
|
|
Umsetzung:
|
|
|
|
- `HrKpiOptions.Year` wurde von `int` auf `int?` geaendert.
|
|
- `Austrittsjahr` ist in der UI jetzt ein `MudSelect<int?>` mit `Clearable`.
|
|
- Die Jahresauswahl wird aus den vorhandenen Austrittsdaten gebaut.
|
|
- Neues Result-Feld: `ExitYearOptions`.
|
|
- Wenn `Austrittsjahr` leer ist, werden alle Austrittsjahre geladen.
|
|
- Wenn `Von Austritt` oder `Bis Austritt` gesetzt ist, hat dieser Zeitraum Vorrang vor `Austrittsjahr`.
|
|
|
|
Regel:
|
|
|
|
```text
|
|
Von/Bis gesetzt -> Austrittsdatum muss im Zeitraum liegen
|
|
Von/Bis leer und Austrittsjahr gesetzt -> Austrittsjahr muss passen
|
|
Von/Bis leer und Austrittsjahr leer -> alle Austritte
|
|
```
|
|
|
|
Nach der Architektur-/Formelpruefung wurde zusaetzlich korrigiert:
|
|
|
|
- `Austrittsjahr` ist auch beim Start leer und wird nicht mehr automatisch mit dem aktuellen Kalenderjahr vorbelegt.
|
|
- Bei leerem Austrittsjahr werden keine Jahres-/Quartals-/Monats-Fluktuationskennzahlen als Jahreswerte vorgetaeuscht; die Anzeige wird als `Fluktuation Auswahl` gefuehrt.
|
|
- Bei Von/Bis oder Mehrjahresauswahl zeigt die Timeline Jahresgruppen, wenn kein eindeutiges einzelnes Auswertungsjahr vorliegt.
|
|
- Die Fluktuationsberechnung nutzt fuer Mitarbeitendenfilter nur Felder, die in Mitarbeitendenbestand und Austrittsdaten vergleichbar sind: Organisation, Mitarbeitertyp, Eintrittsjahr und Suche.
|
|
- Kostenstelle, GLZ und Restferien filtern aktive Mitarbeitende/Absenzen, aber nicht Fluktuation, weil die Austrittsdatei diese Felder nicht stabil enthaelt. Das Cockpit weist darauf hin.
|
|
- Fluktuationsvisuals zaehlen Austritte distinct nach Personalnummer statt Zeilen.
|
|
- Fluktuationsraten nutzen Headcount, nicht FTE.
|
|
- `Headcount Monat` wird als Durchschnitt aus Monatsanfang und Monatsende berechnet.
|
|
- `Avg Headcount Quartal` ist der Durchschnitt der Monats-Headcounts im Quartal.
|
|
- `Avg Headcount Jahr` ist der Durchschnitt der Monats-Headcounts im Jahr.
|
|
- `Headcount nach Organisation` zaehlt Personalnummern distinct und ignoriert leere Personalnummern.
|
|
- Krankenquote nutzt neu `Krankheitstage / (FTE * 21 Tage)` statt `Krankheitstage / (Headcount * 21 Tage)`.
|
|
|
|
## Fluktuationslogik
|
|
|
|
Die Fluktuation wird aus den ausgeschiedenen Personen berechnet.
|
|
|
|
Grundlage gemaess `formeln.docx`:
|
|
|
|
- Monat: Arbeitnehmerkuendigungen des jeweiligen Monats / Headcount des Monats.
|
|
- Quartal: Arbeitnehmerkuendigungen des aktuellen Quartals / durchschnittlicher Headcount des Quartals.
|
|
- Hochrechnung Jahr: aktuelle Quartals-Fluktuation x 4.
|
|
- Effektiv Jahr: Arbeitnehmerkuendigungen des gesamten Jahres / durchschnittlicher Headcount des Jahres.
|
|
- Nenner ist Headcount der Festangestellten, nicht FTE.
|
|
|
|
Relevant ist ein Austritt, wenn:
|
|
|
|
- Austrittsart als Arbeitnehmer-/Mitarbeiterkuendigung erkannt wird.
|
|
- Mitarbeitertyp nicht ausgeschlossen ist.
|
|
- Austrittsgrund nicht als befristet, Pensionierung, Arbeitgeberkuendigung oder anderer Ausschlussgrund erkannt wird.
|
|
|
|
Ausgeschlossen werden unter anderem:
|
|
|
|
- Praktikant
|
|
- Werkstudent
|
|
- Aushilfe
|
|
- Lehrling
|
|
- befristeter Vertrag
|
|
- Pensionierung/Rente
|
|
- Kuendigung durch Trafag/Arbeitgeber
|
|
|
|
Zusaetzlich korrigiert:
|
|
|
|
- Rexx-Werte mit Umlaut wie `Kuendigung AN` werden trotz Originalschreibweise `Kündigung AN` als Arbeitnehmerkuendigung erkannt.
|
|
- `Kuendigung AG` bleibt als Arbeitgeberkuendigung ausgeschlossen.
|
|
- `Ruhestand` wird als Pensionierung ausgeschlossen.
|
|
|
|
## Architektur-Cleanup
|
|
|
|
Vorher:
|
|
|
|
- `HrKpiService` enthielt Import, Mapping, Filter, KPI-Berechnung, Visual-Daten und Excel-Parsing in einer grossen Klasse.
|
|
- `HrKpi.razor` enthielt Route, Filter, alle Tabs, Tabellen, Visualisierungen und CSS.
|
|
|
|
Nachher:
|
|
|
|
- `HrKpiService.cs` ist nur noch DI-/Service-Fassade.
|
|
- `HrKpiDashboardBuilder.cs` enthaelt die Build-Pipeline fuer Import, Mapping, Filter und KPI-Berechnung.
|
|
- `HrKpi.razor` bleibt fuer Route, Filter und Laden zustaendig.
|
|
- `HrKpiDashboardTabs.razor` enthaelt die Tabs, Tabellen, Fluktuationsvisuals und Styles.
|
|
- HR-Datenquellen sind ueber `HrKpiDataSourceOptions` konfigurierbar.
|
|
|
|
## Tests
|
|
|
|
Neue HR-KPI-Regressionstests:
|
|
|
|
- Organisation-Filter wirkt auch auf Absenzen.
|
|
- Von/Bis-Austrittsdatum hat Vorrang vor Austrittsjahr.
|
|
- Leeres Austrittsjahr liefert Austritte aus allen Jahren.
|
|
- Austrittsjahr ist standardmaessig leer.
|
|
- Employee-only Filter verzerren die Fluktuationsbasis nicht.
|
|
- Fluktuationsvisuals zaehlen distinct nach Personalnummer.
|
|
- Rexx-Austrittsarten `Kündigung AN`, `Kündigung AG` und `Ruhestand` werden korrekt klassifiziert.
|
|
- Fluktuationsraten verwenden durchschnittlichen Headcount statt aktuellen Stichtagsbestand.
|
|
- Mitarbeitende ohne Personalnummer werden nicht im Distinct-Headcount gezaehlt.
|
|
- FTE-Fallback aus Arbeitszeitmodell/Sollzeit wird verwendet, wenn SAP-Beschaeftigungsgrad fehlt.
|
|
- Fluktuationsrelevanz und Visual-Daten werden klassifiziert.
|
|
|
|
Aktueller Teststand nach der Korrektur:
|
|
|
|
```text
|
|
dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false --verbosity minimal
|
|
dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal
|
|
```
|
|
|
|
Ergebnis:
|
|
|
|
- Build erfolgreich.
|
|
- Tests erfolgreich: `69/69`.
|
|
|
|
Kontrollwert aus `C:\temp\Personalausgeschieden.xlsx`:
|
|
|
|
- Austritte total: `104`
|
|
- `Kündigung AN`: `42`
|
|
- `Kündigung AG`: `34`
|
|
- Fluktuationsrelevant nach aktueller HR-Logik: `33`
|
|
- Avg Headcount 2025 nach Intervalllogik: `211.3`
|
|
- Fluktuation Jahr effektiv 2025: `15.6%`
|
|
|
|
## Offene fachliche Pruefpunkte
|
|
|
|
Diese Punkte sind nicht automatisch geloest und muessen fachlich von HR bestaetigt werden:
|
|
|
|
- Ob die Abgrenzung "fluktuationsrelevant" exakt der Trafag-HR-Definition entspricht.
|
|
- Ob Arbeitnehmerkuendigungen anhand der vorhandenen Austrittsart-Texte vollstaendig erkannt werden.
|
|
- Ob Praktikanten, Werkstudenten, Aushilfen und Lehrlinge immer aus der Fluktuation ausgeschlossen werden sollen.
|
|
- Ob FTE-Fallback bei fehlendem SAP-Beschaeftigungsgrad fachlich akzeptiert ist.
|
|
- Ob `8.4 Stunden = 1 Krankheitstag` als Standardumrechnung fuer alle relevanten Gruppen korrekt ist.
|
|
- Ob GLZ- und Restferien-Ampeln mit den internen HR-Grenzwerten uebereinstimmen.
|
|
|
|
## Commit-Stand
|
|
|
|
Bereits erstellt:
|
|
|
|
- `20be752 Add HR KPI cockpit`
|
|
- `1cd0ad9 Refactor HR KPI cockpit architecture`
|
|
- `001e2a7 Commit pending finance and Power BI work`
|
|
|
|
Noch nicht committed zum Zeitpunkt dieser Nachdoku:
|
|
|
|
- Korrektur `Austrittsjahr` optional / Von-Bis Vorrang.
|
|
- Diese Nachdokumentation.
|