-
Notifications
You must be signed in to change notification settings - Fork 0
Berechnungen
Seit Version 1.7.0 bündelt das Modul sp5lib.calculations alle fachlichen
Rechenregeln von Schichtplaner5 in einer zentralen, seiteneffektfreien Schicht:
reine Funktionen über den gelesenen Tabellen-Records — ohne eigenes I/O und ohne
Abhängigkeit von SP5Database. Beide Fassaden (SP5Database auf DBF und
SP5PostgresDatabase auf PostgreSQL) rufen dieselben Funktionen auf; die
Ergebnisgleichheit der Backends wird durch Tests abgesichert.
Wer einfach nur Auswertungen braucht, nutzt die fertigen Methoden der Fassade
(get_statistics, get_zeitkonto, get_leave_balance, … — siehe API-Referenz).
Diese Seite beschreibt, was die Rechenschicht selbst bietet — für eigene Werkzeuge,
Skripte und Reports direkt auf den Daten.
get_nominal_hours() berechnet das Stundensoll eines Mitarbeiters für einen
beliebigen Zeitraum. Die Berechnungsbasis kommt aus den Mitarbeiter-Stammdaten
(CALCBASE): Tagesbasis (Arbeitstage × Stunden/Tag), Wochenbasis,
Monatsbasis oder Gesamtbasis. Berücksichtigt werden dabei:
- die Arbeitstage-Maske des Mitarbeiters (
WORKDAYS, Montag–Sonntag + Feiertag), - das Beschäftigungsverhältnis: Zeiträume werden automatisch auf Ein-/Austrittsdatum
(
EMPSTART/EMPEND) begrenzt, - Feiertage (optional Soll-mindernd über
DEDUCTHOL), - Soll-Korrekturen über Kontobuchungen (5BOOK).
get_actual_hours() / get_work_hours() summieren die tatsächlichen Stunden:
- Schichtdauern je Tagesindex — eine Schicht kann pro Wochentag andere Zeiten
haben (
DURATION0= Montag …DURATION6= Sonntag, Index 7 = Feiertag), - Sonderschichten (5SPSHI) ersetzen am betreffenden Tag die regulären Dienste,
- Zyklusdienste: zugewiesene Schichtmodelle werden expandiert mitgerechnet,
-
Abwesenheits-Anrechnung nach den Regeln der Abwesenheitsart
(
CHARGETYP/CHARGEHRS/COUNTALL, halbe Tage überINTERVAL), - Ist-Korrekturen über Kontobuchungen.
-
get_saldo()= Ist − Soll über denselben Zeitraum. Es gibt keinen persistierten Kontostand — Korrekturen erfolgen ausschließlich über 5BOOK-Buchungen (Konto-Typen: Ist, Soll, Überstunden). -
get_overtime_hours()führt das Überstundenkonto: 5OVER-Einträge plus Überstunden-Buchungen, abzüglich Abwesenheiten von Arten, die Überstunden abbauen.
-
leave_account()berechnet je (Mitarbeiter × Jahr × Abwesenheitsart) die fünf Kontowerte: Anspruch, Rest (Übertrag aus dem Vorjahr), Gesamt, Genommen, Verbleibend — wahlweise in Tagen oder Stunden (INDAYS). -
annual_close()bildet den Jahresabschluss ab (Übertrag der Restansprüche ins Folgejahr, optional unter Beibehaltung der Ansprüche). -
forfeit_rest()setzt den Verfall von Resturlaub um.
get_extracharge_hours() berechnet Zeitzuschläge (5XCHAR) über Zeitfenster:
Die tatsächlichen Arbeitsintervalle eines Tages werden mit den Zuschlagsfenstern
(z. B. Nacht, Wochenende, Feiertag) geschnitten — nicht pauschal über
Schichtdauern. Auch frei wählbare Auswertungszeiträume sind möglich.
-
personnel_table_row()liefert die Kennzahlen einer Personaltabellen-Zeile (Dienste-Zählung je Schicht inkl. Sonderschichten). -
demand_for_day(),count_assigned()undutilization_status()stellen den Besetzungsbedarf (Min/Max) der tatsächlichen Besetzung gegenüber.
expand_cycle_assignments() expandiert eine Zyklus-Zuweisung (5CYASS) in konkrete
Dienste: Aus Modell, Tagesfolge und Startdatum entsteht die tatsächliche Schichtfolge
je Mitarbeiter und Tag — dieselbe Logik, mit der die Fassade Zyklusdienste im
Dienstplan-Lesepfad einblendet, ohne sie zu materialisieren.
to_date, parse_day_mask, parse_startend, holiday_calendar (5HOLID →
Feiertagskalender), day_index (0 = Montag … 6 = Sonntag, 7 = Feiertag),
is_employed, count_working_days, booking_sum u. a.
Die Mitarbeiter-Rechenparameter reisen als EmployeeContext (erzeugt direkt aus dem
5EMPL-Record), der Feiertagskalender als Dictionary aus holiday_calendar():
from datetime import date
from sp5lib import calculations as calc
from sp5lib.dbf_reader import read_dbf
daten = "/pfad/zu/SP5/Daten"
empl = read_dbf(f"{daten}/5EMPL.DBF")
holid = read_dbf(f"{daten}/5HOLID.DBF")
shifts = read_dbf(f"{daten}/5SHIFT.DBF")
mashi = read_dbf(f"{daten}/5MASHI.DBF")
absen = read_dbf(f"{daten}/5ABSEN.DBF")
leavt = read_dbf(f"{daten}/5LEAVT.DBF")
emp_id = 1
emp = calc.EmployeeContext.from_record(
next(r for r in empl if r["ID"] == emp_id)
)
holidays = calc.holiday_calendar(holid)
shifts_by_id = {s["ID"]: s for s in shifts}
leave_types_by_id = {lt["ID"]: lt for lt in leavt}
von, bis = date(2026, 6, 1), date(2026, 6, 30)
soll = calc.get_nominal_hours(emp, von, bis, holidays=holidays)
saldo = calc.get_saldo(
emp, von, bis,
holidays=holidays,
shifts_by_id=shifts_by_id,
manual_shifts=[r for r in mashi if r.get("EMPLOYEEID") == emp_id],
absences=[r for r in absen if r.get("EMPLOYEEID") == emp_id],
leave_types_by_id=leave_types_by_id,
)
print(f"Soll: {soll:.2f} h, Saldo: {saldo:+.2f} h")Dasselbe Ergebnis liefert auf höherer Ebene SP5Database.calculate_time_balance()
bzw. get_zeitkonto() — die Fassade übernimmt dann das Einlesen und Filtern der
Tabellen (API-Referenz).
Die Auswertungen laufen auf PostgreSQL über dieselben Funktionen wie auf DBF (Berechnungs-Parität). Drei dokumentierte Abweichungen:
- Der Jahresabschluss (
run_annual_close/get_annual_close_preview) ist auf PostgreSQL nicht verfügbar und wirftNotImplementedError. - Das PG-Schema kennt keine
CALCBASE-Spalte;HRSMONTH > 0wird dort als Monatsbasis interpretiert. - Zyklus-Ausnahmen (5CYEXC) haben keinen SQL-Spiegel und werden auf PostgreSQL nicht angewandt.
Details zum SQL-Spiegel: ORM-und-Sync.
Home — Startseite
- Installation — PyPI, Git, Docker
-
CLI — Das
sp5lib-Kommando
- Datenbankformat — DBF/CDX aus Nutzersicht
- Berechnungen — Soll/Ist, Konten, Zuschläge
-
ORM-und-Sync — SQLAlchemy-Spiegel &
sync_all
-
API-Referenz —
SP5Database& Module
- Entwicklung — Setup, Tests, Repo-Verbund