269 lines
12 KiB
Python
269 lines
12 KiB
Python
import sys
|
|
from logging import exception
|
|
|
|
from nicegui import *
|
|
from samba.graph import pad_char
|
|
|
|
import ui
|
|
from definitions import *
|
|
from web_ui import *
|
|
from users import *
|
|
from datetime import datetime
|
|
|
|
import calendar
|
|
|
|
|
|
# Überblicksseite zum Ausdrucken oder als PDF speichern
|
|
@ui.page('/api/overview/month/{username}/{year}-{month}')
|
|
def page_overview_month(username: str, year: int, month: int):
|
|
|
|
try:
|
|
current_user = user(username)
|
|
ui.page_title(f"Bericht für {current_user.fullname} für {calendar.month_name[month]} {year}")
|
|
ui.label(datetime.now().strftime('%d.%m.%Y')).classes('absolute top-5 right-5')
|
|
ui.space()
|
|
ui.markdown(f'#Bericht für {current_user.fullname} für {calendar.month_name[month]} {year}')
|
|
|
|
pad_x = 4
|
|
pad_y = 0
|
|
|
|
color_weekend = "gray-100"
|
|
color_holiday = "gray-100"
|
|
|
|
def overview_table():
|
|
# Timestamp in ein Array schreiben
|
|
timestamps = current_user.get_timestamps(year, month)
|
|
timestamps.sort()
|
|
|
|
# Abwesenheitsdaten in ein Dict schreiben
|
|
user_absent = current_user.get_absence(year, month)
|
|
|
|
# Dictionary für sortierte Timestamps
|
|
timestamps_dict = { }
|
|
|
|
# Dictionary mit zunächst leeren Tageinträgen befüllen
|
|
for day in range(1, monthrange(year, month)[1] + 1):
|
|
# Jeder Tag bekommt eine leere Liste
|
|
timestamps_dict[day] = [ ]
|
|
|
|
# Timestamps den Monatstagen zuordnen
|
|
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
|
|
|
|
with ui.grid(columns='auto auto 1fr 1fr 1fr').classes(f'gap-0 border px-0 py-0'):
|
|
ui.markdown("**Datum**").classes(f'border px-{pad_x} py-{pad_y}')
|
|
ui.markdown("**Buchungen**").classes(f'border px-{pad_x} py-{pad_y}')
|
|
ui.markdown("**Ist**").classes(f'border px-{pad_x} py-{pad_y}')
|
|
ui.markdown("**Soll**").classes(f'border px-{pad_x} py-{pad_y}')
|
|
ui.markdown("**Saldo**").classes(f'border px-{pad_x} py-{pad_y}')
|
|
|
|
# Gehe jeden einzelnen Tag des Dictionaries für die Timestamps durch
|
|
for day in list(timestamps_dict):
|
|
booking_text = ""
|
|
color_day = 'inherit'
|
|
if datetime(year, month, day).strftime('%w') in ["0", "6"]:
|
|
color_day = color_weekend
|
|
|
|
current_day_date = f"{datetime(year, month, day).strftime('%a')}, {day}.{month}.{year}"
|
|
day_text_element = ui.markdown(current_day_date).classes(f'border px-{pad_x} py-{pad_y} bg-{color_day}')
|
|
|
|
|
|
# Abwesenheitseinträge
|
|
booking_color = "inherit"
|
|
booking_text_color = "inherit"
|
|
try:
|
|
# Abwesenheitszeiten behandeln
|
|
for i in list(user_absent):
|
|
if int(i) == day:
|
|
booking_text += absence_entries[user_absent[i]]["name"] + "<br>"
|
|
booking_color = absence_entries[user_absent[i]]["color"]
|
|
booking_text_color = absence_entries[user_absent[i]]["text-color"]
|
|
except:
|
|
pass
|
|
|
|
# Buchungen behandeln
|
|
for i in range(len(timestamps_dict[day])):
|
|
try:
|
|
temp_pair = [timestamps_dict[day][i], timestamps_dict[day][i + 1]]
|
|
booking_text = booking_text + str(datetime.fromtimestamp(temp_pair[0]).strftime('%H:%M')) + "-" + str(datetime.fromtimestamp(temp_pair[1]).strftime('%H:%M')) + "<br>"
|
|
|
|
except:
|
|
if len(timestamps_dict[day]) % 2 != 0:
|
|
booking_text += datetime.fromtimestamp(int(timestamps_dict[day][i])).strftime('%H:%M')
|
|
print(booking_text)
|
|
|
|
booking_text_element = ui.markdown(booking_text).classes(f'border px-{pad_x} py-{pad_y} bg-{booking_color} text-{booking_text_color}')
|
|
|
|
# Ist-Zeiten berechnen
|
|
timestamps_of_this_day = []
|
|
|
|
# Suche mir alle timestamps für diesen Tag
|
|
for i in timestamps:
|
|
actual_timestamp = datetime.fromtimestamp(int(i))
|
|
timestamp_day = actual_timestamp.strftime('%-d')
|
|
|
|
if int(timestamp_day) == int(day):
|
|
timestamps_of_this_day.append(i)
|
|
|
|
timestamps_of_this_day.sort()
|
|
time_sum = 0
|
|
if len(timestamps_of_this_day) > 1:
|
|
|
|
if len(timestamps_of_this_day) % 2 == 0:
|
|
for i in range(0, len(timestamps_of_this_day), 2):
|
|
time_delta = int(
|
|
timestamps_of_this_day[i + 1]) - int(
|
|
timestamps_of_this_day[i])
|
|
time_sum = time_sum + time_delta
|
|
else:
|
|
for i in range(0, len(timestamps_of_this_day) - 1, 2):
|
|
time_delta = int(
|
|
timestamps_of_this_day[i + 1]) - int(
|
|
timestamps_of_this_day[i])
|
|
time_sum = time_sum + time_delta
|
|
|
|
is_time = convert_seconds_to_hours(time_sum) + " h"
|
|
else:
|
|
is_time = "Kein"
|
|
|
|
ui.markdown(is_time).classes(f'border px-{pad_x} py-{pad_y} text-center')
|
|
# Sollzeit bestimmen
|
|
|
|
hours_to_work = int(current_user.get_day_workhours(year, month, day))
|
|
|
|
if hours_to_work < 0:
|
|
target_time = ""
|
|
else:
|
|
target_time = f"{convert_seconds_to_hours(int(hours_to_work) * 3600)} h"
|
|
if int(hours_to_work) == 0:
|
|
booking_text = "Kein Arbeitstag"
|
|
booking_text_element.set_content(booking_text)
|
|
|
|
ui.markdown(target_time).classes(f'border px-{pad_x} py-{pad_y} text-center')
|
|
|
|
# Saldo für den Tag berechnen
|
|
day_in_list = datetime(year, month, day)
|
|
if time.time() > day_in_list.timestamp():
|
|
|
|
time_duty = int(current_user.get_day_workhours(year, month, day)) * 3600
|
|
if time_duty < 0:
|
|
saldo = 0
|
|
total = ""
|
|
booking_text = "Kein Arbeitsverhältnis"
|
|
booking_text_element.set_content(booking_text)
|
|
else:
|
|
saldo = int(time_sum) - int(time_duty)
|
|
# Nach Abwesenheitseinträgen suchen
|
|
try:
|
|
for i in list(user_absent):
|
|
if int(i) == day and user_absent[i] != "UU":
|
|
saldo = 0
|
|
except:
|
|
pass
|
|
|
|
general_saldo = general_saldo + saldo
|
|
total = f"{convert_seconds_to_hours(saldo)} h"
|
|
|
|
else:
|
|
total = "-"
|
|
if total == "-":
|
|
total_class = 'text-center'
|
|
else:
|
|
total_class = 'text-right'
|
|
ui.markdown(total).classes(total_class).classes(f'border px-{pad_x} py-{pad_y}')
|
|
|
|
# Überstundenzusammenfassung
|
|
ui.markdown("Überstunden aus Vormonat:").classes(f'col-span-4 text-right border px-{pad_x} py-{pad_y}')
|
|
last_months_overtime = current_user.get_last_months_overtime(year, month)
|
|
ui.markdown(f"{convert_seconds_to_hours(last_months_overtime)} h").classes(f'text-right border px-{pad_x} py-{pad_y}')
|
|
ui.markdown("Überstunden diesen Monat:").classes(f'col-span-4 text-right border px-{pad_x} py-{pad_y}')
|
|
ui.markdown(f"{convert_seconds_to_hours(general_saldo)} h").classes(f'text-right border px-{pad_x} py-{pad_y}')
|
|
ui.markdown("**Überstunden Gesamt:**").classes(f'col-span-4 text-right border px-{pad_x} py-{pad_y}')
|
|
overtime_overall = last_months_overtime + general_saldo
|
|
ui.markdown(f"**{convert_seconds_to_hours(overtime_overall)} h**").classes(f'text-right border px-{pad_x} py-{pad_y}')
|
|
|
|
overview_table()
|
|
|
|
def absence_table():
|
|
absences_this_month = current_user.get_absence(year, month)
|
|
absence_dict = { }
|
|
|
|
for abbr in list(absence_entries):
|
|
absence_dict[abbr] = 0
|
|
|
|
for key, value in absences_this_month.items():
|
|
if value in list(absence_dict):
|
|
absence_dict[value] += 1
|
|
|
|
total_absence_days = 0
|
|
for key, value in absence_dict.items():
|
|
total_absence_days += absence_dict[key]
|
|
|
|
if total_absence_days > 0:
|
|
ui.markdown("###Abwesenheitstage diesen Monat:")
|
|
|
|
with ui.grid(columns='auto 20%').classes(f'gap-0 border px-0 py-0'):
|
|
|
|
for key,value in absence_dict.items():
|
|
if value > 0:
|
|
ui.markdown(absence_entries[key]['name']).classes(f"border px-{pad_x} py-{pad_y}")
|
|
ui.markdown(str(value)).classes(f'border px-{pad_x} py-{pad_y} text-center')
|
|
|
|
absence_table()
|
|
|
|
except Exception as e:
|
|
print(str(type(e).__name__) + " " + str(e))
|
|
if type(e) == UnboundLocalError:
|
|
ui.markdown('#Fehler')
|
|
ui.markdown('Benutzer existiert nicht')
|
|
else:
|
|
ui.markdown('#Fehler')
|
|
ui.markdown(str(type(e)))
|
|
ui.markdown(str(e))
|
|
|
|
@ui.page('/api/overview/vacation/{username}/{year}-{month}-{day}')
|
|
def page_overview_vacation(username: str, year: int, month: int, day: int):
|
|
try:
|
|
current_user = user(username)
|
|
|
|
ui.page_title(f"Urlaubsanspruch für {current_user.fullname} für {year}")
|
|
ui.label(datetime.now().strftime('%d.%m.%Y')).classes('absolute top-5 right-5')
|
|
ui.space()
|
|
ui.markdown(f'#Urlaubsanspruch für {current_user.fullname} für {year}')
|
|
|
|
pad_x = 4
|
|
pad_y = 0
|
|
|
|
with ui.grid(columns='auto auto').classes(f'gap-0 border px-0 py-0'):
|
|
ui.markdown(f"Urlaubsübersicht für {year}:").classes(f'border px-{pad_x} py-{pad_y}')
|
|
vacationclaim = int(current_user.get_vacation_claim(year, month, day))
|
|
ui.markdown(f"{vacationclaim} Tage").classes(f'text-right border px-{pad_x} py-{pad_y}')
|
|
ui.markdown("Registrierte Urlaubstage").classes(f'border px-{pad_x} py-{pad_y} col-span-2')
|
|
vacation_counter = 0
|
|
try:
|
|
for i in range(1, 13):
|
|
absence_entries = current_user.get_absence(year, i)
|
|
for day, absence_type in absence_entries.items():
|
|
print(day + "." + str(i) + " " + absence_type)
|
|
if absence_type == "U":
|
|
day_in_list = datetime(int(year), int(i), int(day)).strftime("%d.%m.%Y")
|
|
ui.markdown(day_in_list).classes(f'border px-{pad_x} py-{pad_y}')
|
|
ui.markdown("-1 Tag").classes(f'border px-{pad_x} py-{pad_y} text-center')
|
|
vacation_counter += 1
|
|
except Exception as e:
|
|
print(str(type(e).__name__) + " " + str(e))
|
|
ui.markdown("**Resturlaub:**").classes(f'border px-{pad_x} py-{pad_y}')
|
|
ui.markdown(f'**{str(vacationclaim - vacation_counter)} Tage**').classes(f'border px-{pad_x} py-{pad_y} text-center')
|
|
except Exception as e:
|
|
print(str(type(e).__name__) + " " + str(e))
|
|
if type(e) == UnboundLocalError:
|
|
ui.markdown('#Fehler')
|
|
ui.markdown('Benutzer existiert nicht')
|
|
else:
|
|
ui.markdown('#Fehler')
|
|
ui.markdown(str(type(e)))
|
|
ui.markdown(str(e)) |