Feiertagshandling erweitert

Automatische Eintragungen für gesetzliche Feiertage hinzugefügt
Feiertagsauswertung in API
This commit is contained in:
Alexander Malzkuhn 2025-05-04 21:08:52 +02:00
parent 2d6e64fe0d
commit 446e588d70
9 changed files with 168 additions and 36 deletions

126
admin.py
View File

@ -1,5 +1,8 @@
from datetime import datetime
import dateutil.easter
from dateutil.easter import *
from nicegui import ui, app, events
from users import *
@ -396,7 +399,6 @@ Dies kann nicht rückgägig gemacht werden!''')
actual_date = start_date
while actual_date <= end_date:
current_user.workhours
absences = current_user.get_absence(actual_date.year, actual_date.month)
if str(actual_date.day) in list(absences):
@ -550,17 +552,131 @@ Dies kann nicht rückgägig gemacht werden!''')
del(data['holidays'][entry.strftime('%Y-%m-%d')])
holiday_buttons_grid.refresh()
def defined_holidays():
with ui.dialog() as dialog, ui.card():
ui.markdown("Bitte wählen Sie aus, welche Feiertage eingetragen werden sollen. Vom Osterdatum abhängige Feiertage werden für die verschiedenen Jahre berechnet.:")
with ui.grid(columns='auto auto'):
with ui.column().classes('gap-0'): # Auswahlen für Feiertage
checkbox_classes = 'py-0'
new_year = ui.checkbox("Neujahr (1. Januar)").classes(checkbox_classes)
heilige_drei_koenige = ui.checkbox("Heilige Drei Könige (6. Januar)").classes(checkbox_classes)
womens_day = ui.checkbox("Internationaler Frauentag (8. März)").classes(checkbox_classes)
gruendonnerstag = ui.checkbox("Gründonnerstag (berechnet").classes(checkbox_classes)
karfreitag = ui.checkbox("Karfreitag (berechnet").classes(checkbox_classes)
easter_sunday = ui.checkbox("Ostersonntag (berechnet)").classes(checkbox_classes)
easter_monday = ui.checkbox("Ostermontag (berechnet)").classes(checkbox_classes)
first_of_may = ui.checkbox("Tag der Arbeit (1. Mai)").classes(checkbox_classes)
liberation_day = ui.checkbox("Tag der Befreiung (8. Mai)").classes(checkbox_classes)
ascension_day = ui.checkbox("Christi Himmelfahrt (berechnet)").classes(checkbox_classes)
whitsun_sunday = ui.checkbox("Pfingssonntag (berechnet)").classes(checkbox_classes)
whitsun_monday = ui.checkbox("Pfingsmontag (berechnet)").classes(checkbox_classes)
fronleichnam = ui.checkbox("Fronleichnam (berechnet)").classes(checkbox_classes)
peace_party = ui.checkbox("Friedensfest (Augsburg - 8. August)").classes(checkbox_classes)
mary_ascension = ui.checkbox("Mariä Himmelfahrt (15. August)").classes(checkbox_classes)
childrens_day = ui.checkbox("Weltkindertag (20. September)").classes(checkbox_classes)
unity_day = ui.checkbox("Tag der deutschen Einheit (3. Oktober)").classes(checkbox_classes)
reformation_day = ui.checkbox("Reformationstag (30. Oktober)").classes(checkbox_classes)
all_hallows = ui.checkbox("Allerheiligen (1. November)").classes(checkbox_classes)
praying_day = ui.checkbox("Buß- und Bettag (berechnet)").classes(checkbox_classes)
christmas_day = ui.checkbox("1. Weihnachtsfeiertag (25. Dezember)").classes(checkbox_classes)
boxing_day = ui.checkbox("2. Weihnachtsfeiertag (26. Dezember)").classes(checkbox_classes)
def enter_holidays():
for year in range (int(starting_year.value), int(end_year.value) + 1):
ostersonntag = dateutil.easter.easter(year)
if new_year.value:
data["holidays"][f"{year}-01-01"] = f"Neujahr"
if heilige_drei_koenige.value:
data["holidays"][f"{year}-01-06"] = f"Hl. Drei Könige"
if womens_day.value:
data["holidays"][f"{year}-03-08"] = f"Intern. Frauentag"
if gruendonnerstag.value:
datum_dt = ostersonntag - datetime.timedelta(days=3)
datum = datum_dt.strftime("%Y-%m-%d")
data["holidays"][f"{datum}"] = f"Gründonnerstag"
if karfreitag.value:
datum_dt = ostersonntag - datetime.timedelta(days=2)
datum = datum_dt.strftime("%Y-%m-%d")
data["holidays"][f"{datum}"] = f"Karfreitag"
if easter_sunday.value:
datum_dt = ostersonntag
datum = datum_dt.strftime("%Y-%m-%d")
data["holidays"][f"{datum}"] = "Ostersonntag"
if easter_monday.value:
datum_dt = ostersonntag + datetime.timedelta(days=1)
datum = datum_dt.strftime("%Y-%m-%d")
data["holidays"][f"{datum}"] = "Ostermontag"
if first_of_may.value:
data["holidays"][f"{year}-05-01"] = f"Tage der Arbeit"
if liberation_day.value:
data["holidays"][f"{year}-05-08"] = f"Tag der Befreiung"
if ascension_day.value:
datum_dt = ostersonntag + datetime.timedelta(days=39)
datum = datum_dt.strftime("%Y-%m-%d")
data["holidays"][f"{datum}"] = f"Christi Himmelfahrt"
if whitsun_sunday.value:
datum_dt = ostersonntag + datetime.timedelta(days=49)
datum = datum_dt.strftime("%Y-%m-%d")
data["holidays"][f"{datum}"] = f"Pfingssonntag"
if whitsun_monday.value:
datum_dt = ostersonntag + datetime.timedelta(days=49)
datum = datum_dt.strftime("%Y-%m-%d")
data["holidays"][f"{datum}"] = f"Pfingstmontag"
if fronleichnam.value:
datum_dt = ostersonntag + datetime.timedelta(days=60)
datum = datum_dt.strftime("%Y-%m-%d")
data["holidays"][f"{datum}"] = f"Fronleichnam"
if peace_party.value:
data["holidays"][f"{year}-08-08"] = f"Friedensfest"
if mary_ascension.value:
data["holidays"][f"{year}-08-15"] = f"Mariä Himmelfahrt"
if childrens_day.value:
data["holidays"][f"{year}-09-20"] = f"Intern. Kindertag"
if unity_day.value:
data["holidays"][f"{year}-10-03"] = f"Tag der deutschen Einheit"
if reformation_day.value:
data["holidays"][f"{year}-10-30"] = f"Reformationstag"
if all_hallows.value:
data["holidays"][f"{year}-11-01"] = f"Allerheiligen"
if praying_day.value:
starting_day = datetime.datetime(year, 11 ,23)
for i in range(1, 8):
test_day = starting_day - datetime.timedelta(days=-i)
if test_day.weekday() == 2:
datum_dt = test_day
break
datum = datum_dt.strftime("%Y-%m-%d")
data["holidays"][f"{datum}"] = f"Bu0- und Bettag"
if christmas_day.value:
data["holidays"][f"{year}-12-25"] = f"1. Weihnachtsfeiertag"
if boxing_day.value:
data["holidays"][f"{year}-12-26"] = f"2. Weihnachtsfeiertag"
dialog.close()
holiday_buttons_grid.refresh()
with ui.column():
starting_year = ui.number(value=datetime.datetime.now().year, label="Startjahr")
end_year = ui.number(value=starting_year.value, label="Endjahr")
with ui.row():
ui.button("Anwenden", on_click=enter_holidays)
ui.button("Abbrechen", on_click=dialog.close)
dialog.open()
with ui.grid(columns='auto auto'):
ui.space()
with ui.row():
ui.button("Neuer Eintrag", on_click=new_holiday_entry)
ui.button("Gesetzliche Feiertage eintragen", on_click=defined_holidays)
ui.button("Eigener Eintrag", on_click=new_holiday_entry)
ui.separator().classes('col-span-2')
for year_entry in year_list:
ui.markdown(f"{str(year_entry)}:")
with ui.row():
for entry in year_dict[year_entry]:
date_label = entry.strftime("%d.%m.%Y")
ui.button(f"{data['holidays'][entry.strftime('%Y-%m-%d')]} ({date_label})", on_click=lambda entry=entry: del_holiday_entry(entry)).classes('bg-blue')
date_label = entry.strftime("%d.%m.")
ui.button(f"{data['holidays'][entry.strftime('%Y-%m-%d')]} ({date_label})", on_click=lambda entry=entry: del_holiday_entry(entry)).classes('text-sm')
holiday_buttons_grid()
holiday_section()

6
api.py
View File

@ -17,6 +17,8 @@ import calendar
@ui.page('/api/month/{username}/{year}-{month}')
def page_overview_month(username: str, year: int, month: int):
data = load_adminsettings()
try:
current_user = user(username)
ui.page_title(f"Bericht für {current_user.fullname} für {calendar.month_name[month]} {year}")
@ -50,7 +52,6 @@ def page_overview_month(username: str, year: int, month: int):
for stamp in timestamps:
day_of_month_of_timestamp = datetime.fromtimestamp(int(stamp)).day
timestamps_dict[day_of_month_of_timestamp].append(int(stamp))
timestamps_dict[day_of_month_of_timestamp].append(int(stamp))
general_saldo = 0
@ -140,6 +141,9 @@ def page_overview_month(username: str, year: int, month: int):
target_time = f"{convert_seconds_to_hours(int(hours_to_work) * 3600)} h"
if int(hours_to_work) == 0:
booking_text = "Kein Arbeitstag"
date_dt = datetime(year, month, day)
if date_dt.strftime("%Y-%m-%d") in data["holidays"]:
booking_text = f'**{data["holidays"][date_dt.strftime("%Y-%m-%d")]}**'
booking_text_element.set_content(booking_text)
ui.markdown(target_time).classes(f'border px-{pad_x} py-{pad_y} text-center')

View File

@ -4,7 +4,7 @@
"port": "8090",
"secret": "ftgzuhjikg,mt5jn46uzer8sfi9okrmtzjhndfierko5zltjhdgise",
"holidays": {
"2024-01-01": "Tag der Arbeit",
"2024-05-01": "Tag der Arbeit",
"2024-12-25": "1. Weihnachtsfeiertag",
"2025-01-01": "Neujahr",
"2025-05-01": "Tag der Arbeit"

View File

@ -15,15 +15,16 @@ import locale
def page_touchscreen():
def button_click(name):
nonlocal buttons
#nonlocal buttons
current_user = user(name)
current_user.timestamp()
if current_user.stamp_status() == status_in:
buttons[name].props('color=green')
ui.notify(status_in)
else:
buttons[name].props('color=red')
ui.notify(status_out)
#if current_user.stamp_status() == status_in:
# buttons[name].props('color=green')
# ui.notify(status_in)
#else:
# buttons[name].props('color=red')
# ui.notify(status_out)
user_buttons.refresh()
pageheader("Bitte User auswählen:")
@ -31,27 +32,29 @@ def page_touchscreen():
number_of_users = len(userlist)
buttons = { }
if number_of_users > 5:
number_of_columns = 5
else:
number_of_columns = number_of_users
@ui.refreshable
def user_buttons():
if number_of_users > 5:
number_of_columns = 5
else:
number_of_columns = number_of_users
with ui.grid(columns=number_of_columns):
for name in userlist:
current_user = user(name)
current_button = ui.button(on_click=lambda name=name: button_click(name))
with current_button:
try:
with open(current_user.photofile, 'r') as file:
with ui.grid(columns=number_of_columns):
for name in userlist:
current_user = user(name)
current_button = ui.button(on_click=lambda name=name: button_click(name))
with current_button:
try:
with open(current_user.photofile, 'r') as file:
pass
file.close()
ui.image(current_user.photofile)
except:
pass
file.close()
ui.image(current_user.photofile)
except:
pass
ui.label(current_user.fullname)
if current_user.stamp_status() == status_in:
current_button.props('color=green')
else:
current_button.props('color=red')
buttons[name] = current_button
ui.label(current_user.fullname)
if current_user.stamp_status() == status_in:
current_button.props('color=green')
else:
current_button.props('color=red')
buttons[name] = current_button
user_buttons()

View File

@ -394,3 +394,4 @@ def load_adminsettings():
except:
return(-1)

View File

@ -0,0 +1,2 @@
1746385124
1746385127

View File

View File

@ -0,0 +1,4 @@
{
"archived": 0,
"total_hours": 0
}

View File

@ -0,0 +1,2 @@
1746385111
1746385118