Abewesenheit logik fertig inkl. Rest fuer naechstes Jahr usw.

This commit is contained in:
Holger Trampe 2020-05-29 23:14:09 +02:00
parent 94a32a8abc
commit 5a633c5dd2
14 changed files with 355 additions and 120 deletions

View File

@ -272,9 +272,15 @@ class AbsenceReasonDeleteView(LoginRequiredMixin, DeleteView):
template_name = 'dasettings/absencereason_confirm_delete.html'
def delete(self, request, *args, **kwargs):
try:
response = super(AbsenceReasonDeleteView, self).delete(request, *args, **kwargs)
messages.success(request, f'Abwesenheitskategorie wurde gelöscht!')
return response
except:
messages.success(request, f'Abwesenheitskategorie kann nicht gelöscht werden, da Abwesenheiten eingetragen wurden.')
return redirect('dasettings')
def get_context_data(self, **kwargs):
context = super(AbsenceReasonDeleteView, self).get_context_data(**kwargs)

View File

@ -1,6 +1,6 @@
from django import template
from django.contrib.auth.models import Group, User
from users.models import AgencyGroup, Agency, AgencyNetwork, AgencyNetworkPreperation
from users.models import AgencyGroup, Agency, AgencyNetwork, AgencyNetworkPreperation, UserTime
from standards.models import Standards, StandardCommentRate, StandardComments
from timemanagement.models import Workday, FreeDays, Absence
from message.models import Message
@ -498,3 +498,12 @@ def getUserIsRep(user):
return repstring
# Check, if a user is behind a day in agency (working startdate)
@register.simple_tag
def startdatecheck(usertocheck, day):
uertime = list(UserTime.objects.filter(user=usertocheck))[0]
if uertime.startdate < day:
return True
else:
return False

View File

@ -15,7 +15,9 @@ class AddAbsence(forms.ModelForm):
"end_ishalf" : "Halber Tag?",
"reason" : "Abwesenheitsgrund",
"representator" : "Vertreter",
"info" : "Begründung"
"info" : "Begründung",
"startday_info" : "",
"endday_info" : ""
}
widgets = {
'start': DatePickerInput(options={"format":'DD.MM.YYYY', "locale":'de'}),
@ -23,7 +25,8 @@ class AddAbsence(forms.ModelForm):
}
fields = ['start', 'start_ishalf', 'end','end_ishalf', 'reason', "representator", 'info']
#fields = ['start', 'start_ishalf', 'end','end_ishalf', 'reason', "representator", 'info']
fields = ['start', 'startday_info', 'end','endday_info', 'reason', "representator", 'info']
def __init__(self, *arg, **kwargs):
super(AddAbsence, self).__init__(*arg, **kwargs)

View File

@ -31,13 +31,21 @@ class AbsenceReason(models.Model):
return f'{self.name}'
class Absence(models.Model):
dayinfochoices = [
(0, 'Ganzer Tag'),
(1, 'Nur Vormittags'),
(2, 'Nur Nachmittags')
]
startday_info = models.CharField(max_length=2, choices=dayinfochoices, default=0)
endday_info = models.CharField(max_length=2, choices=dayinfochoices, default=0)
user = models.ForeignKey(User, on_delete=models.CASCADE)
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
start = models.DateField(default=None, null=True, blank=True)
end = models.DateField(default=None, null=True, blank=True)
start_ishalf = models.BooleanField(default=False, blank=True)
end_ishalf = models.BooleanField(default=False, blank=True)
reason = models.ForeignKey("AbsenceReason", on_delete=models.SET_NULL, null=True, blank=True)
reason = models.ForeignKey("AbsenceReason", on_delete=models.PROTECT, null=True, blank=True)
info = models.TextField(blank=True, verbose_name='Abwesenheitsbegründung', default="")
'''
CONFIRM_STATUS INFOS
@ -52,6 +60,8 @@ class Absence(models.Model):
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)
holidays_normal_next = models.FloatField(default=0.0, max_length=9, blank=True)
holidays_rest_next = models.FloatField(default=0.0, max_length=9, blank=True)
class FreeDays(models.Model):

View File

@ -27,10 +27,13 @@
{% isfreeday user da as isfree %}
{% isfreedayname user da as isfreename %}
{% getabscenceday user us da as abday %}
{% startdatecheck us da as startdatecheck %}
{% if isfree %}
<!-- FREEDAYS -->
<td id="{{actfcounter}}_{{forloop.counter}}_{{us.pk}}_free" style="background-color: #9C9C9C" data-toggle="tooltip" data-placement="top" title="{{isfreename}}">
<!-- USER NOT STARTED YET -->
{% elif startdatecheck == False %}
<td id="{{actfcounter}}_{{forloop.counter}}_{{us.pk}}_free" style="background-color: #d3d3d3">
{% elif da.weekday == 5 or da.weekday == 6 %}
<!-- WEEKEND -->
<td id="{{actfcounter}}_{{forloop.counter}}_{{us.pk}}_free" style="background-color: #d3d3d3">
@ -39,11 +42,19 @@
{% if abday.confirm_status == 0 %}
{% if user|usergperm:"absencemanager" %}
<td id="{{actfcounter}}_{{forloop.counter}}_{{us.pk}}_{{abday.pk}}_absence"
{% if abday.start_ishalf and abday.start.day == da.day %}
{% if abday.startday_info == "2" and abday.start.day == da.day %}
class="partialfilling negative"
style="background-size: 50% 100%;background-image: linear-gradient(to right, {{abday.reason.color}} 0%, {{abday.reason.color}} 17%, {{abday.reason.color}} 33%, {{abday.reason.color}} 67%, {{abday.reason.color}} 83%, {{abday.reason.color}} 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% elif abday.end_ishalf and abday.end.day == da.day %}
{% elif abday.startday_info == "1" and abday.start.day == da.day %}
class="partialfilling"
style="background-size: 50% 100%;background-image: linear-gradient(to right, {{abday.reason.color}} 0%, {{abday.reason.color}} 17%, {{abday.reason.color}} 33%, {{abday.reason.color}} 67%, {{abday.reason.color}} 83%, {{abday.reason.color}} 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% elif abday.endday_info == "2" and abday.end.day == da.day %}
class="partialfilling negative"
style="background-size: 50% 100%; background-image: linear-gradient(to right, {{abday.reason.color}} 0%, {{abday.reason.color}} 17%, {{abday.reason.color}} 33%, {{abday.reason.color}} 67%, {{abday.reason.color}} 83%, {{abday.reason.color}} 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% elif abday.endday_info == "1" and abday.end.day == da.day %}
class="partialfilling "
style="background-size: 50% 100%; background-image: linear-gradient(to right, {{abday.reason.color}} 0%, {{abday.reason.color}} 17%, {{abday.reason.color}} 33%, {{abday.reason.color}} 67%, {{abday.reason.color}} 83%, {{abday.reason.color}} 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
@ -51,27 +62,62 @@
style="background-color: {{abday.reason.color}}"
{% endif %}
data-toggle="tooltip" data-placement="top" title="{{abday.reason.name}} {% if abday.representator != None %} | Vertreter {{abday.representator.first_name}} {{abday.representator.last_name}} {% endif %} ">
{% else %}
{% elif abday.user == user %}
<td id="{{actfcounter}}_{{forloop.counter}}_{{us.pk}}_{{abday.pk}}_absence"
{% if abday.start_ishalf and abday.start.day == da.day %}
{% if abday.startday_info == "2" and abday.start.day == da.day %}
class="partialfilling negative"
style="background-size: 50% 100%; background-image: linear-gradient(to right, {{abday.reason.color}} 0%, {{abday.reason.color}} 17%, {{abday.reason.color}} 33%, {{abday.reason.color}} 67%, {{abday.reason.color}} 83%, {{abday.reason.color}} 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% elif abday.end_ishalf and abday.end.day == da.day %}
{% elif abday.startday_info == "1" and abday.start.day == da.day %}
class="partialfilling"
style="background-size: 50% 100%; background-image: linear-gradient(to right, {{abday.reason.color}} 0%, {{abday.reason.color}} 17%, {{abday.reason.color}} 33%, {{abday.reason.color}} 67%, {{abday.reason.color}} 83%, {{abday.reason.color}} 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% elif abday.endday_info == "2" and abday.end.day == da.day %}
class="partialfilling negative"
style="background-size: 50% 100%; background-image: linear-gradient(to right, {{abday.reason.color}} 0%, {{abday.reason.color}} 17%, {{abday.reason.color}} 33%, {{abday.reason.color}} 67%, {{abday.reason.color}} 83%, {{abday.reason.color}} 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% elif abday.endday_info == "1" and abday.end.day == da.day %}
class="partialfilling"
style="background-size: 50% 100%; background-image: linear-gradient(to right, {{abday.reason.color}} 0%, {{abday.reason.color}} 17%, {{abday.reason.color}} 33%, {{abday.reason.color}} 67%, {{abday.reason.color}} 83%, {{abday.reason.color}} 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% else %}
style="background-color: {{abday.reason.color}}"
{% endif %} data-toggle="tooltip" data-placement="top" title="Abwesend {% if abday.representator != None %} | Vertreter {{abday.representator.first_name}} {{abday.representator.last_name}} {% endif %} ">
{% endif %} data-toggle="tooltip" data-placement="top" title="{% if abday.user == user %} {{abday.reason.name}} {% else %} Abwesend {% endif %} {% if abday.representator != None %} | Vertreter {{abday.representator.first_name}} {{abday.representator.last_name}} {% endif %} ">
{% else %}
<td id="{{actfcounter}}_{{forloop.counter}}_{{us.pk}}_{{abday.pk}}_absence"
{% if abday.starday_info == 2 and abday.start.day == da.day %}
class="partialfilling negative"
style="background-size: 50% 100%; background-image: linear-gradient(to right, #858796 0%, #858796 17%, #858796 33%, #858796 67%, #858796 83%, #858796 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% elif abday.starday_info == 1 and abday.start.day == da.day %}
class="partialfilling"
style="background-size: 50% 100%; background-image: linear-gradient(to right, #858796 0%, #858796 17%, #858796 33%, #858796 67%, #858796 83%, #858796 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% elif abday.endday_info == "2" and abday.end.day == da.day %}
class="partialfilling negative"
style="background-size: 50% 100%; background-image: linear-gradient(to right, #858796 0%, #858796 17%, #858796 33%, #858796 67%, #858796 83%, #858796 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% elif abday.endday_info == "1" and abday.end.day == da.day %}
class="partialfilling"
style="background-size: 50% 100%; background-image: linear-gradient(to right, #858796 0%, #858796 17%, #858796 33%, #858796 67%, #858796 83%, #858796 100%); /* your gradient */
background-repeat: no-repeat; /* don't remove */"
{% else %}
style="background-color: #858796"
{% endif %} data-toggle="tooltip" data-placement="top" title="{% if abday.user == user %} {{abday.reason.name}} {% else %} Abwesend {% endif %} {% if abday.representator != None %} | Vertreter {{abday.representator.first_name}} {{abday.representator.last_name}} {% endif %} ">
{% endif %}
{% elif abday.confirm_status == 1 %}
{% if user|usergperm:"absencemanager" %}
<td id="{{actfcounter}}_{{forloop.counter}}_{{us.pk}}_{{abday.pk}}_absencetoc"
{% if abday.start_ishalf and abday.start.day == da.day %}
{% if abday.startday_info == "2" and abday.start.day == da.day %}
class="partialfilling_nf negative_nf"
style="background-size: 50% 100%"
{% elif abday.end_ishalf and abday.end.day == da.day %}
{% elif abday.startday_info == "1" and abday.start.day == da.day %}
class="partialfilling_nf"
style="background-size: 50% 100%"
{% elif abday.endday_info == "2" and abday.end.day == da.day %}
class="partialfilling_nf negative_nf"
style="background-size: 50% 100%"
{% elif abday.endday_info == "1" and abday.end.day == da.day %}
class="partialfilling_nf"
style="background-size: 50% 100%"
{% else %}
@ -80,15 +126,21 @@
data-toggle="tooltip" data-placement="top" title="Nicht bestätigt | {{abday.reason.name}} {% if abday.representator != None %} | Vertreten durch {{abday.representator.first_name}} {{abday.representator.last_name}} {% endif %} ">
{% else %}
<td id="{{actfcounter}}_{{forloop.counter}}_{{us.pk}}_{{abday.pk}}_absencetoc"
{% if abday.start_ishalf and abday.start.day == da.day %}
{% if abday.startday_info == "2" and abday.start.day == da.day %}
class="partialfilling_nf negative_nf"
style="background-size: 50% 100%"
{% elif abday.end_ishalf and abday.end.day == da.day %}
{% elif abday.startday_info == "1" and abday.start.day == da.day %}
class="partialfilling_nf"
style="background-size: 50% 100%"
{% elif abday.endday_info == "2" and abday.end.day == da.day %}
class="partialfilling_nf negative_nf"
style="background-size: 50% 100%"
{% elif abday.endday_info == "1" and abday.end.day == da.day %}
class="partialfilling_nf"
style="background-size: 50% 100%"
{% else %}
style="background-color: #858796"
{% endif %} data-toggle="tooltip" data-placement="top" title="Nicht bestätigt | Abwesend {% if abday.representator != None %} | Vertreten durch {{abday.representator.first_name}} {{abday.representator.last_name}} {% endif %}">
{% endif %} data-toggle="tooltip" data-placement="top" title="Nicht bestätigt | {% if abday.user == user %} {{abday.reason.name}} {% else %} Abwesend {% endif %} {% if abday.representator != None %} | Vertreten durch {{abday.representator.first_name}} {{abday.representator.last_name}} {% endif %}">
{% endif %}
{% else %}
<td id="{{actfcounter}}_{{forloop.counter}}_{{us.pk}}_{{da|date:'Y-m-d'}}" {% if us.pk == user.pk or user|usergperm:"absencemanager" %}class="tm-ab-tdhover"{% endif %}>
@ -309,11 +361,16 @@ function recalculateChoosenDays(){
userid : userid,
startdate : date_start.getFullYear() + "__" + (date_start.getMonth()+1) + "__" + date_start.getDate(),
enddate : date_end.getFullYear() + "__" + (date_end.getMonth()+1) + "__" + date_end.getDate(),
start_half : $("#id_start_ishalf").prop("checked"),
end_half : $("#id_end_ishalf").prop("checked"),
//start_half : $("#id_start_ishalf").prop("checked"),
//end_half : $("#id_end_ishalf").prop("checked"),
startday_info : $("#id_startday_info").val(),
endday_info : $("#id_endday_info").val(),
},
success : function(data){
console.log(data);
$("#startAbsenceProgress").modal("show");
@ -322,10 +379,11 @@ function recalculateChoosenDays(){
$("#detail_rest").html(data["restholiday_thisyear"]);
$("#detail_resthol").html(data["restholiday_lastyear"]);
$("#detail_next").html(data["restholiday_nextyear"]);
$("#detail_next_rest").html(data["restholiday_nextyear_rest"]);
$("#detail_tocontract").html(data["need_days"]);
$("#detail_tocontract_overall").html(data["need_days"]);
$("#detail_sum").html(data["restholiday_thisyear"]+data["restholiday_lastyear"]+data["restholiday_nextyear"]);
$("#detail_sum").html(data["restholiday_thisyear"]+data["restholiday_lastyear"]+data["restholiday_nextyear"]+data["restholiday_nextyear_rest"]);
if(data["restholiday_thisyear"] < 0 || data["restholiday_lastyear"] < 0 || data["restholiday_nextyear"] < 0){
$("#start_absence_contract").prop("disabled", true);
@ -336,15 +394,17 @@ function recalculateChoosenDays(){
if(seldates.length == 1){
$("#div_id_end").hide();
$("#div_id_end_ishalf").hide();
$("#div_id_endday_info").hide();
}
else{
$("#div_id_end").show();
$("#div_id_endday_info").show();
}
}
});
}
function recalculateChoosenDaysAfterInit(){
console.log(sameday);
new_start = $("#id_start").datepicker().val();
new_end = $("#id_end").datepicker().val();
@ -368,19 +428,36 @@ function recalculateChoosenDaysAfterInit(){
userid : userid,
startdate : new_start[2] + "__" + new_start[1] + "__" + new_start[0],
enddate : new_end[2] + "__" + new_end[1] + "__" + new_end[0],
start_half : $("#id_start_ishalf").prop("checked"),
end_half : $("#id_end_ishalf").prop("checked"),
//start_half : $("#id_start_ishalf").prop("checked"),
//end_half : $("#id_end_ishalf").prop("checked"),
startday_info : $("#id_startday_info").val(),
endday_info : $("#id_endday_info").val(),
},
success : function(data){
console.log(data);
$("#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_sum").html(data["restholiday_thisyear"]+data["restholiday_lastyear"]+data["restholiday_nextyear"]+data["restholiday_nextyear_rest"]);
$("#detail_tocontract").html(data["need_days"]);
$("#detail_tocontract_overall").html(data["need_days"]);
if(data["two_years"] == true){
$("#detail_tocontract").html(data["need_days_this"]);
$("#two_years").show();
$("#holidayyear_next").html(new_end[2]);
$("#detail_next_rest").html(data["restholiday_nextyear_rest"]);
$("#detail_next").html(data["restholiday_nextyear"]);
$("#detail_tocontract_next").html(data["need_days_next"]);
$("#restholidays_next").html(data["restholiday_nextyear"]);
$("#detail_tocontract_overall").html(data["need_days_next"]+data["need_days_this"]);
}
else{
$("#two_years").hide();
}
behindcheck = false;
if(+behindcheck_start == +behindcheck_end){
@ -415,6 +492,7 @@ $("#id_end").blur(function(){
recalculateChoosenDaysAfterInit();
})
/*
$("#id_start_ishalf").change(function(){
recalculateChoosenDaysAfterInit();
})
@ -422,6 +500,14 @@ $("#id_start_ishalf").change(function(){
$("#id_end_ishalf").change(function(){
recalculateChoosenDaysAfterInit();
})
*/
$("#id_startday_info").change(function(){
recalculateChoosenDaysAfterInit();
})
$("#id_endday_info").change(function(){
recalculateChoosenDaysAfterInit();
})
$( function() {
@ -537,3 +623,4 @@ $( function() {
</script>

View File

@ -89,9 +89,18 @@
</div>
<div class="modal-body">
<div id="restholidays_container">
<h5><b style="color: red"><span id="detail_tocontract"></span>&nbsp;Tage&nbsp;/&nbsp;<span id="restholidays"></span>&nbsp;verbleibend im Jahr&nbsp;<span id="holidayyear"></span></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>
<h5><b style="color: red"><span id="detail_tocontract"></span>&nbsp;Tage&nbsp;/&nbsp;<span id="restholidays"></span>&nbsp;verbleibend im Jahr&nbsp;<span id="holidayyear"></span></b> </h5>
<!-- ONE YEAR -->
<h5>
<b style="color: red">
<span id="detail_tocontract"></span>&nbsp;Tage&nbsp;/&nbsp;<span id="restholidays"></span>&nbsp;verbleibend im Jahr&nbsp;<span id="holidayyear"></span>
</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>
<!-- TWO YEARS -->
<div id="two_years" style="display: none;">
<h5><b style="color: red"><span id="detail_tocontract_next"></span>&nbsp;Tage&nbsp;/&nbsp;<span id="restholidays_next"></span>&nbsp;verbleibend im Jahr&nbsp;<span id="holidayyear_next"></span></b>
</h5>
</div>
<div id="holiday_detail_div" style="display: none">
<hr>
<div class="col-6" style="margin-left: -10px">
@ -100,7 +109,7 @@
<tbody>
<tr>
<td>Gewünschte Tage</td>
<td><span id="detail_tocontract"></span></td>
<td><span id="detail_tocontract_overall"></span></td>
</tr>
<tr>
<td>Resturlaub</td>
@ -108,7 +117,7 @@
</tr>
<tr>
<td>Urlaub nächstes Jahr</td>
<td><span id="detail_next"></span></td>
<td><span id="detail_next"></span> + Rest (<span id="detail_next_rest"></span>)</td>
</tr>
<tr>
<td><b>Summe Urlaubstage</b></td>
@ -117,31 +126,6 @@
</tbody>
</table>
</div>
<!--<h5>Verbleibender Urlaub <span id="holidayyear"></span>:&nbsp;<b style="color: red;"><span id="restholidays">Lade...</span> Tage</b>&nbsp;<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>
<!--
# TODO: Abwesenheiten - Meine Abwesenheiten, Übersicht über aktuelle Tage, Resturlaub in Jahren usw.
@ -161,11 +145,12 @@
<div class="row">
<div class="col-6">
{{abscenceform.start |as_crispy_field }}
{{abscenceform.start_ishalf |as_crispy_field }}
{{abscenceform.startday_info |as_crispy_field }}
</div>
<div class="col-6">
{{abscenceform.end |as_crispy_field }}
{{abscenceform.end_ishalf |as_crispy_field }}
{{abscenceform.endday_info |as_crispy_field }}
</div>
</div>
<hr>
@ -183,6 +168,7 @@
</div>
</div>
</div>
<!-- Fields for rest-logic -->
<div style="display: none;">
{{abscenceform.nextmonth}}
{{abscenceform.prevmonth}}

View File

@ -1,39 +1,57 @@
{% load l10n %}
{% load mathfilters %}
<div class="row mt-3">
<div class="col-4 mr-2">
<div class="col-5 mr-2">
<div class="card">
<div class="card-body">
<!-- CANVAS -->
<h6>Urlaubsübersicht</h6>
<div class="chart-container" style="">
<canvas id="datainfo_reason"></canvas>
</div>
<hr>
<h6>Übersicht nach Abwesenheitskategorien</h6>
<div class="chart-container" style="">
<canvas id="datainfo_restdays"></canvas>
</div>
<hr>
<h6>Übersicht</h6>
<button class="btn btn-secondary btn-sm" style="float: right;" onclick="javascript:$('#alloverview_detail').toggle()"><i class="fas fa-eye" id="show_detailview"></i></button>
<div id="alloverview_detail" style="display: none;">
<h6>Übersicht nach Abwesenheitskategorien</h6>
<table class="table table-sm">
<tbody>
<tr>
<td>Gesamturlaub</td>
<td>Verfügbare Urlaube</td>
<td>{{yearinfo.days}}&nbsp;Tage</td>
</tr>
<tr>
<td>Genommener Urlaub</td>
<td>{{yearinfo.days_inuse}}&nbsp;Tage</td>
</tr>
<tr>
<td>Resturlaub</td>
<td>{{yearinfo.days|sub:yearinfo.days_inuse}}&nbsp;Tage</td>
<td>Resturlaub aus Vorjahr</td>
<td>{{yearinfo.restdays}}&nbsp;Tage</td>
</tr>
</tbody>
</table>
<h6>Übersicht nach Abwesenheitskategorien</h6>
<table class="table table-sm">
<tbody>
{% for ele in final_reasons %}
<tr>
<td>{{ele.0}}</td>
<td>{{ele.1}} Tage</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col-7">
<div class="col-7" style="margin-left:-10px !important;">
<div class="table-responsive">
<table class="table table-hover" id="table_userownab">
<thead>
@ -85,7 +103,37 @@
</script>
<script>
var ctx = document.getElementById("datainfo_restdays");
var myChart = new Chart(ctx, {
var chart_reasons = new Chart(ctx, {
type: 'doughnut',
data: {
labels: [
{% for ele in final_reasons %}
'{{ele.0}}',
{% endfor %}
],
datasets: [{
backgroundColor: [
{% for ele in final_reasons %}
'{{ele.0.color}}',
{% endfor %}
],
data : [
{% for ele in final_reasons %}
{{ele.1|unlocalize}},
{% endfor %} ]
}]
},
options : {
legend: {
display: true,
position: 'bottom',
}
}
});
var ctx = document.getElementById("datainfo_reason");
var chart_holiday = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Verfügbarer Urlaub', 'Genommener Urlaub'],

View File

@ -87,7 +87,8 @@ def AbsenceManagmenet(request, activemonth=False, activeyear=False):
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"], 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 Benutzerzuweisung!')
@ -164,6 +165,17 @@ def AbsenceManagmenet(request, activemonth=False, activeyear=False):
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)
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"),
@ -176,6 +188,7 @@ def AbsenceManagmenet(request, activemonth=False, activeyear=False):
"activemonth" : activemonth,
"activeyear" : activeyear,
"inuse" : inuse,
"final_reasons" : final_reasons,
"yearinfo" : yearinfo,
"kontingent" : kontingent,
"abscenceform" : AddAbsence(instance=request.user),
@ -411,13 +424,15 @@ def TimeAjax(request):
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
end_half = True
if request.GET["end_half"] == "false":
# 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])
@ -426,11 +441,17 @@ def TimeAjax(request):
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
@ -457,20 +478,44 @@ def TimeAjax(request):
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)
#days_next_year = end_day_obj - date_splitter_postyear
#days_this_year = date_splitter_preyear - start_day_obj
need_days_this = (calculateHolidays(request, start_day_obj, date_splitter, start_half, False))*(-1)
need_days_next = (calculateHolidays(request, date_splitter, end_day_obj, False, end_half))*(-1)
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_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))*(-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
data = {
"restholiday_thisyear" : holiday_thisyear,
"restholiday_lastyear" : holiday_lastyear,
"restholiday_nextyear" : holiday_nextyear,
"need_days" : need_days
"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,
}
# REQUEST USER NO RIGHTS
else:
@ -531,17 +576,18 @@ def calculatingHolidaysByAbsence(request, absence):
finalholidayinabsence = 0
# Start und Ende gleich, nur ein Tag. Checken, ob Halber Tag
if(absence.start == absence.end):
if(absence.start_ishalf):
if abscence.startday_info == "1" or abscence.startday_info == "2":
finalholidayinabsence = 0.5
else:
finalholidayinabsence = 1
return finalholidayinabsence
else:
if(absence.start_ishalf):
if abscence.startday_info == "1" or abscence.startday_info == "2":
finalholidayinabsence -= 0.5
if(absence.end_ishalf):
if abscence.endday_info == "1" or abscence.endday_info == "2":
finalholidayinabsence -= 0.5
weekdays = [6,7]
@ -561,3 +607,4 @@ def calculatingHolidaysByAbsence(request, absence):
def daterange(date1, date2):
for n in range(int ((date2 - date1).days)+1):
yield date1 + timedelta(n)

View File

@ -455,25 +455,26 @@ def save_newabsence(sender, instance, **kwargs):
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.restdays = abinfo_nextyear.restdays - newdata[3][3]
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.holidays_normal = newdata[3][0]
instance.holidays_rest = 0
instance.holidays_normal_next = newdata[3][1]
instance.holidays_rest_next = newdata[3][3]
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):
@ -500,13 +501,12 @@ def delete_absence(sender, instance, **kwargs):
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.days_inuse = abinfo.days_inuse - instance.holidays_normal
abinfo.save()
abinfo_nextyear.days_inuse = abinfo_nextyear.days_inuse - instance.holidays_normal
abinfo_nextyear.days_inuse = abinfo_nextyear.days_inuse - instance.holidays_normal_next
abinfo_nextyear.restdays = abinfo_nextyear.restdays + instance.holidays_rest_next
abinfo_nextyear.save()
else:
# Gleiches Jahr MIT Rest
@ -530,8 +530,16 @@ def getFinalHolidayData(abscence):
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
#start_half = abscence.start_ishalf
#end_half = abscence.end_ishalf
start_half = False
if abscence.startday_info == "1" or abscence.startday_info == "2":
start_half = True
end_half = False
if abscence.endday_info == "1" or abscence.endday_info == "2":
end_half = True
choosenyear = abscence.start.year
yeardata = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency, year=choosenyear))[0]
@ -544,6 +552,8 @@ def getFinalHolidayData(abscence):
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
@ -572,15 +582,37 @@ def getFinalHolidayData(abscence):
need_days = [temp_holiday, holiday_lastyear, False]
# 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)
#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]
need_days_this = (calculateHolidays(user, start_day_obj, date_splitter, start_half, False))*(-1)
holiday_thisyear = yeardata.days - yeardata.days_inuse - (calculateHolidays(user, start_day_obj, date_splitter, start_half, False))*(-1)
need_days_next = (calculateHolidays(user, date_splitter, end_day_obj, False, end_half))*(-1)
need_days = (calculateHolidays(user, start_day_obj, date_splitter, start_half, False))*(-1) + (calculateHolidays(user, 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(user, date_splitter, end_day_obj, False, end_half))*(-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
# TAGE NORMAL, TAGE NEXT NORMAL, TRUE für 2jahre, TAGE NEXT REST
need_days = [need_days_this, days_nextyear_normal, True, days_nextyear_rest]
data = [ holiday_thisyear, holiday_lastyear, holiday_nextyear, need_days ]
return data

View File

@ -440,7 +440,6 @@
<button id="chatButton" class="btn btn-primary" style="position: fixed; right: 36px; bottom: 30px;"><i class="far fa-comments"></i></button>
<!-- CHATAREA -->
<div id="dynamicchatwindow" class="col-4" style="position: absolute; bottom: 30px; right: 23px; display: none;z-index: 999;">
<div class="card">

View File

@ -8,6 +8,7 @@
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form|crispy}}
<div class="form-group">
<button type="submit" class="btn btn-primary">Supportanfrage verschicken</button>&nbsp;
<a href="{% url 'users-dashboard' %}" class="btn">Abbrechen</a>
@ -15,6 +16,13 @@
</form>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#id_problem').summernote({
height: 320,
lang: "de-DE",
disableDragAndDrop: true
});
});
</script>
{% endblock content %}

View File

@ -160,7 +160,7 @@ class SupportForm(forms.Form):
self.fields['name'] = forms.CharField(required=True, label="Name", initial=user_name)
self.fields['mail'] = forms.EmailField(required=True, label="E-Mail", initial=user.email)
self.fields['problemconc'] = forms.CharField(required=True, label="Problemzusammenfassung")
self.fields['problem'] = forms.CharField(required=True, widget=forms.Textarea, label="Ausführliche Beschreibung")
self.fields['problem'] = forms.CharField(required=True, widget=forms.Textarea, label="Ausführliche Problembeschreibung")
self.fields['name'].widget.attrs['readonly'] = True
self.fields['mail'].widget.attrs['readonly'] = True

View File

@ -757,7 +757,7 @@ def support(request):
"email": mail,
"subject": 'Digitale Agentur: '+problemconc,
"ip": "1.1.1.1",
"message": "*****************************\nAgentur: "+ request.user.profile.agency.name +" (ID: "+ str(request.user.profile.agency.pk) +")\nBenutzer: "+request.user.first_name+" "+request.user.last_name+" (ID: "+ str(request.user.pk) +")\n*******************************\n\n" + problem
"message": "data/html;charset=utf-8;*****************************\nAgentur: "+ request.user.profile.agency.name +" (ID: "+ str(request.user.profile.agency.pk) +")\nBenutzer: "+request.user.first_name+" "+request.user.last_name+" (ID: "+ str(request.user.pk) +")\n*******************************\n\n" + problem
}
json_data = json.dumps(ostdata)