from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from django.http import JsonResponse from .models import Workday, Breaks, FreeDays, AbsenceReason, Absence from django.utils import timezone import requests, csv, os from django.templatetags.static import static from django.conf import settings from datetime import date from django.contrib.auth.models import User from calendar import monthrange import datetime import calendar from .forms import AddAbsence, ConfirmAbsenceForm, UpdateAbsence, UpdateWorkdayForm, AddBreakForm, AddWorkdayForm from django.contrib import messages from users.models import UserFullName, UserYearAbsenceInfo from users.models import UserTime from datetime import timedelta from django.db.models.signals import post_save from users.signals import save_newabsence import locale # Load freedays def loadingFreeDays(plz): # Getting land file_path = os.path.join(settings.STATIC_ROOT, 'users/extra/plz_short.csv') land = False with open(file_path, 'rt') as csvfile: filecsv = csv.reader(csvfile, delimiter=';') for row in filecsv: if row[1] == plz: land = row[6] break; if(land != False): # CALCULATE FREEDAYS AS JSON year = today = date.today().year URL = "https://feiertage-api.de/api/" PARAMS = {'jahr':year,'nur_land':land} r = requests.get(url = URL, params = PARAMS) return r.json() else: return False def get_datetime_range(year, month): nb_days = monthrange(year, month)[1] return [datetime.date(year, month, day) for day in range(1, nb_days+1)] @login_required def AbsenceUpdate(request, pk): if request.method == "GET": absence = Absence.objects.get(pk=pk) timeinfo_thisyear = list(UserYearAbsenceInfo.objects.filter(year=absence.start.year, user=absence.user))[0] try: timeinfo_nextyear = list(UserYearAbsenceInfo.objects.filter(year=absence.start.year+1, user=absence.user))[0] except: timeinfo_nextyear = False context = { "active_link" : "abscence", "form" : UpdateAbsence(instance=request.user), "absence" : absence, "timeinfo_thisyear" : timeinfo_thisyear, "timeinfo_nextyear" : timeinfo_nextyear, "start" : absence.start.strftime("%d.%m.%Y"), "end" : absence.end.strftime("%d.%m.%Y"), } return render(request, 'timemanagement/tm_ab_update.html', context) elif request.method == "POST": absence = Absence.objects.get(pk=pk) formtocheck = UpdateAbsence(request.POST, instance=request.user) if(formtocheck.is_valid()): abinfo = list(UserYearAbsenceInfo.objects.filter(user=absence.user, year=absence.start.year))[0] abinfo_lastyear = "" abinfo_nextyear = "" is_lastyear = False abinfo_lastyear = list(UserYearAbsenceInfo.objects.filter(user=absence.user, year=absence.start.year-1)) if(len(abinfo_lastyear) > 0): is_lastyear = True abinfo_lastyear = abinfo_lastyear[0] is_nextyear = False abinfo_nextyear = list(UserYearAbsenceInfo.objects.filter(user=absence.user, year=absence.start.year+1)) if(len(abinfo_nextyear) > 0): is_nextyear = True abinfo_nextyear = abinfo_nextyear[0] abinfo.days_inuse -= formtocheck.cleaned_data["holidays_normal"] abinfo.restdays -= formtocheck.cleaned_data["holidays_rest"] abinfo.save() abinfo_nextyear.days_inuse -= formtocheck.cleaned_data["holidays_normal_next"] abinfo_nextyear.restdays -= formtocheck.cleaned_data["holidays_rest_next"] abinfo_nextyear.save() absence.start = formtocheck.cleaned_data["start"] absence.end = formtocheck.cleaned_data["end"] absence.startday_info = str(formtocheck.cleaned_data["startday_info"]) absence.endday_info = str(formtocheck.cleaned_data["endday_info"]) absence.reason = formtocheck.cleaned_data["reason"] rep = None if(formtocheck.cleaned_data["representator"] != None): rep = User.objects.get(pk=formtocheck.cleaned_data["representator"].pk) absence.representator = rep absence.info = formtocheck.cleaned_data["info"] absence.holidays_normal = 0.0 absence.holidays_rest = 0.0 absence.holidays_normal_next = 0.0 absence.holidays_rest_next = 0.0 absence.save() messages.success(request, f'Abwesenheit aktualisiert!') else: messages.success(request, f'Fehler bei Abwesenheitsaktualisierung!') context = { "active_link" : "abscence", } return redirect("tma-management") @login_required def AbsenceManagmenet(request, activemonth=False, activeyear=False): # NEW ABSENCE if(request.method == "POST"): ''' Nachdem eine neue Abwesenheit gespeichert wurde, geht es zur normalen Seite zurück, jedoch mit den Daten des aktuell angezeigten Monate/Jahr ''' if(request.POST.get("form_type") == "absenceform"): formtocheck = AddAbsence(request.POST, instance=request.user) if(formtocheck.is_valid()): try: workinguser = UserFullName.objects.get(pk=formtocheck.cleaned_data["userid"]) # DIFFERENT USER AGENCY if(workinguser.profile.agency != request.user.profile.agency): messages.success(request, f'Das dürfen Sie nicht!') return redirect('tma-management', formtocheck.cleaned_data['activemonth'], formtocheck.cleaned_data['activeyear']) # ALL OK - START SAVING ABSENCE else: confirmstat = 0 reason = AbsenceReason.objects.filter(name=formtocheck.cleaned_data["reason"], agency=request.user.profile.agency)[0] if(request.user.has_perm("users.absencemanager") == False and reason.need_confirm == True): confirmstat = 1 messages.success(request, f'Abwesenheit beantragt') # SEND NOTIFICATION elif(request.user.has_perm("users.absencemanager") == False and reason.need_confirm == False): confirm_status = 0 messages.success(request, f'Abwesenheit eingetragen') else: messages.success(request, f'Abwesenheit eingetragen') rep = None if(formtocheck.cleaned_data["representator"] != None): rep = User.objects.get(pk=formtocheck.cleaned_data["representator"].pk) #newab = Absence(agency=request.user.profile.agency, user=workinguser, start=formtocheck.cleaned_data["start"],end=formtocheck.cleaned_data["end"], representator=rep, confirm_status=confirmstat, info=formtocheck.cleaned_data["info"], reason=formtocheck.cleaned_data["reason"], start_ishalf=formtocheck.cleaned_data["start_ishalf"], end_ishalf=formtocheck.cleaned_data["end_ishalf"]).save() newab = Absence(agency=request.user.profile.agency, user=workinguser, start=formtocheck.cleaned_data["start"],end=formtocheck.cleaned_data["end"], representator=rep, confirm_status=confirmstat, info=formtocheck.cleaned_data["info"], reason=formtocheck.cleaned_data["reason"], startday_info=formtocheck.cleaned_data["startday_info"], endday_info=formtocheck.cleaned_data["endday_info"]).save() # USER NOT FOUND except: messages.success(request, f'Fehler bei Abwesenheitsbearbeitung! Bitte wenden Sie sich an den Support.') return redirect('tma-management', formtocheck.cleaned_data['activemonth'], formtocheck.cleaned_data['activeyear']) return redirect('tma-management', formtocheck.cleaned_data['activemonth'], formtocheck.cleaned_data['activeyear']) else: messages.success(request, f'Fehler beim eintragen der neuen Abwesenheit!') return redirect('tma-management', formtocheck.cleaned_data['activemonth'], formtocheck.cleaned_data['activeyear']) else: return redirect('tma-management') # NORMAL VIEW else: prevmonth = "" nextmonth = "" #MONTH if(not activemonth or activemonth > 12 or activemonth < 1): activemonth = int(activemonth) #Active month activemonth=date.today().month if(activemonth == 1): prevmonth = 12 else: prevmonth = activemonth-1 if(activemonth == 12): nextmonth = 1 else: nextmonth = activemonth + 1 else: if(activemonth == 1): prevmonth = 12 else: prevmonth = activemonth-1 if(activemonth == 12): nextmonth = 1 else: nextmonth = activemonth + 1 #YEAR nextyear = date.today().year prevyear = date.today().year if(not activeyear): activeyear = date.today().year else: if(nextmonth == 1): nextyear = activeyear + 1 else: nextyear = activeyear if(prevmonth == 12): prevyear = activeyear - 1 else: prevyear = activeyear missinguserdata = [] #CHECK, ob alle nötigen Infos zur Urlaubsberechnung vorliegen for user in User.objects.filter(profile__agency=request.user.profile.agency): tempTime = UserTime.objects.get(user=user) if(tempTime.startdate == None): missinguserdata.append(user) kontingent = 0 inuse = 0 yearinfo = False try: yearinfo = list(UserYearAbsenceInfo.objects.filter(year=activeyear, user=request.user))[0] inuse = yearinfo.days_inuse kontingent = yearinfo.days - inuse except: pass # ABSENCE AUFLISTUNG NACH GRUND allreasons = AbsenceReason.objects.filter(agency=request.user.profile.agency).order_by("name") final_reasons = [] for ar in allreasons: tempabsece = Absence.objects.filter(reason=ar, user=request.user, start__year=activeyear, confirm_status=0) temp_sum = 0.0 for t in tempabsece: temp_sum += calculatingHolidaysByAbsence(request, t) final_reasons.append([ar, temp_sum]) context = { "active_link" : "abscence", "usersofagency" : User.objects.filter(profile__agency=request.user.profile.agency).order_by("-last_name"), "days_this_month" : get_datetime_range(activeyear,activemonth), "nextmonth" : nextmonth, "missinguserdata" : missinguserdata, "prevmonth" : prevmonth, "nextyear" : nextyear, "prevyear" : prevyear, "activemonth" : activemonth, "activeyear" : activeyear, "inuse" : inuse, "final_reasons" : final_reasons, "yearinfo" : yearinfo, "kontingent" : kontingent, "today" : date.today(), "abscenceform" : AddAbsence(instance=request.user), "userown" : Absence.objects.filter(agency=request.user.profile.agency, user=request.user).order_by("-start") } if(request.user.has_perm("users.absencemanager")): context.update({ "needtoconfirm" : Absence.objects.filter(agency=request.user.profile.agency, confirm_status=1).order_by("-start"), "allabsences" : Absence.objects.filter(agency=request.user.profile.agency).order_by("-start") }) return render(request, 'timemanagement/tm_ab_management.html', context) @login_required def TimeManagementTeamSingle(request, pk, activemonth=False, activeyear=False): if(request.user.has_perm("users.usermanager")): # Setzt die Monatsausgabe auf Deutsch locale.setlocale(locale.LC_TIME, 'de_DE.UTF-8') user = User.objects.get(pk=pk) # Hier wird der Monat und das Jahr für die Buttons gebaut if(activemonth == False): today = datetime.datetime.today() active_month = str(today.strftime("%B")) active_year = str(today.strftime("%Y")) activemonth = today.month else: today = datetime.datetime(activeyear, activemonth, 1) active_month = activemonth active_month = str(today.strftime("%B")) active_year = str(today.strftime("%Y")) prev_year = active_year next_year = active_year next_month = today.month + 1 if(next_month == 13): next_month = 1 next_year = int(next_year) + 1 prev_month = today.month - 1 if(prev_month == 0): prev_month = 12 prev_year = int(prev_year) - 1 # Initialprüfung, ob Arbeitstage vorliegen tempworkday = Workday.objects.filter(agency=request.user.profile.agency, user=user).order_by("start").exclude(end=None)[:1] user_has_workdays = False if len(tempworkday) == 1: user_has_workdays = True # Hier werden nur die Arbeitstage gefiltert, die auch aktuell zur Ansicht stehen sollen context = { "next_month" : next_month, "breakmonthline" : date.today() - timedelta(days=30), "prev_month" : prev_month, "next_year" : next_year, "prev_year" : prev_year, "active_year" : int(active_year), "active_month" : active_month, "activemonth" : activemonth, "active_link" : "timemanagement", "days_this_month" : get_datetime_range(int(active_year), int(activemonth)), "workdays" : Workday.objects.filter(agency=request.user.profile.agency, user=user, start__month=activemonth, start__year=active_year).order_by("start").exclude(end=None), "userhasworkdays" : user_has_workdays, "user" : user } return render(request, 'timemanagement/timemanagement_teamview_single.html', context) # Requestet User has no rights... else: messages.success(request, f'Das würfen Sie nicht!') return redirect("tm-management") @login_required def TimeManagement(request, activemonth=False, activeyear=False): # Setzt die Monatsausgabe auf Deutsch locale.setlocale(locale.LC_TIME, 'de_DE.UTF-8') # Hier wird der Monat und das Jahr für die Buttons gebaut if(activemonth == False): today = datetime.datetime.today() active_month = str(today.strftime("%B")) active_year = str(today.strftime("%Y")) activemonth = today.month else: today = datetime.datetime(activeyear, activemonth, 1) active_month = activemonth active_month = str(today.strftime("%B")) active_year = str(today.strftime("%Y")) prev_year = active_year next_year = active_year next_month = today.month + 1 if(next_month == 13): next_month = 1 next_year = int(next_year) + 1 prev_month = today.month - 1 if(prev_month == 0): prev_month = 12 prev_year = int(prev_year) - 1 # Initialprüfung, ob Arbeitstage vorliegen tempworkday = Workday.objects.filter(agency=request.user.profile.agency, user=request.user).order_by("start").exclude(end=None)[:1] user_has_workdays = False if len(tempworkday) == 1: user_has_workdays = True # Hier werden nur die Arbeitstage gefiltert, die auch aktuell zur Ansicht stehen sollen context = { "next_month" : next_month, "breakmonthline" : date.today() - timedelta(days=30), "prev_month" : prev_month, "next_year" : next_year, "prev_year" : prev_year, "active_year" : int(active_year), "active_month" : active_month, "activemonth" : activemonth, "active_link" : "timemanagement", "days_this_month" : get_datetime_range(int(active_year), int(activemonth)), "workdays" : Workday.objects.filter(agency=request.user.profile.agency, user=request.user, start__month=activemonth, start__year=active_year).order_by("start").exclude(end=None), "userhasworkdays" : user_has_workdays } if(request.user.has_perm("users.usermanager")): context.update({"usersofagencytm" : User.objects.filter(profile__agency=request.user.profile.agency).order_by('last_name')}) return render(request, 'timemanagement/timemanagement_management.html', context) @login_required def TimeUpdate(request, pk, team=0): workday = Workday.objects.get(pk=pk) user = workday.user if(request.method == "POST"): if(team == 0): form = UpdateWorkdayForm(request.POST, instance=request.user) else: form = UpdateWorkdayForm(request.POST, instance=user) start = datetime.datetime(int(workday.start.year), int(workday.start.month), int(workday.start.day), int(((str(form["start"].value()).split(":"))[0])), int(((str(form["start"].value()).split(":"))[1]))) end = datetime.datetime(int(workday.end.year), int(workday.end.month), int(workday.end.day), int(((str(form["end"].value()).split(":"))[0])), int(((str(form["end"].value()).split(":"))[1]))) workday.start = start workday.end = end workday.target = form["target"].value() workday.save() messages.success(request, f'Arbeitstag aktualisiert') if(team == 1): return redirect('tm-team-single', user.pk, workday.start.month, workday.start.year) else: return redirect('tm-management') else: context = { "active_link" : "timemanagement", "workday" : Workday.objects.get(pk=pk), "form" : UpdateWorkdayForm(instance= Workday.objects.get(pk=pk)), "team" : team, "user" : workday.user } return render(request, 'timemanagement/timemanagement_update.html', context) @login_required def TimeAdd(request, team=0, pk=0): if(team == 0): user = request.user form = AddWorkdayForm(request.POST, instance=request.user) else: user = User.objects.get(pk=pk) form = AddWorkdayForm(request.POST, instance=user) if(request.method == "POST"): if form.is_valid(): #start = datetime.datetime(int(workday.start.year), int(workday.start.month), int(workday.start.day), int(((str(form["start"].value()).split(":"))[0])), int(((str(form["start"].value()).split(":"))[1]))) #end = datetime.datetime(int(workday.end.year), int(workday.end.month), int(workday.end.day), int(((str(form["end"].value()).split(":"))[0])), int(((str(form["end"].value()).split(":"))[1]))) workday = Workday(start=form.cleaned_data["start"], end=form.cleaned_data["end"], target=form.cleaned_data["target"], user=user, agency=request.user.profile.agency) if workday.start.day != workday.end.day or workday.start.month != workday.end.month or workday.start.year != workday.end.year or workday.start > workday.end: messages.success(request, f'Der Arbeitstag darf nur an einem Tag stattfinden und das Ende muss nach dem Anfang liegen.') context = { "active_link" : "timemanagement", "form" : AddWorkdayForm(), "team" : team, "user" : user } return render(request, 'timemanagement/timemanagement_add.html', context) else: workday.save() messages.success(request, f'Arbeitstag hinzugefügt') if (team == 1): return redirect('tm-team-single', user.pk, workday.start.month, workday.start.year) else: return redirect('tm-management') else: messages.success(request, f'Bitte valide Daten eingeben!') context = { "active_link" : "timemanagement", "form" : AddWorkdayForm(), "team" : team, "user" : user } return render(request, 'timemanagement/timemanagement_add.html', context) else: context = { "active_link" : "timemanagement", "form" : AddWorkdayForm(), "team" : team, "user" : user } return render(request, 'timemanagement/timemanagement_add.html', context) @login_required def AddBreak(request, pk, team=0): workday = Workday.objects.get(pk=pk) user = workday.user if(request.method == "POST"): if(team == 0): form = AddBreakForm(request.POST, instance=request.user) else: form = AddBreakForm(request.POST, instance=user) start = datetime.datetime(int(workday.start.year), int(workday.start.month), int(workday.start.day), int(((str(form["start"].value()).split(":"))[0])), int(((str(form["start"].value()).split(":"))[1]))) end = datetime.datetime(int(workday.end.year), int(workday.end.month), int(workday.end.day), int(((str(form["end"].value()).split(":"))[0])), int(((str(form["end"].value()).split(":"))[1]))) if(team == 0): newbreak = Breaks.objects.create(workday=workday, user=request.user, agency=request.user.profile.agency, start=start, end=end) else: newbreak = Breaks.objects.create(workday=workday, user=user, agency=user.profile.agency, start=start, end=end) workday.breaks.add(newbreak) workday.save() messages.success(request, f'Pause hinzugefügt') if(team == 0): return redirect('tm-update', pk=pk) else: return redirect('tm-team-single', user.pk, workday.start.month, workday.start.year) else: if(team == 0): context = { "active_link" : "timemanagement", "workday" : Workday.objects.get(pk=pk), "form" : AddBreakForm(instance=request.user) } else: context = { "active_link" : "timemanagement", "workday" : Workday.objects.get(pk=pk), "form" : AddBreakForm(instance=user) } return render(request, 'timemanagement/timemanagement_break.html', context) @login_required def TimeAjax(request): data = {} if request.method == "GET": # START WORKDAY if request.GET["action"] == "start_day": today = date.today() targettime = 0.0 if(today.isoweekday() == 1): targettime = request.user.usertime.wd_mo elif(today.isoweekday() == 2): targettime = request.user.usertime.wd_tu elif(today.isoweekday() == 3): targettime = request.user.usertime.wd_we elif(today.isoweekday() == 4): targettime = request.user.usertime.wd_th elif(today.isoweekday() == 5): targettime = request.user.usertime.wd_fr elif(today.isoweekday() == 6): targettime = request.user.usertime.wd_sa elif(today.isoweekday() == 7): targettime = request.user.usertime.wd_so wd = Workday(user=request.user, agency=request.user.profile.agency, start=timezone.now(), target=targettime) wd.save() data = { "success" : True, "wd_starttime" : wd.start.strftime("%H:%M:%S"), "wd_starttime_complete" : wd.start } # END DAY elif request.GET["action"] == "end_day": wd = list(Workday.objects.filter(user=request.user, agency=request.user.profile.agency, end=None))[0] # END ALL BREAKS for b in wd.breaks.all(): if b.end == None: b.end = timezone.now() b.save() wd.end = timezone.now() wd.save() breaksum = 0 for b in wd.breaks.all(): if(b.end != None): breaksum += (b.end - b.start).seconds data = { "success" : True, "wd_endtime" : wd.end.strftime("%H:%M:%S"), "actualbreaktime" : breaksum*1000 } # START A BREAK elif request.GET["action"] == "start_break": wd = list(Workday.objects.filter(user=request.user, agency=request.user.profile.agency, end=None))[0] newbreak = Breaks(workday=wd, user=request.user, agency=request.user.profile.agency, start=timezone.now()) newbreak.save() wd.breaks.add(newbreak) data = { "success" : True, "break_starttime" : newbreak.start, } # END BREAK elif request.GET["action"] == "end_break": wd = list(Workday.objects.filter(user=request.user, agency=request.user.profile.agency, end=None))[0] toendbreak = list(wd.breaks.filter(end=None))[0] toendbreak.end = timezone.now() toendbreak.save() wd = list(Workday.objects.filter(user=request.user, agency=request.user.profile.agency, end=None))[0] breaksum = 0 for b in wd.breaks.all(): if(b.end != None): breaksum += (b.end - b.start).seconds data = { "success" : True, "actualbreaktime" : breaksum*1000 } # REMOVE WORKDAY elif request.GET["action"] == "remove_workday": wd = Workday.objects.get(pk=request.GET.get("workday")) if(wd.agency == request.user.profile.agency): wd.delete() data = { "success" : True } else: data = { "success" : False} # REMOVE BREAK elif request.GET["action"] == "remove_break": breakwd = Breaks.objects.get(pk=request.GET.get("break")) if(breakwd.agency == request.user.profile.agency): breakwd.delete() data = { "success" : True } else: data = { "success" : False} # LOADING INTIAIL WORKDAYS elif request.GET["action"] == "initial_load": allfreedays = FreeDays.objects.filter(agency=request.user.profile.agency, day__gt=request.user.usertime.usetime_start, day__lt=date.today()) weekdays = [6,7] for dt in daterange(request.user.usertime.usetime_start, date.today()): if dt.isoweekday() not in weekdays: in_freedays = False for freeday in allfreedays.all(): if(dt == freeday.day): in_freedays = True break; if(not in_freedays): # MONDAY if(dt.isoweekday() == 1): start_time = datetime.timedelta(hours=8) start_date = datetime.date(int(dt.year), int(dt.month), int(dt.day)) end_time = datetime.timedelta(hours=request.user.usertime.wd_mo) + start_time time_start = datetime.datetime.strptime(str(start_time), "%H:%M:%S").time() time_end = datetime.datetime.strptime(str(end_time), "%H:%M:%S").time() start_datetime = datetime.datetime.combine(start_date, time_start) end_datetime = datetime.datetime.combine(start_date, time_end) Workday.objects.create(user=request.user, agency=request.user.profile.agency, start=start_datetime, end=end_datetime, target=request.user.usertime.wd_mo) if(dt.isoweekday() == 2): start_time = datetime.timedelta(hours=8) start_date = datetime.date(int(dt.year), int(dt.month), int(dt.day)) end_time = datetime.timedelta(hours=request.user.usertime.wd_tu) + start_time time_start = datetime.datetime.strptime(str(start_time), "%H:%M:%S").time() time_end = datetime.datetime.strptime(str(end_time), "%H:%M:%S").time() start_datetime = datetime.datetime.combine(start_date, time_start) end_datetime = datetime.datetime.combine(start_date, time_end) Workday.objects.create(user=request.user, agency=request.user.profile.agency, start=start_datetime, end=end_datetime, target=request.user.usertime.wd_tu) if(dt.isoweekday() == 3): start_time = datetime.timedelta(hours=8) start_date = datetime.date(int(dt.year), int(dt.month), int(dt.day)) end_time = datetime.timedelta(hours=request.user.usertime.wd_we) + start_time time_start = datetime.datetime.strptime(str(start_time), "%H:%M:%S").time() time_end = datetime.datetime.strptime(str(end_time), "%H:%M:%S").time() start_datetime = datetime.datetime.combine(start_date, time_start) end_datetime = datetime.datetime.combine(start_date, time_end) Workday.objects.create(user=request.user, agency=request.user.profile.agency, start=start_datetime, end=end_datetime, target=request.user.usertime.wd_we) if(dt.isoweekday() == 4): start_time = datetime.timedelta(hours=8) start_date = datetime.date(int(dt.year), int(dt.month), int(dt.day)) end_time = datetime.timedelta(hours=request.user.usertime.wd_th) + start_time time_start = datetime.datetime.strptime(str(start_time), "%H:%M:%S").time() time_end = datetime.datetime.strptime(str(end_time), "%H:%M:%S").time() start_datetime = datetime.datetime.combine(start_date, time_start) end_datetime = datetime.datetime.combine(start_date, time_end) Workday.objects.create(user=request.user, agency=request.user.profile.agency, start=start_datetime, end=end_datetime, target=request.user.usertime.wd_th) if(dt.isoweekday() == 5): start_time = datetime.timedelta(hours=8) start_date = datetime.date(int(dt.year), int(dt.month), int(dt.day)) end_time = datetime.timedelta(hours=request.user.usertime.wd_fr) + start_time time_start = datetime.datetime.strptime(str(start_time), "%H:%M:%S").time() time_end = datetime.datetime.strptime(str(end_time), "%H:%M:%S").time() start_datetime = datetime.datetime.combine(start_date, time_start) end_datetime = datetime.datetime.combine(start_date, time_end) Workday.objects.create(user=request.user, agency=request.user.profile.agency, start=start_datetime, end=end_datetime, target=request.user.usertime.wd_fr) if(dt.isoweekday() == 6): start_time = datetime.timedelta(hours=8) start_date = datetime.date(int(dt.year), int(dt.month), int(dt.day)) end_time = datetime.timedelta(hours=request.user.usertime.wd_sa) + start_time time_start = datetime.datetime.strptime(str(start_time), "%H:%M:%S").time() time_end = datetime.datetime.strptime(str(end_time), "%H:%M:%S").time() start_datetime = datetime.datetime.combine(start_date, time_start) end_datetime = datetime.datetime.combine(start_date, time_end) Workday.objects.create(user=request.user, agency=request.user.profile.agency, start=start_datetime, end=end_datetime, target=request.user.usertime.wd_sa) if(dt.isoweekday() == 7): start_time = datetime.timedelta(hours=8) start_date = datetime.date(int(dt.year), int(dt.month), int(dt.day)) end_time = datetime.timedelta(hours=request.user.usertime.wd_so) + start_time time_start = datetime.datetime.strptime(str(start_time), "%H:%M:%S").time() time_end = datetime.datetime.strptime(str(end_time), "%H:%M:%S").time() start_datetime = datetime.datetime.combine(start_date, time_start) end_datetime = datetime.datetime.combine(start_date, time_end) Workday.objects.create(user=request.user, agency=request.user.profile.agency, start=start_datetime, end=end_datetime, target=request.user.usertime.wd_so) # Get Rendered Table elif request.GET["action"] == "getrenderedtable": prevmonth = "" nextmonth = "" activemonth = int(request.GET["activemonth"]) activeyear = int(request.GET["activeyear"]) #MONTH if(not activemonth or activemonth > 12 or activemonth < 1): activemonth = int(activemonth) #Active month activemonth=date.today().month if(activemonth == 1): prevmonth = 12 else: prevmonth = activemonth-1 if(activemonth == 12): nextmonth = 1 else: nextmonth = activemonth + 1 else: if(activemonth == 1): prevmonth = 12 else: prevmonth = activemonth-1 if(activemonth == 12): nextmonth = 1 else: nextmonth = activemonth + 1 #YEAR nextyear = date.today().year prevyear = date.today().year if(not activeyear): activeyear = date.today().year else: if(nextmonth == 1): nextyear = activeyear + 1 else: nextyear = activeyear if(prevmonth == 12): prevyear = activeyear - 1 else: prevyear = activeyear missinguserdata = [] #CHECK, ob alle nötigen Infos zur Urlaubsberechnung vorliegen for user in User.objects.filter(profile__agency=request.user.profile.agency): tempTime = UserTime.objects.get(user=user) if(tempTime.startdate == None): missinguserdata.append(user) context = { "active_link" : "abscence", "usersofagency" : User.objects.filter(profile__agency=request.user.profile.agency).order_by("-last_name"), "days_this_month" : get_datetime_range(activeyear,activemonth), "activemonth" : activemonth, "missinguserdata" : missinguserdata, "activeyear" : activeyear, "nextmonth" : nextmonth, "prevmonth" : prevmonth, "nextyear" : nextyear, "prevyear" : prevyear, "today" : date.today(), } return render(request, "timemanagement/rendered_table.html", context) # Prüfung, ob eine Vertretung nötig ist oder nicht elif request.GET["action"] == "checkrequired": reason = AbsenceReason.objects.get(pk=request.GET["rid"]) if(reason.agency == request.user.profile.agency): data = { "success" : True, "isreq" : reason.need_rep, "isholiday" : reason.is_holiday } else: data = { "success" : False } # DELETE ABSENCE elif request.GET["action"] == "remove_absence": absence = Absence.objects.get(pk=request.GET["ab"]) if(request.user.has_perm("users.absencemanager") and absence.agency == request.user.profile.agency): absence.delete() data = { "success" : True } # GET FORM FOR CONFIRM ABSENCE elif request.GET["action"] == "getrenderedform": absence = Absence.objects.get(pk=request.GET["abscenceid"]) timeinfo_thisyear = list(UserYearAbsenceInfo.objects.filter(year=absence.start.year, user=absence.user))[0] try: timeinfo_nextyear = list(UserYearAbsenceInfo.objects.filter(year=absence.start.year+1, user=absence.user))[0] except: timeinfo_nextyear = False # POrüfen, ob es in diesem Zeitraum noch andere Abwesenheiten gibt other_absences = Absence.objects.filter(start__lte=absence.start, end__gte=absence.end, agency=request.user.profile.agency, confirm_status=0).exclude(user=absence.user) other_absences_string = False if (len(other_absences) > 0): other_absences_string = [] for a in other_absences: other_absences_string.append(a.user.first_name + " " + a.user.last_name + " - Vom " + a.start.strftime("%d.%m.%Y") + " bis " + a.end.strftime("%d.%m.%Y")) context = { "confirmform" : ConfirmAbsenceForm(instance=request.user), "absence" : absence, "other_absences_string" : other_absences_string, "timeinfo_thisyear" : timeinfo_thisyear, "timeinfo_nextyear" : timeinfo_nextyear } return render(request, "timemanagement/rendered_confirmform.html", context) elif request.GET["action"] == "confirmornotabscence": absence = Absence.objects.get(pk=request.GET["absencetowork"]) new_stat = request.GET["newconfstat"] info = request.GET["info"] # Eingeloggter Nutzer hat Rechte, Urlaube einzutragen if(absence.user.profile.agency == request.user.profile.agency and request.user.has_perm("users.absencemanager")): absence.confirm_status = new_stat # Wenn eine Abwesenheit abgelehnt wurde, werden hier die Tage wieder auf das Kontingent geschrieben. Die Abewesenheit selber wird aber nicht gelöscht, sondern ist dann einfach "leer" if(new_stat == "2"): year = absence.start.year userabinfo_thisyear = list(UserYearAbsenceInfo.objects.filter(user=absence.user, year=year))[0] userabinfo_nextyear = list(UserYearAbsenceInfo.objects.filter(user=absence.user, year=year+1))[0] userabinfo_thisyear.days_inuse = userabinfo_thisyear.days_inuse - absence.holidays_normal - absence.holidays_rest userabinfo_thisyear.restdays = userabinfo_thisyear.restdays + absence.holidays_rest userabinfo_nextyear.days_inuse = userabinfo_nextyear.days_inuse - absence.holidays_normal_next - absence.holidays_rest_next userabinfo_nextyear.restdays = userabinfo_nextyear.restdays + absence.holidays_rest_next userabinfo_thisyear.save() userabinfo_nextyear.save() absence.holidays_normal = 0 absence.holidays_rest = 0 absence.holidays_normal_next = 0 absence.holidays_rest_next = 0 absence.confirm_info = info post_save.disconnect(save_newabsence, sender=Absence) absence.save() post_save.connect(save_newabsence, sender=Absence) messages.success(request, f'Abwesenheit gespeichert!') else: messages.success(request, f'Das dürfen Sie nicht!') data = { "success" : True, "activemonth" : request.GET["activemonth"], "activeyear" : request.GET["activeyear"] } # Berechnung starten, da Urlaub vorhanden ist elif request.GET["action"] == "getrestholidays": user = User.objects.get(pk=request.GET["userid"]) usertimedata = UserTime.objects.get(user=user) today = date.today() if(user.profile.agency == request.user.profile.agency): start_day = request.GET["startdate"].split("__") start_day_obj = datetime.date(int(start_day[0]), int(start_day[1]), int(start_day[2])) end_day = request.GET["enddate"].split("__") end_day_obj = datetime.date(int(end_day[0]), int(end_day[1]), int(end_day[2])) try: holidayloose_date = datetime.date(start_day_obj.year, int(usertimedata.loose_holidedate.split(".")[1]), int(usertimedata.loose_holidedate.split(".")[0])) except: holidayloose_date = datetime.date(2020, int(usertimedata.loose_holidedate.split(".")[1]), int(usertimedata.loose_holidedate.split(".")[0])) # GET INFO IF DAY IS HALF OR NOT, EQUAL PRE-POST-DAY start_half = False if request.GET["startday_info"] == "1" or request.GET["startday_info"] == "2": start_half = True end_half = False if request.GET["endday_info"] == "1" or request.GET["endday_info"] == "2": end_half = True choosenyear = int(start_day[0]) yeardata = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency, year=choosenyear))[0] holiday_thisyear = 0 holiday_lastyear = yeardata.restdays holiday_nextyear = 0 holiday_nextyear_rest = 0 two_years = False need_days_next = 0 need_days_this = 0 try: holiday_nextyear = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency, year=choosenyear+1))[0].days - list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency, year=choosenyear+1))[0].days_inuse holiday_nextyear_rest = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency, year=choosenyear+1))[0].restdays except: holiday_nextyear = yeardata.days # Urlaub innerhalb eines Jahres inkl. Prüfung auf Resturlaubsanspruch if(end_day_obj.year == start_day_obj.year): # Startt des Urlaubs NACH Verfallsdatum - nur aktuelles JAhr und die Zahl interessiert if(start_day_obj > holidayloose_date): need_days = (calculateHolidays(request, start_day_obj, end_day_obj, start_half, end_half, user))*(-1) holiday_thisyear = yeardata.days - yeardata.days_inuse - need_days else: need_days = (calculateHolidays(request, start_day_obj, end_day_obj, start_half, end_half, user))*(-1) # Kein Resturlaub if(yeardata.restdays == 0.0): holiday_thisyear = yeardata.days - yeardata.days_inuse - need_days # Resturlaub vorhanden, berechne mit Resturlaub else: holiday_lastyear = yeardata.restdays holiday_thisyear = yeardata.days - yeardata.days_inuse temp_holiday = holiday_lastyear - need_days if(temp_holiday < 0): holiday_lastyear = 0 holiday_thisyear = yeardata.days - yeardata.days_inuse + temp_holiday else: holiday_lastyear = yeardata.restdays - need_days # Urlaub geht über das nächstes Jahr hinweg else: two_years = True holiday_lastyear = yeardata.restdays date_splitter = datetime.date(end_day_obj.year, 1, 1) need_days_this = (calculateHolidays(request, start_day_obj, date_splitter, start_half, False), user)*(-1) need_days_next = (calculateHolidays(request, date_splitter, end_day_obj, False, end_half, user))*(-1) need_days = (calculateHolidays(request, start_day_obj, date_splitter, start_half, False, user))*(-1) + (calculateHolidays(request, date_splitter, end_day_obj, False, end_half))*(-1) holiday_thisyear = yeardata.days - yeardata.days_inuse - need_days_this days_nextyear_normal = 0 days_nextyear_rest = 0 # Urlaub nächstes Jahr MIT und OHNE Rest if(holiday_nextyear_rest == 0.0): holiday_nextyear = holiday_nextyear - (calculateHolidays(request, date_splitter, end_day_obj, False, end_half, user))*(-1) else: temprest = holiday_nextyear_rest - need_days_next # Rest reicht! if(temprest >= 0): holiday_nextyear_rest = temprest days_nextyear_normal = 0 days_nextyear_rest = need_days_next # Rest reicht nicht else: holiday_nextyear_rest = 0 holiday_nextyear += temprest days_nextyear_rest = need_days_next + temprest days_nextyear_normal = temprest * -1 # POrüfen, ob es in diesem Zeitraum noch andere Abwesenheiten gibt other_absences = Absence.objects.filter(start__lte=start_day_obj, end__gte=end_day_obj, agency=request.user.profile.agency, confirm_status=0).exclude(user=user) other_absences_string = False if (len(other_absences) > 0): other_absences_string = "" for a in other_absences: other_absences_string += a.user.first_name + " " + a.user.last_name + " - Vom " + a.start.strftime("%d.%m.%Y") + " bis " + a.end.strftime("%d.%m.%Y") + "
" # Prüfen, ob der Nutzer selbst schon Abwesenheiten in diesem Zeitraum hat userown_absences = Absence.objects.filter(start__lte=start_day_obj, end__gte=end_day_obj, agency=request.user.profile.agency, user=user, confirm_status=0) userown_absences_string = False if (len(userown_absences) > 0): userown_absences_string = "" for a in userown_absences: userown_absences_string += a.reason.name + " - Vom " + a.start.strftime("%d.%m.%Y") + " bis " + a.end.strftime("%d.%m.%Y") + "
" data = { "restholiday_thisyear" : holiday_thisyear, "restholiday_lastyear" : holiday_lastyear, "restholiday_nextyear" : holiday_nextyear, "restholiday_nextyear_rest" : holiday_nextyear_rest, "two_years" : two_years, "need_days" : need_days, "need_days_next" : need_days_next, "need_days_this" : need_days_this, "other_absences" : other_absences_string, "userown_absences" : userown_absences_string, "choosenuser_name" : user.first_name + " " + user.last_name } # REQUEST USER NO RIGHTS else: data = { "success" : False } # GET REQUEST ACTION UNKNOWN else: data = { "success" : False } return JsonResponse(data) ''' Gibt einen Integer zurück, welcher die Urlaubstage von Start zu Enddatum auf der Grundlage von Freitagen berechnet. Berücksichtigt sowohl Wochenende als auch in der Agentur hinterlegte Freitage/Schließtage ''' @login_required def calculateHolidays(request, start, end, start_half, end_half, user): restdays = 0 allfreedays = FreeDays.objects.filter(agency=request.user.profile.agency) if(end == start): if(start_half): return restdays - 0.5 else: return restdays - 1 else: if(end < start): return False else: counter = 0 if(start_half): counter -= 0.5 if(end_half): counter -= 0.5 weekdays = [] freedaycounter = 0 for dt in daterange(start, end): if dt.isoweekday() not in weekdays: counter += 1 for freeday in allfreedays.all(): if(dt == freeday.day): freedaycounter += 1 # Prüfung, ob der Mitarbeiter an diesem Tag überhaupt arbeitet. Wenn nicht, wird der Freedaycounter einfach erhöht if(dt.isoweekday() == 1): if user.usertime.wd_mo == 0.0: freedaycounter += 1 elif(dt.isoweekday() == 2): if user.usertime.wd_tu == 0.0:# freedaycounter += 1 elif(dt.isoweekday() == 3): if user.usertime.wd_we == 0.0: freedaycounter += 1 elif(dt.isoweekday() == 4): if user.usertime.wd_th == 0.0: freedaycounter += 1 elif(dt.isoweekday() == 5): if user.usertime.wd_fr == 0.0: freedaycounter += 1 elif(dt.isoweekday() == 6): if user.usertime.wd_sa == 0.0: freedaycounter += 1 elif(dt.isoweekday() == 7): if user.usertime.wd_so == 0.0: freedaycounter += 1 return restdays - counter + freedaycounter @login_required def calculatingHolidaysByAbsence(request, absence): # Freitage laden, die innerhalb der gewünschten Abwesenheit liegen allfreedays = FreeDays.objects.filter(agency=request.user.profile.agency, day__gt=absence.start, day__lt=absence.end) finalholidayinabsence = 0 # Start und Ende gleich, nur ein Tag. Checken, ob Halber Tag if(absence.start == absence.end): if absence.startday_info == "1" or absence.startday_info == "2": finalholidayinabsence = 0.5 else: finalholidayinabsence = 1 return finalholidayinabsence else: if absence.startday_info == "1" or absence.startday_info == "2": finalholidayinabsence -= 0.5 if absence.endday_info == "1" or absence.endday_info == "2": finalholidayinabsence -= 0.5 weekdays = [] freedaycounter = 0 for dt in daterange(absence.start, absence.end): if dt.isoweekday() not in weekdays: finalholidayinabsence += 1 # Prüfung, ob freie Tage vorhanden sind for freeday in allfreedays.all(): # FREEDAY FOUND if(dt == freeday.day): freedaycounter += 1 # Prüfung, ob der Mitarbeiter an diesem Tag überhaupt arbeitet. Wenn nicht, wird der Freedaycounter einfach erhöht stat = False if(dt.isoweekday() == 1): if absence.user.usertime.wd_mo == 0.0: freedaycounter += 1 elif(dt.isoweekday() == 2): if absence.user.usertime.wd_tu == 0.0:# freedaycounter += 1 elif(dt.isoweekday() == 3): if absence.user.usertime.wd_we == 0.0: freedaycounter += 1 elif(dt.isoweekday() == 4): if absence.user.usertime.wd_th == 0.0: freedaycounter += 1 elif(dt.isoweekday() == 5): if absence.user.usertime.wd_fr == 0.0: freedaycounter += 1 elif(dt.isoweekday() == 6): if absence.user.usertime.wd_sa == 0.0: freedaycounter += 1 elif(dt.isoweekday() == 7): if absence.user.usertime.wd_so == 0.0: freedaycounter += 1 return finalholidayinabsence - freedaycounter # Gibt die Woche als Wochentage zurück def daterange(date1, date2): for n in range(int ((date2 - date1).days)+1): yield date1 + timedelta(n)