Zeiterfassung bis auf Bearbeiten durch andere Mitarbeiter fertig für Betatest
This commit is contained in:
parent
51d7a746f7
commit
0de2a48c9e
|
|
@ -10,6 +10,7 @@
|
|||
<th scope="col">Nachname</th>
|
||||
<th scope="col">E-Mail</th>
|
||||
<th scope="col">Agenturfunktion</th>
|
||||
<th scope="col">Gleitzeit</th>
|
||||
<th scope="col">Letzter Login</th>
|
||||
<th scope="col">Tätigkeit</th>
|
||||
<th scope="col">Telefon</th>
|
||||
|
|
@ -24,6 +25,18 @@
|
|||
<td><a href="{% url 'user_updateprofile' item.pk 0 %}">{{ item.last_name }}</a></td>
|
||||
<td>{{ item.email }}</td>
|
||||
<td>{% if item.profile.func == None %}-{%else%}{{ item.profile.func }}{%endif%}</td>
|
||||
<td>
|
||||
{% if item.usertime.usetime %}
|
||||
{% loadaccounttime item as actualaccounttime %}
|
||||
{% if actualaccounttime.1 == 0 %}
|
||||
<b><span style="color: green">+{{actualaccounttime.0}}</span></b>
|
||||
{% else %}
|
||||
<b><span style="color: red">-{{actualaccounttime.0}}</span></b>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{% if item.last_login != Nonte %}{{ item.last_login }}{% endif %}</td>
|
||||
<td>{{ item.profile.compfunc }}</td>
|
||||
<td>{{ item.profile.phoneland }}</td>
|
||||
|
|
@ -76,4 +89,3 @@ $(document).ready(function(){
|
|||
|
||||
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,3 +17,13 @@ six==1.13.0
|
|||
sqlparse==0.3.0
|
||||
urllib3==1.25.7
|
||||
webcolors==1.10
|
||||
django-summernote==0.8.11.6
|
||||
django-mathfilters==1.0.0
|
||||
django-cleanup==5.0.0
|
||||
django-user-agents==0.4.0
|
||||
djangorestframework==3.11.0
|
||||
django-channels==0.7.0
|
||||
django-channels-presence==1.0.0
|
||||
django-cryptography==1.0
|
||||
channels-redis==3.0.1
|
||||
filetype==1.0.7
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@
|
|||
<!--
|
||||
|
||||
# TODO: Sichtbarkeit durch andere Nutzer absprechen?
|
||||
# TODO: Bis wann darf rückwirkend eine Abwesenheit bearbeitet werden? Monatlich?
|
||||
# TODO: CronJob einmal umbauen
|
||||
# TODO: Halber Tag mit Workday verbinden
|
||||
Aktuell sieht man den Gleitzeitkontostand in der Mitarbeitertabelle, ein Bearbeiten muss ich nachschieben
|
||||
-->
|
||||
|
||||
<div class="table-responsive ">
|
||||
|
|
@ -63,14 +61,129 @@
|
|||
{% if abday.start == da%}
|
||||
{% if abday.startday_info == "1" %}
|
||||
(nur Vormittags)
|
||||
{% for workday in workdays %}
|
||||
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
|
||||
<br />
|
||||
{{workday.start|date:"H:i"}} - {{workday.end|date:"H:i"}},
|
||||
{% getsumworkdayexcludebreak workday as sumworkday %}
|
||||
{{ sumworkday }},
|
||||
{% getsumbreak workday as sumbreakofday %}
|
||||
{{sumbreakofday}} min. ({{workday.breaks.all|length}}),
|
||||
{% getsumworkday workday as sumwd %}
|
||||
{{sumwd}},
|
||||
{% gettimeoveralldiff workday user as erg%}
|
||||
{% if erg.1 == 0 %}
|
||||
<span style="color: green">+{{erg.0}}</span>
|
||||
{% elif erg.1 == 1 %}
|
||||
<span>{{erg.0}}</span>
|
||||
{% else %}
|
||||
<span style="color: red">-{{erg.0}}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if breakmonthline < da %}
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
|
||||
{% elif abday.startday_info == "2" %}
|
||||
(nur Nachmittags)
|
||||
|
||||
{% for workday in workdays %}
|
||||
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
|
||||
<br />
|
||||
{{workday.start|date:"H:i"}} - {{workday.end|date:"H:i"}}
|
||||
{% getsumworkdayexcludebreak workday as sumworkday %}
|
||||
{{ sumworkday }},
|
||||
{% getsumbreak workday as sumbreakofday %}
|
||||
{{sumbreakofday}} min. ({{workday.breaks.all|length}}),
|
||||
{% getsumworkday workday as sumwd %}
|
||||
{{sumwd}},
|
||||
{% gettimeoveralldiff workday user as erg%}
|
||||
{% if erg.1 == 0 %}
|
||||
<span style="color: green">+{{erg.0}}</span>
|
||||
{% elif erg.1 == 1 %}
|
||||
<span>{{erg.0}}</span>
|
||||
{% else %}
|
||||
<span style="color: red">-{{erg.0}}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if breakmonthline < da %}
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% elif abday.end == da%}
|
||||
{% if abday.endday_info == "1" %}
|
||||
(nur Vormittags)
|
||||
|
||||
|
||||
|
||||
{% for workday in workdays %}
|
||||
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
|
||||
<br />
|
||||
{{workday.start|date:"H:i"}} - {{workday.end|date:"H:i"}}
|
||||
{% getsumworkdayexcludebreak workday as sumworkday %}
|
||||
{{ sumworkday }},
|
||||
{% getsumbreak workday as sumbreakofday %}
|
||||
{{sumbreakofday}} min. ({{workday.breaks.all|length}}),
|
||||
{% getsumworkday workday as sumwd %}
|
||||
{{sumwd}},
|
||||
{% gettimeoveralldiff workday user as erg%}
|
||||
{% if erg.1 == 0 %}
|
||||
<span style="color: green">+{{erg.0}}</span>
|
||||
{% elif erg.1 == 1 %}
|
||||
<span>{{erg.0}}</span>
|
||||
{% else %}
|
||||
<span style="color: red">-{{erg.0}}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if breakmonthline < da %}
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% elif abday.endday_info == "2" %}
|
||||
(nur Nachmittags)
|
||||
|
||||
|
||||
|
||||
{% for workday in workdays %}
|
||||
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
|
||||
<br />
|
||||
{{workday.start|date:"H:i"}} - {{workday.end|date:"H:i"}}
|
||||
{% getsumworkdayexcludebreak workday as sumworkday %}
|
||||
{{ sumworkday }},
|
||||
{% getsumbreak workday as sumbreakofday %}
|
||||
{{sumbreakofday}} min. ({{workday.breaks.all|length}}),
|
||||
{% getsumworkday workday as sumwd %}
|
||||
{{sumwd}},
|
||||
{% gettimeoveralldiff workday user as erg%}
|
||||
{% if erg.1 == 0 %}
|
||||
<span style="color: green">+{{erg.0}}</span>
|
||||
{% elif erg.1 == 1 %}
|
||||
<span>{{erg.0}}</span>
|
||||
{% else %}
|
||||
<span style="color: red">-{{erg.0}}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if breakmonthline < da %}
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
|
@ -212,9 +325,10 @@
|
|||
|
||||
|
||||
{% counterWDUp %}
|
||||
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% if breakmonthline < da %}
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ def TimeManagement(request, activemonth=False, activeyear=False):
|
|||
# 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,
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@
|
|||
<a style="color: #999; text-decoration: none;" href="{% url 'impressumda' %}">Impressum</a>
|
||||
</div>
|
||||
<div style="margin-top: 10px; margin-bottom: 5px;" class="sidebar-heading">
|
||||
Version 0.9.1
|
||||
Version 0.9.2
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
|
|
@ -872,7 +872,3 @@ $("#chatButton").click(function(){
|
|||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
132
users/views.py
132
users/views.py
|
|
@ -974,70 +974,102 @@ def cronactions(request, code):
|
|||
|
||||
|
||||
|
||||
'''
|
||||
Gibt False zurück, wenn der User an diesem Tag KEINE Abwesenheiten hat, ansonsten True!
|
||||
|
||||
'''
|
||||
def absencecheck(user, daytocheck):
|
||||
returnstat = False
|
||||
absencedays = Absence.objects.filter(agency=user.profile.agency, user=user, confirm_status=0) & (Absence.objects.filter(agency=user.profile.agency, user=user, start=daytocheck) | (Absence.objects.filter(agency=user.profile.agency, user=user, start__lt=daytocheck) & Absence.objects.filter(agency=user.profile.agency, user=user, end__gt=daytocheck)) | Absence.objects.filter(agency=user.profile.agency, user=user, end=daytocheck))
|
||||
if(len(absencedays) > 0):
|
||||
returnstat = True
|
||||
|
||||
return returnstat
|
||||
|
||||
# CRONJOBS UM 00:01!
|
||||
def cronactionsdaily(request, code):
|
||||
data = {}
|
||||
if(code == settings.CRONAPIKEY):
|
||||
allusers = User.objects.all()
|
||||
data = {}
|
||||
if(code == settings.CRONAPIKEY):
|
||||
allusers = User.objects.all()
|
||||
'''
|
||||
Pro User gibt es das Feld loose_holiday in der UserTime-Info. Ist dieser Tag vorbei, muss die Differenz der days_inuse des VORJHARES in den Rest das AKTUELLEN JAHRES gespeichert werden!
|
||||
'''
|
||||
today = date.today()
|
||||
for user in allusers:
|
||||
# REST URLAUB BERECHNUNG
|
||||
usertimedata = UserTime.objects.get(user=user)
|
||||
day_tocheck = usertimedata.loose_holidedate.split(".")[0]
|
||||
month_tocheck = usertimedata.loose_holidedate.split(".")[1]
|
||||
month = today.month
|
||||
if month < 10:
|
||||
month = "0" + str(month)
|
||||
day = today.day
|
||||
if day < 10:
|
||||
day = "0" + str(day)
|
||||
|
||||
'''
|
||||
# Restetag erreicht, Reste ins nächste Jahr übertragen
|
||||
if(str(day_tocheck) == str(day) and str(month_tocheck) == str(month)):
|
||||
sourceyear = today.year
|
||||
this_year = list(UserYearAbsenceInfo.objects.filter(year=sourceyear, user=user))[0]
|
||||
next_year = list(UserYearAbsenceInfo.objects.filter(year=sourceyear+1, user=user))[0]
|
||||
next_year.restdays = this_year.days - this_year.days_inuse
|
||||
next_year.save()
|
||||
|
||||
Pro User gibt es das Feld loose_holiday in der UserTime-Info. Ist dieser Tag vorbei, muss die Differenz der days_inuse des VORJHARES in den Rest das AKTUELLEN JAHRES gespeichert werden!
|
||||
# ARBEITSTAGE BEENDEN
|
||||
# Benutzer hat Zeiterfassung aktiv
|
||||
if(user.usertime.usetime):
|
||||
workdays = Workday.objects.filter(user=user, end=None)
|
||||
for wd in workdays:
|
||||
wd.end = datetime(wd.start.year, wd.start.month, wd.start.day, 23, 59)
|
||||
wd.save()
|
||||
|
||||
'''
|
||||
today = date.today()
|
||||
for user in allusers:
|
||||
# REST URLAUB BERECHNUNG
|
||||
usertimedata = UserTime.objects.get(user=user)
|
||||
yesterday = date.today() - timedelta(days=1)
|
||||
weekday = yesterday.weekday()
|
||||
workdays_yesterday = len(Workday.objects.filter(user=user, start__day=yesterday.day, start__month=yesterday.month, start__year=yesterday.year))
|
||||
# Mitarbeiter hat für den gestrigen Tag keine Zeiten erfasst, daher automatisch auf null wenn KEINE Abwesenheit eingetragen wurde
|
||||
|
||||
day_tocheck = usertimedata.loose_holidedate.split(".")[0]
|
||||
month_tocheck = usertimedata.loose_holidedate.split(".")[1]
|
||||
if(workdays_yesterday == 0 and absencecheck(user, yesterday) == False):
|
||||
targettworktime = 0.0
|
||||
if(weekday == 0):
|
||||
targettworktime = user.usertime.wd_mo
|
||||
if(weekday == 1):
|
||||
targettworktime = user.usertime.wd_tu
|
||||
if(weekday == 2):
|
||||
targettworktime = user.usertime.wd_we
|
||||
if(weekday == 3):
|
||||
targettworktime = user.usertime.wd_th
|
||||
if(weekday == 4):
|
||||
targettworktime = user.usertime.wd_fr
|
||||
if(weekday == 5):
|
||||
targettworktime = user.usertime.wd_sa
|
||||
if(weekday == 6):
|
||||
targettworktime = user.usertime.wd_so
|
||||
|
||||
month = today.month
|
||||
workdaytemp = Workday(user=user, agency=user.profile.agency, start=datetime(yesterday.year, yesterday.month, yesterday.day, 8, 0), end=datetime(yesterday.year, yesterday.month, yesterday.day, 8, 0), target=targettworktime)
|
||||
workdaytemp.save()
|
||||
|
||||
if month < 10:
|
||||
month = "0" + str(month)
|
||||
|
||||
day = today.day
|
||||
if day < 10:
|
||||
day = "0" + str(day)
|
||||
# Erinnerungsmails/Push bei Vertretung verschicken
|
||||
one_week_later = date.today() + timedelta(days=7)
|
||||
repre_absence = Absence.objects.filter(representator=user, start=one_week_later, confirm_status=0)
|
||||
|
||||
# Restetag erreicht, Reste ins nächste Jahr übertragen
|
||||
if(str(day_tocheck) == str(day) and str(month_tocheck) == str(month)):
|
||||
sourceyear = today.year
|
||||
this_year = list(UserYearAbsenceInfo.objects.filter(year=sourceyear, user=user))[0]
|
||||
next_year = list(UserYearAbsenceInfo.objects.filter(year=sourceyear+1, user=user))[0]
|
||||
next_year.restdays = this_year.days - this_year.days_inuse
|
||||
next_year.save()
|
||||
for r in repre_absence:
|
||||
if(r.representator.usernotifications.absence_user_is_rep_reminder_mail):
|
||||
sendMailNoti(" in einer Woche startet Ihre Vertretung für " + r.user.first_name + " " + r.user.last_name + "!", user)
|
||||
|
||||
# ARBEITSTAGE BEENDEN
|
||||
# Benutzer hat Zeiterfassung aktiv
|
||||
if(user.usertime.usetime):
|
||||
workdays = Workday.objects.filter(user=user, end=None)
|
||||
for wd in workdays:
|
||||
wd.end = datetime(wd.start.year, wd.start.month, wd.start.day, 23, 59)
|
||||
wd.save()
|
||||
if(r.representator.usernotifications.absence_user_is_rep_reminder_push):
|
||||
newnotification = UserNotification(touser=user, notificationtext="Erinnerung für Abwesenheitsvertretung!", notificationtype="", elementid=r.pk)
|
||||
newnotification.save()
|
||||
|
||||
# Erinnerungsmails/Push bei Vertretung verschicken
|
||||
one_week_later = date.today() + timedelta(days=7)
|
||||
repre_absence = Absence.objects.filter(representator=user, start=one_week_later, confirm_status=0)
|
||||
channel_layer = channels.layers.get_channel_layer()
|
||||
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | In einer Woche startet Ihre Vertretung für " + r.user.first_name + " " + r.user.last_name + "!"})
|
||||
data.update({"status" : "ok"})
|
||||
|
||||
for r in repre_absence:
|
||||
if(r.representator.usernotifications.absence_user_is_rep_reminder_mail):
|
||||
sendMailNoti(" in einer Woche startet Ihre Vertretung für " + r.user.first_name + " " + r.user.last_name + "!", user)
|
||||
if(r.representator.usernotifications.absence_user_is_rep_reminder_push):
|
||||
newnotification = UserNotification(touser=user, notificationtext="Erinnerung für Abwesenheitsvertretung!", notificationtype="", elementid=r.pk)
|
||||
newnotification.save()
|
||||
else:
|
||||
print("API CODE FAILED")
|
||||
data.update({"status" : "failed"})
|
||||
|
||||
channel_layer = channels.layers.get_channel_layer()
|
||||
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | In einer Woche startet Ihre Vertretung für " + r.user.first_name + " " + r.user.last_name + "!"})
|
||||
|
||||
data.update({"status" : "ok"})
|
||||
|
||||
else:
|
||||
print("API CODE FAILED")
|
||||
data.update({"status" : "failed"})
|
||||
return JsonResponse(data)
|
||||
return JsonResponse(data)
|
||||
|
||||
|
||||
def sendMailNoti(notificationtext, user_touched, linktarget=""):
|
||||
|
|
|
|||
Loading…
Reference in New Issue