Skip to content

Berechnungen

Matthias Schabhüttl edited this page Jun 12, 2026 · 1 revision

Berechnungen (sp5lib.calculations)

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.


Funktionsumfang

Soll-Stunden

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).

Ist-Stunden

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 über INTERVAL),
  • Ist-Korrekturen über Kontobuchungen.

Saldo und Überstunden

  • 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.

Urlaubskonto

  • 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.

Zuschläge

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.

Personaltabelle, Bedarf und Auslastung

  • personnel_table_row() liefert die Kennzahlen einer Personaltabellen-Zeile (Dienste-Zählung je Schicht inkl. Sonderschichten).
  • demand_for_day(), count_assigned() und utilization_status() stellen den Besetzungsbedarf (Min/Max) der tatsächlichen Besetzung gegenüber.

Zyklen (Schichtmodelle)

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.

Basis-Helfer

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.


Code-Beispiel: Soll, Ist und Saldo eines Mitarbeiters

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).


Hinweise zum PostgreSQL-Backend

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 wirft NotImplementedError.
  • Das PG-Schema kennt keine CALCBASE-Spalte; HRSMONTH > 0 wird dort als Monatsbasis interpretiert.
  • Zyklus-Ausnahmen (5CYEXC) haben keinen SQL-Spiegel und werden auf PostgreSQL nicht angewandt.

Details zum SQL-Spiegel: ORM-und-Sync.

libopenschichtplaner5 v1.7.0

Home — Startseite


Einstieg

Konzepte

Referenz

Mitwirken


Verwandte Wikis

Links

Clone this wiki locally