Zusätzliche Überprüfung ob Archivierung sinnvoll mit zustzlichen Hinweisen.

This commit is contained in:
Alexander Malzkuhn 2025-05-14 10:50:39 +02:00
parent 4b1a222132
commit 3209d0d91f
9 changed files with 74 additions and 68 deletions

View File

@ -132,7 +132,7 @@ def page_admin():
def update_month_and_year():
current_user = user(time_user.value)
# Archivstatus
days_with_errors = current_user.archiving_validity_check(int(select_year.value), int(select_month.value))
with ui.grid(columns='auto auto auto 1fr 1fr 1fr 1fr') as table_grid:
if int(select_month.value) > 1:
archive_status = current_user.get_archive_status(int(select_year.value),
@ -310,22 +310,26 @@ Dies kann nicht rückgängig gemacht werden!''')
timestamp_button = ui.button(datetime.datetime.fromtimestamp(int(timestamps_dict[day][i])).strftime('%H:%M'), on_click=lambda t_stamp=timestamps_dict[day][i], day=day: edit_entry(t_stamp, day))
if archive_status:
timestamp_button.disable()
with ui.row():
# Fehlerhinweis
if day in days_with_errors:
ui.icon('warning', color='red').tooltip("Keine Schlussbuchung").classes('text-2xl')
# Notizen anzeigen
days_notes = current_user.get_day_notes(select_year.value, select_month.value, day)
if days_notes != { }:
with ui.icon('o_description').classes('text-2xl'):
with ui.tooltip():
with ui.grid(columns='auto auto'):
for username, text in days_notes.items():
admins_name = load_adminsettings()["admin_user"]
if username == admins_name:
ui.markdown('Administrator:')
else:
ui.markdown(current_user.fullname)
ui.markdown(text)
else:
ui.space()
# Notizen anzeigen
days_notes = current_user.get_day_notes(select_year.value, select_month.value, day)
if days_notes != { }:
with ui.icon('o_description').classes('text-2xl'):
with ui.tooltip():
with ui.grid(columns='auto auto'):
for username, text in days_notes.items():
admins_name = load_adminsettings()["admin_user"]
if username == admins_name:
ui.markdown('Administrator:')
else:
ui.markdown(current_user.fullname)
ui.markdown(text)
else:
ui.space()
# Arbeitszeit Ist bestimmen
@ -586,6 +590,7 @@ Dies kann nicht rückgängig gemacht werden!''')
current_user = user(time_user.value)
month_header.set_content(f"###Buchungen für **{current_user.fullname}** für **{calendar.month_name[int(select_month.value)]} {select_year.value}**")
month_header.set_content(f"###Buchungen für **{current_user.fullname}** für **{calendar.month_name[int(select_month.value)]} {select_year.value}**")
timetable()
button_update = ui.button("Aktualisieren", on_click=timetable.refresh)
button_update.move(timetable_header)

18
api.py
View File

@ -21,6 +21,7 @@ def page_overview_month(username: str, year: int, month: int):
try:
current_user = user(username)
days_with_errors = current_user.archiving_validity_check(year, month)
ui.page_title(f"Bericht für {current_user.fullname} für {calendar.month_name[month]} {year}")
if current_user.get_archive_status(year, month):
with ui.column().classes('w-full items-end gap-0'):
@ -80,7 +81,8 @@ def page_overview_month(username: str, year: int, month: int):
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}')
with ui.link_target(day):
ui.markdown(current_day_date).classes(f'border px-{pad_x} py-{pad_y} bg-{color_day}')
# Abwesenheitseinträge
@ -100,11 +102,11 @@ def page_overview_month(username: str, year: int, month: int):
for i in range(0, len(timestamps_dict[day]), 2):
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>"
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')
booking_text += datetime.fromtimestamp(int(timestamps_dict[day][i])).strftime('%H:%M') + " - ***Buchung fehlt!***"
booking_text_element = ui.markdown(booking_text).classes(f'border px-{pad_x} py-{pad_y} bg-{booking_color} text-{booking_text_color}')
@ -258,7 +260,15 @@ def page_overview_month(username: str, year: int, month: int):
dialog.open()
if archivable == True:
ui.button("Archivieren", on_click=archive_dialog)
if len(days_with_errors) > 0:
ui.label("Es gibt Inkonsistenzen in den Buchungen. Folgende Tage müssen überprüft werden:")
with ui.grid(columns=len(days_with_errors)):
for i in days_with_errors:
ui.link(f"{i}.", f'#{i}')
archive_button = ui.button("Archivieren", on_click=archive_dialog)
if len(days_with_errors) > 0:
archive_button.disable()
archive()

View File

@ -3,6 +3,7 @@ import hashlib
# User bezogene Funktionen
import os
from calendar import monthrange
from stat import S_IREAD, S_IWUSR
import datetime
import time
@ -223,6 +224,25 @@ class user:
except:
return -1
def archiving_validity_check(self, year: int, month: int):
timestampfilename = f"{self.userfolder}/{year}-{month}.txt"
try:
with open(timestampfilename) as timestampfile:
timestamps = timestampfile.readlines()
timestamps.sort()
days_with_errors = [ ]
for day in range(1, monthrange(year, month)[1] + 1):
day_dt = datetime.datetime(year, month, day)
timestamps_of_this_day = [ ]
for i in timestamps:
i_dt = datetime.datetime.fromtimestamp(int(i))
if day_dt.year == i_dt.year and day_dt.month == i_dt.month and day_dt.day == i_dt.day:
timestamps_of_this_day.append(i)
if len(timestamps_of_this_day) % 2 != 0:
days_with_errors.append(day)
return days_with_errors
except:
return [ ]
def archive_hours(self, year, month, overtime: int):
filename = f"{self.userfolder}/{year}-{month}.json"

2
users/testuser1/2025-3.json Normal file → Executable file
View File

@ -1 +1 @@
{"archived": 1, "overtime": -528928}
{"archived": 0, "overtime": -528928}

32
users/testuser1/2025-3.txt Normal file → Executable file
View File

@ -1,30 +1,4 @@
1743965819
1743965909
1743966022
1743966045
1743966047
1743966049
1743967346
1744889948
1744889966
1744989797
1744989827
1744989830
1744989883
1744989909
1744989914
1744989916
1744991169
1744991171
1744991288
1744991291
1744991473
1744991477
1744991770
1744991777
1745181046
1745181050
1745240760
1745240762
1740996000
1740997800
1742460540
1741038540
1742464500

13
users/testuser1/2025-4.json Executable file → Normal file
View File

@ -1 +1,12 @@
{"archived": 0, "overtime": -860821, "absence": {"7": "U", "8": "K", "9": "KK", "10": "UU", "11": "F", "14": "EZ"}}
{
"archived": 1,
"overtime": -877154,
"absence": {
"7": "U",
"8": "K",
"9": "KK",
"10": "UU",
"11": "F",
"14": "EZ"
}
}

16
users/testuser1/2025-4.txt Executable file → Normal file
View File

@ -1,21 +1,5 @@
1744889948
1744890300
1744989797
1744989827
1744989830
1744989883
1744989909
1744989914
1744989916
1744991169
1744991171
1744991288
1744991291
1744991473
1744991477
1744991770
1745215200
1745229600
1745390818
1745390894
1745390894

View File

@ -2,7 +2,6 @@
"archived": 0,
"overtime": 0,
"absence": {
"14": "U",
"2": "SO"
},
"notes": {

View File

@ -6,3 +6,6 @@
1746608922
1746609024
1746609037
1747206908
1747207022
1747813500