Info welcher Mitarbeiter schon Abwesenheiten in diesem Zeitraum hat

This commit is contained in:
Holger Trampe 2020-05-30 00:41:17 +02:00
parent 5a633c5dd2
commit 763a3a5247
13 changed files with 169 additions and 43 deletions

View File

@ -19,7 +19,13 @@
{% endfor %} {% endfor %}
</tr> </tr>
<tr> <tr>
<th scope="row">Resturlaub</th> <th scope="row">Genommener Urlaub</th>
{% for ab_info in user_years.all %}
<td>{{ab_info.days_inuse}}</td>
{% endfor %}
</tr>
<tr>
<th scope="row">Resturlaub aus Vorjahr</th>
{% for ab_info in user_years.all %} {% for ab_info in user_years.all %}
{% if forloop.counter0 > 0 %} {% if forloop.counter0 > 0 %}
<td class="" id="rest_holiday_{{ab_info.pk}}"> <td class="" id="rest_holiday_{{ab_info.pk}}">

View File

@ -15,7 +15,13 @@
{% endfor %} {% endfor %}
</tr> </tr>
<tr> <tr>
<th scope="row">Resturlaub Vorjahr</th> <th scope="row">Genommener Urlaub</th>
{% for ab_info in user_years.all %}
<td>{{ab_info.days_inuse}}</td>
{% endfor %}
</tr>
<tr>
<th scope="row">Resturlaub aus Vorjahr</th>
{% for ab_info in user_years.all %} {% for ab_info in user_years.all %}
{% if forloop.counter0 > 0 %} {% if forloop.counter0 > 0 %}
<td class="readytochange_holiday_rest" id="rest_holiday_{{ab_info.pk}}">{{ab_info.restdays}}</td> <td class="readytochange_holiday_rest" id="rest_holiday_{{ab_info.pk}}">{{ab_info.restdays}}</td>

View File

@ -213,7 +213,13 @@
{% endfor %} {% endfor %}
</tr> </tr>
<tr> <tr>
<th scope="row">Resturlaub</th> <th scope="row">Genommener Urlaub</th>
{% for ab_info in user_years.all %}
<td>{{ab_info.days_inuse}}</td>
{% endfor %}
</tr>
<tr>
<th scope="row">Resturlaub aus Vorjahr</th>
{% for ab_info in user_years.all %} {% for ab_info in user_years.all %}
{% if forloop.counter0 > 0 %} {% if forloop.counter0 > 0 %}
<td class="readytochange_holiday_rest" id="rest_holiday_{{ab_info.pk}}">{{ab_info.restdays}}</td> <td class="readytochange_holiday_rest" id="rest_holiday_{{ab_info.pk}}">{{ab_info.restdays}}</td>

View File

@ -37,3 +37,7 @@ urlpatterns = [
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
if settings.DEBUG: if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# ERROR HANDLERS
handler404 = 'users.views.handler404'
handler500 = 'users.views.handler500'

View File

@ -1,4 +1,5 @@
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% load mathfilters %}
<h5>Abwesenheit für {{absence.user.first_name}} {{absence.user.last_name}} annehmen oder ablehnen</h5> <h5>Abwesenheit für {{absence.user.first_name}} {{absence.user.last_name}} annehmen oder ablehnen</h5>
<hr> <hr>
<h6>Informationen der Abwesenheit</h6> <h6>Informationen der Abwesenheit</h6>
@ -7,6 +8,23 @@ Bis: {{absence.end|date:"d.m Y"}}<br />
Grund: {{absence.reason.name}}<br /> Grund: {{absence.reason.name}}<br />
Informationen: {{absence.info}}<br /> Informationen: {{absence.info}}<br />
<hr> <hr>
<h5>Übersicht Urlaubstage wenn Anfrage genehmigt</h5>
<table class="table table-sm">
<tbody>
<tr>
<td>Gewünschte Tage</td>
<td>{{absence.holidays_normal|addition:absence.holidays_rest|addition:absence.holidays_normal_next|addition:absence.holidays_rest_next}}</td>
</tr>
<tr>
<td>Resturlaub {{absence.start.year}}</td>
<td>{{timeinfo_thisyear.restdays|addition:timeinfo_thisyear.days|sub:timeinfo_thisyear.days_inuse|addition:absence.holidays_rest}}</td>
</tr>
<tr>
<td>Resturlaub {{timeinfo_nextyear.year}}</td>
<td>{{timeinfo_nextyear.restdays|addition:timeinfo_nextyear.days|sub:timeinfo_nextyear.days_inuse|addition:absence.holidays_rest_next}}</td>
</tr>
</tbody>
</table>
<form method="POST"> <form method="POST">
<input type="hidden" name="form_type" value="confirmform"> <input type="hidden" name="form_type" value="confirmform">
{% csrf_token %} {% csrf_token %}

View File

@ -369,7 +369,13 @@ function recalculateChoosenDays(){
success : function(data){ success : function(data){
console.log(data); if(data["other_absences"] != false){
$("#otherholidays").show();
$("#otherholidays_users").html(data["other_absences"]);
}
else{
$("#otherholidays").hide();
}
$("#startAbsenceProgress").modal("show"); $("#startAbsenceProgress").modal("show");
@ -434,7 +440,15 @@ function recalculateChoosenDaysAfterInit(){
endday_info : $("#id_endday_info").val(), endday_info : $("#id_endday_info").val(),
}, },
success : function(data){ success : function(data){
console.log(data);
if(data["other_absences"] != false){
$("#otherholidays").show();
$("#otherholidays_users").html(data["other_absences"]);
}
else{
$("#otherholidays").hide();
}
$("#restholidays").html(data["restholiday_thisyear"]); $("#restholidays").html(data["restholiday_thisyear"]);
$("#detail_rest").html(data["restholiday_thisyear"]); $("#detail_rest").html(data["restholiday_thisyear"]);
$("#detail_resthol").html(data["restholiday_lastyear"]); $("#detail_resthol").html(data["restholiday_lastyear"]);

View File

@ -127,11 +127,6 @@
</table> </table>
</div> </div>
</div> </div>
<!--
# TODO: Abwesenheiten - Meine Abwesenheiten, Übersicht über aktuelle Tage, Resturlaub in Jahren usw.
Bezug zu Urlaubsjahren mit Daten für Resturlaubsberechnung
-->
</div> </div>
<div id="noholidays_container" style="display: none;"> <div id="noholidays_container" style="display: none;">
<h6>Abwesenheitsgrund ohne Urlaubsanspruch</h6> <h6>Abwesenheitsgrund ohne Urlaubsanspruch</h6>
@ -168,6 +163,12 @@
</div> </div>
</div> </div>
</div> </div>
<div id="otherholidays" style="display: none;">
<hr>
In diesem Zeitraum haben bereits folgende Mitarbeiter Abwesenheiten:
<br />
<div id="otherholidays_users"></div>
</div>
<!-- Fields for rest-logic --> <!-- Fields for rest-logic -->
<div style="display: none;"> <div style="display: none;">
{{abscenceform.nextmonth}} {{abscenceform.nextmonth}}

View File

@ -380,9 +380,18 @@ def TimeAjax(request):
# GET FORM FOR CONFIRM ABSENCE # GET FORM FOR CONFIRM ABSENCE
elif request.GET["action"] == "getrenderedform": 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
context = { context = {
"confirmform" : ConfirmAbsenceForm(instance=request.user), "confirmform" : ConfirmAbsenceForm(instance=request.user),
"absence" : Absence.objects.get(pk=request.GET["abscenceid"]) "absence" : absence,
"timeinfo_thisyear" : timeinfo_thisyear,
"timeinfo_nextyear" : timeinfo_nextyear
} }
return render(request, "timemanagement/rendered_confirmform.html", context) return render(request, "timemanagement/rendered_confirmform.html", context)
@ -507,6 +516,14 @@ def TimeAjax(request):
days_nextyear_rest = need_days_next + temprest days_nextyear_rest = need_days_next + temprest
days_nextyear_normal = temprest * -1 days_nextyear_normal = temprest * -1
other_absences = Absence.objects.filter(start__lte=start_day_obj, end__gte=end_day_obj, agency=request.user.profile.agency) | Absence.objects.filter(start__lte=start_day_obj, end__lte=end_day_obj, agency=request.user.profile.agency) | Absence.objects.filter(start__gte=start_day_obj, end__lte=start_day_obj, agency=request.user.profile.agency) | Absence.objects.filter(start__lte=end_day_obj, end__gte=end_day_obj, agency=request.user.profile.agency)
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") + "<br />"
data = { data = {
"restholiday_thisyear" : holiday_thisyear, "restholiday_thisyear" : holiday_thisyear,
"restholiday_lastyear" : holiday_lastyear, "restholiday_lastyear" : holiday_lastyear,
@ -516,6 +533,7 @@ def TimeAjax(request):
"need_days" : need_days, "need_days" : need_days,
"need_days_next" : need_days_next, "need_days_next" : need_days_next,
"need_days_this" : need_days_this, "need_days_this" : need_days_this,
"other_absences" : other_absences_string
} }
# REQUEST USER NO RIGHTS # REQUEST USER NO RIGHTS
else: else:
@ -578,16 +596,16 @@ def calculatingHolidaysByAbsence(request, absence):
# Start und Ende gleich, nur ein Tag. Checken, ob Halber Tag # Start und Ende gleich, nur ein Tag. Checken, ob Halber Tag
if(absence.start == absence.end): if(absence.start == absence.end):
if abscence.startday_info == "1" or abscence.startday_info == "2": if absence.startday_info == "1" or absence.startday_info == "2":
finalholidayinabsence = 0.5 finalholidayinabsence = 0.5
else: else:
finalholidayinabsence = 1 finalholidayinabsence = 1
return finalholidayinabsence return finalholidayinabsence
else: else:
if abscence.startday_info == "1" or abscence.startday_info == "2": if absence.startday_info == "1" or absence.startday_info == "2":
finalholidayinabsence -= 0.5 finalholidayinabsence -= 0.5
if abscence.endday_info == "1" or abscence.endday_info == "2": if absence.endday_info == "1" or absence.endday_info == "2":
finalholidayinabsence -= 0.5 finalholidayinabsence -= 0.5
weekdays = [6,7] weekdays = [6,7]
@ -608,3 +626,4 @@ def daterange(date1, date2):
for n in range(int ((date2 - date1).days)+1): for n in range(int ((date2 - date1).days)+1):
yield date1 + timedelta(n) yield date1 + timedelta(n)

View File

@ -500,13 +500,12 @@ def delete_absence(sender, instance, **kwargs):
multiple_info_needays = False multiple_info_needays = False
if(hasattr(newdata[3], "__len__")): if(hasattr(newdata[3], "__len__")):
multiple_info_needays = True multiple_info_needays = True
# Mehrere Jahre oder nicht
if(instance.start.year != instance.end.year): if(instance.start.year != instance.end.year):
abinfo.days_inuse = abinfo.days_inuse - instance.holidays_normal abinfo.days_inuse = abinfo.days_inuse - instance.holidays_normal
abinfo.save() abinfo.save()
abinfo_nextyear.days_inuse = abinfo_nextyear.days_inuse - instance.holidays_normal_next abinfo_nextyear.days_inuse = abinfo_nextyear.days_inuse - instance.holidays_normal_next
abinfo_nextyear.restdays = abinfo_nextyear.restdays + instance.holidays_rest_next abinfo_nextyear.restdays = abinfo_nextyear.restdays + instance.holidays_rest_next
abinfo_nextyear.save() abinfo_nextyear.save()
else: else:
# Gleiches Jahr MIT Rest # Gleiches Jahr MIT Rest

View File

@ -0,0 +1,6 @@
{% extends "users/base.html" %}
{% block content %}
<div class="content-section col-md-5">
<h3>Hopala! Fehler 404 - Die aufgerufene Seite existiert nicht.</h3>
</div>
{% endblock content %}

View File

@ -0,0 +1,6 @@
{% extends "users/base.html" %}
{% block content %}
<div class="content-section col-md-5">
<h3>Hopala! Fehler 500 - Interner Serverfehler. Bitte kontaktieren Sie den Support!</h3>
</div>
{% endblock content %}

View File

@ -7,7 +7,7 @@ from django.views.generic import CreateView, ListView, UpdateView, DetailView, D
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.models import User, Permission from django.contrib.auth.models import User, Permission
from django.db import models from django.db import models
from .models import Profile, Agency, UserTime from .models import Profile, Agency, UserTime, UserYearAbsenceInfo
from django.core.mail import send_mail from django.core.mail import send_mail
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
from areas.models import Areas from areas.models import Areas
@ -40,6 +40,7 @@ from asgiref.sync import async_to_sync
from channels_presence.models import Room from channels_presence.models import Room
from channels_presence.models import Presence from channels_presence.models import Presence
import channels.layers import channels.layers
from datetime import date
def randomString(stringLength=10): def randomString(stringLength=10):
"""Generate a random string of fixed length """ """Generate a random string of fixed length """
@ -801,6 +802,25 @@ def impressum(request):
else: else:
return render(request, 'users/impressum_p.html') return render(request, 'users/impressum_p.html')
'''
ERROR HANDLER VIEWS
'''
def handler404(request, exception):
context = {}
response = render(request, "users/errors/404.html", context=context)
response.status_code = 404
return response
def handler500(request):
context = {}
response = render(request, "users/errors/500.html", context=context)
response.status_code = 500
return response
''' '''
CRONJOB FUNCTION CRONJOB FUNCTION
@ -811,21 +831,18 @@ def cronactions(request, code):
if(code == settings.CRONAPIKEY): if(code == settings.CRONAPIKEY):
# NEWS CHECKING # NEWS CHECKING
all_unnotifc_news = News.objects.filter(agnotify=False, go_online_on__lt=timezone.now()) all_unnotifc_news = News.objects.filter(agnotify=False, go_online_on__lt=timezone.now())
allusers = User.objects.all()
for news in all_unnotifc_news: for news in all_unnotifc_news:
targeturl = settings.BASE_URL + "news/news/" + str(news.pk) + "/single" targeturl = settings.BASE_URL + "news/news/" + str(news.pk) + "/single"
usersofagency = User.objects.filter(profile__agency=news.agency)
news.agnotify = True news.agnotify = True
news.save() news.save()
for user in usersofagency: for user in allusers:
if(user.profile.news_mail): if(user.profile.news_mail and news.agency == user.profile.agency):
notificationtext = "Neue Agenturnews: " + news.name notificationtext = "Neue Agenturnews: " + news.name
username = user.first_name + " " + user.last_name username = user.first_name + " " + user.last_name
msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext, 'linktarget' : targeturl}) msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext, 'linktarget' : targeturl})
GLOBALSENDMAILS = True
if(GLOBALSENDMAILS):
send_mail( send_mail(
'Agentur-Benachrichtigung', 'Agentur-Benachrichtigung',
'Hallo ' + user.first_name + ' ' + user.last_name + '! ' + notificationtext, 'Hallo ' + user.first_name + ' ' + user.last_name + '! ' + notificationtext,
@ -835,7 +852,7 @@ def cronactions(request, code):
fail_silently=True fail_silently=True
) )
if(user.profile.news_push): if(user.profile.news_push and news.agency == user.profile.agency):
newnotification = UserNotification(touser=user, notificationtext="Neue Agenturnews: " + news.name, notificationtype="agencynews", elementid=news.pk) newnotification = UserNotification(touser=user, notificationtext="Neue Agenturnews: " + news.name, notificationtype="agencynews", elementid=news.pk)
newnotification.save() newnotification.save()
@ -846,6 +863,29 @@ def cronactions(request, code):
''' '''
today = date.today()
for user in allusers:
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()
data.update({"status" : "ok"}) data.update({"status" : "ok"})
elif(code == settings.MAILINFOKEY): elif(code == settings.MAILINFOKEY):
@ -876,3 +916,4 @@ def cronactions(request, code):
print("API CODE FAILED") print("API CODE FAILED")
data.update({"status" : "failed"}) data.update({"status" : "failed"})
return JsonResponse(data) return JsonResponse(data)