Zeiterfassung weiter gebaut, rdy fuer hochladen damit die Berechnung wieder passt

This commit is contained in:
holger.trampe 2021-01-18 11:23:40 +01:00
parent 886d1ff0d7
commit 57358fd8a2
15 changed files with 314 additions and 195 deletions

View File

@ -465,6 +465,7 @@ class AbsenceReasonForm(forms.ModelForm):
"name" : "Bezeichnung", "name" : "Bezeichnung",
"need_confirm" : "Muss bestätigt werden", "need_confirm" : "Muss bestätigt werden",
"need_rep" : "Muss vertreten werden", "need_rep" : "Muss vertreten werden",
"is_holiday" : "Geht vom Urlaub ab" "is_holiday" : "Geht vom Urlaub ab",
"is_time" : "Geht vom Gleitzeitkonto ab"
} }
fields = ["name", "need_confirm", "need_rep", "is_holiday", "rgb_color"] fields = ["name", "need_confirm", "need_rep", "is_holiday", "is_time", "rgb_color"]

View File

@ -9,6 +9,7 @@
<th scope="col">Bezeichnung</th> <th scope="col">Bezeichnung</th>
<th scope="col">Bestätigung</th> <th scope="col">Bestätigung</th>
<th scope="col">Vertretung</th> <th scope="col">Vertretung</th>
<th scope="col">Gleitzeit</th>
<th scope="col">Urlaubstag</th> <th scope="col">Urlaubstag</th>
<th scope="col">Farbe</th> <th scope="col">Farbe</th>
<th scope="col">&nbsp;</th> <th scope="col">&nbsp;</th>
@ -20,6 +21,7 @@
<td><b>{{ab.name}}</b></td> <td><b>{{ab.name}}</b></td>
<td>{% if ab.need_confirm %} <i class="fas fa-check"></i> {% else %} {% endif %}</td> <td>{% if ab.need_confirm %} <i class="fas fa-check"></i> {% else %} {% endif %}</td>
<td>{% if ab.need_rep %} <i class="fas fa-check"></i> {% else %} {% endif %}</td> <td>{% if ab.need_rep %} <i class="fas fa-check"></i> {% else %} {% endif %}</td>
<td>{% if ab.is_time %} <i class="fas fa-check"></i> {% endif %}</td>
<td>{% if ab.is_holiday %} <i class="fas fa-check"></i> {% endif %}</td> <td>{% if ab.is_holiday %} <i class="fas fa-check"></i> {% endif %}</td>
<td><i style="color: {{ab.color}}" class="fas fa-square-full"></i></td> <td><i style="color: {{ab.color}}" class="fas fa-square-full"></i></td>
<td> <td>

View File

@ -223,7 +223,7 @@
</div> </div>
<h5 class="mt-2 mb-1">Urlaub Jahresübersicht&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Hier sehen Sie die aktuelle Jahresübersicht des Mitarbeiters. Beachten Sie das Format beim manuellen anpassen: XX,0 oder XX,5!" class="far fa-question-circle"></i></small> <h5 class="mt-2 mb-1">Urlaub Jahresübersicht&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Hier sehen Sie die aktuelle Jahresübersicht des Mitarbeiters. Beachten Sie das Format beim manuellen anpassen: XX,0 oder XX,5!" class="far fa-question-circle"></i></small>
<button type="button" id="changeHolidayData" style="float: right" class="btn btn-secondary btn-sm" onclick="javascript:loadUpdateTableHolidays()" data-toggle="tooltip" data-placement="top" title="Passen Sie die Urlaubstage und Resturlaubstage manuell an."><small><i class="fas fa-pen"></i></small></button> <button type="button" id="changeHolidayData" style="float: right" class="btn btn-secondary btn-sm" onclick="javascript:loadUpdateTableHolidays()" data-toggle="tooltip" data-placement="top" title="Passen Sie die Urlaubstage und Resturlaubstage manuell an."><small><i class="fas fa-pen"></i></small></button>
<button type="button" id="changeHolidayDataSave" style="float: right; display: none" class="btn btn-primary btn-sm" onclick="javascript:saveUpdateTableHolidays()" data-toggle="tooltip" data-placement="top" title="Urlaub- und Resttage speichern."><small><i class="fas fa-check"></i></small></button> <button type="button" id="changeHolidayDataSave" style="float: right; display: none" class="btn btn-primary btn-sm" onclick="javascript:saveUpdateTableHolidays()" data-toggle="tooltip" data-placement="top" title="Urlaub- und Resttage speichern."><small>Speichern</small></button>
</h5> </h5>
<div id="year_overview"> <div id="year_overview">
<table class="table table-hover"> <table class="table table-hover">
@ -339,7 +339,6 @@
</div> </div>
</div> </div>
</div> </div>
<div class="modal fade " id="resetTimeManagementMessage" data-backdrop="static" data-keyboard="false"> <div class="modal fade " id="resetTimeManagementMessage" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-xl"> <div class="modal-dialog modal-xl">
<div class="modal-content"> <div class="modal-content">
@ -355,7 +354,6 @@
</div> </div>
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
function toggleDoDelBtn(){ function toggleDoDelBtn(){
if($('#confirmDel').prop('checked')){ if($('#confirmDel').prop('checked')){
@ -386,7 +384,22 @@
</script> </script>
<!-- Modal -->
<div class="modal" id="calculatingAbsences" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Aktualisieren der Urlaubstage</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
Urlaubstage werden neu berechnet. Bitte warten und nicht das Fenster aktualisieren!
</div>
</div>
</div>
</div>
<script> <script>
/* /*
@ -427,8 +440,13 @@ function saveUpdateTableHolidays(){
new_data_info : new_data_arr, new_data_info : new_data_arr,
userid: {{vieweduser}} userid: {{vieweduser}}
}, },
beforeSend: function(){
$("#calculatingAbsences").modal("show");
},
success: function( data ) success: function( data )
{ {
$("#calculatingAbsences").modal("hide");
$("#year_overview").html(data); $("#year_overview").html(data);
$("#changeHolidayDataSave").hide(); $("#changeHolidayDataSave").hide();
$("#changeHolidayData").show(); $("#changeHolidayData").show();

View File

@ -22,7 +22,7 @@ import webcolors
import datetime import datetime
from datetime import date from datetime import date
from standards.models import Standards from standards.models import Standards
from timemanagement.models import AbsenceReason, FreeDays, Workday from timemanagement.models import AbsenceReason, FreeDays, Workday, Absence
from django.core.mail import send_mail from django.core.mail import send_mail
from django.conf import settings from django.conf import settings
import re, os, csv, requests import re, os, csv, requests
@ -35,7 +35,7 @@ import re
import json import json
from django.conf import settings # import the settings file from django.conf import settings # import the settings file
from PIL import Image from PIL import Image
from datetime import date, timedelta
''' MAIL ''' ''' MAIL '''
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
from django.core.mail import EmailMultiAlternatives from django.core.mail import EmailMultiAlternatives
@ -997,6 +997,14 @@ def SettingsAjaxRouter(request):
context = { context = {
"user_years" : UserYearAbsenceInfo.objects.filter(user=User.objects.get(pk=request.GET["userid"])), "user_years" : UserYearAbsenceInfo.objects.filter(user=User.objects.get(pk=request.GET["userid"])),
} }
user_to_recalculate = User.objects.get(pk=request.GET["userid"])
absences = Absence.objects.filter(user=user_to_recalculate)
for ab in absences:
getFinalHolidayData(ab)
return render(request, 'dasettings/data_absence_yeardata.html', context) return render(request, 'dasettings/data_absence_yeardata.html', context)
# RESET TIMEMANAGEMENT # RESET TIMEMANAGEMENT
elif request.method == "GET" and request.GET['action'] == "del_tmdata" : elif request.method == "GET" and request.GET['action'] == "del_tmdata" :
@ -1030,6 +1038,171 @@ def SettingsAjaxRouter(request):
success = False success = False
return JsonResponse({"success" : success, "data" : data}) return JsonResponse({"success" : success, "data" : data})
''' BERECHNUNG URLAUBSTAGE USW. '''
''' AB HIER WIEDER RAUSNEHMEN '''
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
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]
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
holiday_nextyear_rest = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency,
year=choosenyear+1))[0].restdays
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:
two_years = True
holiday_lastyear = yeardata.restdays
date_splitter = datetime.date(end_day_obj.year, 1, 1)
need_days_this = (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
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 = []
freedaycounter = 0
for dt in daterange(start, end):
day_found = False
if dt.isoweekday() not in weekdays:
counter += 1
for freeday in allfreedays.all():
if(dt == freeday.day):
freedaycounter += 1
day_found = True
if day_found == False:
if(dt.isoweekday() == 1):
if user.usertime.wd_mo == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 2):
if user.usertime.wd_tu == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 3):
if user.usertime.wd_we == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 4):
if user.usertime.wd_th == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 5):
if user.usertime.wd_fr == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 6):
if user.usertime.wd_sa == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 7):
if user.usertime.wd_so == 0.0:
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)
''' BERECHNUNG URLAUBSTAGE USW ENDE '''
def randomStringNum(stringLength=20): def randomStringNum(stringLength=20):
"""Generate a random string of fixed length """ """Generate a random string of fixed length """
lettersAndNumbers = string.ascii_lowercase + string.digits + string.ascii_uppercase lettersAndNumbers = string.ascii_lowercase + string.digits + string.ascii_uppercase
@ -1281,7 +1454,7 @@ def NewUserFirstStep(request):
newuserform = UserNewUserForm(request.POST) newuserform = UserNewUserForm(request.POST)
if newuserform.is_valid(): if newuserform.is_valid():
if(request.POST.get("sendmailnewuser")): if(request.POST.get("sendmailnewuser")):
msg_html = render_to_string('users/register_mail.html', {'username': newuserform.cleaned_data.get('first_name') + " " + newuserform.cleaned_data.get('last_name')}) msg_html = render_to_string('users/newusers_email.html', {'username': newuserform.cleaned_data.get('first_name') + " " + newuserform.cleaned_data.get('last_name')})
send_mail(request.user.profile.agency.name + ' Account', 'Hallo ' + newuserform.cleaned_data.get('first_name') + ' ' + newuserform.cleaned_data.get('last_name') + '! Bitte setzen sie sich auf https://app.digitale-agentur.com/password-reset/ ein Passwort.','noreply@digitale-agentur.com',[newuserform.cleaned_data.get('email')],html_message=msg_html,fail_silently=True) send_mail(request.user.profile.agency.name + ' Account', 'Hallo ' + newuserform.cleaned_data.get('first_name') + ' ' + newuserform.cleaned_data.get('last_name') + '! Bitte setzen sie sich auf https://app.digitale-agentur.com/password-reset/ ein Passwort.','noreply@digitale-agentur.com',[newuserform.cleaned_data.get('email')],html_message=msg_html,fail_silently=True)
newuser = newuserform.save(commit=False) newuser = newuserform.save(commit=False)
newuser.username = newuser.email newuser.username = newuser.email

BIN
dump.rdb

Binary file not shown.

View File

@ -264,10 +264,7 @@
$('#area_tabs li:first-child a').tab('show'); $('#area_tabs li:first-child a').tab('show');
} }
$('[data-toggle="popover"]').popover(); $('[data-toggle="popover"]').popover();
$('#userownstandards').DataTable({ $('#userownstandards').DataTable({
responsive: true, responsive: true,
columnDefs: [ columnDefs: [

View File

@ -341,6 +341,29 @@ def getactualworkingday(user):
returnstat = list(wd)[0].start returnstat = list(wd)[0].start
return returnstat return returnstat
# Berechnet die gesamte Arbeitszeit im Monat und gibt diese zurück
@register.simple_tag
def loadmonthwork(nextmonth, user):
nextmonth = int(nextmonth)
month = nextmonth - 1
if month == 0:
month = 12
workdays = Workday.objects.filter(user=user, agency=user.profile.agency, start__month=month)
finalsum = 0
for ele in workdays.all():
if ele.end != None:
print(ele)
finalsum += (ele.end - ele.start).seconds
mon, sec = divmod(finalsum, 60)
hr, mon = divmod(mon, 60)
#return ("%d Stunden und %02d:%02d" % (hr, mon, sec))
return ("%d:%02d" % (hr, mon))
# Return formatted Time-String # Return formatted Time-String
@register.simple_tag @register.simple_tag
def getformatedstarttime(user): def getformatedstarttime(user):

View File

@ -32,6 +32,7 @@ class AbsenceReason(models.Model):
need_confirm = models.BooleanField(default=True) need_confirm = models.BooleanField(default=True)
need_rep = models.BooleanField(default=True) need_rep = models.BooleanField(default=True)
is_holiday = models.BooleanField(default=True) is_holiday = models.BooleanField(default=True)
is_time = models.BooleanField(default=False)
color = RGBColorField(colors=['#FFB900', '#E74856', '#0078D7', '#0099BC', '#7A7574'], default='#0099BC', blank=True) color = RGBColorField(colors=['#FFB900', '#E74856', '#0078D7', '#0099BC', '#7A7574'], default='#0099BC', blank=True)
def __str__(self): def __str__(self):

View File

@ -1,9 +1,27 @@
{% load counter_tag %} {% load counter_tag %}
<div class="btn-group" role="group" aria-label="" style="min-width: 100% !important"> <div class="btn-group" role="group" aria-label="" style="min-width: 100% !important">
<a type="button" class="btn btn-primary mr-1" href="{% url 'tm-management' prev_month prev_year %}" ><i class="fas fa-arrow-circle-left"></i></a> <a type="button" class="btn btn-primary mr-1" href="{% url 'tm-management' prev_month prev_year %}" ><i class="fas fa-arrow-circle-left"></i></a>
<button type="button" class="btn btn-primary mr-1" style="min-width: 150px !important;" onclick="javascript:fastChangeModal()">{{active_month}} {{active_year}}</button> <button type="button" class="btn btn-primary mr-1" style="min-width: 150px !important;" onclick="javascript:fastChangeModal()">{{active_month}} {{active_year}}</button>
<a type="button" class="btn btn-primary mr-1" href="{% url 'tm-management' next_month next_year %}"><i class="fas fa-arrow-circle-right"></i></a> <a type="button" class="btn btn-primary mr-1" href="{% url 'tm-management' next_month next_year %}"><i class="fas fa-arrow-circle-right"></i></a>
<span style="float: right !important; text-align: right; min-width: 82%; margin-bottom: -20px; margin-top: -10px; ">
{% loadmonthwork next_month user as monthwork %}
Arbeitszeit im Monat: {{monthwork}}<br />
{% loadaccounttime user as actualaccounttime %}
Gleitzeitkonto:
{% if actualaccounttime.1 == 0 %}
<b><span style="color: green">+{{actualaccounttime.0}}&nbsp;Stunden</span></b>
{% else %}
<b><span style="color: red">-{{actualaccounttime.0}}&nbsp;Stunden</span></b>
{% endif %}
</span>
</div> </div>
<hr> <hr>
<div class="table-responsive "> <div class="table-responsive ">
<table class="table table-hover" id="table_timemanagement" > <table class="table table-hover" id="table_timemanagement" >
@ -17,6 +35,7 @@
<th scope="col">Pausen</th> <th scope="col">Pausen</th>
<th scope="col">Arbeitszeit</th> <th scope="col">Arbeitszeit</th>
<th scope="col">Gleitzeit</th> <th scope="col">Gleitzeit</th>
<!--<th scope="col">Gleitzeitstand</th>-->
<th scope="col">&nbsp;</th> <th scope="col">&nbsp;</th>
</tr> </tr>
</thead> </thead>
@ -293,6 +312,9 @@
{% endfor %} {% endfor %}
</td> </td>
<!-- <td style="text-align: center;">
</td>-->
<td style="text-align: right;"> <td style="text-align: right;">
{% counterWDreset %} {% counterWDreset %}
@ -330,7 +352,6 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
{% if breakmonthline < da %} {% if breakmonthline < da %}

View File

@ -9,6 +9,22 @@
<a type="button" class="btn btn-primary mr-1" href="{% url 'tm-team-single' user.pk prev_month prev_year %}" ><i class="fas fa-arrow-circle-left"></i></a> <a type="button" class="btn btn-primary mr-1" href="{% url 'tm-team-single' user.pk prev_month prev_year %}" ><i class="fas fa-arrow-circle-left"></i></a>
<button type="button" class="btn btn-primary mr-1" style="min-width: 150px !important;" onclick="javascript:fastChangeModal()">{{active_month}} {{active_year}}</button> <button type="button" class="btn btn-primary mr-1" style="min-width: 150px !important;" onclick="javascript:fastChangeModal()">{{active_month}} {{active_year}}</button>
<a type="button" class="btn btn-primary mr-1" href="{% url 'tm-team-single' user.pk next_month next_year %}"><i class="fas fa-arrow-circle-right"></i></a> <a type="button" class="btn btn-primary mr-1" href="{% url 'tm-team-single' user.pk next_month next_year %}"><i class="fas fa-arrow-circle-right"></i></a>
<span style="float: right !important; text-align: right; min-width: 82%; margin-bottom: -20px; margin-top: -10px; ">
{% loadmonthwork next_month user as monthwork %}
Arbeitszeit im Monat: {{monthwork}}<br />
{% loadaccounttime user as actualaccounttime %}
Gleitzeitkonto:
{% if actualaccounttime.1 == 0 %}
<b><span style="color: green">+{{actualaccounttime.0}}&nbsp;Stunden</span></b>
{% else %}
<b><span style="color: red">-{{actualaccounttime.0}}&nbsp;Stunden</span></b>
{% endif %}
</span>
</div> </div>
<hr> <hr>
<div class="table-responsive "> <div class="table-responsive ">
@ -23,7 +39,6 @@
<th scope="col">Pausen</th> <th scope="col">Pausen</th>
<th scope="col">Arbeitszeit</th> <th scope="col">Arbeitszeit</th>
<th scope="col">Gleitzeit</th> <th scope="col">Gleitzeit</th>
<th scope="col">Manuell geändert</th>
<th scope="col">&nbsp;</th> <th scope="col">&nbsp;</th>
</tr> </tr>
</thead> </thead>
@ -37,6 +52,15 @@
style="background-color: #d3d3d3;" style="background-color: #d3d3d3;"
{% elif abday != False %} {% elif abday != False %}
style="background-color: {{abday.reason.color}}; color: #ffffff" style="background-color: {{abday.reason.color}}; color: #ffffff"
{% else %}
{% for workday in workdays %}
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
{% getWorkDayHistory workday as wd_history %}
{% if wd_history.history_user != None %}
style="background-color: #fdcc98;"
{% endif %}
{% endif %}
{% endfor %}
{% endif %}> {% endif %}>
<td> <td>
{{da|date:"l"}} {{da|date:"l"}}
@ -298,18 +322,6 @@
{% endfor %} {% endfor %}
</td> </td>
<td>
{% for workday in workdays %}
{% if workday.end|date:"d-m-y" == da|date:"d-m-y" %}
{% getWorkDayHistory workday as wd_history %}
{% if wd_history.history_user != None %}
{{wd_history.history_date|date:"d.m.Y, H:i"}} von {{wd_history.history_user.first_name}} {{wd_history.history_user.last_name}}
{% endif %}
{% endif %}
{% endfor %}
</td>
<td style="text-align: right;"> <td style="text-align: right;">
{% counterWDreset %} {% counterWDreset %}
@ -324,6 +336,31 @@
{% counterWDUp %} {% counterWDUp %}
{% getWorkDayHistory workday as wd_history %}
{% if wd_history.history_user != None %}
<a href="#/" onclick="javascript:$('#wd_history_{{workday.pk}}').modal('toggle');"><i class="fas fa-cog"></i></a>
<div class="modal fade" id="wd_history_{{workday.pk}}" tabindex="-1" role="dialog" data-backdrop="static">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Manuelle Änderung vom {{workday.start|date:"d.m.Y"}}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" style="text-align: left;">
<p>Geändert am {{wd_history.history_date|date:"d.m.Y, H:i"}} von {{wd_history.history_user.first_name}} {{wd_history.history_user.last_name}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Schließen</button>
</div>
</div>
</div>
</div>
{% endif %}
{% if workday.freefield != "" %} {% if workday.freefield != "" %}
@ -358,7 +395,7 @@
{% endfor %} {% endfor %}
</td> </td>
{% else %} {% else %}
<td></td><td></td><td></td><td></td><td></td><td style="display: none;"></td><td style="display: none;"></td> <td></td><td></td><td></td><td></td><td style="display: none;"></td><td style="display: none;"></td>
{% endif %} {% endif %}
</tr> </tr>
{% endfor %} {% endfor %}

View File

@ -79,13 +79,14 @@ def checkDefaultAbsenceReasons(sender, user, request, **kwargs):
new_ar_ill = AbsenceReason(agency=user.profile.agency, name="Krankheit", color="#E74C3C", need_confirm=False, need_rep=False, is_holiday=False) new_ar_ill = AbsenceReason(agency=user.profile.agency, name="Krankheit", color="#E74C3C", need_confirm=False, need_rep=False, is_holiday=False)
new_ar_ill.save() new_ar_ill.save()
new_ar_school = AbsenceReason(agency=user.profile.agency, name="Berufsschule", color="#16A085", need_confirm=False, need_rep=False, is_holiday=False) new_ar_school = AbsenceReason(agency=user.profile.agency, name="Berufsschule", color="#16A085", need_confirm=False, need_rep=False, is_holiday=False)
new_ar_school.save() new_ar_school.save()
new_ar_education = AbsenceReason(agency=user.profile.agency, name="Fortbildung", color="#2ECC71", need_confirm=True, need_rep=True, is_holiday=False) new_ar_education = AbsenceReason(agency=user.profile.agency, name="Fortbildung", color="#2ECC71", need_confirm=True, need_rep=True, is_holiday=False)
new_ar_education.save() new_ar_education.save()
new_ar_time = AbsenceReason(agency=user.profile.agency, name="Gleitzeit", color="#9B59B6", need_confirm=True, need_rep=False, is_holiday=False) new_ar_time = AbsenceReason(agency=user.profile.agency, name="Gleitzeit", color="#9B59B6", need_confirm=True, need_rep=False, is_holiday=False, is_time=True)
new_ar_time.save() new_ar_time.save()
today = date.today() today = date.today()

View File

@ -127,7 +127,7 @@
<p> <p>
{% block reset_link %} {% block reset_link %}
<h4><a href="{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}">{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}</a></h4> {% endblock %} <h4><a href="{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}">{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}</a></h4> {% endblock %}
<h4>Ihr Benutzername: {{ user.get_username }}</h4> <h4>Ihre E-Mailadresse: {{ user.email }}</h4>
</p> Sollten Sie kein Passwort angefordert haben, ignorieren Sie diese E-Mail. </p> Sollten Sie kein Passwort angefordert haben, ignorieren Sie diese E-Mail.
<p>Mit freundlichen Grüßen</p> <p>Mit freundlichen Grüßen</p>
<p>Ihr Team von Digitale Agentur</p> <p>Ihr Team von Digitale Agentur</p>

View File

@ -46,7 +46,7 @@ urlpatterns = [
path('icsall/<int:ag>', views.getICSFileAll, name="geticsall"), path('icsall/<int:ag>', views.getICSFileAll, name="geticsall"),
path('icspublic/<slug:code>/<int:ag>', views.getICSFileEx, name="getics"), path('icspublic/<slug:code>/<int:ag>', views.getICSFileEx, name="getics"),
path('icspublicall/<slug:code>/<int:ag>', views.getICSFileExAll, name="geticsall"), path('icspublicall/<slug:code>/<int:ag>', views.getICSFileExAll, name="geticsall"),
path('recalculateabsence/<slug:code>', views.recalculateAbsence, name="recalculateabsence"), #path('recalculateabsence/<slug:code>', views.recalculateAbsence, name="recalculateabsence"),
] ]

View File

@ -1450,16 +1450,19 @@ class landingPage(TemplateView):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
''' '''
Gibt False zurück, wenn der User an diesem Tag KEINE Abwesenheiten hat, ansonsten True! Gibt False zurück, wenn der User an diesem Tag KEINE Abwesenheiten hat, ansonsten True! Zudem wird gecheckt, ob der Tag tatsächlich Urlaub ist.
''' '''
def absencecheck(user, daytocheck): def absencecheck(user, daytocheck):
returnstat = False returnstat = False
absencedays = Absence.objects.filter(agency=user.profile.agency, user=user, confirm_status=0) & (Absence.objects.filter(agency=user.profile.agency, user=user, start=daytocheck) | (Absence.objects.filter(agency=user.profile.agency, user=user, start__lt=daytocheck) & Absence.objects.filter(agency=user.profile.agency, user=user, end__gt=daytocheck)) | Absence.objects.filter(agency=user.profile.agency, user=user, end=daytocheck)) absencedays = Absence.objects.filter(agency=user.profile.agency, user=user, confirm_status=0) & (Absence.objects.filter(agency=user.profile.agency, user=user, start=daytocheck) | (Absence.objects.filter(agency=user.profile.agency, user=user, start__lt=daytocheck) & Absence.objects.filter(agency=user.profile.agency, user=user, end__gt=daytocheck)) | Absence.objects.filter(agency=user.profile.agency, user=user, end=daytocheck))
if(len(absencedays) > 0): if(len(absencedays) > 0):
returnstat = True for ab in absencedays:
if ab.reason.is_time == True:
return returnstat returnstat = False
else:
returnstat = True
return returnstat
@ -1935,161 +1938,3 @@ def sendMailNoti(notificationtext, user_touched, linktarget=""):
def isAlive(request): def isAlive(request):
return JsonResponse({"status" : True}) return JsonResponse({"status" : True})
''' AB HIER WIEDER RAUSNEHMEN '''
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
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]
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
holiday_nextyear_rest = list(UserYearAbsenceInfo.objects.filter(user=user, agency=user.profile.agency,
year=choosenyear+1))[0].restdays
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:
two_years = True
holiday_lastyear = yeardata.restdays
date_splitter = datetime.date(end_day_obj.year, 1, 1)
need_days_this = (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
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 = []
freedaycounter = 0
for dt in daterange(start, end):
day_found = False
if dt.isoweekday() not in weekdays:
counter += 1
for freeday in allfreedays.all():
if(dt == freeday.day):
freedaycounter += 1
day_found = True
if day_found == False:
if(dt.isoweekday() == 1):
if user.usertime.wd_mo == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 2):
if user.usertime.wd_tu == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 3):
if user.usertime.wd_we == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 4):
if user.usertime.wd_th == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 5):
if user.usertime.wd_fr == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 6):
if user.usertime.wd_sa == 0.0:
freedaycounter += 1
elif(dt.isoweekday() == 7):
if user.usertime.wd_so == 0.0:
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)