Abwesenheit usw.

This commit is contained in:
holger.trampe 2021-02-25 17:10:25 +01:00
parent 7c49e9cdb5
commit 2059671f3c
18 changed files with 434 additions and 22 deletions

View File

@ -1,6 +1,8 @@
from django import forms from django import forms
from django.forms import ModelForm from django.forms import ModelForm
from users.models import AgencyBills from users.models import AgencyBills
from timemanagement.models import Absence, AbsenceReason, FreeDays, Workday, Breaks
from bootstrap_datepicker_plus import DatePickerInput
class AgencyBillForm(forms.ModelForm): class AgencyBillForm(forms.ModelForm):
@ -11,3 +13,45 @@ class AgencyBillForm(forms.ModelForm):
'agency' : "Agentur", 'agency' : "Agentur",
'start' : "Leistungszeitraum Start", 'start' : "Leistungszeitraum Start",
} }
class AdmWorkdayForm(forms.ModelForm):
class Meta:
model = Workday
labels = {
"start" : "Start",
"end" : "Ende",
"target" : "Zielarbeitszeit",
"freefield" : "Notiz"
}
fields = [
"start", "end", "target", "freefield"
]
widgets = {
'start': DatePickerInput(options={"format":'DD.MM.YYYY HH:mm', "locale":'de'}),
'end': DatePickerInput(options={"format":'DD.MM.YYYY HH:mm', "locale":'de'}),
}
# ADD BREAK FORM
class AdmBreakAddForm(forms.ModelForm):
class Meta:
model = Breaks
labels = {
"start" : "Start",
"end" : "Ende"
}
fields = [
"start", "end"
]
widgets = {
'start': DatePickerInput(options={"format":'DD.MM.YYYY HH:mm', "locale":'de'}),
'end': DatePickerInput(options={"format":'DD.MM.YYYY HH:mm', "locale":'de'}),
}
def __init__(self, *arg, **kwargs):
super(AdmBreakAddForm, self).__init__(*arg, **kwargs)
self.fields['start'].required = True
self.fields['end'].required = True

View File

@ -0,0 +1,22 @@
{% extends "adm/adm_base.html" %}
{% block content %}
{% load crispy_forms_tags %}
{% if request.user.profile.agency.module_timemanagement %}
<div class="content-section col-7">
<h3>Zum Arbeitstag am {{workday.start|date:"d.m.Y"}} Pause hinzufügen</h3>
<hr>
<div class="col-6" style="margin-left: -10px;">
<form method="POST" class="">
{% csrf_token %}
{{form.media}}
{{form}}
<hr>
<a class="btn" href="{% url 'adm-workday-update' workday.pk %}">Abbrechen</a>
<button type="submit" class="btn btn-primary">Pause hinzufügen</button>
</form>
</div>
{% endif %}
{% endblock content %}

View File

@ -0,0 +1,13 @@
{% extends "adm/adm_base.html" %}
{% block content %}
{% load crispy_forms_tags %}
<div class="content-section col-12">
<h4>Pause des Arbeitstags von {{object.user.get_full_name}} am {{object.workday.start|date:"d.m.Y"}} löschen?</h4>
<hr>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p>Achtung! Das Löschen kann nicht rückgängig gemacht werden. Die Pause von {{object.start|date:"H:i"}} bis {{object.end|date:"H:i"}} wird entfernt!</p>
<a class="btn btn-secondary" href="{% url 'adm-workday-update' object.workday.pk %}" name="action">Abbrechen</a>
<button style="float: right" class="btn btn-primary" type="submit" name="action">Pause löschen</button>
</form>
{% endblock content %}

View File

@ -144,22 +144,26 @@
<div class="tab-pane fade" id="nav-contract" role="tabpanel" aria-labelledby="nav-contract-tab"> <div class="tab-pane fade" id="nav-contract" role="tabpanel" aria-labelledby="nav-contract-tab">
<br /> <br />
<h5>Arbeitstage</h5> <h5>Arbeitstage</h5>
<a class="btn btn-sm btn-primary" href="{% url 'adm-workday-add' userdata.pk %}">+ Arbeitstag</a><br />
<br />
<table class="table table-hover" id="user_workdays" > <table class="table table-hover" id="user_workdays" >
<thead> <thead>
<tr> <tr>
<th scope="col"></th> <th scope="col">ID</th>
<th scope="col">Start</th> <th scope="col">Start</th>
<th scope="col">Ende</th> <th scope="col">Ende</th>
<th scope="col">Ziel</th> <th scope="col">Ziel</th>
<th scope="col"></th>
</tr> </tr>
</thead> </thead>
<tbody > <tbody >
{% for wd in workdays %} {% for wd in workdays %}
<tr> <tr>
<td>{{forloop.counter}}</td> <td>{{wd.pk}}</td>
<td>{{wd.start|date:"d.m.Y H:i"}}</td> <td>{{wd.start|date:"d.m.Y H:i"}}</td>
<td>{{wd.end|date:"d.m.Y H:i"}}</td> <td>{{wd.end|date:"d.m.Y H:i"}}</td>
<td>{{wd.target}}</td> <td>{{wd.target}}</td>
<td><a class="btn btn-secondary btn-sm " href="{% url 'adm-workday-update' wd.pk %}"><i class="fas fa-pen"></i></a>&nbsp;<a class="btn btn-sm " href="{% url 'adm-workday-delete' wd.pk %}"><i class="fas fa-trash"></i></a></td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -203,7 +207,7 @@
<table class="table table-hover" id="user_absences" > <table class="table table-hover" id="user_absences" >
<thead> <thead>
<tr> <tr>
<th scope="col"></th> <th scope="col">ID</th>
<th scope="col">Art</th> <th scope="col">Art</th>
<th scope="col">Start</th> <th scope="col">Start</th>
<th scope="col">Ende</th> <th scope="col">Ende</th>
@ -220,7 +224,7 @@
<tbody > <tbody >
{% for ab in absences %} {% for ab in absences %}
<tr> <tr>
<td>{{forloop.counter}}</td> <td>{{ab.pk}}</td>
<td>{{ab.reason.name}}</td> <td>{{ab.reason.name}}</td>
<td>{{ab.start|date:"d.m.Y"}}</td> <td>{{ab.start|date:"d.m.Y"}}</td>
<td>{{ab.end|date:"d.m.Y"}}</td> <td>{{ab.end|date:"d.m.Y"}}</td>

View File

@ -0,0 +1,23 @@
{% extends "adm/adm_base.html" %}
{% block content %}
{% load crispy_forms_tags %}
{% if request.user.profile.agency.module_timemanagement %}
<div class="content-section col-7">
<h3>Arbeitstag für {{user.get_full_name}} erstellen</h3>
<hr>
<div class="col-6" style="margin-left: -10px;">
<form method="POST" class="">
{% csrf_token %}
{{form.media}}
{{form|crispy}}
<hr>
<a class="btn" href="{% url 'adm-user-single' user.pk %}">Abbrechen</a>
<button type="submit" class="btn btn-primary">Arbeitstag speichern</button>
</form>
</div>
{% endif %}
{% endblock content %}

View File

@ -0,0 +1,13 @@
{% extends "adm/adm_base.html" %}
{% block content %}
{% load crispy_forms_tags %}
<div class="content-section col-12">
<h4>Arbeitstag von {{object.user.get_full_name}} am {{object.start|date:"d.m.Y"}} löschen?</h4>
<hr>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p>Achtung! Das Löschen kann nicht rückgängig gemacht werden. Der komplette Arbeitstag wird entfernt!</p>
<a class="btn btn-secondary" href="{% url 'adm-user-single' object.user.pk %}" name="action">Abbrechen</a>
<button style="float: right" class="btn btn-primary" type="submit" name="action">Arbeitstag löschen</button>
</form>
{% endblock content %}

View File

@ -0,0 +1,67 @@
{% extends "adm/adm_base.html" %}
{% block content %}
{% load crispy_forms_tags %}
<div class="content-section col-12">
<h4>Arbeitstag von {{object.user.get_full_name}} am {{object.start|date:"d.m.Y"}} aktualisieren</h4>
<hr>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form.media}}
{{form|crispy}}
<hr>
<h5>Pausen</h5>
<a class="btn btn-sm btn-primary" href="{% url 'adm-break-add' object.pk %}">+ Pause</a><br /><br />
{% if object.breaks.all|length > 0 %}
<table class="table table-hover" id="user_breaks" >
<thead>
<tr>
<th scope="col"></th>
<th scope="col">Start</th>
<th scope="col">Ende</th>
<th scope="col"></th>
</tr>
</thead>
<tbody >
{% for break in object.breaks.all %}
<tr>
<td>{{forloop.counter}}</td>
<td>{{break.start|date:"H:i"}}</td>
<td>{{break.end|date:"H:i"}}</td>
<td><a class="btn btn-secondary btn-sm " href="{% url 'adm-break-delete' break.pk %}"><i class="fas fa-trash"></i></a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>Arbeitstag hat keine Pausen</p>
{% endif %}
<a class="btn btn-secondary" href="{% url 'adm-user-single' object.user.pk %}" name="action">Abbrechen</a>
<button style="float: right" class="btn btn-primary" type="submit" name="action">Speichern</button>
</form>
<script type="text/javascript">
$(document).ready(function(){
$('#user_breaks').DataTable({
"language": {
"search" : "Suche",
"info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
"lengthMenu": "Zeige _MENU_ Einträge",
"zeroRecords": "Nichts gefunden",
"infoEmpty": "Keine Einträge",
"paginate": {
"first": "Erste",
"last": "Letzte",
"next": "Nächste",
"previous": "Zurück"
},
},
"pageLength": 10,
"buttons" : {
"className" : "btn-danger"
}
});
})
</script>
{% endblock content %}

View File

@ -17,5 +17,11 @@ urlpatterns = [
path('usersingle/<int:uspk>', AdmUserSingle.as_view(), name="adm-user-single"), path('usersingle/<int:uspk>', AdmUserSingle.as_view(), name="adm-user-single"),
path('cron/<slug:code>', statisticCronJob, name="adm-cron"), path('cron/<slug:code>', statisticCronJob, name="adm-cron"),
path('getorders/', getCSVRDOrders, name="getorders"), path('getorders/', getCSVRDOrders, name="getorders"),
path('adm/addbill', AdmAddBill.as_view(), name="admbill-add") path('adm/addbill', AdmAddBill.as_view(), name="admbill-add"),
path('wd/<int:pk>/update', AdmWorkdayUpdate.as_view(), name="adm-workday-update"),
path('wd/add/<int:uspk>', AdmWorkdayAdd.as_view(), name="adm-workday-add"),
path('wd/<int:pk>/delete', AdmWorkdayDelete.as_view(), name="adm-workday-delete"),
path('wd/break/<int:pk>/delete', AdmBreakDelete.as_view(), name="adm-break-delete"),
path('wd/<int:pk>/break/add', AdmAddBreak.as_view(), name="adm-break-add"),
] ]

View File

@ -13,9 +13,9 @@ import csv, os
from auditlog.models import LogEntry from auditlog.models import LogEntry
import json import json
from users.models import UserYearAbsenceInfo, UserTime from users.models import UserYearAbsenceInfo, UserTime
from timemanagement.models import Workday, Absence from timemanagement.models import Workday, Absence, Breaks
from recoverdir.models import * from recoverdir.models import *
from .forms import AgencyBillForm from .forms import AgencyBillForm, AdmWorkdayForm, AdmBreakAddForm
from datetime import date, timedelta, datetime from datetime import date, timedelta, datetime
from organizer.models import QuickLinks, AGContacts, AGPassword from organizer.models import QuickLinks, AGContacts, AGPassword
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
@ -547,8 +547,6 @@ def getLexOfficeBill(billid):
return returnvalue return returnvalue
def convert_size(size_bytes): def convert_size(size_bytes):
if size_bytes == 0: if size_bytes == 0:
return "0B" return "0B"
@ -561,10 +559,98 @@ def convert_size(size_bytes):
''' WORKDAY VIEWS
Hier sind alle Views für Arbeitstage und Pausen (Create, Update, Delete)
'''
class AdmWorkdayAdd(CreateView):
model = Workday
template_name = "adm/adm_workday_add.html"
form_class = AdmWorkdayForm
def form_valid(self, form):
wd_user = User.objects.get(pk=self.kwargs['uspk'])
wd = Workday(user=wd_user, agency=wd_user.profile.agency, start=form.cleaned_data['start'], end=form.cleaned_data['end'], target=form.cleaned_data["target"], freefield=form.cleaned_data["freefield"])
wd.save()
return HttpResponseRedirect(self.get_success_url())
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'adm-users'})
context.update({'user' : User.objects.get(pk=self.kwargs['uspk'])})
return context
def get_success_url(self):
return reverse('adm-user-single', kwargs={'uspk': self.kwargs['uspk']})
class AdmWorkdayUpdate(UpdateView):
model = Workday
form_class = AdmWorkdayForm
template_name = "adm/adm_workday_update.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'adm-users'})
return context
def get_success_url(self):
return reverse('adm-user-single', kwargs={'uspk': self.get_object().user.pk})
class AdmWorkdayDelete(DeleteView):
model = Workday
template_name = "adm/adm_workday_delete.html"
def get_success_url(self):
return reverse('adm-user-single', kwargs={'uspk': self.get_object().user.pk})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'adm-users'})
return context
class AdmBreakDelete(DeleteView):
model = Breaks
template_name = "adm/adm_break_delete.html"
def get_success_url(self):
return reverse('adm-workday-update', kwargs={'pk': self.get_object().workday.pk})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'adm-users'})
return context
class AdmAddBreak(CreateView):
model = Breaks
template_name = "adm/adm_break_add.html"
form_class = AdmBreakAddForm
def form_valid(self, form):
wd = Workday.objects.get(pk=self.kwargs['pk'])
b = Breaks(user=wd.user, agency=wd.user.profile.agency, workday=wd, start=form.cleaned_data["start"], end=form.cleaned_data["end"])
b.save()
wd.breaks.add(b)
wd.save()
return HttpResponseRedirect(self.get_success_url())
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'adm-users'})
context.update({'workday' : Workday.objects.get(pk=self.kwargs['pk'])})
return context
def get_success_url(self):
return reverse('adm-workday-update', kwargs={'pk': self.kwargs['pk']})

View File

@ -0,0 +1,41 @@
from datetime import timedelta
'''
Hier sind alle Methoden gesammelt, die bei der Zeiterfassung eine Rolle spielen.
daterange()
- Gibt jeden Tag zwischen zwei Daten zurück
@param:
date1 - Startdatum
date2 - Enddatum
@return:
Array mit den entsprechenden Tagen
getIsAbsenceStartEndHalf()
- Gibt True zurücke, wenn der Anfang oder das Ende einer Abwesenheit nur ein halber Tag ist, ansonsten False
@param:
absence - Die zu prüfende Abwesenheit
@return:
True -> Ist nur ein halber Tag
False -> Ist ein ganzer Tag
'''
# Gibt die Woche als Wochentage zurück
def daterange(date1, date2):
for n in range(int ((date2 - date1).days)+1):
yield date1 + timedelta(n)
# Gibt True zurück, wenn eine Tag einer Abwesenheit nur ein halber Tag ist
def getIsAbsenceStartEndHalf(absence):
if absence.startday_info == "1" or absence.startday_info == "2" or absence.endday_info == "1" or absence.endday_info == "2":
return True
else:
return False

78
digitaleagentur/utils.py Normal file
View File

@ -0,0 +1,78 @@
from timemanagement.models import *
from digitaleagentur.timemanagement_utils import *
'''
Hier sind Funktion implementiert, die in verschiedenen Module benötigt werden
getAbsenceForOneDay - Gibt Abwesenheit eines Users für einen Tag zurück
'''
# getAbsenceForOneDay
'''
Gibt eine Abwesenheit für einen übergebenen Tag zurück oder False, wenn keine Abwesenheit vorliegt.
@param:
- user (der entsprechende Nutzer)
- day (Tag, welcher auf Abwesenheiten geprüft werden soll)
'''
def getAbsenceForOneDay(user, day):
absencedays = Absence.objects.filter(agency=user.profile.agency, user=user, confirm_status=0) & (Absence.objects.filter(agency=user.profile.agency, user=user, start=day) | (Absence.objects.filter(agency=user.profile.agency, user=user, start__lt=day) & Absence.objects.filter(agency=user.profile.agency, user=user, end__gt=day)) | Absence.objects.filter(agency=user.profile.agency, user=user, end=day))
# Gibt es eine Abwesenheit an diesem Tag, welche einen halben Tag ist, dann gibt die Methode True zurück und bricht die Schleife ab!
for ab in absencedays:
if ab.startday_info == "1" or ab.startday_info == "2" or ab.endday_info == "1" or ab.endday_info == "2":
return True
# Es gibt an diesem Tag keine Abwesenheit mit einem halben Tag
return False
'''
# checkAbsenceWorkdayCollide()
Prüft, ob eine aktualisierte Abwesenheit Einfluss auf bereits bestehende Arbeitstage hat. Wenn zB nachträglich Arbeitstage eingetragen werden, dann würden diese hier angepasst werden.
Folgende Fälle werden berücksichtigt:
- Halber Tag der Abwesenheit verringert die Zielarbeitszeit dieses Tags auf die Hälfte
- Abwesenheit ist der komplette Tag, dann wird dieser Arbeitstag gelöscht, wenn es is_time false ist, sprich die Zeiterfassung soll nicht angefasst werden
- Abwesenheit ist kompletter Tag und die Abwesenheit soll Zeiterfassung beeinflussen (z.B. Gleitzeit) dann wird der Arbeitstag nicht verändert. Ist die Gleitzeit ein halber Tag, wird die Zielarbeitszeit halbiert.
'''
def checkAbsenceWorkdayCollide(absence):
# Alle einzelnen Tage der Abwesenheit werden durchgegangen:
for day in daterange(absence.start, absence.end):
# Arbeitstage an diesem Tag werden geladen
workdays = Workday.objects.filter(user=absence.user, start__day=absence.start.day, start__month=absence.start.month, start__year=absence.start.year)
# Wenn es Arbeitstage gibt, dann wird geprüft, ob die Abwesenheit diesen verändert hat.
for workday in workdays:
# Arbeitstag in Tag ohne Zeit umwandeln
# Wenn die Abwesenheit die Zeiterfassung NICHT ändert, muss diese ggf. geändert werden. Ansonsten bleibt sie gleich.
if absence.reason.is_time == False:
# Prüfung, ob der Tag halb ist oder nicht. Wenn ja, dann Zielarbeitszeit des Tages um die Hälfte reduzieren.
if (workday.start.day == absence.start.day and workday.start.month == absence.start.month and workday.start.year == absence.start.year) or (workday.end.day == absence.end.day and workday.end.month == absence.end.month and workday.end.year == absence.end.year):
if(getIsAbsenceStartEndHalf(absence)):
workday.target = workday.target / 2
workday.save()
# Ganzer Tag vorhanden, Arbeitstag wird gelöscht
else:
workday.delete()

BIN
dump.rdb

Binary file not shown.

View File

@ -26,8 +26,8 @@ mysqlclient==2.0.1
Pillow==6.2.1 Pillow==6.2.1
pycparser==2.20 pycparser==2.20
python-bidi==0.4.2 python-bidi==0.4.2
python-dateutil==2.6.0
python-magic-bin==0.4.14 python-magic-bin==0.4.14
python-dateutil==2.6.0
pytz==2019.3 pytz==2019.3
requests==2.22.0 requests==2.22.0
requests-oauthlib==1.3.0 requests-oauthlib==1.3.0

View File

@ -45,8 +45,6 @@ class AddAbsence(forms.ModelForm):
self.fields['activeyear'] = 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['userid'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput())
class UpdateAbsence(forms.ModelForm): class UpdateAbsence(forms.ModelForm):
class Meta: class Meta:

View File

@ -35,6 +35,8 @@
</thead> </thead>
<tbody id="table_contacts" > <tbody id="table_contacts" >
{% for da in days_this_month %} {% for da in days_this_month %}
{% getabscenceday request.user request.user da as abday %} {% getabscenceday request.user request.user da as abday %}
<tr id="da_{{da|date:"d-m-y"}}" <tr id="da_{{da|date:"d-m-y"}}"
{% if da.weekday == 5 or da.weekday == 6 %} {% if da.weekday == 5 or da.weekday == 6 %}

View File

@ -21,6 +21,8 @@ from users.signals import save_newabsence
import locale import locale
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.core.mail import send_mail from django.core.mail import send_mail
from digitaleagentur.utils import *
# Load freedays # Load freedays
def loadingFreeDays(plz): def loadingFreeDays(plz):
@ -589,6 +591,11 @@ def TimeAjax(request):
elif(today.isoweekday() == 7): elif(today.isoweekday() == 7):
targettime = request.user.usertime.wd_so targettime = request.user.usertime.wd_so
# Liegt eine halbe Abwesenheit vor, wird hier die Zielarbeitszeit halbiert
if(getAbsenceForOneDay(request.user, today) != False):
targettime = targettime / 2
wd = Workday(user=request.user, agency=request.user.profile.agency, start=timezone.now(), target=targettime) wd = Workday(user=request.user, agency=request.user.profile.agency, start=timezone.now(), target=targettime)
wd.save() wd.save()

View File

@ -33,6 +33,8 @@ from channels_presence.signals import presence_changed
from organizer.models import * from organizer.models import *
from chat.models import ChatMessage from chat.models import ChatMessage
from digitaleagentur.utils import *
def loadingFreeDays(plz, year): def loadingFreeDays(plz, year):
# Getting land # Getting land
file_path = os.path.join(settings.STATIC_ROOT, 'users/extra/plz_short.csv') file_path = os.path.join(settings.STATIC_ROOT, 'users/extra/plz_short.csv')
@ -641,6 +643,8 @@ def save_newabsence(sender, instance, **kwargs):
instance.holidays_rest_next = newdata[3][3] instance.holidays_rest_next = newdata[3][3]
instance.save() instance.save()
checkAbsenceWorkdayCollide(instance)
# NEUE ABWESENHEIT ERSTELLT # NEUE ABWESENHEIT ERSTELLT
if(kwargs["created"]): if(kwargs["created"]):
@ -710,8 +714,8 @@ def save_newabsence(sender, instance, **kwargs):
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Sie wurden als Vertreter für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"}) async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Sie wurden als Vertreter für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"})
else: else:
print("Absence-Object is no holiday...") # Kein Urlaubsanspruch, dennoch prüfen ob bereits bestehende Arbeitstage involviert sind
checkAbsenceWorkdayCollide(instance)
post_save.connect(save_newabsence, sender=sender) post_save.connect(save_newabsence, sender=sender)
# Neue Chatnachricht wurde verschickt - Hier Reaktion NUR auf PUSH! # Neue Chatnachricht wurde verschickt - Hier Reaktion NUR auf PUSH!

View File

@ -48,7 +48,7 @@ from django.db.models.signals import m2m_changed
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from users.signals import adjust_group_notifications_permission from users.signals import adjust_group_notifications_permission
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from digitaleagentur.utils import *
from organizer.models import QuickLinks from organizer.models import QuickLinks
from areas.models import Areas from areas.models import Areas
from tasks.models import Tasks from tasks.models import Tasks
@ -1637,8 +1637,13 @@ def cronactionsdaily(request, code):
if(weekday == 6): if(weekday == 6):
targettworktime = user.usertime.wd_so targettworktime = user.usertime.wd_so
day_half_found = False
if(getAbsenceForOneDay(user, yesterday) != False):
targettworktime = targettworktime / 2
day_half_found = True
# Es wird nur ein Arbeitstag erstellt, wenn KEINE Abwesenheiten vorliegen und der Nutzer an diesem Tag arbeiten muss # Es wird nur ein Arbeitstag erstellt, wenn KEINE Abwesenheiten vorliegen und der Nutzer an diesem Tag arbeiten muss
if(workdays_yesterday == 0 and absencecheck(user, yesterday) == False and targettworktime > 0.0 and user.usertime.usetime_start < today): if(workdays_yesterday == 0 and (absencecheck(user, yesterday) == False or day_half_found) and targettworktime > 0.0 and user.usertime.usetime_start < today):
workdaytemp = Workday(user=user, agency=user.profile.agency, start=datetime(yesterday.year, yesterday.month, yesterday.day, 8, 0), end=datetime(yesterday.year, yesterday.month, yesterday.day, 8, 0), target=targettworktime) workdaytemp = Workday(user=user, agency=user.profile.agency, start=datetime(yesterday.year, yesterday.month, yesterday.day, 8, 0), end=datetime(yesterday.year, yesterday.month, yesterday.day, 8, 0), target=targettworktime)
workdaytemp.save() workdaytemp.save()
except: except:
@ -1680,7 +1685,6 @@ def cronactionsdaily(request, code):
#["htrampe@gmail.com"], #["htrampe@gmail.com"],
fail_silently=True, fail_silently=True,
) )
return JsonResponse(data) return JsonResponse(data)
#import datetime #import datetime