zeiterfassung/api.py

207 lines
8.1 KiB
Python

import sys
from logging import exception
from nicegui import *
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(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}')
columns = [
{'name': 'date', 'label': 'Datum', 'field': 'date', 'required': True, 'align': 'left'},
{'name:': 'bookings', 'label': 'Buchungen', 'field': 'bookings', 'align': 'left'},
{'name:': 'is_time', 'label': 'Ist', 'field': 'is_time', 'align': 'left'},
{'name:': 'target_time', 'label': 'Soll', 'field': 'target_time', 'align': 'left'},
{'name:': 'total', 'label': 'Saldo', 'field': 'total', 'align': 'left'}
]
rows = [ ]
# 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
# Gehe jeden einzelnen Tag des Dictionaries für die Timestamps durch
for day in list(timestamps_dict):
booking_text = ""
current_day_date = f"{datetime(year, month, day).strftime('%a')}, {day}.{month}.{year}"
# Abwesenheitseinträge
try:
# Abwesenheitszeiten behandeln
for i in list(user_absent):
if int(i) == day:
booking_text += absence_entries[user_absent[i]]["name"] + " "
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')) + "\n"
except:
if len(timestamps_dict[day]) % 2 != 0:
booking_text += datetime.fromtimestamp(int(timestamps_dict[day][i])).strftime('%H:%M')
# 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"
# 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"
# 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"
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 = "-"
rows.append({'date': current_day_date, 'bookings': booking_text, 'is_time': is_time, 'target_time': target_time, 'total': total})
overview_table = ui.table(columns=columns, rows=rows, row_key='date').classes('w-full')
# Zeilenumbruch umsetzen
overview_table.add_slot('body-cell', r'''
<td :props="props" :style="{'white-space':'pre-line'}">{{ props.value }}</td>
''')
# Überstundenzusammenfassung
with ui.grid(columns=2).classes('w-full gap-0'):
ui.markdown("Überstunden aus Vormonat:")
last_months_overtime = current_user.get_last_months_overtime(year, month)
ui.markdown(f"{convert_seconds_to_hours(last_months_overtime)} h")
ui.markdown("Überstunden diesen Monat:")
ui.markdown(f"{convert_seconds_to_hours(general_saldo)} h")
ui.markdown("**Überstunden Gesamt:**")
overtime_overall = last_months_overtime + general_saldo
ui.markdown(f"**{convert_seconds_to_hours(overtime_overall)} h**")
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:")
a_columns = [
{'name': 'type', 'label': 'Typ', 'field': 'type', 'required': True, 'align': 'left'},
{'name': 'sum', 'label': 'Tage', 'field': 'sum', 'required': True, 'align': 'left'},
]
a_row = [ ]
for key,value in absence_dict.items():
if value > 0:
a_row.append({'type': absence_entries[key]['name'], 'sum': value})
absence_table = ui.table(columns=a_columns, rows=a_row)
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))