Zeiterfassung bis auf Bearbeiten durch andere Mitarbeiter fertig für Betatest
This commit is contained in:
parent
51d7a746f7
commit
0de2a48c9e
|
|
@ -1,15 +1,16 @@
|
|||
{% load counter_tag %}
|
||||
<a href="{% url 'newuserfirst' %}"class="btn btn-primary active" data-toggle="tooltip" data-placement="top" title="Fügen Sie hier einen weiteren Mitarbeiter Ihrer Agentur hinzu."><i class="fas fa-plus"></i> Mitarbeiter</a>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="table-responsive">
|
||||
<div class="row">
|
||||
<div class="table-responsive">
|
||||
<table class="table hover" id="usertableall">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Vorname</th>
|
||||
<th scope="col">Nachname</th>
|
||||
<th scope="col">Vorname</th>
|
||||
<th scope="col">Nachname</th>
|
||||
<th scope="col">E-Mail</th>
|
||||
<th scope="col">Agenturfunktion</th>
|
||||
<th scope="col">Gleitzeit</th>
|
||||
<th scope="col">Letzter Login</th>
|
||||
<th scope="col">Tätigkeit</th>
|
||||
<th scope="col">Telefon</th>
|
||||
|
|
@ -21,21 +22,33 @@
|
|||
{% for item in usersofagency %}
|
||||
<tr>
|
||||
<td><a href="{% url 'user_updateprofile' item.pk 0 %}">{{item.first_name }}</a></td>
|
||||
<td><a href="{% url 'user_updateprofile' item.pk 0 %}">{{ item.last_name }}</a></td>
|
||||
<td><a href="{% url 'user_updateprofile' item.pk 0 %}">{{ item.last_name }}</a></td>
|
||||
<td>{{ item.email }}</td>
|
||||
<td>{% if item.profile.func == None %}-{%else%}{{ item.profile.func }}{%endif%}</td>
|
||||
<td>
|
||||
{% if item.usertime.usetime %}
|
||||
{% loadaccounttime item as actualaccounttime %}
|
||||
{% if actualaccounttime.1 == 0 %}
|
||||
<b><span style="color: green">+{{actualaccounttime.0}}</span></b>
|
||||
{% else %}
|
||||
<b><span style="color: red">-{{actualaccounttime.0}}</span></b>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{% if item.last_login != Nonte %}{{ item.last_login }}{% endif %}</td>
|
||||
<td>{{ item.profile.compfunc }}</td>
|
||||
<td>{{ item.profile.phoneland }}</td>
|
||||
<td>{{ item.profile.phonemobile }}</td>
|
||||
<td>
|
||||
{% if item != request.user %}
|
||||
{% if item != request.user %}
|
||||
<a href="{% url 'users-delete' item.pk %}" ><button class="btn btn-sm btn-secondary"><i class="fas fa-trash"></i></button></a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -51,7 +64,7 @@
|
|||
<script>
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
|
||||
$('#usertableall').DataTable({
|
||||
"order" : [],
|
||||
"language": {
|
||||
|
|
@ -71,9 +84,8 @@ $(document).ready(function(){
|
|||
"className" : "btn-danger"
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,3 +17,13 @@ six==1.13.0
|
|||
sqlparse==0.3.0
|
||||
urllib3==1.25.7
|
||||
webcolors==1.10
|
||||
django-summernote==0.8.11.6
|
||||
django-mathfilters==1.0.0
|
||||
django-cleanup==5.0.0
|
||||
django-user-agents==0.4.0
|
||||
djangorestframework==3.11.0
|
||||
django-channels==0.7.0
|
||||
django-channels-presence==1.0.0
|
||||
django-cryptography==1.0
|
||||
channels-redis==3.0.1
|
||||
filetype==1.0.7
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@
|
|||
<!--
|
||||
|
||||
# TODO: Sichtbarkeit durch andere Nutzer absprechen?
|
||||
# TODO: Bis wann darf rückwirkend eine Abwesenheit bearbeitet werden? Monatlich?
|
||||
# TODO: CronJob einmal umbauen
|
||||
# TODO: Halber Tag mit Workday verbinden
|
||||
Aktuell sieht man den Gleitzeitkontostand in der Mitarbeitertabelle, ein Bearbeiten muss ich nachschieben
|
||||
-->
|
||||
|
||||
<div class="table-responsive ">
|
||||
|
|
@ -63,14 +61,129 @@
|
|||
{% if abday.start == da%}
|
||||
{% if abday.startday_info == "1" %}
|
||||
(nur Vormittags)
|
||||
{% for workday in workdays %}
|
||||
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
|
||||
<br />
|
||||
{{workday.start|date:"H:i"}} - {{workday.end|date:"H:i"}},
|
||||
{% getsumworkdayexcludebreak workday as sumworkday %}
|
||||
{{ sumworkday }},
|
||||
{% getsumbreak workday as sumbreakofday %}
|
||||
{{sumbreakofday}} min. ({{workday.breaks.all|length}}),
|
||||
{% getsumworkday workday as sumwd %}
|
||||
{{sumwd}},
|
||||
{% gettimeoveralldiff workday user as erg%}
|
||||
{% if erg.1 == 0 %}
|
||||
<span style="color: green">+{{erg.0}}</span>
|
||||
{% elif erg.1 == 1 %}
|
||||
<span>{{erg.0}}</span>
|
||||
{% else %}
|
||||
<span style="color: red">-{{erg.0}}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if breakmonthline < da %}
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
|
||||
{% elif abday.startday_info == "2" %}
|
||||
(nur Nachmittags)
|
||||
|
||||
{% for workday in workdays %}
|
||||
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
|
||||
<br />
|
||||
{{workday.start|date:"H:i"}} - {{workday.end|date:"H:i"}}
|
||||
{% getsumworkdayexcludebreak workday as sumworkday %}
|
||||
{{ sumworkday }},
|
||||
{% getsumbreak workday as sumbreakofday %}
|
||||
{{sumbreakofday}} min. ({{workday.breaks.all|length}}),
|
||||
{% getsumworkday workday as sumwd %}
|
||||
{{sumwd}},
|
||||
{% gettimeoveralldiff workday user as erg%}
|
||||
{% if erg.1 == 0 %}
|
||||
<span style="color: green">+{{erg.0}}</span>
|
||||
{% elif erg.1 == 1 %}
|
||||
<span>{{erg.0}}</span>
|
||||
{% else %}
|
||||
<span style="color: red">-{{erg.0}}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if breakmonthline < da %}
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% elif abday.end == da%}
|
||||
{% if abday.endday_info == "1" %}
|
||||
(nur Vormittags)
|
||||
|
||||
|
||||
|
||||
{% for workday in workdays %}
|
||||
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
|
||||
<br />
|
||||
{{workday.start|date:"H:i"}} - {{workday.end|date:"H:i"}}
|
||||
{% getsumworkdayexcludebreak workday as sumworkday %}
|
||||
{{ sumworkday }},
|
||||
{% getsumbreak workday as sumbreakofday %}
|
||||
{{sumbreakofday}} min. ({{workday.breaks.all|length}}),
|
||||
{% getsumworkday workday as sumwd %}
|
||||
{{sumwd}},
|
||||
{% gettimeoveralldiff workday user as erg%}
|
||||
{% if erg.1 == 0 %}
|
||||
<span style="color: green">+{{erg.0}}</span>
|
||||
{% elif erg.1 == 1 %}
|
||||
<span>{{erg.0}}</span>
|
||||
{% else %}
|
||||
<span style="color: red">-{{erg.0}}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if breakmonthline < da %}
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% elif abday.endday_info == "2" %}
|
||||
(nur Nachmittags)
|
||||
|
||||
|
||||
|
||||
{% for workday in workdays %}
|
||||
{% if workday.start|date:"d-m-y" == da|date:"d-m-y" %}
|
||||
<br />
|
||||
{{workday.start|date:"H:i"}} - {{workday.end|date:"H:i"}}
|
||||
{% getsumworkdayexcludebreak workday as sumworkday %}
|
||||
{{ sumworkday }},
|
||||
{% getsumbreak workday as sumbreakofday %}
|
||||
{{sumbreakofday}} min. ({{workday.breaks.all|length}}),
|
||||
{% getsumworkday workday as sumwd %}
|
||||
{{sumwd}},
|
||||
{% gettimeoveralldiff workday user as erg%}
|
||||
{% if erg.1 == 0 %}
|
||||
<span style="color: green">+{{erg.0}}</span>
|
||||
{% elif erg.1 == 1 %}
|
||||
<span>{{erg.0}}</span>
|
||||
{% else %}
|
||||
<span style="color: red">-{{erg.0}}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if breakmonthline < da %}
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
|
@ -212,9 +325,10 @@
|
|||
|
||||
|
||||
{% counterWDUp %}
|
||||
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% if breakmonthline < da %}
|
||||
<button class="btn btn-secondary btn-sm ml-2" onclick="window.location.href='{% url 'tm-update' workday.pk %}'"><small><i class="fas fa-pen"></i></small></button>
|
||||
<button class="btn btn-secondary btn-sm " onclick="javascript:$('#confirm-delete_{{workday.pk}}').modal('toggle')"><small><i class="fas fa-trash"></i></small></button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ def TimeManagement(request, activemonth=False, activeyear=False):
|
|||
# Hier werden nur die Arbeitstage gefiltert, die auch aktuell zur Ansicht stehen sollen
|
||||
context = {
|
||||
"next_month" : next_month,
|
||||
"breakmonthline" : date.today() - timedelta(days=30),
|
||||
"prev_month" : prev_month,
|
||||
"next_year" : next_year,
|
||||
"prev_year" : prev_year,
|
||||
|
|
@ -331,7 +332,7 @@ def TimeManagement(request, activemonth=False, activeyear=False):
|
|||
"days_this_month" : get_datetime_range(int(active_year), int(activemonth)),
|
||||
"workdays" : Workday.objects.filter(agency=request.user.profile.agency, user=request.user, start__month=activemonth, start__year=active_year).order_by("start").exclude(end=None),
|
||||
"userhasworkdays" : user_has_workdays
|
||||
}
|
||||
}
|
||||
|
||||
return render(request, 'timemanagement/timemanagement_management.html', context)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,43 +12,43 @@
|
|||
<title>Digitale Agentur</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
|
||||
|
||||
<link rel="canonical" href="https://www.digitale-agentur.com">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.js" type="text/javascript"></script>
|
||||
|
||||
|
||||
|
||||
<link href="{%static 'users/vendor/fontawesome-free/css/all.min.css' %}" rel="stylesheet" type="text/css">
|
||||
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
<!--<link href="{%static 'users/css/bootstrap.min.css' %}" rel="stylesheet">-->
|
||||
<link href='https://fonts.googleapis.com/css?family=Roboto&display=swap' rel='stylesheet' type='text/css'>
|
||||
|
||||
<!-- include summernote css/js -->
|
||||
<!--<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.15/dist/summernote.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.15/dist/summernote.min.js"></script>-->
|
||||
|
||||
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js"></script>
|
||||
|
||||
<!-- <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>-->
|
||||
<!-- CROPPER -->
|
||||
<link href="{% static 'users/css/cropper.min.css' %}" type="text/css" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- DATATABLES -->
|
||||
<link href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css" type="text/css" rel="stylesheet">
|
||||
<link href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" type="text/css" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="{% static 'users/css/sb-admin-2.css' %}" type="text/css" rel="stylesheet">
|
||||
|
||||
|
||||
<link href="{% static 'users/css/theme.css' %}" type="text/css" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/summernote@0.8.16/dist/summernote-bs4.js"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.16/dist/summernote.css" rel="stylesheet" type="text/css">
|
||||
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.16/dist/summernote.css" rel="stylesheet" type="text/css">
|
||||
<script type="text/javascript" src="{% static 'summernote/lang/summernote-de-DE.min.js' %}"></script>
|
||||
|
||||
|
||||
|
|
@ -59,8 +59,8 @@
|
|||
<div id="wrapper">
|
||||
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class=" bg-gray-900 sidebar sidebar-dark accordion fixed-top" id="accordionSidebar">
|
||||
<!-- Sidebar -->
|
||||
<ul class=" bg-gray-900 sidebar sidebar-dark accordion fixed-top" id="accordionSidebar">
|
||||
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="{% url 'users-dashboard' %}">
|
||||
|
|
@ -148,7 +148,7 @@
|
|||
<i class="fas fa-envelope"></i>
|
||||
<span>Mitteilungen
|
||||
{% if gs > 0 %}
|
||||
<span class="badge badge-primary badge-counter" id="messcounter_badge" style="margin-right: 85px;"><span id="messcounter">{{gs}}</span></span>
|
||||
<span class="badge badge-primary badge-counter" id="messcounter_badge" style="margin-right: 85px;"><span id="messcounter">{{gs}}</span></span>
|
||||
{% endif %}
|
||||
</span>
|
||||
</a>
|
||||
|
|
@ -162,7 +162,7 @@
|
|||
{% else%}
|
||||
<li class="nav-item">
|
||||
{%endif%}
|
||||
|
||||
|
||||
<a class="nav-link " href="{% url 'chat:chat-management' %}" aria-expanded="true">
|
||||
<i class="fas fa-comments"></i>
|
||||
<span>Chat <sup>BETA</sup></span>
|
||||
|
|
@ -205,7 +205,7 @@
|
|||
<style scoped>
|
||||
#bottom_info {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
||||
<div id="bottom_info">
|
||||
|
|
@ -214,7 +214,7 @@
|
|||
<li class="nav-item active">
|
||||
{% else%}
|
||||
<li class="nav-item">
|
||||
{%endif%}
|
||||
{%endif%}
|
||||
<a class="nav-link " href="{% url 'dasettings' %}" aria-expanded="true" style="margin-top: -15px">
|
||||
<i class="fas fa-cog"></i>
|
||||
<span>Einstellungen</span>
|
||||
|
|
@ -224,13 +224,13 @@
|
|||
<li class="nav-item active">
|
||||
{% else%}
|
||||
<li class="nav-item">
|
||||
{%endif%}
|
||||
{%endif%}
|
||||
<a class="nav-link " href="{% url 'supportda' %}" aria-expanded="true" style="margin-top: -15px">
|
||||
<i class="fas fa-question"></i>
|
||||
<span>Support</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
<div style="" class="sidebar-heading ">
|
||||
<!--<span style="float: left"><small>poweder by </small><img src="{% static 'users/img/VVE-Logo.png' %}" width="27%" class="mb-2"></span>-->
|
||||
<img src="{% static 'users/img/VVE-Logo.png' %}" width="27%" class="mb-2">
|
||||
|
|
@ -239,9 +239,9 @@
|
|||
<a style="color: #999; text-decoration: none;" href="{% url 'impressumda' %}">Impressum</a>
|
||||
</div>
|
||||
<div style="margin-top: 10px; margin-bottom: 5px;" class="sidebar-heading">
|
||||
Version 0.9.1
|
||||
Version 0.9.2
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
|
@ -267,7 +267,7 @@
|
|||
<div id="content-wrapper">
|
||||
<!-- Main Content -->
|
||||
<!-- Topbar -->
|
||||
<nav id="topnavbarmain" class="navbar navbar-expand navbar-light bg-white topbar fixed-top mb-4 static-top shadow" style="margin-left: 224px;">
|
||||
<nav id="topnavbarmain" class="navbar navbar-expand navbar-light bg-white topbar fixed-top mb-4 static-top shadow" style="margin-left: 224px;">
|
||||
<!-- Sidebar Toggle (Topbar) -->
|
||||
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3" onclick="javascript:toggleSidebar()">
|
||||
<i class="fa fa-bars"></i>
|
||||
|
|
@ -276,7 +276,7 @@
|
|||
<!-- Topbar Search -->
|
||||
<form class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<div class="input-group">
|
||||
<input list="searchres" placeholder="Agenturweite Suche..." id="search_string" onkeyup="javascript:startSearch(this.value)" class="form-control bg-light border-0 small" >
|
||||
<input list="searchres" placeholder="Agenturweite Suche..." id="search_string" onkeyup="javascript:startSearch(this.value)" class="form-control bg-light border-0 small" >
|
||||
<!--
|
||||
<input type="text" onkeyup="javascript:startSearch(this.value)" class="form-control bg-light border-0 small" placeholder="Suche..." aria-label="Suche" aria-describedby="basic-addon2" id="searchfield">
|
||||
-->
|
||||
|
|
@ -296,7 +296,7 @@
|
|||
|
||||
{% getUserIsRep request.user as repstring %}
|
||||
{% if repstring != False %}
|
||||
<div class="alert alert-info alert-dismissible" id="repholinfo" style="margin-bottom: -2px; text-align: center; display: none; float: right;"> <i class="fas fa-info-circle"></i>
|
||||
<div class="alert alert-info alert-dismissible" id="repholinfo" style="margin-bottom: -2px; text-align: center; display: none; float: right;"> <i class="fas fa-info-circle"></i>
|
||||
{{repstring}}
|
||||
<button type="button" class="close" data-dismiss="alert" onclick="javascript:closeRepHolInfo()">×</button>
|
||||
</div>
|
||||
|
|
@ -316,7 +316,7 @@
|
|||
{% endif %}
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto ">
|
||||
<ul class="navbar-nav ml-auto ">
|
||||
{% if request.user.usertime.usetime and user.usertime.usetime_start != None %}
|
||||
<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">
|
||||
|
|
@ -325,7 +325,7 @@
|
|||
|
||||
<div class="dropdown-list dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="alertsDropdown" id="timemanagement_clock" name="timemanagement_clock" aria-role="static">
|
||||
<h6 class="dropdown-header text-white">
|
||||
Zeiterfassung
|
||||
Zeiterfassung
|
||||
</h6>
|
||||
<div>
|
||||
{% block timemanagement_content_realtime %}
|
||||
|
|
@ -337,7 +337,7 @@
|
|||
</li>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
<!-- ALERT_AREA -->
|
||||
<!-- Nav Item - Alerts -->
|
||||
<li class="nav-item dropdown no-arrow mx-1">
|
||||
|
|
@ -363,9 +363,9 @@
|
|||
border-radius: 50%;
|
||||
-webkit-box-shadow: 0px 0px 4px 5px {{onlinecolor}};
|
||||
-moz-box-shadow: 0px 0px 4px 5px {{onlinecolor}};
|
||||
box-shadow: 0px 0px 4px 5px {{onlinecolor}};
|
||||
box-shadow: 0px 0px 4px 5px {{onlinecolor}};
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
|
|
@ -376,19 +376,19 @@
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(0)" href="#/">
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(0)" href="#/">
|
||||
<i class="fas fa-circle mr-2" style="color: green"></i>
|
||||
Online
|
||||
</a>
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(1)" href="#/">
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(1)" href="#/">
|
||||
<i class="fas fa-circle mr-2" style="color: red"></i>
|
||||
Beschäftigt
|
||||
</a>
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(2)" href="#/">
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(2)" href="#/">
|
||||
<i class="fas fa-circle mr-2" style="color: yellow"></i>
|
||||
Abwesend
|
||||
</a>
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(3)" href="#/">
|
||||
<a class="dropdown-item" onclick="javascript:changeOnlineStatus(3)" href="#/">
|
||||
<i class="fas fa-circle mr-2" style="color: grey"></i>
|
||||
Offline anzeigen
|
||||
</a>
|
||||
|
|
@ -396,14 +396,14 @@
|
|||
|
||||
<div class="dropdown-divider"></div>
|
||||
<!--<a class="dropdown-item" onclick="userGoToSettings({{user.pk}})" href="{% url 'orga-single' user.pk %}">-->
|
||||
<a class="dropdown-item" onclick="userGoToSettings()" href="#/">
|
||||
<a class="dropdown-item" onclick="userGoToSettings()" href="#/">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Einstellungen
|
||||
</a>
|
||||
<a class="dropdown-item" onclick="userGoToNotification()" href="#/">
|
||||
</a>
|
||||
<a class="dropdown-item" onclick="userGoToNotification()" href="#/">
|
||||
<i class="fas fa-bell fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Benachrichtigungen
|
||||
</a>
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="{% url 'users-logout' %}">
|
||||
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
|
|
@ -416,12 +416,12 @@
|
|||
|
||||
<!-- End of Topbar -->
|
||||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid" >
|
||||
<div class="container-fluid" >
|
||||
|
||||
<div id="searchcontent" style="min-height: 100%; margin-top: 85px;">
|
||||
</div>
|
||||
|
||||
<div id="maincontent" style="min-height: 100%; margin-top: 85px;" >
|
||||
|
||||
<div id="maincontent" style="min-height: 100%; margin-top: 85px;" >
|
||||
<!-- MESSAGES -->
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
|
|
@ -434,17 +434,17 @@
|
|||
{% endfor %}
|
||||
{% endif %}
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div style="height: 300px"> </div>
|
||||
</div> <!-- End of Main Content CONTAINER FLUID-->
|
||||
</div> <!-- End of Main Content CONTAINER FLUID-->
|
||||
<!-- End of Content Wrapper -->
|
||||
{% if active_link != 'chat' %}
|
||||
{% if request.user.profile.agency.module_chat %}
|
||||
<div id="chat_alluserscontent" style="position: fixed; bottom: 75px; right: 36px; z-index: 999;"></div>
|
||||
<button id="chatButton" class="btn btn-primary" style="position: fixed; right: 36px; bottom: 30px;"><i class="far fa-comments"></i></button>
|
||||
|
||||
<!-- CHATAREA -->
|
||||
<!-- CHATAREA -->
|
||||
<div id="dynamicchatwindow" class="col-4" style="position: fixed; bottom: 30px; right: 23px; display: none;z-index: 999;">
|
||||
|
||||
<div class="card">
|
||||
|
|
@ -454,10 +454,10 @@
|
|||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
</script>
|
||||
{% endif %}
|
||||
<!-- CHATAREA END -->
|
||||
<!-- CHATAREA END -->
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -489,14 +489,14 @@
|
|||
<script type="text/javascript" src="{%static 'users/vendor/jquery-easing/jquery.easing.min.js' %}"></script>
|
||||
<!-- DATABLES JS -->
|
||||
<script type="text/javascript" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
|
||||
<script type="text/javascript" src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script type="text/javascript" src="{%static 'users/js/sb-admin-2.js' %}"></script>
|
||||
<!-- CUSTOM FONT -->
|
||||
<!--<link href="{% static 'users/css/custom.css' %}" rel="stylesheet">-->
|
||||
|
||||
|
||||
|
||||
<!-- TABLE SORT -->
|
||||
<!--<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>-->
|
||||
|
||||
|
|
@ -509,14 +509,14 @@
|
|||
|
||||
|
||||
<link href="{% static 'users/css/custom.css' %}" type="text/css" rel="stylesheet">
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
{% if request.user.profile.showtooltips %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
$(document).ready(function(){
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
|
@ -524,18 +524,18 @@
|
|||
<script type="text/javascript">
|
||||
|
||||
function userGoToSettings(){
|
||||
localStorage.setItem('activeTabSettings', "profil");
|
||||
localStorage.setItem('activeTabSettings', "profil");
|
||||
location.href = "{% url 'dasettings' %}"
|
||||
}
|
||||
|
||||
function userGoToNotification(){
|
||||
localStorage.setItem('activeTabSettings', "notifications");
|
||||
localStorage.setItem('activeTabSettings', "notifications");
|
||||
location.href = "{% url 'dasettings' %}"
|
||||
}
|
||||
|
||||
function clearSF(){
|
||||
$("#searchcontent").empty();
|
||||
$("#searchcontent").hide();
|
||||
$("#searchcontent").hide();
|
||||
$("#maincontent").show();
|
||||
$("#search_string").val("");
|
||||
}
|
||||
|
|
@ -549,26 +549,26 @@ function clearSF(){
|
|||
data:{
|
||||
searchstring: searchstring
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
success: function( data )
|
||||
{
|
||||
$("#maincontent").hide();
|
||||
$("#searchcontent").show();
|
||||
$("#searchcontent").html(data);
|
||||
$("#searchcontent").html(data);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
} else {
|
||||
$("#searchcontent").empty();
|
||||
$("#searchcontent").hide();
|
||||
$("#searchcontent").hide();
|
||||
$("#maincontent").show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
$(document).ready(function(){
|
||||
if($( window ).width() < 768)
|
||||
{
|
||||
$("#accordionSidebar").addClass("toggled");
|
||||
$("#content-wrapper").css("margin-left" , "0px");
|
||||
$("#content-wrapper").css("margin-left" , "0px");
|
||||
|
||||
$("#topnavbarmain").css("margin-left" , "0px");
|
||||
|
||||
|
|
@ -577,21 +577,21 @@ $(document).ready(function(){
|
|||
});
|
||||
|
||||
// Toggle the side navigation
|
||||
function toggleSidebar(){
|
||||
function toggleSidebar(){
|
||||
|
||||
if(sidebar_hidden == false){
|
||||
$("#accordionSidebar").addClass("toggled");
|
||||
$("#accordionSidebar").addClass("toggled");
|
||||
$("#content-wrapper").css("margin-left" , "105px");
|
||||
|
||||
$("#topnavbarmain").css("margin-left" , "105px");
|
||||
$("#topnavbarmain").css("margin-left" , "105px");
|
||||
|
||||
sidebar_hidden = true;
|
||||
}
|
||||
else{
|
||||
$("#accordionSidebar").removeClass("toggled");
|
||||
$("#content-wrapper").css("margin-left" , "0px");
|
||||
$("#topnavbarmain").css("margin-left" , "0px");
|
||||
sidebar_hidden = false;
|
||||
$("#content-wrapper").css("margin-left" , "0px");
|
||||
$("#topnavbarmain").css("margin-left" , "0px");
|
||||
sidebar_hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -599,16 +599,16 @@ $( window ).resize(function() {
|
|||
if($( window ).width() < 750)
|
||||
{
|
||||
$("#accordionSidebar").addClass("toggled");
|
||||
$("#content-wrapper").css("margin-left" , "0px");
|
||||
$("#topnavbarmain").css("margin-left" , "0px");
|
||||
$("#content-wrapper").css("margin-left" , "0px");
|
||||
$("#topnavbarmain").css("margin-left" , "0px");
|
||||
sidebar_hidden = false;
|
||||
}
|
||||
else{
|
||||
$("#accordionSidebar").removeClass("toggled");
|
||||
$("#accordionSidebar").removeClass("toggled");
|
||||
$("#content-wrapper").css("margin-left" , "212px");
|
||||
|
||||
$("#topnavbarmain").css("margin-left" , "224px");
|
||||
sidebar_hidden = true;
|
||||
sidebar_hidden = true;
|
||||
}
|
||||
});
|
||||
/*
|
||||
|
|
@ -624,8 +624,8 @@ function loadUnsendNotifications(){
|
|||
data : {
|
||||
action : "checknotifications"
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
success: function( data )
|
||||
{
|
||||
$("#notification_items").html("");
|
||||
notifications = data['unknownnotification'];
|
||||
var i = 0;
|
||||
|
|
@ -634,7 +634,7 @@ function loadUnsendNotifications(){
|
|||
$("#notification_items").append('<span><a href="/'+notifications[i]['elelink']+'" id="notifyid_'+notifications[i]['not_id']+'" class="dropdown-item d-flex align-items-center"><div><div class="small text-gray-500">'+notifications[i]['date']+'</div>'+notifications[i]['text']+'</div></a></span>')
|
||||
i = i + 1;
|
||||
newunknownotificationscounter = newunknownotificationscounter + 1;
|
||||
}
|
||||
}
|
||||
$("#notificationcounter").html("");
|
||||
|
||||
if(i > 0){$("#notificationcounter").html(i);}
|
||||
|
|
@ -650,8 +650,8 @@ function loadUnviewnNotifications(){
|
|||
data : {
|
||||
action : "oldnotifications"
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
success: function( data )
|
||||
{
|
||||
notifications = data['oldnotifications'];
|
||||
i = 0;
|
||||
$("#notification_items").html("");
|
||||
|
|
@ -660,7 +660,7 @@ function loadUnviewnNotifications(){
|
|||
$("#notification_items").append('<a href="/'+notifications[i]['elelink']+'" id="notifyid_'+notifications[i]['not_id']+'" class="dropdown-item d-flex align-items-center"><div><div class="small text-gray-500">'+notifications[i]['date']+'</div>'+notifications[i]['text']+'</div></a>')
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -673,8 +673,8 @@ function changeNewNotToViewed(){
|
|||
data : {
|
||||
action : "newnotificationsviewed"
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
success: function( data )
|
||||
{
|
||||
$("#notificationcounter").html("");
|
||||
}
|
||||
});
|
||||
|
|
@ -711,12 +711,12 @@ $(document).ready(function(){
|
|||
}
|
||||
|
||||
const mainwebsocket = new WebSocket(ws_string+window.location.host+"/ws/")
|
||||
|
||||
mainwebsocket.onmessage = function(e) {
|
||||
if(e["data"] != "presence_update")
|
||||
|
||||
mainwebsocket.onmessage = function(e) {
|
||||
if(e["data"] != "presence_update")
|
||||
{
|
||||
//HANDLER FOR ALL PUSHNOTIFICATIONS
|
||||
if(e["data"].split("__")[0] == "pushnotification"){
|
||||
if(e["data"].split("__")[0] == "pushnotification"){
|
||||
|
||||
/*
|
||||
Check for Chat-Message in CHatview or invisible-Browser
|
||||
|
|
@ -727,7 +727,7 @@ $(document).ready(function(){
|
|||
if(finalsplit[0] != "Chat"){
|
||||
var notify = new Notification('Digitale Agentur', {
|
||||
body: e["data"].split("__")[1]
|
||||
});
|
||||
});
|
||||
}
|
||||
else{
|
||||
{% if active_link == "chat" %}
|
||||
|
|
@ -751,20 +751,20 @@ $(document).ready(function(){
|
|||
else{
|
||||
var notify = new Notification('Digitale Agentur', {
|
||||
body: e["data"].split("__")[1]
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
loadUnsendNotifications();
|
||||
loadUnviewnNotifications();
|
||||
}
|
||||
else{
|
||||
else{
|
||||
|
||||
{% if active_link == "chat" %}
|
||||
if(preventUpdatePresLive == false){
|
||||
updatePresenceLive();
|
||||
updatePresenceLive();
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
|
|
@ -778,10 +778,10 @@ $(document).ready(function(){
|
|||
//HEARTBEAT every minute
|
||||
setInterval(function()
|
||||
{
|
||||
mainwebsocket.send(JSON.stringify("heartbeat"));
|
||||
mainwebsocket.send(JSON.stringify("heartbeat"));
|
||||
console.log("heartbeat is alive...");
|
||||
},60000);
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
|
@ -793,8 +793,8 @@ function changeOnlineStatus(newstat){
|
|||
data : {
|
||||
newstat : newstat
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
success: function( data )
|
||||
{
|
||||
if(data["newstat"] == "0"){
|
||||
$("#userbaseprofilepicture").css({
|
||||
'-webkit-box-shadow' : '0px 0px 4px 5px green',
|
||||
|
|
@ -814,15 +814,15 @@ function changeOnlineStatus(newstat){
|
|||
'-webkit-box-shadow' : '0px 0px 4px 5px orange',
|
||||
'-moz-box-shadow': '0px 0px 4px 5px orange',
|
||||
'box-shadow': '0px 0px 4px 5px orange'
|
||||
})
|
||||
})
|
||||
}
|
||||
else if(data["newstat"] == "3"){
|
||||
$("#userbaseprofilepicture").css({
|
||||
'-webkit-box-shadow' : '0px 0px 4px 5px grey',
|
||||
'-moz-box-shadow': '0px 0px 4px 5px grey',
|
||||
'box-shadow': '0px 0px 4px 5px grey'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -836,7 +836,7 @@ window.onerror = function (msg, url, line) {
|
|||
} else {
|
||||
// check if permission is already granted
|
||||
if (Notification.permission === 'granted') {
|
||||
// show notification here
|
||||
// show notification here
|
||||
} else {
|
||||
// request permission from user
|
||||
Notification.requestPermission().then(function(p) {
|
||||
|
|
@ -851,7 +851,7 @@ window.onerror = function (msg, url, line) {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$("#chatButton").click(function(){
|
||||
|
|
@ -862,8 +862,8 @@ $("#chatButton").click(function(){
|
|||
data : {
|
||||
action : "getloggedusers"
|
||||
},
|
||||
success: function( data )
|
||||
{
|
||||
success: function( data )
|
||||
{
|
||||
$("#chat_alluserscontent").fadeToggle();
|
||||
$("#chat_alluserscontent").html(data);
|
||||
}
|
||||
|
|
@ -872,7 +872,3 @@ $("#chatButton").click(function(){
|
|||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,16 +11,16 @@
|
|||
<title>Digitale Agentur</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
|
||||
|
||||
<link rel="canonical" href="https://www.digitale-agentur.com">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
|
||||
|
||||
|
||||
|
||||
<link href="{%static 'users/vendor/fontawesome-free/css/all.min.css' %}" rel="stylesheet" type="text/css">
|
||||
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
<!--<link href="{%static 'users/css/bootstrap.min.css' %}" rel="stylesheet">-->
|
||||
<link href='https://fonts.googleapis.com/css?family=Roboto&display=swap' rel='stylesheet' type='text/css'>
|
||||
|
||||
|
|
@ -34,37 +34,37 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js"></script>
|
||||
|
||||
<!-- <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>-->
|
||||
<!-- CROPPER -->
|
||||
<link href="{% static 'users/css/cropper.min.css' %}" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
<!-- DATATABLES -->
|
||||
<link href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="{% static 'users/css/sb-admin-2.css' %}" rel="stylesheet">
|
||||
|
||||
|
||||
<link href="{% static 'users/css/theme.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'users/css/custom.css' %}" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.16/dist/summernote-bs4.js"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.16/dist/summernote.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.16/dist/summernote.css" rel="stylesheet">
|
||||
<script src="{% static 'summernote/lang/summernote-de-DE.min.js' %}"></script>
|
||||
|
||||
<style type="text/css">
|
||||
.background-image {
|
||||
background-image: url('{% static 'users/img/registerbackground.jpg' %}');
|
||||
background-size: cover; /* Resize the background image to cover the entire container */
|
||||
background-size: cover; /* Resize the background image to cover the entire container */
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
filter: blur(8px);
|
||||
|
|
@ -85,7 +85,7 @@
|
|||
|
||||
<ul class=" bg-gray-900 navbar sidebar-dark accordion fixed-top" id="accordionSidebar">
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="{% url 'users-dashboard' %}">
|
||||
|
||||
|
||||
<div class="sidebar-brand-text mx-3" style="text-align: left;">
|
||||
<img src="{% static 'users/img/logo.png' %}" style="float: left;" width="7%" class="">
|
||||
<img src="{% static 'users/img/VVE-Logo.png' %}" style="float: right;" width="2.5%" class="">
|
||||
|
|
@ -94,13 +94,13 @@
|
|||
</ul>
|
||||
<style type="text/css">
|
||||
#logincard {
|
||||
width: 35%;
|
||||
width: 35%;
|
||||
min-width: 500px !important;
|
||||
margin-top: 4%;
|
||||
}
|
||||
</style>
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
426
users/views.py
426
users/views.py
|
|
@ -56,10 +56,10 @@ def randomString(stringLength=10):
|
|||
|
||||
@login_required
|
||||
def toUpdate(request):
|
||||
# NO AGENVYJOBS
|
||||
# NO AGENVYJOBS
|
||||
# CREATE DEFAULT
|
||||
'''
|
||||
|
||||
|
||||
Agenturleiter
|
||||
Außendienst
|
||||
Innendienst
|
||||
|
|
@ -97,25 +97,25 @@ def toUpdate(request):
|
|||
temgroup_mitarbeiter_ag.group.user_set.add(user)
|
||||
|
||||
# ADDING ALL RIGHTS TO GROUP "VERWALTUNG"
|
||||
perms = AgencyGroup._meta.permissions
|
||||
perms = AgencyGroup._meta.permissions
|
||||
for p in perms:
|
||||
tempperm = Permission.objects.get(codename=p[0])
|
||||
temgroup_verwaltung_ag.group.permissions.add(tempperm)
|
||||
print("default groups created and users added")
|
||||
else:
|
||||
else:
|
||||
print("default groups existing")
|
||||
|
||||
# CHECK FOR ALL POSSIBLE RIGHTS ON ADMINGROUP
|
||||
m2m_changed.disconnect(adjust_group_notifications_permission, sender=Group.permissions.through)
|
||||
|
||||
|
||||
ag_admingroup = list(AgencyGroup.objects.filter(agency=request.user.profile.agency, is_admin=True))[0]
|
||||
perms = AgencyGroup._meta.permissions
|
||||
perms = AgencyGroup._meta.permissions
|
||||
for p in perms:
|
||||
tempperm = Permission.objects.get(codename=p[0])
|
||||
ag_admingroup.group.permissions.add(tempperm)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# INITIAL ROOT DIR
|
||||
rootdir = DataDir.objects.filter(is_root=True, agency__pk=request.user.profile.agency.pk)
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ def toUpdate(request):
|
|||
print("NO MAIN DIR FOUND - CREATE")
|
||||
rootdir = DataDir(is_root=True, agency=request.user.profile.agency)
|
||||
rootdir.save()
|
||||
print("AGENCY ROOT DIR CREATED")
|
||||
print("AGENCY ROOT DIR CREATED")
|
||||
else:
|
||||
print("MAIN ROOT DIR FOUND - FILESMODULE READY")
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ def toUpdate(request):
|
|||
os.mkdir(os.path.join(settings.MEDIA_ROOT + "/agencydata/", "agency_" + str(request.user.profile.agency.pk) + "/files"))
|
||||
os.mkdir(os.path.join(settings.MEDIA_ROOT + "/agencydata/", "agency_" + str(request.user.profile.agency.pk) + "/agencystats"))
|
||||
os.mkdir(os.path.join(settings.MEDIA_ROOT + "/agencydata/", "agency_" + str(request.user.profile.agency.pk) + "/agencystats/profilepics"))
|
||||
|
||||
|
||||
# DEF STANDARD DIR
|
||||
defstandard = DataDir.objects.filter(is_defaultstandard=True, agency__pk=request.user.profile.agency.pk)
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ def toUpdate(request):
|
|||
# USER TIME MODEL
|
||||
usersofagency = User.objects.filter(profile__agency=request.user.profile.agency)
|
||||
|
||||
for u in usersofagency:
|
||||
for u in usersofagency:
|
||||
# CREATE USERTIME-OBJECT
|
||||
if(len(UserTime.objects.filter(user=u)) == 0):
|
||||
usertime_new = UserTime(user=u)
|
||||
|
|
@ -182,19 +182,19 @@ Templates: welcomeusers.html und base.html
|
|||
'''
|
||||
def registerNewAgency(request):
|
||||
if request.method == "POST":
|
||||
|
||||
|
||||
newagencyform = NewAgencyForm(request.POST)
|
||||
|
||||
if newagencyform.is_valid():
|
||||
|
||||
# Check Mail
|
||||
email = newagencyform.cleaned_data.get('mail')
|
||||
|
||||
|
||||
mailset = User.objects.filter(email=email)
|
||||
if(len(mailset) == 0):
|
||||
newuser_name = newagencyform.cleaned_data.get('first_name') + ' ' + newagencyform.cleaned_data.get('last_name')
|
||||
|
||||
agency = Agency()
|
||||
|
||||
agency = Agency()
|
||||
agency.name = newagencyform.cleaned_data.get("agencyname")
|
||||
agency.vve = newagencyform.cleaned_data.get("vve")
|
||||
agency.save()
|
||||
|
|
@ -212,9 +212,9 @@ def registerNewAgency(request):
|
|||
user.profile = pr
|
||||
user.save()
|
||||
|
||||
msg_html = render_to_string('users/register_mail.html', {'username': newuser_name})
|
||||
|
||||
# E-Mail für Passwort-Setzung!
|
||||
msg_html = render_to_string('users/register_mail.html', {'username': newuser_name})
|
||||
|
||||
# E-Mail für Passwort-Setzung!
|
||||
form = PasswordResetForm({'email': email})
|
||||
if form.is_valid():
|
||||
form.save(request=request,html_email_template_name='users/password_reset_mail.html')
|
||||
|
|
@ -225,10 +225,10 @@ def registerNewAgency(request):
|
|||
'Agenturanmeldung',
|
||||
'Hallo ' + newagencyform.cleaned_data.get('first_name') + ' ' + newagencyform.cleaned_data.get('last_name') + '! Bitte setzen sie sich auf https://digitale-agentur.com/password-reset/ ein Passwort. Anschließend können Sie weitere Details Ihrer Agentur eingeben.',
|
||||
'noreply@digitale-agentur.com',
|
||||
[email],
|
||||
[email],
|
||||
html_message=msg_html,
|
||||
fail_silently=True
|
||||
)
|
||||
)
|
||||
'''
|
||||
return render (request, 'users/registercomplete.html')
|
||||
|
||||
|
|
@ -238,7 +238,7 @@ def registerNewAgency(request):
|
|||
"form" : NewAgencyForm(request.POST)
|
||||
}
|
||||
return render (request, 'users/register.html',context)
|
||||
|
||||
|
||||
else:
|
||||
messages.success(request, f'Es ist ein Fehler aufgetreten.')
|
||||
|
||||
|
|
@ -258,39 +258,39 @@ class AgencyCreateView(CreateView):
|
|||
fields = ['first_name', 'last_name','username', 'email']
|
||||
success_url = '/register/done'
|
||||
|
||||
def form_valid(self, form):
|
||||
def form_valid(self, form):
|
||||
# Send message to the site
|
||||
messages.success(self.request, f'Agentur erstellt! Es wurde eine E-Mail verschickt mit weitere Infos zur Passworterstellung.')
|
||||
# SAVE OBJECTS TO SIGNALE!
|
||||
agency = Agency()
|
||||
agency = Agency()
|
||||
agency.name = self.request.POST.get("agency_name")
|
||||
agency.save()
|
||||
newuser_name = form.cleaned_data.get('first_name') + ' ' + form.cleaned_data.get('last_name')
|
||||
form.instance.agency = agency
|
||||
form.instance.parent = None
|
||||
msg_html = render_to_string('users/register_mail.html', {'username': newuser_name})
|
||||
# E-Mail für Passwort-Setzung!
|
||||
msg_html = render_to_string('users/register_mail.html', {'username': newuser_name})
|
||||
# E-Mail für Passwort-Setzung!
|
||||
send_mail(
|
||||
'Agenturanmeldung',
|
||||
'Hallo ' + form.cleaned_data.get('first_name') + ' ' + form.cleaned_data.get('last_name') + '! Bitte setzen sie sich auf https://digitale-agentur.com/password-reset/ ein Passwort. Anschließend können Sie weitere Details Ihrer Agentur eingeben.',
|
||||
'noreply@digitale-agentur.com',
|
||||
[form.cleaned_data.get('email')],
|
||||
[form.cleaned_data.get('email')],
|
||||
html_message=msg_html,
|
||||
fail_silently=True
|
||||
)
|
||||
return super().form_valid(form)
|
||||
)
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
@login_required
|
||||
def dashboard(request):
|
||||
|
||||
|
||||
# UPDATE FUNCTIONS BY NEW MODEL-CHANGES FOR COPIEN SOME DATA
|
||||
toUpdate(request)
|
||||
|
||||
|
||||
|
||||
#storageinfo = sys.getfilesystemencoding()
|
||||
|
||||
context = {
|
||||
|
||||
context = {
|
||||
'active_link' : 'dashboard',
|
||||
#"systemencode" : storageinfo
|
||||
}
|
||||
|
|
@ -298,8 +298,8 @@ def dashboard(request):
|
|||
# Loading only user same agency
|
||||
# Change context and return for template-data
|
||||
# # Get all Users of the Same Agency as logged user
|
||||
standards_of_agency = Standards.objects.filter(agency__pk=request.user.profile.agency.pk).filter(public=True).exclude(area=None).exclude(task=None).order_by('-last_modified_on')[:5]
|
||||
|
||||
standards_of_agency = Standards.objects.filter(agency__pk=request.user.profile.agency.pk).filter(public=True).exclude(area=None).exclude(task=None).order_by('-last_modified_on')[:5]
|
||||
|
||||
filterdate = datetime.now()
|
||||
news = News.objects.filter(agency__pk=request.user.profile.agency.pk).filter(go_online_on__lt=filterdate).filter(go_offline_on__gt=filterdate).order_by('-go_online_on')[:4]
|
||||
|
||||
|
|
@ -331,19 +331,19 @@ class UsersCreateUser(LoginRequiredMixin, CreateView):
|
|||
model = User
|
||||
fields = ['first_name', 'last_name', 'email']
|
||||
success_url = '/settings/newuser/s2/'
|
||||
|
||||
|
||||
# Adding active_link
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context.update({'active_link' : 'settings'})
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
def form_valid(self, form):
|
||||
# Send message to the site
|
||||
messages.success(self.request, f'Neuer Mitarbeiter angelegt!')
|
||||
# SAVE OBJECTS TO SIGNALE!
|
||||
form.instance.agency = self.request.user.profile.agency
|
||||
form.instance.parent = None
|
||||
form.instance.parent = None
|
||||
newuser_name = form.cleaned_data.get('first_name') + " " + form.cleaned_data.get('last_name')
|
||||
msg_html = render_to_string('users/newusers_email.html', {'username': newuser_name})
|
||||
'''
|
||||
|
|
@ -355,7 +355,7 @@ class UsersCreateUser(LoginRequiredMixin, CreateView):
|
|||
[form.cleaned_data.get('email')],
|
||||
html_message=msg_html,
|
||||
fail_silently=True,
|
||||
)
|
||||
)
|
||||
'''
|
||||
return super().form_valid(form)
|
||||
|
||||
|
|
@ -364,14 +364,14 @@ class UsersCreateUser(LoginRequiredMixin, CreateView):
|
|||
def profile(request):
|
||||
if request.method == 'POST':
|
||||
u_form = UsersChangeProfil(request.POST, instance=request.user)
|
||||
|
||||
|
||||
if u_form.is_valid():
|
||||
u_form.save()
|
||||
prename = request.user.first_name
|
||||
name = request.user.last_name
|
||||
messages.success(request, f'Daten für {prename} {name} aktualisiert!')
|
||||
# Daten neu laden und nicht die "Mächten sie die Daten speichern...?"
|
||||
return redirect('users-dashboard')
|
||||
# Daten neu laden und nicht die "Mächten sie die Daten speichern...?"
|
||||
return redirect('users-dashboard')
|
||||
|
||||
else:
|
||||
# Form in Klammern sind die aktuellen Daten :)
|
||||
|
|
@ -387,16 +387,16 @@ def profile(request):
|
|||
|
||||
# Hier andere Nutzer ändern, wenn man Usersmanagement darf!
|
||||
class UserManagementUpdateForm(LoginRequiredMixin, UpdateView):
|
||||
model = Profile
|
||||
labels = {
|
||||
model = Profile
|
||||
labels = {
|
||||
"phoneland" : "Telefon",
|
||||
"phonemobile" : "Mobil",
|
||||
"compfunc" : "Agenturfunktion",
|
||||
}
|
||||
fields = ['phoneland','phonemobile','compfunc']
|
||||
fields = ['phoneland','phonemobile','compfunc']
|
||||
|
||||
# Update der Zugrifssrechte eines Users
|
||||
class UsersPermUpdateView(LoginRequiredMixin, View):
|
||||
class UsersPermUpdateView(LoginRequiredMixin, View):
|
||||
template_name = 'users/users_perm.html'
|
||||
form_class = UsersPermForm
|
||||
success_url = '/dashboard/usersman/'
|
||||
|
|
@ -405,11 +405,11 @@ class UsersPermUpdateView(LoginRequiredMixin, View):
|
|||
# Form wird geladen; Checkboxen werden vorbereitet und hier rausgerendert.
|
||||
def get(self,request,*args, **kwargs):
|
||||
# User ist der hier Aufgerufene, bzw. das Profil!
|
||||
user_tochange = Profile.objects.get(pk=kwargs['pk']).user
|
||||
user_tochange = Profile.objects.get(pk=kwargs['pk']).user
|
||||
return render (request, self.template_name, {'form':self.form_class(user_tochange), 'active_link': 'usersmanagement', 'user_tochange': user_tochange})
|
||||
|
||||
# Handle POST GTTP requests
|
||||
def post(self, request, *args, **kwargs):
|
||||
def post(self, request, *args, **kwargs):
|
||||
permissions_loaded = dict(request.POST.lists())
|
||||
user_tochange = Profile.objects.get(pk=kwargs['pk']).user
|
||||
# ITERATION Über alle Elemente gehen und Rechte entziehen (nicht vorhanden) oder adden (wenn vorhanden)
|
||||
|
|
@ -418,14 +418,14 @@ class UsersPermUpdateView(LoginRequiredMixin, View):
|
|||
temprof = Profile
|
||||
for ele in temprof._meta.permissions:
|
||||
tempperm = Permission.objects.get(codename=ele[0])
|
||||
if ele[0] in permissions_loaded:
|
||||
if ele[0] in permissions_loaded:
|
||||
user_tochange.user_permissions.add(tempperm)
|
||||
else:
|
||||
else:
|
||||
# Eingeloggter User darf sich nicht selbst die Userverwaltungsrechte entziehen
|
||||
if user_tochange == request.user and ele[0]=='usermanager':
|
||||
messages.warning(request, f'Benutzerverwaltungsrechte für {user_tochange.first_name} {user_tochange.last_name} kann nicht entfernt werden.')
|
||||
else:
|
||||
user_tochange.user_permissions.remove(tempperm)
|
||||
user_tochange.user_permissions.remove(tempperm)
|
||||
user_tochange.save()
|
||||
messages.success(request, f'Berechtigungen für {user_tochange.first_name} {user_tochange.last_name} aktualisiert!')
|
||||
return HttpResponseRedirect('/dashboard/usersman/')
|
||||
|
|
@ -434,7 +434,7 @@ class UsersPermUpdateView(LoginRequiredMixin, View):
|
|||
@login_required
|
||||
def ProfileUpdateView(request, pk):
|
||||
prof_user = User.objects.get(profile__pk=pk)
|
||||
|
||||
|
||||
if request.method == 'POST':
|
||||
profileform_form = UsersAddProfileForm(request.POST, request.FILES, instance=prof_user.profile)
|
||||
#profileform_parents = UsersAddProfileFormParents(request.POST, instance=request.user)
|
||||
|
|
@ -442,25 +442,25 @@ def ProfileUpdateView(request, pk):
|
|||
name = prof_user.last_name
|
||||
|
||||
if profileform_form.is_valid():
|
||||
profileform_form.save()
|
||||
messages.success(request, f'Daten für {prename} {name} aktualisiert!')
|
||||
return redirect('users-management')
|
||||
profileform_form.save()
|
||||
messages.success(request, f'Daten für {prename} {name} aktualisiert!')
|
||||
return redirect('users-management')
|
||||
|
||||
else:
|
||||
# Form in Klammern sind die aktuellen Daten :)
|
||||
profileform_form = UsersAddProfileForm(instance=prof_user.profile)
|
||||
|
||||
|
||||
# Nur User, die im Organigramm auch sichtbar sein, können ausgewählt werden
|
||||
possible_users = User.objects.filter(profile__agency__pk=prof_user.profile.agency.pk).filter(profile__visible=True)
|
||||
possible_users = User.objects.filter(profile__agency__pk=prof_user.profile.agency.pk).filter(profile__visible=True)
|
||||
|
||||
context = {
|
||||
'prof_user' : prof_user,
|
||||
'profileform_form' : profileform_form,
|
||||
'profileform_form' : profileform_form,
|
||||
'active_link' : 'usersmanagement',
|
||||
'possible_users' : possible_users
|
||||
}
|
||||
|
||||
|
||||
|
||||
return render(request, 'users/profile_update.html', context)
|
||||
|
||||
'''
|
||||
|
|
@ -471,13 +471,13 @@ def ProfileUpdateView(request, pk):
|
|||
@login_required
|
||||
def setuserparent(request):
|
||||
if request.method == 'GET':
|
||||
if request.GET['action'] == 'adduserp':
|
||||
if request.GET['action'] == 'adduserp':
|
||||
userid = request.GET['objectid']
|
||||
toadd = request.GET['userid']
|
||||
toadd_user = User.objects.get(pk=toadd)
|
||||
workinguser = User.objects.get(pk=userid)
|
||||
username_clean = toadd_user.first_name + " " + toadd_user.last_name
|
||||
workinguser.profile.parent = toadd_user
|
||||
workinguser.profile.parent = toadd_user
|
||||
workinguser.save()
|
||||
# Getting Remaining-Users
|
||||
possible_users = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk)
|
||||
|
|
@ -486,14 +486,14 @@ def setuserparent(request):
|
|||
final_possible_users = {}
|
||||
for ele in possible_users_js:
|
||||
final_possible_users.update({'first_name':ele['first_name'],'last_name':ele['last_name'],'id':ele['id']})
|
||||
# Counter for remaining users to show/hide "Keine Mitarbeiter"-Div
|
||||
# Counter for remaining users to show/hide "Keine Mitarbeiter"-Div
|
||||
return JsonResponse({'userid' : userid, 'username_clean' : username_clean, 'remaining_users':possible_users_js})
|
||||
else:
|
||||
return HttpResponse("Request method is not a GET")
|
||||
|
||||
@login_required
|
||||
def changeonlinestat(request):
|
||||
if request.method == 'GET':
|
||||
if request.method == 'GET':
|
||||
request.user.profile.onlinestatus = request.GET["newstat"]
|
||||
request.user.save()
|
||||
return JsonResponse({"newstat" : request.GET["newstat"]})
|
||||
|
|
@ -511,9 +511,9 @@ class ProfileDeleteView(LoginRequiredMixin, DeleteView):
|
|||
model = User
|
||||
success_url = '/dasettings/main'
|
||||
template_name = 'users/user_confirm_delete.html'
|
||||
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
user = User.objects.get(pk=kwargs['pk'])
|
||||
logged_user = request.user
|
||||
areas_fs = Areas.objects.filter(created_area_by=user)
|
||||
|
|
@ -549,8 +549,8 @@ class ProfileDeleteView(LoginRequiredMixin, DeleteView):
|
|||
return response
|
||||
|
||||
@login_required
|
||||
def agency(request):
|
||||
context = {
|
||||
def agency(request):
|
||||
context = {
|
||||
'active_link' : 'agencyinfo'
|
||||
}
|
||||
return render(request, 'users/agency.html', context)
|
||||
|
|
@ -563,7 +563,7 @@ class AgencyUpdateView(LoginRequiredMixin, UpdateView):
|
|||
success_url = '/dashboard/agencyinfo'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(AgencyUpdateView, self).get_context_data(**kwargs)
|
||||
context = super(AgencyUpdateView, self).get_context_data(**kwargs)
|
||||
context['active_link'] = 'agencyinfo'
|
||||
return context
|
||||
|
||||
|
|
@ -571,19 +571,19 @@ class AgencyUpdateView(LoginRequiredMixin, UpdateView):
|
|||
# PRIORISIERUNG
|
||||
'''
|
||||
|
||||
Es werden alle Aufgabenbereiche den Bereichen der Agentur zugeordnet und ausgegeben.
|
||||
Es werden alle Aufgabenbereiche den Bereichen der Agentur zugeordnet und ausgegeben.
|
||||
|
||||
'''
|
||||
@login_required
|
||||
def UsersPrio(request, pk):
|
||||
|
||||
user = User.objects.get(pk=pk)
|
||||
|
||||
|
||||
if(user.profile.agency.pk != request.user.profile.agency.pk):
|
||||
return HttpResponseRedirect('users-dashboard')
|
||||
else:
|
||||
prios = Prio.objects.filter(user__pk=pk)
|
||||
areas = Areas.objects.filter(agency__pk=request.user.profile.agency.pk)
|
||||
prios = Prio.objects.filter(user__pk=pk)
|
||||
areas = Areas.objects.filter(agency__pk=request.user.profile.agency.pk)
|
||||
user_first_name = user.first_name
|
||||
user_last_name = user.last_name
|
||||
user_id = user.pk
|
||||
|
|
@ -598,7 +598,7 @@ def UsersPrio(request, pk):
|
|||
|
||||
return render(request, 'users/users_prio.html', context)
|
||||
'''
|
||||
|
||||
|
||||
Ajax-Call für Prio.Updates seitens des Users
|
||||
im Profil
|
||||
|
||||
|
|
@ -645,7 +645,7 @@ def GlobalSearch(request):
|
|||
|
||||
res_files = DataFile.objects.filter(agency__pk=ag).filter(name__icontains=searchfor)
|
||||
|
||||
|
||||
|
||||
|
||||
html = render_to_string('users/searchres.html', {'links': links, 'res_standard': res_standard, 'res_areas': res_areas, 'res_tasks': res_tasks, 'res_pers': res_pers, 'res_news' : res_news, 'res_pass' : res_pass, 'res_contacts' : res_contacts, 'res_files' : res_files, 'user' : request.user})
|
||||
return HttpResponse(html)
|
||||
|
|
@ -657,7 +657,7 @@ def searchStandardRouter(request):
|
|||
if request.method == 'GET':
|
||||
return redirect('/standards/standard/'+request.GET['s_id']+'/single')
|
||||
else:
|
||||
return redirect('dashboard')
|
||||
return redirect('dashboard')
|
||||
'''
|
||||
|
||||
Hier werden die Zuständigkeiten eines Benutzers über alle Bereiche/Aufgaben hinweg gesetzt.
|
||||
|
|
@ -669,14 +669,14 @@ def UsersAreaTaskUpdate(request, pk):
|
|||
|
||||
user = User.objects.get(pk=pk)
|
||||
if request.user.profile.agency.pk != user.profile.agency.pk:
|
||||
return redirect('dashboard')
|
||||
return redirect('dashboard')
|
||||
else:
|
||||
finaldata = {}
|
||||
context = {
|
||||
'active_link' : 'usersmanagement',
|
||||
'user_id' : user.pk,
|
||||
'active_link' : 'usersmanagement',
|
||||
'user_id' : user.pk,
|
||||
}
|
||||
|
||||
|
||||
if request.method == 'POST':
|
||||
form = request.POST
|
||||
areatask_formdata = list(form)
|
||||
|
|
@ -693,22 +693,22 @@ def UsersAreaTaskUpdate(request, pk):
|
|||
area_ids.append(int(tempdata[1]))
|
||||
elif(tempdata[0] == 'task'):
|
||||
task_ids.append(int(tempdata[1]))
|
||||
|
||||
|
||||
# Alle Areas und Tasks laden
|
||||
areas = Areas.objects.filter(agency__pk=user.profile.agency.pk)
|
||||
tasks = Tasks.objects.filter(agency__pk=user.profile.agency.pk)
|
||||
|
||||
|
||||
# Prüfen, ob der User in Area ist oder nicht und ihn ggf. hinzufügen/entfernen
|
||||
for area in areas:
|
||||
if area.pk in area_ids:
|
||||
area.usersfield.add(user)
|
||||
area.usersfield.add(user)
|
||||
else:
|
||||
area.usersfield.remove(user)
|
||||
area.save()
|
||||
|
||||
'''
|
||||
|
||||
Prüfen, ob ein User einem Aufgabenbereich hinzugeprdnet ist.
|
||||
Prüfen, ob ein User einem Aufgabenbereich hinzugeprdnet ist.
|
||||
Ist er im Bereich, passiert nichts. Ist er nicht in diesem
|
||||
Bereich, wird er dem usersfield der Aufgabe und der Tabelle
|
||||
Prio hinzugeüfügt. Damit kann der User seine individuellen
|
||||
|
|
@ -728,7 +728,7 @@ def UsersAreaTaskUpdate(request, pk):
|
|||
task.save()
|
||||
username_message = user.first_name + " " + user.last_name
|
||||
messages.success(request, f'Zuständigkeiten für {username_message} aktualisiert!')
|
||||
return redirect('users-management')
|
||||
return redirect('users-management')
|
||||
else:
|
||||
form = UserAreaTaskForm(user)
|
||||
user_first_name = user.first_name
|
||||
|
|
@ -747,7 +747,7 @@ def UsersAreaTaskUpdate(request, pk):
|
|||
@login_required
|
||||
def support(request):
|
||||
context = {
|
||||
'active_link' : 'support',
|
||||
'active_link' : 'support',
|
||||
'form' : SupportForm(request.user)
|
||||
}
|
||||
|
||||
|
|
@ -758,35 +758,35 @@ def support(request):
|
|||
attachments=[] #myfile is the key of a multi value dictionary, values are the uploaded files
|
||||
for f in request.FILES.getlist('attachment_1'): #myfile is the name of your html file button
|
||||
filename = f.name
|
||||
attachment_type = filetype.guess(f)
|
||||
fileblob = str(base64.b64encode(f.read()))
|
||||
attachment_type = filetype.guess(f)
|
||||
fileblob = str(base64.b64encode(f.read()))
|
||||
fileblob = fileblob[1 : : ]
|
||||
fileblob = fileblob[1 : : ]
|
||||
fileblob = fileblob[:-1:]
|
||||
attachments.append({str(filename) : "data:" + attachment_type.mime + ";base64," + fileblob})
|
||||
fileblob = "data:" + attachment_type.mime + ";base64," + fileblob
|
||||
|
||||
|
||||
for f in request.FILES.getlist('attachment_2'): #myfile is the name of your html file button
|
||||
filename = f.name
|
||||
attachment_type = filetype.guess(f)
|
||||
fileblob = str(base64.b64encode(f.read()))
|
||||
attachment_type = filetype.guess(f)
|
||||
fileblob = str(base64.b64encode(f.read()))
|
||||
fileblob = fileblob[1 : : ]
|
||||
fileblob = fileblob[1 : : ]
|
||||
fileblob = fileblob[:-1:]
|
||||
attachments.append({str(filename) : "data:" + attachment_type.mime + ";base64," + fileblob})
|
||||
for f in request.FILES.getlist('attachment_2'): #myfile is the name of your html file button
|
||||
filename = f.name
|
||||
attachment_type = filetype.guess(f)
|
||||
fileblob = str(base64.b64encode(f.read()))
|
||||
attachment_type = filetype.guess(f)
|
||||
fileblob = str(base64.b64encode(f.read()))
|
||||
fileblob = fileblob[1 : : ]
|
||||
fileblob = fileblob[1 : : ]
|
||||
fileblob = fileblob[:-1:]
|
||||
attachments.append({str(filename) : "data:" + attachment_type.mime + ";base64," + fileblob})
|
||||
'''
|
||||
#image = request.FILES
|
||||
supportdata = dict(form)
|
||||
supportdata = dict(form)
|
||||
# Data from Form to JSON-Format
|
||||
name = str(supportdata['name'][0])
|
||||
name = str(supportdata['name'][0])
|
||||
mail = str(supportdata['mail'][0])
|
||||
problemconc = str(supportdata['problemconc'][0])
|
||||
problem = str(supportdata['problem'][0])
|
||||
|
|
@ -794,31 +794,31 @@ def support(request):
|
|||
# HEADERS CURL
|
||||
headers = {'X-API-Key': 'F025A238EB74914E3653BA2989BFF7C4'}
|
||||
subject = "Digitale Agentur: " + str(problemconc)
|
||||
|
||||
|
||||
# DataJSON
|
||||
ostdata = {
|
||||
"topicId" : '12',
|
||||
"name": name,
|
||||
"email": mail,
|
||||
"email": mail,
|
||||
"subject": 'Digitale Agentur: '+problemconc,
|
||||
"ip": "1.1.1.1",
|
||||
"message": "*****************************\nAgentur: "+ request.user.profile.agency.name +" (ID: "+ str(request.user.profile.agency.pk) +")\nBenutzer: "+request.user.first_name+" "+request.user.last_name+" (ID: "+ str(request.user.pk) +")\n*******************************\n\n" + problem
|
||||
#"attachments" : attachments
|
||||
|
||||
}
|
||||
json_data = json.dumps(ostdata)
|
||||
}
|
||||
json_data = json.dumps(ostdata)
|
||||
|
||||
r = requests.post("https://support.vh-solutions.de/api/http.php/tickets.json", data=json_data, headers=headers)
|
||||
|
||||
# IF request FAILED error-Message
|
||||
r = requests.post("https://support.vh-solutions.de/api/http.php/tickets.json", data=json_data, headers=headers)
|
||||
|
||||
# IF request FAILED error-Message
|
||||
if(r.status_code != 201):
|
||||
messages.warning(request, f'Supportanfrage fehlgeschlagen!' + str(r))
|
||||
messages.warning(request, f'Supportanfrage fehlgeschlagen!' + str(r))
|
||||
else:
|
||||
messages.success(request, f'Supportanfrage erfolgreich! Ihre Ticketnummer ist '+ str(r.json()) +'!')
|
||||
|
||||
messages.success(request, f'Supportanfrage erfolgreich! Ihre Ticketnummer ist '+ str(r.json()) +'!')
|
||||
|
||||
return render(request, 'users/support_done.html', context)
|
||||
else:
|
||||
|
||||
|
||||
return render(request, 'users/support.html', context)
|
||||
|
||||
'''
|
||||
|
|
@ -827,23 +827,23 @@ Schickt eine E-Mail an den User inkl. Passwortlink zum zurücksetzen.
|
|||
|
||||
'''
|
||||
def sendpassmail(request):
|
||||
if(request.method == 'GET'):
|
||||
if(request.method == 'GET'):
|
||||
userid = request.GET['userid']
|
||||
tempuser = User.objects.get(pk=userid)
|
||||
# E-Mail für Passwort-Setzung!
|
||||
tempuser = User.objects.get(pk=userid)
|
||||
# E-Mail für Passwort-Setzung!
|
||||
form = PasswordResetForm({'email': tempuser.email})
|
||||
if form.is_valid():
|
||||
form.save(request=request,html_email_template_name='users/password_reset_mail.html')
|
||||
return render (request, 'users/registercomplete.html')
|
||||
return render (request, 'users/registercomplete.html')
|
||||
return JsonResponse({'message' : 0})
|
||||
|
||||
def datenschutz(request):
|
||||
def datenschutz(request):
|
||||
if request.user.is_authenticated:
|
||||
return render(request, 'users/datenschutz.html')
|
||||
else:
|
||||
return render(request, 'users/datenschutz_p.html')
|
||||
|
||||
def impressum(request):
|
||||
def impressum(request):
|
||||
if request.user.is_authenticated:
|
||||
return render(request, 'users/impressum.html')
|
||||
else:
|
||||
|
|
@ -876,37 +876,37 @@ def handler500(request):
|
|||
# CRONJOBS ALLE 5 MINUTEN
|
||||
def cronactions(request, code):
|
||||
data = {}
|
||||
if(code == settings.CRONAPIKEY):
|
||||
# NEWS CHECKING
|
||||
all_unnotifc_news = News.objects.filter(agnotify=False, go_online_on__lt=timezone.now())
|
||||
if(code == settings.CRONAPIKEY):
|
||||
# NEWS CHECKING
|
||||
all_unnotifc_news = News.objects.filter(agnotify=False, go_online_on__lt=timezone.now())
|
||||
allusers = User.objects.all()
|
||||
for news in all_unnotifc_news:
|
||||
targeturl = settings.BASE_URL + "news/news/" + str(news.pk) + "/single"
|
||||
# NEW NEWS FOUND WHICH HAVE TO GO ONLINE NOW!
|
||||
news.agnotify = True
|
||||
news.save()
|
||||
for user in allusers:
|
||||
for user in allusers:
|
||||
# SEMI-SIGNAL FOR NEWS GOING ONLINE
|
||||
if(user.usernotifications.news_created_mail and news.agency == user.profile.agency):
|
||||
notificationtext = "Neue Agenturnews: " + news.name
|
||||
username = user.first_name + " " + user.last_name
|
||||
msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext, 'linktarget' : targeturl})
|
||||
msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext, 'linktarget' : targeturl})
|
||||
send_mail(
|
||||
'Agentur-Benachrichtigung',
|
||||
'Hallo ' + user.first_name + ' ' + user.last_name + '! ' + notificationtext,
|
||||
'noreply@digitale-agentur.com',
|
||||
[user.email],
|
||||
[user.email],
|
||||
html_message=msg_html,
|
||||
fail_silently=True
|
||||
)
|
||||
|
||||
|
||||
if(user.usernotifications.news_created_push and news.agency == user.profile.agency):
|
||||
newnotification = UserNotification(touser=user, notificationtext="Neue Agenturnews: " + news.name, notificationtype="agencynews", elementid=news.pk)
|
||||
newnotification.save()
|
||||
|
||||
channel_layer = channels.layers.get_channel_layer()
|
||||
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__News | Neue Agenturnews: " + news.name})
|
||||
|
||||
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__News | Neue Agenturnews: " + news.name})
|
||||
|
||||
# LEXOFFICE TEST
|
||||
# HEADERS CURL
|
||||
'''
|
||||
|
|
@ -915,41 +915,41 @@ def cronactions(request, code):
|
|||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
}
|
||||
|
||||
|
||||
# DataJSON
|
||||
lexdata = {
|
||||
lexdata = {
|
||||
"voucherDate": "2020-07-09T00:00:00.000+01:00",
|
||||
"address" : {
|
||||
"name" : "Agenturname XXX",
|
||||
"name" : "Agenturname XXX",
|
||||
"countryCode" : "DE"
|
||||
},
|
||||
"totalPrice" : {
|
||||
"currency" : "EUR",
|
||||
"currency" : "EUR",
|
||||
},
|
||||
"lineItems" : [
|
||||
{
|
||||
"type" : "custom",
|
||||
{
|
||||
"type" : "custom",
|
||||
"name" : "Monatsbeitrag",
|
||||
"quantity" : 1,
|
||||
"unitName" : "Stück",
|
||||
"unitPrice" :
|
||||
"unitPrice" :
|
||||
{
|
||||
"currency" : "EUR",
|
||||
"netAmount" : 10,
|
||||
"netAmount" : 10,
|
||||
"taxRatePercentage" : 16
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"type" : "custom",
|
||||
{
|
||||
"type" : "custom",
|
||||
"name" : "Abwesenheitsmodul",
|
||||
"quantity" : 1,
|
||||
"unitName" : "Stück",
|
||||
"unitPrice" :
|
||||
"unitPrice" :
|
||||
{
|
||||
"currency" : "EUR",
|
||||
"currency" : "EUR",
|
||||
"netAmount" : 10,
|
||||
"taxRatePercentage" : 16
|
||||
},
|
||||
},
|
||||
}
|
||||
],
|
||||
"taxConditions": {
|
||||
|
|
@ -959,96 +959,128 @@ def cronactions(request, code):
|
|||
"shippingDate": "2020-07-09T00:00:00.000+01:00",
|
||||
"shippingType": "service"
|
||||
},
|
||||
}
|
||||
json_data = json.dumps(lexdata)
|
||||
r = requests.get("https://api.lexoffice.io/v1/invoices/0f9b6a1d-1912-4a10-9926-7909e5580202", data=json_data, headers=headers)
|
||||
}
|
||||
json_data = json.dumps(lexdata)
|
||||
r = requests.get("https://api.lexoffice.io/v1/invoices/0f9b6a1d-1912-4a10-9926-7909e5580202", data=json_data, headers=headers)
|
||||
print(r)
|
||||
print(r.text)
|
||||
'''
|
||||
|
||||
|
||||
|
||||
|
||||
else:
|
||||
print("API CODE FAILED")
|
||||
data.update({"status" : "failed"})
|
||||
data.update({"status" : "failed"})
|
||||
return JsonResponse(data)
|
||||
|
||||
|
||||
|
||||
'''
|
||||
Gibt False zurück, wenn der User an diesem Tag KEINE Abwesenheiten hat, ansonsten True!
|
||||
|
||||
'''
|
||||
def absencecheck(user, daytocheck):
|
||||
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))
|
||||
if(len(absencedays) > 0):
|
||||
returnstat = True
|
||||
|
||||
return returnstat
|
||||
|
||||
# CRONJOBS UM 00:01!
|
||||
def cronactionsdaily(request, code):
|
||||
data = {}
|
||||
if(code == settings.CRONAPIKEY):
|
||||
allusers = User.objects.all()
|
||||
|
||||
'''
|
||||
|
||||
Pro User gibt es das Feld loose_holiday in der UserTime-Info. Ist dieser Tag vorbei, muss die Differenz der days_inuse des VORJHARES in den Rest das AKTUELLEN JAHRES gespeichert werden!
|
||||
data = {}
|
||||
if(code == settings.CRONAPIKEY):
|
||||
allusers = User.objects.all()
|
||||
'''
|
||||
Pro User gibt es das Feld loose_holiday in der UserTime-Info. Ist dieser Tag vorbei, muss die Differenz der days_inuse des VORJHARES in den Rest das AKTUELLEN JAHRES gespeichert werden!
|
||||
'''
|
||||
today = date.today()
|
||||
for user in allusers:
|
||||
# REST URLAUB BERECHNUNG
|
||||
usertimedata = UserTime.objects.get(user=user)
|
||||
day_tocheck = usertimedata.loose_holidedate.split(".")[0]
|
||||
month_tocheck = usertimedata.loose_holidedate.split(".")[1]
|
||||
month = today.month
|
||||
if month < 10:
|
||||
month = "0" + str(month)
|
||||
day = today.day
|
||||
if day < 10:
|
||||
day = "0" + str(day)
|
||||
|
||||
'''
|
||||
today = date.today()
|
||||
for user in allusers:
|
||||
# REST URLAUB BERECHNUNG
|
||||
usertimedata = UserTime.objects.get(user=user)
|
||||
# Restetag erreicht, Reste ins nächste Jahr übertragen
|
||||
if(str(day_tocheck) == str(day) and str(month_tocheck) == str(month)):
|
||||
sourceyear = today.year
|
||||
this_year = list(UserYearAbsenceInfo.objects.filter(year=sourceyear, user=user))[0]
|
||||
next_year = list(UserYearAbsenceInfo.objects.filter(year=sourceyear+1, user=user))[0]
|
||||
next_year.restdays = this_year.days - this_year.days_inuse
|
||||
next_year.save()
|
||||
|
||||
day_tocheck = usertimedata.loose_holidedate.split(".")[0]
|
||||
month_tocheck = usertimedata.loose_holidedate.split(".")[1]
|
||||
# ARBEITSTAGE BEENDEN
|
||||
# Benutzer hat Zeiterfassung aktiv
|
||||
if(user.usertime.usetime):
|
||||
workdays = Workday.objects.filter(user=user, end=None)
|
||||
for wd in workdays:
|
||||
wd.end = datetime(wd.start.year, wd.start.month, wd.start.day, 23, 59)
|
||||
wd.save()
|
||||
|
||||
month = today.month
|
||||
yesterday = date.today() - timedelta(days=1)
|
||||
weekday = yesterday.weekday()
|
||||
workdays_yesterday = len(Workday.objects.filter(user=user, start__day=yesterday.day, start__month=yesterday.month, start__year=yesterday.year))
|
||||
# Mitarbeiter hat für den gestrigen Tag keine Zeiten erfasst, daher automatisch auf null wenn KEINE Abwesenheit eingetragen wurde
|
||||
|
||||
if month < 10:
|
||||
month = "0" + str(month)
|
||||
if(workdays_yesterday == 0 and absencecheck(user, yesterday) == False):
|
||||
targettworktime = 0.0
|
||||
if(weekday == 0):
|
||||
targettworktime = user.usertime.wd_mo
|
||||
if(weekday == 1):
|
||||
targettworktime = user.usertime.wd_tu
|
||||
if(weekday == 2):
|
||||
targettworktime = user.usertime.wd_we
|
||||
if(weekday == 3):
|
||||
targettworktime = user.usertime.wd_th
|
||||
if(weekday == 4):
|
||||
targettworktime = user.usertime.wd_fr
|
||||
if(weekday == 5):
|
||||
targettworktime = user.usertime.wd_sa
|
||||
if(weekday == 6):
|
||||
targettworktime = user.usertime.wd_so
|
||||
|
||||
day = today.day
|
||||
if day < 10:
|
||||
day = "0" + str(day)
|
||||
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()
|
||||
|
||||
# Restetag erreicht, Reste ins nächste Jahr übertragen
|
||||
if(str(day_tocheck) == str(day) and str(month_tocheck) == str(month)):
|
||||
sourceyear = today.year
|
||||
this_year = list(UserYearAbsenceInfo.objects.filter(year=sourceyear, user=user))[0]
|
||||
next_year = list(UserYearAbsenceInfo.objects.filter(year=sourceyear+1, user=user))[0]
|
||||
next_year.restdays = this_year.days - this_year.days_inuse
|
||||
next_year.save()
|
||||
|
||||
# ARBEITSTAGE BEENDEN
|
||||
# Benutzer hat Zeiterfassung aktiv
|
||||
if(user.usertime.usetime):
|
||||
workdays = Workday.objects.filter(user=user, end=None)
|
||||
for wd in workdays:
|
||||
wd.end = datetime(wd.start.year, wd.start.month, wd.start.day, 23, 59)
|
||||
wd.save()
|
||||
# Erinnerungsmails/Push bei Vertretung verschicken
|
||||
one_week_later = date.today() + timedelta(days=7)
|
||||
repre_absence = Absence.objects.filter(representator=user, start=one_week_later, confirm_status=0)
|
||||
|
||||
# Erinnerungsmails/Push bei Vertretung verschicken
|
||||
one_week_later = date.today() + timedelta(days=7)
|
||||
repre_absence = Absence.objects.filter(representator=user, start=one_week_later, confirm_status=0)
|
||||
|
||||
for r in repre_absence:
|
||||
if(r.representator.usernotifications.absence_user_is_rep_reminder_mail):
|
||||
sendMailNoti(" in einer Woche startet Ihre Vertretung für " + r.user.first_name + " " + r.user.last_name + "!", user)
|
||||
if(r.representator.usernotifications.absence_user_is_rep_reminder_push):
|
||||
newnotification = UserNotification(touser=user, notificationtext="Erinnerung für Abwesenheitsvertretung!", notificationtype="", elementid=r.pk)
|
||||
newnotification.save()
|
||||
for r in repre_absence:
|
||||
if(r.representator.usernotifications.absence_user_is_rep_reminder_mail):
|
||||
sendMailNoti(" in einer Woche startet Ihre Vertretung für " + r.user.first_name + " " + r.user.last_name + "!", user)
|
||||
|
||||
channel_layer = channels.layers.get_channel_layer()
|
||||
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | In einer Woche startet Ihre Vertretung für " + r.user.first_name + " " + r.user.last_name + "!"})
|
||||
|
||||
data.update({"status" : "ok"})
|
||||
|
||||
else:
|
||||
print("API CODE FAILED")
|
||||
data.update({"status" : "failed"})
|
||||
return JsonResponse(data)
|
||||
if(r.representator.usernotifications.absence_user_is_rep_reminder_push):
|
||||
newnotification = UserNotification(touser=user, notificationtext="Erinnerung für Abwesenheitsvertretung!", notificationtype="", elementid=r.pk)
|
||||
newnotification.save()
|
||||
|
||||
channel_layer = channels.layers.get_channel_layer()
|
||||
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | In einer Woche startet Ihre Vertretung für " + r.user.first_name + " " + r.user.last_name + "!"})
|
||||
data.update({"status" : "ok"})
|
||||
|
||||
else:
|
||||
print("API CODE FAILED")
|
||||
data.update({"status" : "failed"})
|
||||
|
||||
return JsonResponse(data)
|
||||
|
||||
|
||||
def sendMailNoti(notificationtext, user_touched, linktarget=""):
|
||||
|
||||
|
||||
username = user_touched.first_name + " " + user_touched.last_name
|
||||
msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext, 'linktarget' : linktarget})
|
||||
msg_html = render_to_string('notificsys/notification_mail.html', {'username': username, 'notificationtext' : notificationtext, 'linktarget' : linktarget})
|
||||
send_mail(
|
||||
'Agentur-Benachrichtigung',
|
||||
'Hallo ' + user_touched.first_name + ' ' + user_touched.last_name + '! ' + notificationtext,
|
||||
'noreply@digitale-agentur.com',
|
||||
[user_touched.email],
|
||||
[user_touched.email],
|
||||
html_message=msg_html,
|
||||
fail_silently=True
|
||||
)
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue