diff --git a/admin.py b/admin.py
index c7723b1..dd07a58 100644
--- a/admin.py
+++ b/admin.py
@@ -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)
diff --git a/api.py b/api.py
index b636999..508c091 100644
--- a/api.py
+++ b/api.py
@@ -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')) + "
"
+ booking_text = booking_text + str(datetime.fromtimestamp(temp_pair[0]).strftime('%H:%M')) + " - " + str(datetime.fromtimestamp(temp_pair[1]).strftime('%H:%M')) + "
"
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()
diff --git a/users.py b/users.py
index b57f2a9..9d9f2ff 100644
--- a/users.py
+++ b/users.py
@@ -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"
diff --git a/users/testuser1/2025-3.json b/users/testuser1/2025-3.json
old mode 100644
new mode 100755
index 27c5b37..d438ef3
--- a/users/testuser1/2025-3.json
+++ b/users/testuser1/2025-3.json
@@ -1 +1 @@
-{"archived": 1, "overtime": -528928}
\ No newline at end of file
+{"archived": 0, "overtime": -528928}
\ No newline at end of file
diff --git a/users/testuser1/2025-3.txt b/users/testuser1/2025-3.txt
old mode 100644
new mode 100755
index 7350e03..da7ed21
--- a/users/testuser1/2025-3.txt
+++ b/users/testuser1/2025-3.txt
@@ -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
diff --git a/users/testuser1/2025-4.json b/users/testuser1/2025-4.json
old mode 100755
new mode 100644
index 1883f9d..48da952
--- a/users/testuser1/2025-4.json
+++ b/users/testuser1/2025-4.json
@@ -1 +1,12 @@
-{"archived": 0, "overtime": -860821, "absence": {"7": "U", "8": "K", "9": "KK", "10": "UU", "11": "F", "14": "EZ"}}
\ No newline at end of file
+{
+ "archived": 1,
+ "overtime": -877154,
+ "absence": {
+ "7": "U",
+ "8": "K",
+ "9": "KK",
+ "10": "UU",
+ "11": "F",
+ "14": "EZ"
+ }
+}
\ No newline at end of file
diff --git a/users/testuser1/2025-4.txt b/users/testuser1/2025-4.txt
old mode 100755
new mode 100644
index ad67cca..bd42eec
--- a/users/testuser1/2025-4.txt
+++ b/users/testuser1/2025-4.txt
@@ -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
diff --git a/users/testuser1/2025-5.json b/users/testuser1/2025-5.json
index d3b1f01..7ec0e06 100644
--- a/users/testuser1/2025-5.json
+++ b/users/testuser1/2025-5.json
@@ -2,7 +2,6 @@
"archived": 0,
"overtime": 0,
"absence": {
- "14": "U",
"2": "SO"
},
"notes": {
diff --git a/users/testuser1/2025-5.txt b/users/testuser1/2025-5.txt
index 5098bdd..58cd3a9 100644
--- a/users/testuser1/2025-5.txt
+++ b/users/testuser1/2025-5.txt
@@ -6,3 +6,6 @@
1746608922
1746609024
1746609037
+1747206908
+1747207022
+1747813500