From ee77bb43c49d309248039285d4d1a9f994f36d72 Mon Sep 17 00:00:00 2001 From: Holger Trampe Date: Sat, 30 May 2020 19:52:00 +0200 Subject: [PATCH] Zeiterfassung ausser Abwesenheiten fertig --- .../__pycache__/counter_tag.cpython-38.pyc | Bin 12942 -> 14470 bytes standards/templatetags/counter_tag.py | 95 ++++++++++- timemanagement/forms.py | 50 +++++- timemanagement/models.py | 1 + .../timemanagement/realtime_dropdown.html | 42 +++-- .../timemanagement/rendered_table.html | 4 +- .../timemanagement/timemanagement_break.html | 49 ++++++ .../timemanagement_management.html | 110 +++++++++++-- .../timemanagement/timemanagement_update.html | 114 +++++++++++++ timemanagement/urls.py | 12 +- timemanagement/views.py | 153 +++++++++++++++++- users/signals.py | 4 +- users/templates/users/base.html | 12 +- 13 files changed, 588 insertions(+), 58 deletions(-) create mode 100644 timemanagement/templates/timemanagement/timemanagement_break.html create mode 100644 timemanagement/templates/timemanagement/timemanagement_update.html diff --git a/standards/templatetags/__pycache__/counter_tag.cpython-38.pyc b/standards/templatetags/__pycache__/counter_tag.cpython-38.pyc index 490536267f4665c9889900caae038dbdee58053a..7758693fce0a5ce53e9b4844e30edc0c617c7fe9 100644 GIT binary patch delta 2643 zcmZ8jYiwM_6}~g~vG?xF$=W!6t?l@cc(YB269|v~2oWfMfJ9Ym9u^SYde)D%v)i4$ z4zIgeS|dWB2{FU7N!v99+K{3IS)iyAQX^Z_nKNf*zH?>|=N>2}M-qvsfp6&PKi~2CHS@_Xc6>g2)D?z^%yf))ymW3IU!6Z>pKSVKA~rnGdoi215yW;biwABd8ceov32DC^OP9tC1nk8To? z?;4qXi_e%Zx2mI^2_-uAIR_Alyie`uZ&sgnT+SX=$y8eH?A(`nfE06pOhPtO|A4CY zq@4$;drU7Lfr<=XSLRS-GN7VlGE3rec{p4elT&O>FcBoZp zkITbKbZ>DUAvcezW8EX{G4-9U7UlGm*u1){XMi16tNWUnQZMz~RDA+wV+^qT+2~Na z7Ok8I1V)W57!?-qz|32DJ2XNg@8lzb9pW`t@CBClaJ1$jHphh3ZdACiDrU&@(OPW5 zxX!q}w_=4>J}!)DQ(hCA)JIFS8TsTDR~Z$v1fj573>=-aE5qdw7L_*=R0(L0k|LDz zfK1c!S)J-#7pq5dca6==iX1kLJ#{Ivup1s4=T7q;Cs?D;vU}|S+n}ypdop!CGAOPd z+`L6(B664vmQQ7{Zyl?v8~S!T&q6%L9!+#rv18gbL(Ci}VTMewIer_j@QR5MUm981 zI}fdpkMmaAj=4)dO|E|e$XIee_4S@8PI;81wme4tpA*yw76_gp=(qrCcfY-{eIgf> zXZPM&l+(h$duiX_mpOm>Zk$fpg|)$xJjs$=9#_Zu?rGff8d|GvP8EWT*;wnREWZ5s2Z?~!I2ig-)l9rQ} z%NJB>;8ymadTU_MB}YlFQ;%D$g~b`>o`OEDZX5izdlL3I?4;V!op$;$kiVik8B9!- z$7L>uO%?pTxo62oT>D=35oPl9;`zbP7<*CufBj|cFOo@;Ob}d@jq>|hlEt}PRNIGs z$evSYhpuY=HQ6-I#9}Vn#^f25$h?&}OY)`AUsWGw4kllLpSn|&eqkafUsmCUk)Gd@ zQA;BR9%l}AvfL~#U&Bdl$Bs8=w>7;@mW^|AnS2A97IiSY)p;G0c_E-2la;Q@D$SknEjC#evsI2%I+LL-@5?NM=_eg_M?Z`IK-l zvdAuok7sNtOuy!~W?ixdn92%{GyU+;XU-**jI34RYo4>}nL%Mp~14J;8oMb@jPboe!??gIqARH&^!v zMQ$eW>rUWHB$<2;*7ZbC4E&ir<=j}YAj);K97wqXicGYTMY>8gQi+^X0@uAszZ?`P zL+jD;sRE`?6~>EoryTgfYmu9?<9XIL_@~KeL3mR%!sM+ zaSz-r4?t;fi>Hw7Ej-1NW*bH>nB@Q+^j9G-y14uZc3-RRF$4AILV4c_F5z}qfYO%d zp+WbZHyg#g!UGh0fszgmfH&6}w?AK@yR-ubIlC>*#n zOBr5Y?4(-k2Y(v`D0_n*@9*j z9+Q<10!=3t%YPF5i{L{lU^g_)6n(K`UY02ME$Bf(*2?3iYp$RoYXb#S)a)ece=lr0 zIH>qB>@zp3;L;Cly(e|Y=HFBwrd57SaD?D70{TZHpCX|5R~{$OFVruocY@#rf>Q*i z2^I;?5WGt88o@b&HwfM&pi-&}rA`SQ43bSv*eO*TPO|@~Q^Tz$@<*K;ew?}LmMz=d LsE5a8t;N0qOpA5` delta 1181 zcmZvbSxggA6o%)_48w@+AW)js;DXVlajMe9qStC%id$U( z1%xANTq3xy3D{taF$UwVQA6}aqKS#GzWAc?&3mS3d|)Q`%gLGlEcc!}hqttawOXq+ zL*P%*{K2))Dmt`6U>*LmeeZl?ma!tVAnb^^jFrZ!gF*u8Fil#QWsDA0ncj^?eagF2 z@+(IAGC|**{3!L0g&WvXZ~&UnI&Lu>!@1cG+%ax@_7Pr$B{*~|%OSf7`PJwQLN6(!K%V?XiX*x0{|V^>$nGPxS^;N+VN!3ROLA75Z@KmLKk|RhoBR0 zIz74V3$z!zmne+vX_TF^{jU>p5aVH}nXN5EElkM2@7zg}4w=BI$96 zs0Or3-J=Y#2NGaN`9h;;NZ9VmpHmr^;&Q~om(?yrw4l%^ZQ(vcwh8=MR3iOeSYB6GDM$-u6n=JhL=DY(E4Uh2)awvj|6 ziO8;Db(RCWyp@`H9q71fbcJcymv6^k-dVYw|5XATSb%4}Z3eCL&4%lE!Kd?UM|b73 zPs=+)YKxg#9#&@nyOV_CUjR4pcgZxkjHP-W^qNOdr*DFb_)?#l(?@~oaG(km!1~cP z@s0I9`G}jgyKz7cDf0bnms342%MG_|M2IUp$UgLq%5dWhdmAFwUo5ZbY zWwr1HTgr;%K`y`swE*9jZR9m)O!nJ<{!1o~6*DN=2QJcUux9$#j3Lzs#lo@rO<|l_ zG0<>~^0yK?2wj9zgwuo`!X?5L!d1dG!fnDGLNB48@PIHtctUtictM~R%@&5o-xAd9 apSjNhW1x@^hz6?i#a|Kc2D@ 0): - returnstat = list(wd)[0].start + returnstat = list(wd)[0].start return returnstat # Return formatted Time-String @@ -350,7 +350,7 @@ def getdailybreaktime(user): @register.simple_tag def getdailybreaktimetoday(user): today = date.today() - wd = list(Workday.objects.filter(user=user, agency=user.profile.agency, start__day=today.day).order_by("start"))[0] + wd = list(Workday.objects.filter(user=user, agency=user.profile.agency).order_by("start").exclude(end=None))[0] breaksum = 0 for b in wd.breaks.all(): if(b.end != None): @@ -372,7 +372,16 @@ def getsumworkday(workday): mon, sec = divmod(finalsum, 60) hr, mon = divmod(mon, 60) #return ("%d Stunden und %02d:%02d" % (hr, mon, sec)) - return ("%d Stunden, %02d Minuten" % (hr, mon)) + return ("%d:%02d" % (hr, mon)) + +@register.simple_tag +def getsumworkdayexcludebreak(workday): + finalsum = ((workday.end - workday.start).seconds) + + mon, sec = divmod(finalsum, 60) + hr, mon = divmod(mon, 60) + #return ("%d Stunden und %02d:%02d" % (hr, mon, sec)) + return ("%d:%02d" % (hr, mon)) @register.simple_tag def getsumbreak(workday): @@ -507,3 +516,81 @@ def startdatecheck(usertocheck, day): return True else: return False + +# Gibt Minus/Null/Plus Gleitzeit für einen Arbeitstag +@register.simple_tag +def gettimeoveralldiff(workday, user): + sum_break = 0 + + if(len(workday.breaks.all()) > 0): + + for ele in workday.breaks.all(): + sum_break += (ele.end - ele.start).seconds + + finalsum = ((workday.end - workday.start).seconds - sum_break) + hastowork = datetime.timedelta(hours=workday.target) + + # Finale Summe Arbeitszeit inkl. Pausen und Arbeitszeit an diesem Tag + final_info = (int(finalsum) - int(hastowork.total_seconds()))/60 + + status = 0 + # NEGATIVE GLEITZEIT + if(final_info < 0): + final_info = final_info * -1 + status = 2 + # Positive Gleitzeit + elif (final_info == 0): + status = 1 + else: + status = 0 + + final_timeinfo = str(datetime.timedelta(minutes=final_info)) + final_info_data = final_timeinfo.split(":") + final_info = str(final_info_data[0]) + ":" + str(final_info_data[1]) + + return [final_info, status] + + +# Ladet das aktuelle Gleitzeitkonto +@register.simple_tag +def loadaccounttime(user): + status = 0 + workdays = Workday.objects.filter(user=user).exclude(end=None) + + finalaccounttimesum = datetime.timedelta(minutes=0) + + + for workday in workdays: + # Zeit, die der Mitarbeiter gearbeitet haben MUSS + + sum_break = 0 + + if(len(workday.breaks.all()) > 0): + + for ele in workday.breaks.all(): + sum_break += (ele.end - ele.start).seconds + + finalsum = ((workday.end - workday.start).seconds - sum_break) + hastowork = datetime.timedelta(hours=workday.target) + final_info = (int(finalsum) - int(hastowork.total_seconds()))/60 + + if(final_info >= 0.0): + finalaccounttimesum += datetime.timedelta(minutes=final_info) + else: + final_info = final_info * -1 + finalaccounttimesum -= datetime.timedelta(minutes=final_info) + + + # Gesamtgleitzeit einmal schick darstellen mit rot und grün + # Wenn GLeitzeit NEGATIV ist + if(finalaccounttimesum.total_seconds() < 0): + status = 1 + final_info_data = str(datetime.timedelta(seconds=finalaccounttimesum.total_seconds()*(-1))).split(":") + else: + status = 0 + final_info_data = str(datetime.timedelta(seconds=finalaccounttimesum.total_seconds())).split(":") + + final_info = str(final_info_data[0]) + ":" + str(final_info_data[1]) + + return [final_info, status] + diff --git a/timemanagement/forms.py b/timemanagement/forms.py index 1362c51..19a7210 100644 --- a/timemanagement/forms.py +++ b/timemanagement/forms.py @@ -1,7 +1,7 @@ from bootstrap_datepicker_plus import DatePickerInput from django import forms from django.forms import ModelForm -from .models import Absence, AbsenceReason, FreeDays +from .models import Absence, AbsenceReason, FreeDays, Workday, Breaks from users.models import UserFullName from django.forms import HiddenInput @@ -136,4 +136,50 @@ class AddFreeDayForm(forms.ModelForm): def __init__(self, *arg, **kwargs): super(AddFreeDayForm, self).__init__(*arg, **kwargs) self.fields['name'].required = True - self.fields['day'].required = True \ No newline at end of file + self.fields['day'].required = True + + +# UPDATE WORK FORM +class UpdateWorkdayForm(forms.ModelForm): + class Meta: + model = Workday + labels = { + "start" : "Start", + "end" : "Ende", + "target" : "Zielarbeitszeit" + } + + fields = [ + "start", "end", "target" + ] + widgets = { + 'start': DatePickerInput(options={"format":'HH:mm', "locale":'de'}), + 'end': DatePickerInput(options={"format":'HH:mm', "locale":'de'}), + } + + def __init__(self, *arg, **kwargs): + super(UpdateWorkdayForm, self).__init__(*arg, **kwargs) + self.fields['start'].required = True + self.fields['end'].required = True + +# ADD BREAK FORM +class AddBreakForm(forms.ModelForm): + class Meta: + model = Breaks + labels = { + "start" : "Start", + "end" : "Ende" + } + + fields = [ + "start", "end" + ] + widgets = { + 'start': DatePickerInput(options={"format":'HH:mm', "locale":'de'}), + 'end': DatePickerInput(options={"format":'HH:mm', "locale":'de'}), + } + + def __init__(self, *arg, **kwargs): + super(AddBreakForm, self).__init__(*arg, **kwargs) + self.fields['start'].required = True + self.fields['end'].required = True \ No newline at end of file diff --git a/timemanagement/models.py b/timemanagement/models.py index 1d80ed3..11aeef9 100644 --- a/timemanagement/models.py +++ b/timemanagement/models.py @@ -11,6 +11,7 @@ class Workday(models.Model): breaks = models.ManyToManyField("Breaks", blank=True, related_name='breaks_at_day') start = models.DateTimeField(default=None, null=True, blank=True) end = models.DateTimeField(default=None, null=True, blank=True) + target = models.FloatField(default=8.0) class Breaks(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) diff --git a/timemanagement/templates/timemanagement/realtime_dropdown.html b/timemanagement/templates/timemanagement/realtime_dropdown.html index d68fa6d..7e3a745 100644 --- a/timemanagement/templates/timemanagement/realtime_dropdown.html +++ b/timemanagement/templates/timemanagement/realtime_dropdown.html @@ -29,7 +29,13 @@
-Gleitzeitkonto: +00:13 Stunden +{% loadaccounttime user as actualaccounttime %} +Gleitzeitkonto: +{% if actualaccounttime.1 == 0 %} + +{{actualaccounttime.0}} Stunden +{% else %} + -{{actualaccounttime.0}} Stunden +{% endif %} + +{% endif %} +{% endblock content %} \ No newline at end of file diff --git a/timemanagement/templates/timemanagement/timemanagement_management.html b/timemanagement/templates/timemanagement/timemanagement_management.html index 601fd96..2cbb12a 100644 --- a/timemanagement/templates/timemanagement/timemanagement_management.html +++ b/timemanagement/templates/timemanagement/timemanagement_management.html @@ -14,9 +14,8 @@ Ende Arbeitszeit Pausen - Gesamtzeit - Abwesenheit - Gleitzeit in h + Gesamtzeit + Gleitzeit   @@ -27,31 +26,36 @@ {{forloop.counter}} - {{workday.start}} + {{workday.start|date:"d.m.y H:i"}} - {{workday.end}} + {{workday.end|date:"d.m.y H:i"}} - {{ workday.end|timeuntil:workday.start }} + {% getsumworkdayexcludebreak workday as sumworkday %} + {{ sumworkday }} {% getsumbreak workday as sumbreakofday %} - {{sumbreakofday}} min. ({{workday.breaks.all|length}}) - + {{sumbreakofday}} min. ({{workday.breaks.all|length}}) {% getsumworkday workday as sumwd %} {{sumwd}} - - - DROPDOWN + + + {% gettimeoveralldiff workday user as erg%} + {% if erg.1 == 0 %} + +{{erg.0}} + {% elif erg.1 == 1 %} + {{erg.0}} + {% else %} + -{{erg.0}} + {% endif %} - - - - + + @@ -60,6 +64,82 @@ + +{% if user.usertime.usetime_start == None %} + + + +{% elif workdays|length == 0 %} + + +{% endif %} + {% for workday in workdays %} - - - - {% endif %}