Abwesenheit OHNE Benachrichtigungen FERTIG
This commit is contained in:
parent
5b0e5f0214
commit
19447ce4f7
|
|
@ -21,11 +21,15 @@
|
|||
<tr>
|
||||
<th scope="row">Resturlaub</th>
|
||||
{% for ab_info in user_years.all %}
|
||||
{% if forloop.counter0 > 0 %}
|
||||
<td class="" id="rest_holiday_{{ab_info.pk}}">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control readytochange_holiday" id="new_holiday_rest_{{ab_info.pk}}" aria-describedby="" value="{{ab_info.restdays}}">
|
||||
</div>
|
||||
</td>
|
||||
{% else %}
|
||||
<td> </td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -15,10 +15,14 @@
|
|||
{% endfor %}
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Resturlaub</th>
|
||||
{% for ab_info in user_years.all %}
|
||||
<td class="readytochange_holiday_rest" id="rest_holiday_{{ab_info.pk}}">{{ab_info.restdays}}</td>
|
||||
{% endfor %}
|
||||
<th scope="row">Resturlaub Vorjahr</th>
|
||||
{% for ab_info in user_years.all %}
|
||||
{% if forloop.counter0 > 0 %}
|
||||
<td class="readytochange_holiday_rest" id="rest_holiday_{{ab_info.pk}}">{{ab_info.restdays}}</td>
|
||||
{% else %}
|
||||
<td> </td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -210,7 +210,11 @@
|
|||
<tr>
|
||||
<th scope="row">Resturlaub</th>
|
||||
{% for ab_info in user_years.all %}
|
||||
{% if forloop.counter0 > 0 %}
|
||||
<td class="readytochange_holiday_rest" id="rest_holiday_{{ab_info.pk}}">{{ab_info.restdays}}</td>
|
||||
{% else %}
|
||||
<td> </td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -222,7 +226,7 @@
|
|||
<button type="submit" class="btn btn-primary" style="float: right">Vertragsdaten aktualisieren</button>
|
||||
<a class="btn" href="{% url 'dasettings' %} ">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
'''
|
||||
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 and request.user.has_perm("users.absencemanager")):
|
||||
|
||||
# Alle Abwesenheiten laden, die bestätigt oder angefragt sind UND Urlaub sind
|
||||
absences = Absence.objects.filter(user=user, confirm_status=0, reason__is_holiday=True) | Absence.objects.filter(user=user, confirm_status=1, reason__is_holiday=True)
|
||||
|
||||
start_day = request.GET["startdate"].split("__")
|
||||
start_day_ob = 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]))
|
||||
|
||||
start_half = True
|
||||
if request.GET["start_half"] == "false":
|
||||
start_half = False
|
||||
|
||||
end_half = True
|
||||
if request.GET["end_half"] == "false":
|
||||
end_half = False
|
||||
|
||||
|
||||
# USER HAS NO ABSENCE
|
||||
if(len(absences) == 0):
|
||||
# Hier Urlaubstage bei Einstellung mit berücksichtigen
|
||||
if(start_day_ob.year == usertimedata.startdate.year):
|
||||
|
||||
data = {
|
||||
"restholiday" : calculateHolidays(request, usertimedata.holiday_start + usertimedata.holiday, start_day_ob, end_day_obj, start_half, end_half)
|
||||
}
|
||||
# Hier Einstellungstage irrelevant und da noch keine Abwesenheiten eingetragen wurden, einfach aus Profil laden
|
||||
else:
|
||||
data = {
|
||||
"restholiday" : calculateHolidays(request, usertimedata.holiday, start_day_ob, end_day_obj, start_half, end_half)
|
||||
}
|
||||
# ABSENCE-Data found, calculating rest-Days
|
||||
else:
|
||||
finalholidays = 0
|
||||
|
||||
# Besteht noch Anspruch aus Einstellungsjahr?
|
||||
if(start_day_ob.year == usertimedata.startdate.year):
|
||||
finalholidays += usertimedata.holiday_start + usertimedata.holiday
|
||||
# Hier Einstellungstage irrelevant und da noch keine Abwesenheiten eingetragen wurden, einfach normal
|
||||
else:
|
||||
finalholidays += usertimedata.holiday
|
||||
|
||||
# Berechne pro Abwesenheits die verbrauchen Urlaubstage
|
||||
for absence in absences:
|
||||
finalholidays -= calculatingHolidaysByAbsence(request, absence)
|
||||
|
||||
data = {
|
||||
"restholiday" : calculateHolidays(request, finalholidays, start_day_ob, end_day_obj, start_half, end_half)
|
||||
}
|
||||
# REQUEST USER NO RIGHTS
|
||||
else:
|
||||
data = {
|
||||
"success" : False
|
||||
}
|
||||
|
||||
'''
|
||||
|
|
@ -50,6 +50,9 @@ class Absence(models.Model):
|
|||
confirm_status = models.IntegerField(default=0)
|
||||
confirm_info = models.TextField(blank=True, verbose_name='Begründung', default="")
|
||||
representator = models.ForeignKey(User, blank=True, default=None, null=True, on_delete=models.CASCADE, related_name="Vertreter")
|
||||
holidays_normal = models.FloatField(default=0.0, max_length=9, blank=True)
|
||||
holidays_rest = models.FloatField(default=0.0, max_length=9, blank=True)
|
||||
|
||||
|
||||
class FreeDays(models.Model):
|
||||
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
|
||||
|
|
@ -60,3 +63,4 @@ class FreeDays(models.Model):
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ Informationen: {{absence.info}}<br />
|
|||
{{confirmform|crispy}}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" onclick="javascript:noconfirmAbsence({{absence.pk}})">Ablehnen</button>
|
||||
<button type="button" class="btn" onclick="javascript:confirmAbsence({{absence.pk}})">Annehmen</button>
|
||||
<button type="button" class="btn btn-primary" onclick="javascript:confirmAbsence({{absence.pk}})">Annehmen</button>
|
||||
<button type="button" class="btn" onclick="javascript:noconfirmAbsence({{absence.pk}})">Ablehnen</button>
|
||||
</div>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
|
|
|
|||
|
|
@ -305,8 +305,25 @@ function recalculateChoosenDays(){
|
|||
},
|
||||
success : function(data){
|
||||
|
||||
$("#restholidays").html(data["restholiday"])
|
||||
$("#startAbsenceProgress").modal("show");
|
||||
|
||||
|
||||
$("#holidayyear").html(date_start.getFullYear());
|
||||
$("#restholidays").html(data["restholiday_thisyear"]);
|
||||
$("#detail_rest").html(data["restholiday_thisyear"]);
|
||||
$("#detail_resthol").html(data["restholiday_lastyear"]);
|
||||
$("#detail_next").html(data["restholiday_nextyear"]);
|
||||
|
||||
$("#detail_tocontract").html(data["need_days"]);
|
||||
|
||||
$("#detail_sum").html(data["restholiday_thisyear"]+data["restholiday_lastyear"]+data["restholiday_nextyear"]);
|
||||
|
||||
if(data["restholiday_thisyear"] < 0 || data["restholiday_lastyear"] < 0 || data["restholiday_nextyear"] < 0){
|
||||
$("#start_absence_contract").prop("disabled", true);
|
||||
}
|
||||
else{
|
||||
$("#start_absence_contract").prop("disabled", false);
|
||||
}
|
||||
|
||||
if(seldates.length == 1){
|
||||
$("#div_id_end").hide();
|
||||
|
|
@ -315,8 +332,6 @@ function recalculateChoosenDays(){
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function recalculateChoosenDaysAfterInit(){
|
||||
|
||||
new_start = $("#id_start").datepicker().val();
|
||||
|
|
@ -337,9 +352,22 @@ function recalculateChoosenDaysAfterInit(){
|
|||
end_half : $("#id_end_ishalf").prop("checked"),
|
||||
},
|
||||
success : function(data){
|
||||
|
||||
$("#restholidays").html(data["restholiday"])
|
||||
//$("#startAbsenceProgress").modal("show");
|
||||
|
||||
$("#restholidays").html(data["restholiday_thisyear"]);
|
||||
$("#detail_rest").html(data["restholiday_thisyear"]);
|
||||
$("#detail_resthol").html(data["restholiday_lastyear"]);
|
||||
$("#detail_next").html(data["restholiday_nextyear"]);
|
||||
$("#holidayyear").html(new_start[2]);
|
||||
$("#detail_sum").html(data["restholiday_thisyear"]+data["restholiday_lastyear"]+data["restholiday_nextyear"]);
|
||||
|
||||
$("#detail_tocontract").html(data["need_days"]);
|
||||
|
||||
if(data["restholiday_thisyear"] < 0 || data["restholiday_lastyear"] < 0 || data["restholiday_nextyear"] < 0){
|
||||
$("#start_absence_contract").prop("disabled", true);
|
||||
}
|
||||
else{
|
||||
$("#start_absence_contract").prop("disabled", false);
|
||||
}
|
||||
|
||||
if(seldates.length == 1){
|
||||
$("#div_id_end").hide();
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@
|
|||
</li>
|
||||
{% if user|usergperm:"absencemanager" %}
|
||||
<li class="nav-item ">
|
||||
<a class="nav-link" id="absencemanagercontent-tab" data-toggle="tab" href="#absencemanagercontent" role="tab" aria-controls="absencemanagercontent" aria-selected="false">
|
||||
{% if needtoconfirm|length > 0 %}
|
||||
<span class="badge badge-primary badge-counter" style="float: right; margin-left: 5px; margin-top: 0px">{{needtoconfirm|length}} </span>
|
||||
{%endif%}
|
||||
<a class="nav-link" id="absencemanagercontent-tab" data-toggle="tab" href="#absencemanagercontent" role="tab" aria-controls="absencemanagercontent" aria-selected="false">
|
||||
Ausstehende Anträge
|
||||
{% if needtoconfirm|length > 0 %}
|
||||
<span class="badge badge-primary badge-counter" style="float: right !important; margin-right: -20px; margin-top: -10px;">{{needtoconfirm|length}}</span>
|
||||
{%endif%}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item ">
|
||||
|
|
@ -72,50 +72,95 @@
|
|||
</div>
|
||||
<!-- MODAL -->
|
||||
<div class="modal fade" tabindex="-1" role="dialog" id="startAbsenceProgress" data-backdrop="static">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-dialog" role="document" style="min-width: 43% !important;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Abwesenheit beantragen</h5>
|
||||
<h5>Abwesenheit für <b><span id="username_abscence"></span></b> beantragen</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h5>Abwesenheit für <b><span id="username_abscence"></span></b> beantragen</h5>
|
||||
<hr>
|
||||
<div id="restholidays_container">
|
||||
<!--<h6>Verbleibender Urlaub <span id="holidayyear">: <span id="restholidays">Lade...</span></h6>
|
||||
<h5>Verbleibender Urlaub <span id="holidayyear"></span>: <b style="color: red;"><span id="restholidays">Lade...</span> Tage</b> <button class="btn btn-secondary btn-sm" style="float: right;" onclick="javascript:$('#holiday_detail_div').toggle()"><i class="fas fa-eye" id="show_detailview"></i></button></h5>
|
||||
<div id="holiday_detail_div" style="display: none">
|
||||
<hr>
|
||||
<div class="col-6" style="margin-left: -10px">
|
||||
<h6>Detailansicht</h6>
|
||||
<table class="table table-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Gewünschte Tage</td>
|
||||
<td><span id="detail_tocontract"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Resturlaub</td>
|
||||
<td><span id="detail_rest"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Urlaub nächstes Jahr</td>
|
||||
<td><span id="detail_next"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Summe Urlaubstage</b></td>
|
||||
<td><b><span id="detail_sum"></span></b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
# TODO: Abwesenheiten - Meine Abwesenheiten, Übersicht über aktuelle Tage, Resturlaub in Jahren usw.
|
||||
|
||||
Drei Zahlen berechnet Resturlaub, Verbleibender aktuelles Jahr, Nächstes Jahr
|
||||
|
||||
Drei zahlen in Info-Icon, berechnet aus Resturlaub und aktuelles Jahr die Zahl zeigen!
|
||||
|
||||
Runterklappdinger für Jahresaufteilung
|
||||
|
||||
Beim ändern von Urlaubstagen
|
||||
|
||||
2020 2021 2022
|
||||
30 32 30
|
||||
|
||||
Agentur: 30
|
||||
|
||||
Abwesenheiten - Meine Abwesenheiten, Übersicht über aktuelle Tage, Resturlaub in Jahren usw.
|
||||
Bezug zu Urlaubsjahren mit Daten für Resturlaubsberechnung
|
||||
-->
|
||||
<h6>Resturlaub Urlaub 2019: <span id="restholidays">Lade...</span></h6>
|
||||
-->
|
||||
</div>
|
||||
<div id="noholidays_container" style="display: none;">
|
||||
<h6>Abwesenheitsgrund ohne Urlaubsanspruch</h6>
|
||||
</div>
|
||||
<hr>
|
||||
<form method="POST">
|
||||
<form method="POST" class="">
|
||||
<input type="hidden" name="form_type" value="absenceform">
|
||||
{% csrf_token %}
|
||||
{{abscenceform.media}}
|
||||
{{abscenceform|crispy}}
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
{{abscenceform.start |as_crispy_field }}
|
||||
{{abscenceform.start_ishalf |as_crispy_field }}
|
||||
</div>
|
||||
<div class="col-6">
|
||||
{{abscenceform.end |as_crispy_field }}
|
||||
{{abscenceform.end_ishalf |as_crispy_field }}
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row" >
|
||||
<div class="col-6">
|
||||
{{abscenceform.reason|as_crispy_field}}
|
||||
</div>
|
||||
<div class="col-6">
|
||||
{{abscenceform.representator|as_crispy_field}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
{{abscenceform.info|as_crispy_field}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: none;">
|
||||
{{abscenceform.nextmonth}}
|
||||
{{abscenceform.prevmonth}}
|
||||
{{abscenceform.nextyear}}
|
||||
{{abscenceform.prevyear}}
|
||||
{{abscenceform.activemonth}}
|
||||
{{abscenceform.activeyear}}
|
||||
{{abscenceform.userid}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary">Abwesenheit beantragen</button>
|
||||
<button type="submit" class="btn btn-primary" id="start_absence_contract">Abwesenheit beantragen</button>
|
||||
<button type="button" class="btn btn" data-dismiss="modal">Abbrechen</button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
@ -255,6 +300,17 @@ function closeOnly(){
|
|||
closeonly = true;
|
||||
}
|
||||
|
||||
/*
|
||||
$("#show_detailview").hover(
|
||||
function() {
|
||||
$("#holiday_detail_div").show();
|
||||
}, function() {
|
||||
$("#holiday_detail_div").hide();
|
||||
}
|
||||
);
|
||||
*/
|
||||
|
||||
|
||||
function confirmAbscenceFinal(){
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
|
|
|
|||
|
|
@ -13,10 +13,11 @@ import datetime
|
|||
import calendar
|
||||
from .forms import AddAbsence, ConfirmAbsenceForm
|
||||
from django.contrib import messages
|
||||
from users.models import UserFullName
|
||||
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
|
||||
|
||||
def loadingFreeDays(plz):
|
||||
# Getting land
|
||||
|
|
@ -367,7 +368,9 @@ def TimeAjax(request):
|
|||
if(absence.user.profile.agency == request.user.profile.agency and request.user.has_perm("users.absencemanager")):
|
||||
absence.confirm_status = new_stat
|
||||
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!')
|
||||
|
|
@ -376,22 +379,24 @@ def TimeAjax(request):
|
|||
"success" : True,
|
||||
"activemonth" : request.GET["activemonth"],
|
||||
"activeyear" : request.GET["activeyear"]
|
||||
}
|
||||
}
|
||||
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 and request.user.has_perm("users.absencemanager")):
|
||||
|
||||
# Alle Abwesenheiten laden, die bestätigt oder angefragt sind UND Urlaub sind
|
||||
absences = Absence.objects.filter(user=user, confirm_status=0, reason__is_holiday=True) | Absence.objects.filter(user=user, confirm_status=1, reason__is_holiday=True)
|
||||
|
||||
if(user.profile.agency == request.user.profile.agency):
|
||||
|
||||
start_day = request.GET["startdate"].split("__")
|
||||
start_day_ob = datetime.date(int(start_day[0]), int(start_day[1]), int(start_day[2]))
|
||||
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]))
|
||||
|
||||
start_half = True
|
||||
if request.GET["start_half"] == "false":
|
||||
start_half = False
|
||||
|
|
@ -399,39 +404,60 @@ def TimeAjax(request):
|
|||
end_half = True
|
||||
if request.GET["end_half"] == "false":
|
||||
end_half = False
|
||||
|
||||
choosenyear = int(start_day[0])
|
||||
|
||||
yeardata = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency, year=choosenyear))[0]
|
||||
|
||||
# USER HAS NO ABSENCE
|
||||
if(len(absences) == 0):
|
||||
# Hier Urlaubstage bei Einstellung mit berücksichtigen
|
||||
if(start_day_ob.year == usertimedata.startdate.year):
|
||||
holiday_thisyear = 0
|
||||
holiday_lastyear = yeardata.restdays
|
||||
holiday_nextyear = 0
|
||||
|
||||
data = {
|
||||
"restholiday" : calculateHolidays(request, usertimedata.holiday_start + usertimedata.holiday, start_day_ob, end_day_obj, start_half, end_half)
|
||||
}
|
||||
# Hier Einstellungstage irrelevant und da noch keine Abwesenheiten eingetragen wurden, einfach aus Profil laden
|
||||
else:
|
||||
data = {
|
||||
"restholiday" : calculateHolidays(request, usertimedata.holiday, start_day_ob, end_day_obj, start_half, end_half)
|
||||
}
|
||||
# ABSENCE-Data found, calculating rest-Days
|
||||
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
|
||||
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))*(-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))*(-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:
|
||||
finalholidays = 0
|
||||
|
||||
# Besteht noch Anspruch aus Einstellungsjahr?
|
||||
if(start_day_ob.year == usertimedata.startdate.year):
|
||||
finalholidays += usertimedata.holiday_start + usertimedata.holiday
|
||||
# Hier Einstellungstage irrelevant und da noch keine Abwesenheiten eingetragen wurden, einfach normal
|
||||
else:
|
||||
finalholidays += usertimedata.holiday
|
||||
holiday_lastyear = yeardata.restdays
|
||||
date_splitter = datetime.date(end_day_obj.year, 1, 1)
|
||||
|
||||
# Berechne pro Abwesenheits die verbrauchen Urlaubstage
|
||||
for absence in absences:
|
||||
finalholidays -= calculatingHolidaysByAbsence(request, absence)
|
||||
#days_next_year = end_day_obj - date_splitter_postyear
|
||||
#days_this_year = date_splitter_preyear - start_day_obj
|
||||
need_days = (calculateHolidays(request, start_day_obj, date_splitter, start_half, False))*(-1) + (calculateHolidays(request, date_splitter, end_day_obj, False, end_half))*(-1)
|
||||
holiday_thisyear = yeardata.days - yeardata.days_inuse - (calculateHolidays(request, start_day_obj, date_splitter, start_half, False))*(-1)
|
||||
holiday_nextyear = holiday_nextyear - (calculateHolidays(request, date_splitter, end_day_obj, False, end_half))*(-1)
|
||||
|
||||
data = {
|
||||
"restholiday" : calculateHolidays(request, finalholidays, start_day_ob, end_day_obj, start_half, end_half)
|
||||
}
|
||||
data = {
|
||||
"restholiday_thisyear" : holiday_thisyear,
|
||||
"restholiday_lastyear" : holiday_lastyear,
|
||||
"restholiday_nextyear" : holiday_nextyear,
|
||||
"need_days" : need_days
|
||||
}
|
||||
# REQUEST USER NO RIGHTS
|
||||
else:
|
||||
data = {
|
||||
|
|
@ -453,7 +479,8 @@ Berücksichtigt sowohl Wochenende als auch in der Agentur hinterlegte Freitage/S
|
|||
|
||||
'''
|
||||
@login_required
|
||||
def calculateHolidays(request, restdays, start, end, start_half, end_half):
|
||||
def calculateHolidays(request, start, end, start_half, end_half):
|
||||
restdays = 0
|
||||
allfreedays = FreeDays.objects.filter(agency=request.user.profile.agency)
|
||||
if(end == start):
|
||||
if(start_half):
|
||||
|
|
|
|||
|
|
@ -83,14 +83,11 @@ class Agency(models.Model):
|
|||
phone = models.CharField(default="", max_length=50, blank=True)
|
||||
agencypic = models.ImageField(default='ag_default.jpg', upload_to=picturepath_agency, blank=True)
|
||||
|
||||
|
||||
|
||||
# MONEY
|
||||
balance = models.FloatField(default=0.0, max_length=9, blank=True)
|
||||
nextdebiting = models.DateTimeField(default=timezone.now, blank=True)
|
||||
monthlyprice = models.FloatField(default=25.0, max_length=9, blank=True)
|
||||
|
||||
|
||||
# MODULEEINSTELLUNGEN FÜR DIE AGENTUR
|
||||
module_news = models.BooleanField(default=True)
|
||||
module_organizer = models.BooleanField(default=True)
|
||||
|
|
@ -101,10 +98,8 @@ class Agency(models.Model):
|
|||
dynamicprofile = models.BooleanField(default=True)
|
||||
|
||||
module_messages = models.BooleanField(default=True)
|
||||
|
||||
module_chat = models.BooleanField(default=True)
|
||||
|
||||
|
||||
|
||||
# KOSTENPFLICHTIGE MODULE
|
||||
|
||||
# Abwesenheits- und Zeiterfassung
|
||||
|
|
@ -273,6 +268,7 @@ class UserYearAbsenceInfo(models.Model):
|
|||
agency = models.ForeignKey(Agency, on_delete=models.PROTECT, default=None)
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
year = models.IntegerField()
|
||||
days_inuse = models.FloatField(default=0.0)
|
||||
days = models.FloatField(default=24.0)
|
||||
restdays = models.FloatField(default=0.0)
|
||||
|
||||
|
|
|
|||
240
users/signals.py
240
users/signals.py
|
|
@ -1,7 +1,7 @@
|
|||
from django.db.models.signals import post_save, pre_delete, m2m_changed, pre_save
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.dispatch import receiver
|
||||
from .models import Profile, Agency, AgencyGroup, AgencyNetworkPreperation, UserYearAbsenceInfo
|
||||
from .models import Profile, Agency, AgencyGroup, AgencyNetworkPreperation, UserYearAbsenceInfo, UserTime
|
||||
from news.models import News
|
||||
from django.contrib.auth.models import Permission
|
||||
from notificsys.models import UserNotification
|
||||
|
|
@ -14,7 +14,7 @@ from django.conf import settings
|
|||
from django.utils import timezone
|
||||
from standards.models import Standards
|
||||
from django.contrib.auth.signals import user_logged_in, user_logged_out
|
||||
from timemanagement.models import Workday, Breaks, AbsenceReason, FreeDays
|
||||
from timemanagement.models import Workday, Breaks, AbsenceReason, FreeDays, Absence
|
||||
from datetime import date
|
||||
import datetime, json
|
||||
from django.utils import timezone
|
||||
|
|
@ -24,6 +24,8 @@ from django.conf import settings
|
|||
from datetime import date
|
||||
import channels.layers
|
||||
from asgiref.sync import async_to_sync
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from datetime import timedelta
|
||||
|
||||
def loadingFreeDays(plz, year):
|
||||
# Getting land
|
||||
|
|
@ -379,3 +381,237 @@ def receiver_function(sender, **kwargs):
|
|||
def update_presence_live(sender, **kwargs):
|
||||
channel_layer = channels.layers.get_channel_layer()
|
||||
async_to_sync(channel_layer.group_send)(str(kwargs["room"]), {'type' : 'update_presence_live'})
|
||||
|
||||
|
||||
'''
|
||||
|
||||
ABWESENHEIT BERECHNUNG UND SPEICHERUNG DER NEUEN URLAUBSTAGE - VERWEIS AUF timemenagement.views
|
||||
|
||||
|
||||
'''
|
||||
@receiver(signal=post_save, sender=Absence)
|
||||
def save_newabsence(sender, instance, **kwargs):
|
||||
post_save.disconnect(save_newabsence, sender=sender)
|
||||
if(instance.reason.is_holiday):
|
||||
newdata = getFinalHolidayData(instance)
|
||||
|
||||
abinfo = list(UserYearAbsenceInfo.objects.filter(user=instance.user, year=instance.start.year))[0]
|
||||
abinfo_lastyear = ""
|
||||
abinfo_nextyear = ""
|
||||
|
||||
is_lastyear = False
|
||||
|
||||
abinfo_lastyear = list(UserYearAbsenceInfo.objects.filter(user=instance.user, year=instance.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=instance.user, year=instance.start.year+1))
|
||||
if(len(abinfo_nextyear) > 0):
|
||||
is_nextyear = True
|
||||
abinfo_nextyear = abinfo_nextyear[0]
|
||||
|
||||
|
||||
multiple_info_needays = False
|
||||
if(hasattr(newdata[3], "__len__")):
|
||||
multiple_info_needays = True
|
||||
|
||||
# Gleiches Jahr MIT Rest
|
||||
if(multiple_info_needays and newdata[3][2] == False):
|
||||
# Rest ist positiv, daher bleibt rest übrig, rest wird in absence gespeichert und vom rest des Jahres-Restes abgezogen
|
||||
# Rest ist positiv, damit bleibt Rest übrig
|
||||
if(newdata[3][0] > 0):
|
||||
instance.holidays_rest = abinfo.restdays - newdata[3][0]
|
||||
instance.save()
|
||||
abinfo.restdays = newdata[3][0]
|
||||
abinfo.save()
|
||||
# Rest ist negativ
|
||||
elif(newdata[3][0] < 0):
|
||||
instance.holidays_rest = (abinfo.restdays - newdata[3][0]) - newdata[3][0]*(-1)
|
||||
instance.holidays_normal = newdata[3][0]*(-1)
|
||||
instance.save()
|
||||
abinfo.restdays = 0
|
||||
abinfo.days_inuse = abinfo.days_inuse + newdata[3][0]*(-1)
|
||||
abinfo.save()
|
||||
# Rest ist Urlaubsdauer
|
||||
else:
|
||||
instance.holidays_rest = abinfo.restdays
|
||||
instance.save()
|
||||
#abinfo.days_inuse = abinfo.days_inuse + abinfo.restdays
|
||||
abinfo.restdays = 0
|
||||
abinfo.save()
|
||||
# Gleiches Jahr ohne Rest
|
||||
elif(not multiple_info_needays):
|
||||
abinfo.days_inuse = abinfo.days_inuse + newdata[3]
|
||||
abinfo.save()
|
||||
instance.holidays_normal = newdata[3]
|
||||
instance.save()
|
||||
# Mehrere Jahre
|
||||
elif(multiple_info_needays and newdata[3][2] == True):
|
||||
abinfo.days_inuse = abinfo.days_inuse + newdata[3][0]
|
||||
abinfo.save()
|
||||
abinfo_nextyear.days_inuse = abinfo_nextyear.days_inuse + newdata[3][1]
|
||||
abinfo_nextyear.save()
|
||||
|
||||
# Hier werd der REST als vorjahreswert und NORMAL als nächstes Jahr gespeichert
|
||||
instance.holidays_normal = newdata[3][1]
|
||||
instance.holidays_rest = newdata[3][0]
|
||||
instance.save()
|
||||
|
||||
|
||||
else:
|
||||
print("Absence-Object is no holiday...")
|
||||
|
||||
post_save.connect(save_newabsence, sender=sender)
|
||||
|
||||
|
||||
|
||||
|
||||
@receiver(signal=pre_delete, sender=Absence)
|
||||
def delete_absence(sender, instance, **kwargs):
|
||||
if(instance.reason.is_holiday):
|
||||
newdata = getFinalHolidayData(instance)
|
||||
|
||||
abinfo = list(UserYearAbsenceInfo.objects.filter(user=instance.user, year=instance.start.year))[0]
|
||||
abinfo_lastyear = ""
|
||||
abinfo_nextyear = ""
|
||||
|
||||
is_lastyear = False
|
||||
|
||||
abinfo_lastyear = list(UserYearAbsenceInfo.objects.filter(user=instance.user, year=instance.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=instance.user, year=instance.start.year+1))
|
||||
if(len(abinfo_nextyear) > 0):
|
||||
is_nextyear = True
|
||||
abinfo_nextyear = abinfo_nextyear[0]
|
||||
|
||||
multiple_info_needays = False
|
||||
if(hasattr(newdata[3], "__len__")):
|
||||
multiple_info_needays = True
|
||||
|
||||
|
||||
print(newdata)
|
||||
|
||||
if(instance.start.year != instance.end.year):
|
||||
abinfo.days_inuse = abinfo.days_inuse - instance.holidays_rest
|
||||
abinfo.save()
|
||||
abinfo_nextyear.days_inuse = abinfo_nextyear.days_inuse - instance.holidays_normal
|
||||
abinfo_nextyear.save()
|
||||
else:
|
||||
# Gleiches Jahr MIT Rest
|
||||
abinfo.days_inuse = abinfo.days_inuse - instance.holidays_normal
|
||||
abinfo.restdays = abinfo.restdays + instance.holidays_rest
|
||||
abinfo.save()
|
||||
|
||||
else:
|
||||
print("Absence-Object is no holiday...")
|
||||
|
||||
def getFinalHolidayData(abscence):
|
||||
|
||||
user = abscence.user
|
||||
usertimedata = UserTime.objects.get(user=user)
|
||||
today = date.today()
|
||||
start_day_obj = abscence.start
|
||||
end_day_obj = abscence.end
|
||||
|
||||
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]))
|
||||
|
||||
start_half = abscence.start_ishalf
|
||||
end_half = abscence.end_ishalf
|
||||
|
||||
choosenyear = abscence.start.year
|
||||
yeardata = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency, year=choosenyear))[0]
|
||||
|
||||
holiday_thisyear = 0
|
||||
holiday_lastyear = yeardata.restdays
|
||||
holiday_nextyear = 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
|
||||
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(user, start_day_obj, end_day_obj, start_half, end_half))*(-1)
|
||||
holiday_thisyear = yeardata.days - yeardata.days_inuse - need_days
|
||||
else:
|
||||
need_days = (calculateHolidays(user, start_day_obj, end_day_obj, start_half, end_half))*(-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
|
||||
need_days = [temp_holiday, holiday_thisyear, False]
|
||||
else:
|
||||
holiday_lastyear = yeardata.restdays - need_days
|
||||
need_days = [temp_holiday, holiday_lastyear, False]
|
||||
# Urlaub geht über das nächstes Jahr hinweg
|
||||
else:
|
||||
holiday_lastyear = yeardata.restdays
|
||||
date_splitter = datetime.date(end_day_obj.year, 1, 1)
|
||||
|
||||
#days_next_year = end_day_obj - date_splitter_postyear
|
||||
#days_this_year = date_splitter_preyear - start_day_obj
|
||||
need_days = [(calculateHolidays(user, start_day_obj, date_splitter, start_half, False))*(-1), (calculateHolidays(user, date_splitter, end_day_obj, False, end_half))*(-1), True]
|
||||
|
||||
holiday_thisyear = yeardata.days - yeardata.days_inuse - (calculateHolidays(user, start_day_obj, date_splitter, start_half, False))*(-1)
|
||||
holiday_nextyear = holiday_nextyear - (calculateHolidays(user, date_splitter, end_day_obj, False, end_half))*(-1)
|
||||
|
||||
data = [ holiday_thisyear, holiday_lastyear, holiday_nextyear, need_days ]
|
||||
return data
|
||||
|
||||
|
||||
def calculateHolidays(user, start, end, start_half, end_half):
|
||||
restdays = 0
|
||||
allfreedays = FreeDays.objects.filter(agency=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 = [6,7]
|
||||
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
|
||||
|
||||
|
||||
return restdays - counter + 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)
|
||||
|
|
@ -839,6 +839,14 @@ def cronactions(request, code):
|
|||
newnotification = UserNotification(touser=user, notificationtext="Neue Agenturnews: " + news.name, notificationtype="agencynews", elementid=news.pk)
|
||||
newnotification.save()
|
||||
|
||||
# TODO: CronJob für REST-Urlaub implementieren
|
||||
'''
|
||||
|
||||
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!
|
||||
|
||||
|
||||
'''
|
||||
|
||||
data.update({"status" : "ok"})
|
||||
elif(code == settings.MAILINFOKEY):
|
||||
pass
|
||||
|
|
|
|||
Loading…
Reference in New Issue