Modulcommit Zeiterfassung
This commit is contained in:
parent
fe4115df40
commit
f45e761dea
|
|
@ -5,6 +5,16 @@ from users.models import AgencyGroup, Agency, Profile, AgencyJob, AgencyNetwork,
|
|||
from PIL import Image
|
||||
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 Meta:
|
||||
model = Agency
|
||||
|
|
@ -97,7 +107,7 @@ class AgencyModulsForm(forms.ModelForm):
|
|||
'module_files' : "Dateien",
|
||||
'module_organigramm' : "Organigramm",
|
||||
'module_messages' : "Mitteilungen",
|
||||
'module_timemanagement' : "Zeiterfassung",
|
||||
'module_timemanagement' : "Abwesenheits- und Zeiterfassung",
|
||||
}
|
||||
fields = ['module_news','module_organizer','module_files','module_organigramm', 'module_messages', 'module_timemanagement']
|
||||
|
||||
|
|
|
|||
|
|
@ -2,26 +2,65 @@
|
|||
{% load crispy_forms_tags %}
|
||||
{% load counter_tag %}
|
||||
{% block content %}
|
||||
<div class="content-section col-8">
|
||||
<div class="content-section col-9">
|
||||
<h3>Agenturverbund {{agn.name}} beitreten</h3>
|
||||
<hr>
|
||||
<h4>Verbundinfos</h4>
|
||||
{% getsumofallag agn.pk as agsum %}
|
||||
{% getsumofallstandards agn.pk as ag_standardsum %}
|
||||
|
||||
<div class="card">
|
||||
<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>Gegründet von</b> {{agn.creator.first_name }} {{agn.creator.last_name }}</h6>
|
||||
<h6><b>Grüdungsdatum</b> {{agn.created_on }}</h6>
|
||||
<h6><b>Agenturen</b> {{agsum}}</h6>
|
||||
<h6><b>Standards</b> {{agn.standards.all|length}}</h6>
|
||||
<h6><b>Letzte Aktivität</b> {{agn.lastactivity}}</h6>
|
||||
</div>
|
||||
</div>
|
||||
{% if agn.publicjoin %}
|
||||
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 %}
|
||||
|
||||
{% 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.
|
||||
{% endif %}
|
||||
<hr>
|
||||
<h5>Agenturen im Verbund</h5>
|
||||
<b>Verwaltende Agenturen:</b>
|
||||
{% for a in agn.adminagencys.all %}
|
||||
{{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 %}, {% 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>
|
||||
Möchten Sie diesem Verbund beitreten?
|
||||
<br />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -17,7 +17,13 @@
|
|||
<tr>
|
||||
<td>{{formfield.label_tag}}</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>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
@ -28,7 +34,7 @@
|
|||
|
||||
{% 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-dialog " role="document">
|
||||
<div class="modal-dialog modal-lg " role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Moduleinstellungen {{formfield.label_tag}}</h5>
|
||||
|
|
@ -37,18 +43,27 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% if formfield.name != 'module_organigramm' %}
|
||||
Keine Einstellungen vorhanden.
|
||||
{% if formfield.name == 'module_organigramm' %}
|
||||
{% block modulesettings_organigramm %}
|
||||
{% include "dasettings/modulesettings_organigramm.html" %}
|
||||
{% endblock %}
|
||||
{% elif formfield.name == 'module_timemanagement' %}
|
||||
{% block modulesettings_tm %}
|
||||
{% include "dasettings/modulesettings_timemanagement.html" %}
|
||||
{% endblock %}
|
||||
{% else %}
|
||||
{% block modulesettings_organigramm %}
|
||||
{% include "dasettings/modulesettings_organigramm.html" %}
|
||||
{% endblock %}
|
||||
Keine Einstellungen vorhanden.
|
||||
{% endif %}
|
||||
{% if formfield.name == 'module_organigramm' %}
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal">Schließen</button>
|
||||
<button id="" type="button" onclick="javascript:updateOrganigrammSettings()" class="btn btn-success" data-dismiss="modal" >Speichern</button>
|
||||
</div>
|
||||
{% elif formfield.name == 'module_timemanagement' %}
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal">Schließen</button>
|
||||
<button id="" type="button" onclick="javascript:updateTmSettings()" class="btn btn-success" data-dismiss="modal" >Speichern</button>
|
||||
</div>
|
||||
{% else %}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
|
|
|||
|
|
@ -24,4 +24,5 @@ urlpatterns = [
|
|||
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('modsettings/orga/', views.ModSettingsOrga, name="modsettings-orga"),
|
||||
path('modsettings/tm/', views.ModSettingsTm, name="modsettings-tm"),
|
||||
]
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
from django.shortcuts import render, redirect
|
||||
from django.contrib.auth.decorators import login_required
|
||||
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.auth import update_session_auth_hash
|
||||
from django.contrib.auth.forms import PasswordChangeForm
|
||||
|
|
@ -21,6 +21,7 @@ from tasks.models import Tasks
|
|||
import webcolors
|
||||
from datetime import datetime
|
||||
from standards.models import Standards
|
||||
from timemanagement.models import AbsenceReason
|
||||
from django.core.mail import send_mail
|
||||
from django.conf import settings
|
||||
import re
|
||||
|
|
@ -68,6 +69,12 @@ def getAllForms(request, context):
|
|||
modsettings_organigramm = AgencyOrganigrammForm(instance=request.user.profile.agency)
|
||||
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
|
||||
users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk)
|
||||
return context
|
||||
|
|
@ -858,7 +865,7 @@ def AgencyNetworkAjaxSettings(request):
|
|||
|
||||
@login_required
|
||||
def ModSettingsOrga(request):
|
||||
if request.method == 'GET':
|
||||
if request.method == 'GET' and request.user.has_perm("modulesconfig"):
|
||||
if(request.GET['dynorga'] == "true"):
|
||||
ag = request.user.profile.agency
|
||||
ag.dynamicprofile = True
|
||||
|
|
@ -869,4 +876,19 @@ def ModSettingsOrga(request):
|
|||
ag.save()
|
||||
return JsonResponse({})
|
||||
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({})
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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)),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
@ -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')),
|
||||
],
|
||||
),
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -17,3 +17,31 @@ class Breaks(models.Model):
|
|||
start = 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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@
|
|||
<th scope="col">Arbeitszeit</th>
|
||||
<th scope="col">Pausen</th>
|
||||
<th scope="col">Gesamtzeit</th>
|
||||
<th scope="col">Abwesenheit</th>
|
||||
<th scope="col">Gleitzeit in h</th>
|
||||
|
||||
<th scope="col"> </th>
|
||||
|
||||
</tr>
|
||||
|
|
@ -46,11 +48,15 @@
|
|||
{{sumwd}}
|
||||
</td>
|
||||
<td>
|
||||
DROPDOWN
|
||||
</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 " href=""><small><i class="fas fa-pen"></i></small></button>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
@ -127,6 +133,6 @@ $(document).ready(function(){
|
|||
|
||||
</script>
|
||||
{% 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 %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
|
|
@ -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 <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 %}
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
from django.urls import path
|
||||
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!
|
||||
'''
|
||||
|
||||
urlpatterns = [
|
||||
path('', TimeManagement, name='tm-management'),
|
||||
path('abs/', AbsenceManagmenet, name='tma-management'),
|
||||
path('ajax/', TimeAjax, name='tm-ajax'),
|
||||
#path('newsadd/', permission_required('users.modulenews')(views.NewsAdd), name='news-add'),
|
||||
#path('newsupdate/<int:id>/', permission_required('users.modulenews')(views.NewsUpdate), name='news-update'),
|
||||
|
|
|
|||
|
|
@ -3,6 +3,49 @@ from django.contrib.auth.decorators import login_required
|
|||
from django.http import JsonResponse
|
||||
from .models import Workday, Breaks
|
||||
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
|
||||
def TimeManagement(request):
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from django.contrib.auth.models import Permission
|
|||
from message.models import Message
|
||||
from cloud.models import DataFile
|
||||
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(StandardCommentRate)
|
||||
|
|
@ -24,4 +24,5 @@ admin.site.register(DataFile)
|
|||
admin.site.register(UserTime)
|
||||
admin.site.register(Workday)
|
||||
admin.site.register(Breaks)
|
||||
|
||||
admin.site.register(AbsenceReason)
|
||||
admin.site.register(FreeDays)
|
||||
|
|
|
|||
|
|
@ -99,8 +99,14 @@ class Agency(models.Model):
|
|||
module_messages = models.BooleanField(default=True)
|
||||
|
||||
# KOSTENPFLICHTIGE MODULE
|
||||
|
||||
# Abwesenheits- und Zeiterfassung
|
||||
# Modul aktiv/deaktiviert
|
||||
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
|
||||
dynamicprofile = models.BooleanField(default=True)
|
||||
|
|
|
|||
|
|
@ -14,9 +14,40 @@ from django.conf import settings
|
|||
from django.utils import timezone
|
||||
from standards.models import Standards
|
||||
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
|
||||
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
|
||||
@receiver(signal=user_logged_in, sender=User)
|
||||
|
|
@ -31,7 +62,40 @@ def checkForWorkDays(sender, user, request, **kwargs):
|
|||
if(b.end == None):
|
||||
b.end = datetime.datetime(d.start.year, d.start.month, d.start.day, 23, 59, 00)
|
||||
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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -162,6 +162,19 @@
|
|||
{% endif %}
|
||||
|
||||
{% 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' %}
|
||||
<li class="nav-item active">
|
||||
{% else%}
|
||||
|
|
@ -267,7 +280,7 @@
|
|||
</style>
|
||||
<!-- Topbar Navbar -->
|
||||
<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">
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ from organizer.models import AGContacts, AGPassword
|
|||
import socket
|
||||
import sys, os
|
||||
|
||||
|
||||
def randomString(stringLength=10):
|
||||
"""Generate a random string of fixed length """
|
||||
letters = string.ascii_lowercase
|
||||
|
|
@ -258,9 +259,9 @@ class AgencyCreateView(CreateView):
|
|||
return super().form_valid(form)
|
||||
|
||||
|
||||
|
||||
@login_required
|
||||
def dashboard(request):
|
||||
|
||||
|
||||
# UPDATE FUNCTIONS BY NEW MODEL-CHANGES FOR COPIEN SOME DATA
|
||||
toUpdate(request)
|
||||
|
|
|
|||
Loading…
Reference in New Issue