Modulcommit Zeiterfassung

This commit is contained in:
holger.trampe 2020-05-01 00:51:17 +02:00
parent fe4115df40
commit f45e761dea
24 changed files with 15377 additions and 31 deletions

View File

@ -5,6 +5,16 @@ from users.models import AgencyGroup, Agency, Profile, AgencyJob, AgencyNetwork,
from PIL import Image from PIL import Image
from bootstrap_datepicker_plus import DatePickerInput from bootstrap_datepicker_plus import DatePickerInput
class AgencyTimeManagement(forms.ModelForm):
class Meta:
model = Agency
fields = ['module_timemanagement_ze']
labels = {
'module_timemanagement_ze' : "Zeiterfassung aktivieren"
}
class AgencyOrganigrammForm(forms.ModelForm): class AgencyOrganigrammForm(forms.ModelForm):
class Meta: class Meta:
model = Agency model = Agency
@ -97,7 +107,7 @@ class AgencyModulsForm(forms.ModelForm):
'module_files' : "Dateien", 'module_files' : "Dateien",
'module_organigramm' : "Organigramm", 'module_organigramm' : "Organigramm",
'module_messages' : "Mitteilungen", 'module_messages' : "Mitteilungen",
'module_timemanagement' : "Zeiterfassung", 'module_timemanagement' : "Abwesenheits- und Zeiterfassung",
} }
fields = ['module_news','module_organizer','module_files','module_organigramm', 'module_messages', 'module_timemanagement'] fields = ['module_news','module_organizer','module_files','module_organigramm', 'module_messages', 'module_timemanagement']

View File

@ -2,26 +2,65 @@
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% load counter_tag %} {% load counter_tag %}
{% block content %} {% block content %}
<div class="content-section col-8"> <div class="content-section col-9">
<h3>Agenturverbund {{agn.name}} beitreten</h3> <h3>Agenturverbund {{agn.name}} beitreten</h3>
<hr> <hr>
<h4>Verbundinfos</h4>
{% getsumofallag agn.pk as agsum %} <div class="card">
{% getsumofallstandards agn.pk as ag_standardsum %} <div class="card-body">
<h5 class="card-title">Verbundinfos</h5>
{% getsumofallag agn.pk as agsum %}
{% getsumofallstandards agn.pk as ag_standardsum %}
<div class="row mt-3">
<div class="col-8">
<h6><b>Gründeragentur</b> {{agn.creator_agency.name }}</h6> <h6><b>Gründeragentur</b> {{agn.creator_agency.name }}</h6>
<h6><b>Gegründet von</b> {{agn.creator.first_name }} {{agn.creator.last_name }}</h6> <h6><b>Gegründet von</b> {{agn.creator.first_name }} {{agn.creator.last_name }}</h6>
<h6><b>Grüdungsdatum</b> {{agn.created_on }}</h6> <h6><b>Grüdungsdatum</b> {{agn.created_on }}</h6>
<h6><b>Agenturen</b> {{agsum}}</h6> <h6><b>Agenturen</b> {{agsum}}</h6>
<h6><b>Standards</b> {{agn.standards.all|length}}</h6> <h6><b>Standards</b> {{agn.standards.all|length}}</h6>
<h6><b>Letzte Aktivität</b> {{agn.lastactivity}}</h6> <h6><b>Letzte Aktivität</b> {{agn.lastactivity}}</h6>
</div>
</div> {% if agn.publicjoin %}
{% if agn.publicjoin %} <hr>
Das Beitreten zu diesem Verbund ist öffentlich. Sie können daher sofort nach Beitritt die geteilten Informationen einsehen, aber selber keine Informationen in den Verbund teilen. Das Beitreten zu diesem Verbund ist öffentlich. Sie können daher sofort nach Beitritt die geteilten Informationen einsehen, aber selber keine Informationen in den Verbund teilen.
{% endif %} {% endif %}
<hr>
<h5>Agenturen im Verbund</h5>
<b>Verwaltende Agenturen:</b>
{% for a in agn.adminagencys.all %}
&nbsp;{{a.name}}{% if forloop.counter < agn.adminagencys.all|length %},{% endif %}{% endfor %}
<br />
<a href="#\" onclick="javascript:showHiddenAgencys()" style=""><b>Mitgliedsagenturen betrachten</b></a>
<span id="agencys_of_ag" style="display: none;">
<br />
{% for a in agn.members.all %}
{{a.name}}{% if forloop.counter < agn.members.all|length %},{% endif %}{% endfor %}{% if agn.sharemembers.all|length > 0 %},&nbsp;{% endif %}{% for a in agn.sharemembers.all %}{{a.name}}{% if forloop.counter < agn.sharemembers.all|length %},
{% endif %}
{% endfor %}
</span>
</div>
</div>
<script type="text/javascript">
var hidden_ag = true;
function showHiddenAgencys(){
if(hidden_ag){
$("#agencys_of_ag").show();
hidden_ag = false;
}
else{
$("#agencys_of_ag").hide();
hidden_ag = true;
}
}
</script>
<hr> <hr>
Möchten Sie diesem Verbund beitreten? Möchten Sie diesem Verbund beitreten?
<br /> <br />

View File

@ -0,0 +1,24 @@
{% load crispy_forms_tags %}
<form method="POST" enctype="multipart/form-data" name="updateModSettingsTM">
{% csrf_token %}
{{modsettings_tm|crispy}}
</form>
{% for ab in modsettings_tm_abcat %}
{{ab.name}}<br />
{% endfor %}
<script type="text/javascript">
function updateTmSettings(){
$.ajax(
{
type: "GET",
url: "{% url 'modsettings-tm' %}",
data:{
aze: $("#id_module_timemanagement_ze").prop('checked')
},
success: function( data )
{
location.href = location.href;
}
});
}
</script>

View File

@ -17,7 +17,13 @@
<tr> <tr>
<td>{{formfield.label_tag}}</td> <td>{{formfield.label_tag}}</td>
<td>{{formfield}}</td> <td>{{formfield}}</td>
<td>{% if formfield.name == 'module_organigramm' %}<button type="button" class="btn btn-sm btn-primary" onclick="javascript:$('#modulesettings_{{formfield.name}}').modal('toggle');"><i class="fas fa-cog"></i></button>{% endif %}</td> <td>
{% if formfield.name == 'module_organigramm' %}
<button type="button" class="btn btn-sm btn-primary" onclick="javascript:$('#modulesettings_{{formfield.name}}').modal('toggle');"><i class="fas fa-cog"></i></button>
{% elif formfield.name == 'module_timemanagement' %}
<button type="button" class="btn btn-sm btn-primary" onclick="javascript:$('#modulesettings_{{formfield.name}}').modal('toggle');"><i class="fas fa-cog"></i></button>
{% endif %}
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -28,7 +34,7 @@
{% for formfield in modulform %} {% for formfield in modulform %}
<div class="modal fade" id="modulesettings_{{formfield.name}}" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="" aria-hidden="true"> <div class="modal fade" id="modulesettings_{{formfield.name}}" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="" aria-hidden="true">
<div class="modal-dialog " role="document"> <div class="modal-dialog modal-lg " role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title">Moduleinstellungen {{formfield.label_tag}}</h5> <h5 class="modal-title">Moduleinstellungen {{formfield.label_tag}}</h5>
@ -37,18 +43,27 @@
</button> </button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
{% if formfield.name != 'module_organigramm' %} {% if formfield.name == 'module_organigramm' %}
Keine Einstellungen vorhanden. {% block modulesettings_organigramm %}
{% include "dasettings/modulesettings_organigramm.html" %}
{% endblock %}
{% elif formfield.name == 'module_timemanagement' %}
{% block modulesettings_tm %}
{% include "dasettings/modulesettings_timemanagement.html" %}
{% endblock %}
{% else %} {% else %}
{% block modulesettings_organigramm %} Keine Einstellungen vorhanden.
{% include "dasettings/modulesettings_organigramm.html" %}
{% endblock %}
{% endif %} {% endif %}
{% if formfield.name == 'module_organigramm' %} {% if formfield.name == 'module_organigramm' %}
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Schließen</button>&nbsp; <button type="button" class="btn btn-danger" data-dismiss="modal">Schließen</button>&nbsp;
<button id="" type="button" onclick="javascript:updateOrganigrammSettings()" class="btn btn-success" data-dismiss="modal" >Speichern</button> <button id="" type="button" onclick="javascript:updateOrganigrammSettings()" class="btn btn-success" data-dismiss="modal" >Speichern</button>
</div> </div>
{% elif formfield.name == 'module_timemanagement' %}
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Schließen</button>&nbsp;
<button id="" type="button" onclick="javascript:updateTmSettings()" class="btn btn-success" data-dismiss="modal" >Speichern</button>
</div>
{% else %} {% else %}
</div> </div>
<div class="modal-footer"> <div class="modal-footer">

View File

@ -24,4 +24,5 @@ urlpatterns = [
path('managnag/deli/<int:pk>', permission_required('users.agencynetwork')(views.DelAgInv), name='delinvite'), path('managnag/deli/<int:pk>', permission_required('users.agencynetwork')(views.DelAgInv), name='delinvite'),
#path('managnag/delfromagn/<int:agn>/<int:ag>', permission_required('users.agencynetwork')(views.DelFromAgn), name='delagfromagn'), #path('managnag/delfromagn/<int:agn>/<int:ag>', permission_required('users.agencynetwork')(views.DelFromAgn), name='delagfromagn'),
path('modsettings/orga/', views.ModSettingsOrga, name="modsettings-orga"), path('modsettings/orga/', views.ModSettingsOrga, name="modsettings-orga"),
path('modsettings/tm/', views.ModSettingsTm, name="modsettings-tm"),
] ]

View File

@ -1,7 +1,7 @@
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
from .forms import UsersSelfChangeForm, UsersNotificationForm, AgencyGroupPerms, AgencyModulsForm, UserNewUserForm, UserProfileForm, AgencyNetworkForm, AgencyOrganigrammForm, UserTimeForm from .forms import UsersSelfChangeForm, UsersNotificationForm, AgencyGroupPerms, AgencyModulsForm, UserNewUserForm, UserProfileForm, AgencyNetworkForm, AgencyOrganigrammForm, UserTimeForm, AgencyTimeManagement
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import update_session_auth_hash from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth.forms import PasswordChangeForm
@ -21,6 +21,7 @@ from tasks.models import Tasks
import webcolors import webcolors
from datetime import datetime from datetime import datetime
from standards.models import Standards from standards.models import Standards
from timemanagement.models import AbsenceReason
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 import re
@ -68,6 +69,12 @@ def getAllForms(request, context):
modsettings_organigramm = AgencyOrganigrammForm(instance=request.user.profile.agency) modsettings_organigramm = AgencyOrganigrammForm(instance=request.user.profile.agency)
context.update({'modsettings_organigramm' : modsettings_organigramm}) context.update({'modsettings_organigramm' : modsettings_organigramm})
#Modulsettings ABWESENHEIT- UND ZEITERFASSUNG
modsettings_tm = AgencyTimeManagement(instance=request.user.profile.agency)
context.update({'modsettings_tm' : modsettings_tm})
context.update({"modsettings_tm_abcat" : AbsenceReason.objects.filter(agency=request.user.profile.agency).order_by("-name") })
# USER FOR USERTABLE # USER FOR USERTABLE
users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk) users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk)
return context return context
@ -858,7 +865,7 @@ def AgencyNetworkAjaxSettings(request):
@login_required @login_required
def ModSettingsOrga(request): def ModSettingsOrga(request):
if request.method == 'GET': if request.method == 'GET' and request.user.has_perm("modulesconfig"):
if(request.GET['dynorga'] == "true"): if(request.GET['dynorga'] == "true"):
ag = request.user.profile.agency ag = request.user.profile.agency
ag.dynamicprofile = True ag.dynamicprofile = True
@ -869,4 +876,19 @@ def ModSettingsOrga(request):
ag.save() ag.save()
return JsonResponse({}) return JsonResponse({})
else: else:
return JsonResponse({}) return JsonResponse({})
@login_required
def ModSettingsTm(request):
if request.method == 'GET' and request.user.has_perm("modulesconfig"):
if(request.GET['aze'] == "true"):
ag = request.user.profile.agency
ag.module_timemanagement_ze = True
ag.save()
else:
ag = request.user.profile.agency
ag.module_timemanagement_ze = False
ag.save()
return JsonResponse({})
else:
return JsonResponse({})

View File

@ -0,0 +1,44 @@
# Generated by Django 3.0.4 on 2020-04-30 23:06
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('users', '0023_auto_20200430_2306'),
('timemanagement', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='AbsenceReason',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(default='', max_length=200)),
('need_confirm', models.BooleanField(default=True)),
('need_rep', models.BooleanField(default=True)),
('is_holiday', models.BooleanField(default=True)),
('agency', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.Agency')),
],
),
migrations.CreateModel(
name='Absence',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('start', models.DateTimeField(blank=True, default=None, null=True)),
('end', models.DateTimeField(blank=True, default=None, null=True)),
('start_ishalf', models.BooleanField(default=False)),
('end_ishalf', models.BooleanField(default=False)),
('info', models.TextField(blank=True, default='', verbose_name='Abwesenheitsbegründung')),
('confirm_status', models.IntegerField(default=0)),
('confirm_info', models.TextField(blank=True, default='', verbose_name='Begründung')),
('agency', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.Agency')),
('reason', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='timemanagement.AbsenceReason')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -0,0 +1,25 @@
# Generated by Django 3.0.4 on 2020-05-01 00:20
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0023_auto_20200430_2306'),
('timemanagement', '0002_absence_absencereason'),
]
operations = [
migrations.CreateModel(
name='FreeDays',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('day', models.DateTimeField(blank=True, default=None, null=True)),
('name', models.CharField(default='', max_length=200)),
('year', models.IntegerField(default=0)),
('agency', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.Agency')),
],
),
]

View File

@ -17,3 +17,31 @@ class Breaks(models.Model):
start = models.DateTimeField(default=None, null=True, blank=True) start = models.DateTimeField(default=None, null=True, blank=True)
end = models.DateTimeField(default=None, null=True, blank=True) end = models.DateTimeField(default=None, null=True, blank=True)
class AbsenceReason(models.Model):
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
name = models.CharField(default="", max_length=200)
need_confirm = models.BooleanField(default=True)
need_rep = models.BooleanField(default=True)
is_holiday = models.BooleanField(default=True)
class Absence(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
start = models.DateTimeField(default=None, null=True, blank=True)
end = models.DateTimeField(default=None, null=True, blank=True)
start_ishalf = models.BooleanField(default=False)
end_ishalf = models.BooleanField(default=False)
reason = models.ForeignKey("AbsenceReason", on_delete=models.SET_NULL, null=True, blank=True)
info = models.TextField(blank=True, verbose_name='Abwesenheitsbegründung', default="")
confirm_status = models.IntegerField(default=0)
confirm_info = models.TextField(blank=True, verbose_name='Begründung', default="")
class FreeDays(models.Model):
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
day = models.DateTimeField(default=None, null=True, blank=True)
name = models.CharField(default="", max_length=200)
year = models.IntegerField(default=0)

View File

@ -16,7 +16,9 @@
<th scope="col">Arbeitszeit</th> <th scope="col">Arbeitszeit</th>
<th scope="col">Pausen</th> <th scope="col">Pausen</th>
<th scope="col">Gesamtzeit</th> <th scope="col">Gesamtzeit</th>
<th scope="col">Abwesenheit</th>
<th scope="col">Gleitzeit in h</th> <th scope="col">Gleitzeit in h</th>
<th scope="col">&nbsp;</th> <th scope="col">&nbsp;</th>
</tr> </tr>
@ -46,11 +48,15 @@
{{sumwd}} {{sumwd}}
</td> </td>
<td> <td>
DROPDOWN
</td>
<td>
</td> </td>
<td> <td>
<button class="btn btn-secondary btn-sm ml-2" onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button> <button class="btn btn-secondary btn-sm ml-2" onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
<button class="btn btn-secondary btn-sm " href=""><small><i class="fas fa-pen"></i></small></button> <button class="btn btn-secondary btn-sm " href=""><small><i class="fas fa-pen"></i></small></button>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -127,6 +133,6 @@ $(document).ready(function(){
</script> </script>
{% else %} {% else %}
<h3>Das Modul Zeiterfassung wurde in ihrer Agentur deaktiviert.</h3> <h3>Das Modul Abwesenheits- und Zeiterfassung wurde in ihrer Agentur deaktiviert oder die Zeiterfassung wurde im Modul deaktiviert.</h3>
{% endif %} {% endif %}
{% endblock content %} {% endblock content %}

View File

@ -0,0 +1,47 @@
{% extends "users/base.html" %}
{% block content %}
{% load counter_tag %}
{% if request.user.profile.agency.module_timemanagement_ze %}
<div class="content-section col-12">
<h3>Abwesenheiten&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Bearbeiten Sie hier Ihre Abwesenheiten." class="far fa-question-circle"></i></small></h3>
<hr>
{{freedays}}
<style>
/* DATATABLES */
.paginate_button {
padding: 0px !important;
border: 0px !important;
}
</style>
<script>
$(document).ready(function(){
/*
$('#table_timemanagement').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"
},
},
"buttons" : {
"className" : "btn-danger"
}
});
*/
});
</script>
{% else %}
<h3>Das Modul Abwesenheits- und Zeiterfassung wurde in ihrer Agentur deaktiviert.</h3>
{% endif %}
{% endblock content %}

View File

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

View File

@ -3,6 +3,49 @@ from django.contrib.auth.decorators import login_required
from django.http import JsonResponse from django.http import JsonResponse
from .models import Workday, Breaks from .models import Workday, Breaks
from django.utils import timezone from django.utils import timezone
import requests, csv, os
from django.templatetags.static import static
from django.conf import settings
from datetime import date
def loadingFreeDays(plz):
# Getting land
file_path = os.path.join(settings.STATIC_ROOT, 'users/extra/plz_short.csv')
land = False
with open(file_path, 'rt') as csvfile:
filecsv = csv.reader(csvfile, delimiter=';')
for row in filecsv:
if row[1] == plz:
land = row[6]
break;
if(land != False):
# CALCULATE FREEDAYS AS JSON
year = today = date.today().year
URL = "https://feiertage-api.de/api/"
PARAMS = {'jahr':year,'nur_land':land}
r = requests.get(url = URL, params = PARAMS)
return r.json()
else:
return False
@login_required
def AbsenceManagmenet(request):
context = {
"active_link" : "abscence",
"freedays" : loadingFreeDays(request.user.profile.agency.plz)
}
return render(request, 'timemanagement/tm_ab_management.html', context)
@login_required @login_required
def TimeManagement(request): def TimeManagement(request):

View File

@ -6,7 +6,7 @@ from django.contrib.auth.models import Permission
from message.models import Message from message.models import Message
from cloud.models import DataFile from cloud.models import DataFile
from organizer.models import AGContacts from organizer.models import AGContacts
from timemanagement.models import Workday, Breaks from timemanagement.models import Workday, Breaks, AbsenceReason, FreeDays
admin.site.register(StandardComments) admin.site.register(StandardComments)
admin.site.register(StandardCommentRate) admin.site.register(StandardCommentRate)
@ -24,4 +24,5 @@ admin.site.register(DataFile)
admin.site.register(UserTime) admin.site.register(UserTime)
admin.site.register(Workday) admin.site.register(Workday)
admin.site.register(Breaks) admin.site.register(Breaks)
admin.site.register(AbsenceReason)
admin.site.register(FreeDays)

View File

@ -99,8 +99,14 @@ class Agency(models.Model):
module_messages = models.BooleanField(default=True) module_messages = models.BooleanField(default=True)
# KOSTENPFLICHTIGE MODULE # KOSTENPFLICHTIGE MODULE
# Abwesenheits- und Zeiterfassung
# Modul aktiv/deaktiviert
module_timemanagement = models.BooleanField(default=False) module_timemanagement = models.BooleanField(default=False)
module_timemanagement_price = models.FloatField(default=5.0, max_length=9, blank=True) module_timemanagement_price = models.FloatField(default=10.0, max_length=9, blank=True)
# Zeiterfassung Ja/Nein
module_timemanagement_ze = models.BooleanField(default=True)
# Steckbrief dynamisch aus Standard # Steckbrief dynamisch aus Standard
dynamicprofile = models.BooleanField(default=True) dynamicprofile = models.BooleanField(default=True)

View File

@ -14,9 +14,40 @@ from django.conf import settings
from django.utils import timezone from django.utils import timezone
from standards.models import Standards from standards.models import Standards
from django.contrib.auth.signals import user_logged_in from django.contrib.auth.signals import user_logged_in
from timemanagement.models import Workday, Breaks from timemanagement.models import Workday, Breaks, AbsenceReason, FreeDays
from datetime import date from datetime import date
import datetime import datetime, json
from django.utils import timezone
import requests, csv, os
from django.templatetags.static import static
from django.conf import settings
from datetime import date
def loadingFreeDays(plz):
# Getting land
file_path = os.path.join(settings.STATIC_ROOT, 'users/extra/plz_short.csv')
land = False
with open(file_path, 'rt') as csvfile:
filecsv = csv.reader(csvfile, delimiter=';')
for row in filecsv:
if row[1] == plz:
land = row[6]
break;
if(land != False):
# CALCULATE FREEDAYS AS JSON
year = today = date.today().year
URL = "https://feiertage-api.de/api/"
PARAMS = {'jahr':year,'nur_land':land}
r = requests.get(url = URL, params = PARAMS)
return r.json()
else:
return False
# CHECK SOMETHING WHEN USER LOGGED IN # CHECK SOMETHING WHEN USER LOGGED IN
@receiver(signal=user_logged_in, sender=User) @receiver(signal=user_logged_in, sender=User)
@ -31,7 +62,40 @@ def checkForWorkDays(sender, user, request, **kwargs):
if(b.end == None): if(b.end == None):
b.end = datetime.datetime(d.start.year, d.start.month, d.start.day, 23, 59, 00) b.end = datetime.datetime(d.start.year, d.start.month, d.start.day, 23, 59, 00)
b.save() b.save()
# CHECK SOMETHING WHEN USER LOGGED IN
@receiver(signal=user_logged_in, sender=User)
def checkDefaultAbsenceReasons(sender, user, request, **kwargs):
ar = AbsenceReason.objects.filter(agency=user.profile.agency)
if(len(ar) == 0):
new_ar_holidays = AbsenceReason(agency=user.profile.agency, name="Urlaub", need_confirm=True, need_rep=True, is_holiday=True)
new_ar_holidays.save()
new_ar_specialholidays = AbsenceReason(agency=user.profile.agency, name="Sonderurlaub", need_confirm=True, need_rep=True, is_holiday=False)
new_ar_specialholidays.save()
new_ar_ill = AbsenceReason(agency=user.profile.agency, name="Krankheit", need_confirm=False, need_rep=False, is_holiday=False)
new_ar_ill.save()
new_ar_school = AbsenceReason(agency=user.profile.agency, name="Berufsschule", need_confirm=False, need_rep=False, is_holiday=False)
new_ar_school.save()
@receiver(signal=user_logged_in, sender=User)
def checkAllFreeDaysLoaded(sender, user, request, **kwargs):
allFreeDays = FreeDays.objects.filter(agency=user.profile.agency, year=date.today().year)
# NO DAYS FOR THIS YEAR
if(len(allFreeDays) == 0):
tempdays = loadingFreeDays(user.profile.agency.plz)
for k in tempdays.keys():
tempdate = tempdays[k]["datum"].split("-")
FreeDays(agency=user.profile.agency, name=k, day=datetime.datetime(int(tempdate[0]),int(tempdate[1]),int(tempdate[2])), year=date.today().year).save()
# Deletes all Notifications added to to delete news # Deletes all Notifications added to to delete news

File diff suppressed because it is too large Load Diff

View File

@ -162,6 +162,19 @@
{% endif %} {% endif %}
{% if request.user.profile.agency.module_timemanagement %} {% if request.user.profile.agency.module_timemanagement %}
{% if active_link == 'abscence' %}
<li class="nav-item active">
{% else%}
<li class="nav-item">
{%endif%}
<a class="nav-link " href="{% url 'tma-management' %}" aria-expanded="true">
<i class="fas fa-umbrella-beach"></i>
<span>Abwesenheiten</span>
</a>
</li>
{% endif %}
{% if request.user.profile.agency.module_timemanagement_ze %}
{% if active_link == 'timemanagement' %} {% if active_link == 'timemanagement' %}
<li class="nav-item active"> <li class="nav-item active">
{% else%} {% else%}
@ -267,7 +280,7 @@
</style> </style>
<!-- Topbar Navbar --> <!-- Topbar Navbar -->
<ul class="navbar-nav ml-auto "> <ul class="navbar-nav ml-auto ">
{% if request.user.profile.agency.module_timemanagement %} {% if request.user.profile.agency.module_timemanagement_ze %}
<li class="nav-item dropdown no-arrow mx-1"> <li class="nav-item dropdown no-arrow mx-1">
<a class="nav-link dropdown-toggle" onclick="" id="timemanagement_realtime" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link dropdown-toggle" onclick="" id="timemanagement_realtime" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="far fa-clock"></i> <i class="far fa-clock"></i>

View File

@ -38,6 +38,7 @@ from organizer.models import AGContacts, AGPassword
import socket import socket
import sys, os import sys, os
def randomString(stringLength=10): def randomString(stringLength=10):
"""Generate a random string of fixed length """ """Generate a random string of fixed length """
letters = string.ascii_lowercase letters = string.ascii_lowercase
@ -258,9 +259,9 @@ class AgencyCreateView(CreateView):
return super().form_valid(form) return super().form_valid(form)
@login_required @login_required
def dashboard(request): def dashboard(request):
# UPDATE FUNCTIONS BY NEW MODEL-CHANGES FOR COPIEN SOME DATA # UPDATE FUNCTIONS BY NEW MODEL-CHANGES FOR COPIEN SOME DATA
toUpdate(request) toUpdate(request)