Zusätzliche Überprüfung ob Archivierung sinnvoll mit zustzlichen Hinweisen.
This commit is contained in:
parent
4b1a222132
commit
3209d0d91f
7
admin.py
7
admin.py
@ -132,7 +132,7 @@ def page_admin():
|
|||||||
def update_month_and_year():
|
def update_month_and_year():
|
||||||
current_user = user(time_user.value)
|
current_user = user(time_user.value)
|
||||||
# Archivstatus
|
# 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:
|
with ui.grid(columns='auto auto auto 1fr 1fr 1fr 1fr') as table_grid:
|
||||||
if int(select_month.value) > 1:
|
if int(select_month.value) > 1:
|
||||||
archive_status = current_user.get_archive_status(int(select_year.value),
|
archive_status = current_user.get_archive_status(int(select_year.value),
|
||||||
@ -310,6 +310,10 @@ 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))
|
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:
|
if archive_status:
|
||||||
timestamp_button.disable()
|
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
|
# Notizen anzeigen
|
||||||
days_notes = current_user.get_day_notes(select_year.value, select_month.value, day)
|
days_notes = current_user.get_day_notes(select_year.value, select_month.value, day)
|
||||||
@ -586,6 +590,7 @@ Dies kann nicht rückgängig gemacht werden!''')
|
|||||||
current_user = user(time_user.value)
|
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}**")
|
||||||
|
|
||||||
|
month_header.set_content(f"###Buchungen für **{current_user.fullname}** für **{calendar.month_name[int(select_month.value)]} {select_year.value}**")
|
||||||
timetable()
|
timetable()
|
||||||
button_update = ui.button("Aktualisieren", on_click=timetable.refresh)
|
button_update = ui.button("Aktualisieren", on_click=timetable.refresh)
|
||||||
button_update.move(timetable_header)
|
button_update.move(timetable_header)
|
||||||
|
16
api.py
16
api.py
@ -21,6 +21,7 @@ def page_overview_month(username: str, year: int, month: int):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
current_user = user(username)
|
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}")
|
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):
|
if current_user.get_archive_status(year, month):
|
||||||
with ui.column().classes('w-full items-end gap-0'):
|
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
|
color_day = color_weekend
|
||||||
|
|
||||||
current_day_date = f"{datetime(year, month, day).strftime('%a')}, {day}.{month}.{year}"
|
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
|
# Abwesenheitseinträge
|
||||||
@ -104,7 +106,7 @@ def page_overview_month(username: str, year: int, month: int):
|
|||||||
|
|
||||||
except:
|
except:
|
||||||
if len(timestamps_dict[day]) % 2 != 0:
|
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}')
|
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()
|
dialog.open()
|
||||||
|
|
||||||
if archivable == True:
|
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()
|
archive()
|
||||||
|
|
||||||
|
20
users.py
20
users.py
@ -3,6 +3,7 @@ import hashlib
|
|||||||
# User bezogene Funktionen
|
# User bezogene Funktionen
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from calendar import monthrange
|
||||||
from stat import S_IREAD, S_IWUSR
|
from stat import S_IREAD, S_IWUSR
|
||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
@ -223,6 +224,25 @@ class user:
|
|||||||
except:
|
except:
|
||||||
return -1
|
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):
|
def archive_hours(self, year, month, overtime: int):
|
||||||
|
|
||||||
filename = f"{self.userfolder}/{year}-{month}.json"
|
filename = f"{self.userfolder}/{year}-{month}.json"
|
||||||
|
2
users/testuser1/2025-3.json
Normal file → Executable file
2
users/testuser1/2025-3.json
Normal file → Executable file
@ -1 +1 @@
|
|||||||
{"archived": 1, "overtime": -528928}
|
{"archived": 0, "overtime": -528928}
|
32
users/testuser1/2025-3.txt
Normal file → Executable file
32
users/testuser1/2025-3.txt
Normal file → Executable 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
|
1740996000
|
||||||
1740997800
|
1742460540
|
||||||
|
1741038540
|
||||||
|
1742464500
|
||||||
|
13
users/testuser1/2025-4.json
Executable file → Normal file
13
users/testuser1/2025-4.json
Executable file → Normal 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
16
users/testuser1/2025-4.txt
Executable file → Normal file
@ -1,21 +1,5 @@
|
|||||||
1744889948
|
1744889948
|
||||||
1744890300
|
1744890300
|
||||||
1744989797
|
|
||||||
1744989827
|
|
||||||
1744989830
|
|
||||||
1744989883
|
|
||||||
1744989909
|
|
||||||
1744989914
|
|
||||||
1744989916
|
|
||||||
1744991169
|
|
||||||
1744991171
|
|
||||||
1744991288
|
|
||||||
1744991291
|
|
||||||
1744991473
|
|
||||||
1744991477
|
|
||||||
1744991770
|
|
||||||
1745215200
|
|
||||||
1745229600
|
|
||||||
1745390818
|
1745390818
|
||||||
1745390894
|
1745390894
|
||||||
1745390894
|
1745390894
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
"archived": 0,
|
"archived": 0,
|
||||||
"overtime": 0,
|
"overtime": 0,
|
||||||
"absence": {
|
"absence": {
|
||||||
"14": "U",
|
|
||||||
"2": "SO"
|
"2": "SO"
|
||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
|
@ -6,3 +6,6 @@
|
|||||||
1746608922
|
1746608922
|
||||||
1746609024
|
1746609024
|
||||||
1746609037
|
1746609037
|
||||||
|
1747206908
|
||||||
|
1747207022
|
||||||
|
1747813500
|
||||||
|
Loading…
x
Reference in New Issue
Block a user