Abwesenheit fertig ausser Benachrichtigungen

This commit is contained in:
Holger Trampe 2020-05-30 12:25:09 +02:00
parent 9719fe6457
commit 642e1ee8bb
7 changed files with 555 additions and 8 deletions

View File

@ -45,6 +45,54 @@ class AddAbsence(forms.ModelForm):
self.fields['activeyear'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
self.fields['userid'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
class UpdateAbsence(forms.ModelForm):
class Meta:
model = Absence
labels = {
"start" : "Beginn der Abwesenheit",
"start_ishalf" : "Halber Tag?",
"end" : "Ende der Abwesenheit",
"end_ishalf" : "Halber Tag?",
"reason" : "Abwesenheitsgrund",
"representator" : "Vertreter",
"info" : "Begründung",
"startday_info" : "",
"endday_info" : ""
}
widgets = {
'start': DatePickerInput(options={"format":'DD.MM.YYYY', "locale":'de'}),
'end': DatePickerInput(options={"format":'DD.MM.YYYY', "locale":'de'}),
}
#fields = ['start', 'start_ishalf', 'end','end_ishalf', 'reason', "representator", 'info']
fields = ['start', 'startday_info', 'end','endday_info', 'reason', "representator", 'info', 'holidays_normal', 'holidays_rest', 'holidays_normal_next', 'holidays_rest_next' ]
def __init__(self, *arg, **kwargs):
super(UpdateAbsence, self).__init__(*arg, **kwargs)
self.fields['reason'].queryset = AbsenceReason.objects.filter(agency=kwargs['instance'].profile.agency).order_by('-name')
self.fields['representator'].queryset = UserFullName.objects.filter(profile__agency=kwargs['instance'].profile.agency, )
self.fields['info'].widget.attrs['rows'] = 3
self.fields['start'].required = True
self.fields['end'].required = True
self.fields['reason'].required = True
self.fields['nextmonth'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
self.fields['prevmonth'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
self.fields['nextyear'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
self.fields['prevyear'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
self.fields['activemonth'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
self.fields['activeyear'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
self.fields['userid'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
self.fields['holidays_normal'] = forms.FloatField(required=False, widget=forms.HiddenInput())
self.fields['holidays_rest'] = forms.FloatField(required=False, widget=forms.HiddenInput())
self.fields['holidays_normal_next'] = forms.FloatField(required=False, widget=forms.HiddenInput())
self.fields['holidays_rest_next'] = forms.FloatField(required=False, widget=forms.HiddenInput())
'''
def clean(self):
start_date = self.cleaned_data['start']

View File

@ -458,7 +458,8 @@ function recalculateChoosenDaysAfterInit(){
$("#detail_tocontract").html(data["need_days"]);
$("#detail_tocontract_overall").html(data["need_days"]);
$("#detail_next_rest").html(data["restholiday_nextyear_rest"]);
if(data["two_years"] == true){
$("#detail_tocontract").html(data["need_days_this"]);
$("#two_years").show();

View File

@ -23,7 +23,8 @@
<td>{{abday.reason.name}}</td>
<td>{{abday.info}}</td>
<td>{% if abday.confirm_status == 0 %} Genehmigt {% elif abday.confirm_status == 1 %} Beantragt {% else %} Abgelehnt {% endif %}</td>
<td>
<td style="float: right;">
<button type="button " class="btn btn-secondary btn-sm mr-1" onclick="javascript:changeAbsence({{abday.pk}})"><i class="fas fa-pen"></i></button>
<button type="button " class="btn btn-secondary btn-sm" onclick="javascript:$('#confirm-delete_{{abday.pk}}').modal('toggle')"><i class="fas fa-trash"></i></button>
</td>
</tr>
@ -33,6 +34,12 @@
</div>
</div>
<script type="text/javascript">
function changeAbsence(abscencepk){
location.href = "/tm/abs/update/" + abscencepk + "/"
}
$(document).ready(function(){
$('#table_allabsences').DataTable({

View File

@ -35,10 +35,7 @@
</a>
</li>
{% endif %}
</ul>
</div>
<div class="tab-content" id="absencetabsContent">

View File

@ -0,0 +1,409 @@
{% extends "users/base.html" %}
{% block content %}
{% load crispy_forms_tags %}
{% load counter_tag %}
{% load l10n %}
{% load mathfilters %}
{% if request.user.profile.agency.module_timemanagement %}
<div class="content-section col-8">
<h3>Abwesenheit von {{absence.user.first_name}} {{absence.user.last_name}} Bearbeiten</h3>
<hr>
<div class="row">
<div class="col-6">
<form method="POST" class="">
{% csrf_token %}
{{form.media}}
<div class="row">
<div class="col-6">
{{form.start |as_crispy_field }}
{{form.startday_info |as_crispy_field }}
</div>
<div class="col-6">
{{form.end |as_crispy_field }}
{{form.endday_info |as_crispy_field }}
</div>
</div>
<hr>
<div class="row" >
<div class="col-6">
{{form.reason|as_crispy_field}}
</div>
<div class="col-6">
{{form.representator|as_crispy_field}}
</div>
</div>
<div class="row">
<div class="col-12">
{{form.info|as_crispy_field}}
</div>
</div>
</div>
<div class="col-5 ml-3">
<div id="restholidays_container">
<h5>Übersicht Urlaubstage</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>
</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">
<div class="col-12" style="margin-left: -10px">
<table class="table table-sm">
<tbody>
<tr>
<td>Gewünschte Tage</td>
<td><span id="detail_tocontract_overall"></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> + Rest (<span id="detail_next_rest"></span>)</td>
</tr>
<tr>
<td><b>Summe Urlaubstage</b></td>
<td><b><span id="detail_sum"></span></b></td>
</tr>
</tbody>
</table>
</div>
<div id="otherholidays" style="display: none;">
<hr>
In diesem Zeitraum haben bereits folgende Mitarbeiter Abwesenheiten:
<br />
<div id="otherholidays_users"></div>
</div>
</div>
</div>
<div id="noholidays_container" style="display: none;">
<h5>Abwesenheitsgrund ohne Urlaubsanspruch</h5>
</div>
</div>
</div>
<hr>
<div style="display: none;">
{{form.holidays_normal}}
{{form.holidays_rest}}
{{form.holidays_normal_next}}
{{form.holidays_rest_next}}
</div>
<a class="btn" href="{% url 'tma-management' %} ">Abbrechen</a>
<button type="submit" class="btn btn-primary" style="float: right" id="updateAbsence">Abwesenheit aktualisieren</button>
</form>
<script type="text/javascript">
var sameday = false;
$(document).ready(function(){
date_start = "{{start}}";
date_end = "{{end}}";
$('#id_reason option[value="{{absence.reason.pk}}"]').attr("selected",true);
$('#id_representator option[value="{{absence.representator.pk}}"]').attr("selected",true);
$('#id_startday_info option[value="{{absence.startday_info}}"]').attr("selected",true);
$('#id_endday_info option[value="{{absence.endday_info}}"]').attr("selected",true);
$("#id_holidays_normal").val({{absence.holidays_normal|unlocalize}});
$("#id_holidays_rest").val({{absence.holidays_rest|unlocalize}});
$("#id_holidays_normal_next").val({{absence.holidays_normal_next|unlocalize}});
$("#id_holidays_rest_next").val({{absence.holidays_rest_next|unlocalize}});
new_start = date_start.split(".");
new_end = date_end.split(".");
date_start = new Date(new_start[2], (parseInt(new_start[1])-1), new_start[0]);
date_end = new Date(new_end[2], (parseInt(new_end[1])-1), new_end[0]);
$("#id_start").data("DateTimePicker").date(date_start);
$("#id_end").data("DateTimePicker").date(date_end);
if(+new_start == +new_end){
sameday = true;
}
else{
sameday = false;
}
if(sameday){
date_end = date_start;
new_end = new_start;
}
reasonid = $('#id_reason :selected').val();
//Get required-rep
$.ajax(
{
type: "GET",
url: "{% url 'tm-ajax' %}",
data:{
action : "checkrequired",
rid : reasonid
},
success : function(data){
//CHANGE REPRESENTOR
if(data["isreq"]){
$("#id_representator").prop('required',true);
$("label[for*='id_representator']").html("Vertreter*");
}
else{
$("#id_representator").prop('required',false);
$("label[for*='id_representator']").html("Vertreter");
}
//CHANGE HOLIDAYCOUNT
if(data["isholiday"] == false){
$("#noholidays_container").show();
$("#restholidays_container").hide();
$("#start_absence_contract").prop("disabled", false);
}
else{
$("#noholidays_container").hide();
$("#restholidays_container").show();
}
}
});
$.ajax({
type: "GET",
url: "{% url 'tm-ajax' %}",
data:{
action : "getrestholidays",
userid : {{absence.user.pk}},
startdate : date_start.getFullYear() + "__" + (date_start.getMonth()+1) + "__" + date_start.getDate(),
enddate : date_end.getFullYear() + "__" + (date_end.getMonth()+1) + "__" + date_end.getDate(),
startday_info : $("#id_startday_info").val(),
endday_info : $("#id_endday_info").val(),
},
success : function(data){
if(data["other_absences"] != false){
$("#otherholidays").show();
$("#otherholidays_users").html(data["other_absences"]);
}
else{
$("#otherholidays").hide();
}
$("#restholidays").html(data["restholiday_thisyear"] + parseFloat($("#id_holidays_normal").val()) + parseFloat($("#id_holidays_rest").val()));
$("#detail_rest").html(data["restholiday_thisyear"] + parseFloat($("#id_holidays_normal").val()) + parseFloat($("#id_holidays_rest").val()));
$("#detail_resthol").html(data["restholiday_lastyear"]);
$("#detail_next").html(data["restholiday_nextyear"] + parseFloat($("#id_holidays_normal_next").val()) + parseFloat($("#id_holidays_rest_next").val()));
$("#holidayyear").html(new_start[2]);
$("#detail_sum").html(data["restholiday_thisyear"]+data["restholiday_lastyear"]+data["restholiday_nextyear"]+data["restholiday_nextyear_rest"] + parseFloat($("#id_holidays_normal").val()) + parseFloat($("#id_holidays_rest").val()));
$("#detail_tocontract").html(data["need_days"]);
$("#detail_tocontract_overall").html(data["need_days"]);
$("#detail_next_rest").html(data["restholiday_nextyear_rest"]+parseFloat($("#id_holidays_rest_next").val()));
if(data["two_years"] == true){
$("#detail_tocontract").html(data["need_days_this"]);
$("#two_years").show();
$("#holidayyear_next").html(new_end[2]);
$("#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();
}
if(data["other_absences"] != false){
$("#otherholidays").show();
$("#otherholidays_users").html(data["other_absences"]);
}
else{
$("#otherholidays").hide();
}
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);
}
}
});
});
/*
CHANGE LISTENER
*/
$("#id_start").blur(function(){
recalculateChoosenDays();
})
$("#id_end").blur(function(){
recalculateChoosenDays();
})
/*
$("#id_start_ishalf").change(function(){
recalculateChoosenDays();
})
$("#id_end_ishalf").change(function(){
recalculateChoosenDays();
})
*/
$("#id_startday_info").change(function(){
recalculateChoosenDays();
})
$("#id_endday_info").change(function(){
recalculateChoosenDays();
})
function recalculateChoosenDays(){
date_start = $("#id_start").datepicker().val();
date_end = $("#id_end").datepicker().val();
new_start = date_start.split(".");
new_end = date_end.split(".");
date_start = new Date(new_start[2], (parseInt(new_start[1])-1), new_start[0]);
date_end = new Date(new_end[2], (parseInt(new_end[1])-1), new_end[0]);
$('.ui-datepicker-calendar').hide();
$('.ui-datepicker-header').hide();
$.ajax({
type: "GET",
url: "{% url 'tm-ajax' %}",
data:{
action : "getrestholidays",
userid : {{absence.user.pk}},
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"),
startday_info : $("#id_startday_info").val(),
endday_info : $("#id_endday_info").val(),
},
success : function(data){
if(data["other_absences"] != false){
$("#otherholidays").show();
$("#otherholidays_users").html(data["other_absences"]);
}
else{
$("#otherholidays").hide();
}
$("#restholidays").html(data["restholiday_thisyear"] + parseFloat($("#id_holidays_normal").val()) + parseFloat($("#id_holidays_rest").val()));
$("#detail_rest").html(data["restholiday_thisyear"] + parseFloat($("#id_holidays_normal").val()) + parseFloat($("#id_holidays_rest").val()));
$("#detail_resthol").html(data["restholiday_lastyear"]);
$("#detail_next").html(data["restholiday_nextyear"] + parseFloat($("#id_holidays_normal_next").val()) + parseFloat($("#id_holidays_rest_next").val()));
$("#holidayyear").html(new_start[2]);
$("#detail_sum").html(data["restholiday_thisyear"]+data["restholiday_lastyear"]+data["restholiday_nextyear"]+data["restholiday_nextyear_rest"] + parseFloat($("#id_holidays_normal").val()) + parseFloat($("#id_holidays_rest").val()));
$("#holidayyear").html(date_start.getFullYear());
$("#detail_next_rest").html(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]+parseFloat($("#id_holidays_normal").val()));
$("#detail_next_rest").html(data["restholiday_nextyear_rest"]+ parseFloat($("#id_holidays_rest").val()));
$("#detail_next").html(data["restholiday_nextyear"]+ parseFloat($("#id_holidays_normal").val()));
$("#detail_tocontract_next").html(data["need_days_next"]);
$("#restholidays_next").html(data["restholiday_nextyear"]+ parseFloat($("#id_holidays_normal").val()));
$("#detail_tocontract_overall").html(data["need_days_next"]+data["need_days_this"]);
}
else{
$("#two_years").hide();
}
$("#detail_sum").html(data["restholiday_thisyear"]+data["restholiday_lastyear"]+data["restholiday_nextyear"]+data["restholiday_nextyear_rest"]);
sum_thisyear = data["restholiday_thisyear"] + parseFloat($("#id_holidays_normal").val()) + parseFloat($("#id_holidays_rest").val());
sum_nextyear = data["restholiday_nextyear"]+ parseFloat($("#id_holidays_normal").val())
if(+date_start == +date_end){
if(data["restholiday_thisyear"] < 0 || data["restholiday_lastyear"] < 0 || data["restholiday_nextyear"] < 0 || sum_thisyear < 0 || sum_nextyear < 0){
$("#updateAbsence").prop("disabled", true);
}
else{
$("#updateAbsence").prop("disabled", false);
}
}
else if(+date_start < +date_end == true){
if(data["restholiday_thisyear"] < 0 || data["restholiday_lastyear"] < 0 || data["restholiday_nextyear"] < 0 || sum_thisyear < 0 || sum_nextyear < 0){
$("#updateAbsence").prop("disabled", true);
}
else{
$("#updateAbsence").prop("disabled", false);
}
}
else{
$("#updateAbsence").prop("disabled", true);
}
}
});
}
//Set required repr or not
document.getElementById("id_reason").addEventListener("change", function(){
reasonid = $('#id_reason :selected').val();
//Get required-rep
$.ajax(
{
type: "GET",
url: "{% url 'tm-ajax' %}",
data:{
action : "checkrequired",
rid : reasonid
},
success : function(data){
//CHANGE REPRESENTOR
if(data["isreq"]){
$("#id_representator").prop('required',true);
$("label[for*='id_representator']").html("Vertreter*");
}
else{
$("#id_representator").prop('required',false);
$("label[for*='id_representator']").html("Vertreter");
}
//CHANGE HOLIDAYCOUNT
if(data["isholiday"] == false){
$("#noholidays_container").show();
$("#restholidays_container").hide();
$("#start_absence_contract").prop("disabled", false);
}
else{
$("#noholidays_container").hide();
$("#restholidays_container").show();
recalculateChoosenDays();
}
}
});
})
</script>
{% endif %}
{% endblock content %}

View File

@ -1,6 +1,6 @@
from django.urls import path
from django.contrib.auth.decorators import login_required, permission_required
from .views import TimeManagement, TimeAjax, AbsenceManagmenet
from .views import TimeManagement, TimeAjax, AbsenceManagmenet, AbsenceUpdate
'''
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
'''
@ -10,6 +10,7 @@ urlpatterns = [
path('abs/', AbsenceManagmenet, name='tma-management'),
path('abs/<int:activemonth>/<int:activeyear>', AbsenceManagmenet, name='tma-management'),
path('ajax/', TimeAjax, name='tm-ajax'),
path('abs/update/<int:pk>/', AbsenceUpdate, name='tma-update'),
#path('newsadd/', permission_required('users.modulenews')(views.NewsAdd), name='news-add'),
#path('newsupdate/<int:id>/', permission_required('users.modulenews')(views.NewsUpdate), name='news-update'),
#path('news/<int:pk>/delete', permission_required('users.modulenews')(NewsDeleteView.as_view()), name='news-delete'),

View File

@ -11,7 +11,7 @@ from django.contrib.auth.models import User
from calendar import monthrange
import datetime
import calendar
from .forms import AddAbsence, ConfirmAbsenceForm
from .forms import AddAbsence, ConfirmAbsenceForm, UpdateAbsence
from django.contrib import messages
from users.models import UserFullName, UserYearAbsenceInfo
from users.models import UserTime
@ -50,6 +50,90 @@ def get_datetime_range(year, month):
nb_days = monthrange(year, month)[1]
return [datetime.date(year, month, day) for day in range(1, nb_days+1)]
@login_required
def AbsenceUpdate(request, pk):
if request.method == "GET":
absence = Absence.objects.get(pk=pk)
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 = {
"active_link" : "abscence",
"form" : UpdateAbsence(instance=request.user),
"absence" : absence,
"timeinfo_thisyear" : timeinfo_thisyear,
"timeinfo_nextyear" : timeinfo_nextyear,
"start" : absence.start.strftime("%d.%m.%Y"),
"end" : absence.end.strftime("%d.%m.%Y"),
}
return render(request, 'timemanagement/tm_ab_update.html', context)
elif request.method == "POST":
absence = Absence.objects.get(pk=pk)
formtocheck = UpdateAbsence(request.POST, instance=request.user)
if(formtocheck.is_valid()):
abinfo = list(UserYearAbsenceInfo.objects.filter(user=absence.user, year=absence.start.year))[0]
abinfo_lastyear = ""
abinfo_nextyear = ""
is_lastyear = False
abinfo_lastyear = list(UserYearAbsenceInfo.objects.filter(user=absence.user, year=absence.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=absence.user, year=absence.start.year+1))
if(len(abinfo_nextyear) > 0):
is_nextyear = True
abinfo_nextyear = abinfo_nextyear[0]
print(formtocheck.cleaned_data["holidays_normal"])
print(formtocheck.cleaned_data["holidays_rest"])
print(formtocheck.cleaned_data["startday_info"])
print(formtocheck.cleaned_data["endday_info"])
abinfo.days_inuse -= formtocheck.cleaned_data["holidays_normal"]
abinfo.restdays -= formtocheck.cleaned_data["holidays_rest"]
abinfo.save()
abinfo_nextyear.days_inuse -= formtocheck.cleaned_data["holidays_normal_next"]
abinfo_nextyear.restdays -= formtocheck.cleaned_data["holidays_rest_next"]
abinfo_nextyear.save()
absence.start = formtocheck.cleaned_data["start"]
absence.end = formtocheck.cleaned_data["end"]
absence.startday_info = str(formtocheck.cleaned_data["startday_info"])
absence.endday_info = str(formtocheck.cleaned_data["endday_info"])
absence.reason = formtocheck.cleaned_data["reason"]
rep = None
if(formtocheck.cleaned_data["representator"] != None):
rep = User.objects.get(pk=formtocheck.cleaned_data["representator"].pk)
absence.representator = rep
absence.info = formtocheck.cleaned_data["info"]
absence.holidays_normal = 0.0
absence.holidays_rest = 0.0
absence.holidays_normal_next = 0.0
absence.holidays_rest_next = 0.0
absence.save()
messages.success(request, f'Abwesenheit aktualisiert!')
else:
messages.success(request, f'Fehler bei Abwesenheitsaktualisierung!')
context = {
"active_link" : "abscence",
}
return redirect("tma-management")
@login_required
def AbsenceManagmenet(request, activemonth=False, activeyear=False):
@ -530,7 +614,7 @@ def TimeAjax(request):
days_nextyear_normal = temprest * -1
# POrüfen, ob es in diesem Zeitraum noch andere Abwesenheiten gibt
other_absences = Absence.objects.filter(start__lte=start_day_obj, end__gte=end_day_obj, agency=request.user.profile.agency)
other_absences = Absence.objects.filter(start__lte=start_day_obj, end__gte=end_day_obj, agency=request.user.profile.agency).exclude(user=user)
other_absences_string = False
if (len(other_absences) > 0):