Umbau auf NC als neuer Branch

This commit is contained in:
Holger Trampe 2021-10-18 07:01:36 +02:00
parent 9637138092
commit 401fd60ca4
71 changed files with 2988 additions and 1029 deletions

View File

@ -1,5 +1,3 @@
digitale agentur - README digitale agentur - README
Quellcode für Prod aktuell Agenturstand zur Migration in Nextcloud.
Aktuelle Version für die Prod!

View File

@ -22,12 +22,11 @@ class AdmWorkdayForm(forms.ModelForm):
"start" : "Start", "start" : "Start",
"end" : "Ende", "end" : "Ende",
"target" : "Zielarbeitszeit", "target" : "Zielarbeitszeit",
"freefield" : "Notiz", "freefield" : "Notiz"
"delflag" : "Nicht berücksichtigen (delflag)"
} }
fields = [ fields = [
"start", "end", "target", "freefield", "delflag" "start", "end", "target", "freefield"
] ]
widgets = { widgets = {
'start': DatePickerInput(options={"format":'DD.MM.YYYY HH:mm', "locale":'de'}), 'start': DatePickerInput(options={"format":'DD.MM.YYYY HH:mm', "locale":'de'}),

View File

@ -97,6 +97,16 @@
<span>Agenturen</span></a> <span>Agenturen</span></a>
</li> </li>
{% if active_link == 'adm-import' %}
<li class="nav-item active">
{% else %}
<li class="nav-item">
{%endif%}
<a class="nav-link" href="{% url 'adm-import' %}">
<i class="fas fa-file-invoice-dollar"></i>
<span>Import</span></a>
</li>
{% if active_link == 'adm-bills' %} {% if active_link == 'adm-bills' %}
<li class="nav-item active"> <li class="nav-item active">
{% else %} {% else %}
@ -118,17 +128,6 @@
<span>Benutzer</span></a> <span>Benutzer</span></a>
</li> </li>
<!-- Nav Item - Dashboard -->
{% if active_link == 'adm-tm-wd-bug' %}
<li class="nav-item active">
{% else %}
<li class="nav-item">
{%endif%}
<a class="nav-link" href="{% url 'adm-tm-wd-bug' %}">
<i class="fas fa-user"></i>
<span>TM-WD-Bug</span></a>
</li>
<hr class="sidebar-divider my-0"> <hr class="sidebar-divider my-0">
<li class="nav-item"> <li class="nav-item">
@ -296,7 +295,7 @@
<div class="container-fluid" > <div class="container-fluid" >
<div id="maincontent" style="min-height: 100%; margin-top: 85px;" > <div id="maincontent" style="min-height: 100%; margin-top: 155px;" >
<!-- MESSAGES --> <!-- MESSAGES -->
{% if messages %} {% if messages %}
{% for message in messages %} {% for message in messages %}
@ -543,7 +542,7 @@ function removeNotification(notifyid){
} }
/*
$(document).on('click', function (e) { $(document).on('click', function (e) {
if(e.target["id"] != 'chatButton'){ if(e.target["id"] != 'chatButton'){
@ -551,13 +550,13 @@ $(document).on('click', function (e) {
$("#chat_alluserscontent").fadeOut(); $("#chat_alluserscontent").fadeOut();
} }
} }
}); });*/
</script> </script>
<!-- WEBSOCKETS --> <!-- WEBSOCKETS -->
<script type="text/javascript"> <script type="text/javascript">
/*
$(document).ready(function(){ $(document).ready(function(){
$("#chat_alluserscontent").hide(); $("#chat_alluserscontent").hide();
@ -579,9 +578,7 @@ $(document).ready(function(){
//HANDLER FOR ALL PUSHNOTIFICATIONS //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
*/
tempsplit = e["data"].split("__"); tempsplit = e["data"].split("__");
finalsplit = tempsplit[1].split(" "); finalsplit = tempsplit[1].split(" ");
@ -731,5 +728,5 @@ $("#chatButton").click(function(){
}); });
}); });
*/
</script> </script>

View File

@ -0,0 +1,264 @@
{% extends "adm/adm_base.html" %}
{% block content %}
{% load adm_tags %}
<div class="content-section col-12">
<h4>Agenturimport der Agentur {{agency.name}}</h4>
<small>Die Seite nicht verlassen oder neu laden!</small>
<hr>
<div>
<h5 id="groups_process">Es werden {{groups|length}} Gruppen angelegt...</h5>
<div id="groups_process_groups"></div>
<h5 id="user_process" style="display: none;">Es werden {{users|length}} Benutzer angelegt und in die Gruppen gepackt. Die Nutzer müssen sich dann ein neues Passwort setzen.</h5>
<div id="user_process_user" style="display: none;"></div>
<h5 id="cloud_process" style="display: none;">Es werden {{files|length}} Dateien und {{dirs|length}} Ordner angelegt und mit Zugriffsrechten gesetzt.</h5>
<div id="cloud_process_main" style="display: none;">Gruppenordner wird angelegt</div>
<div id="cloud_process_cloud" style="display: none;"></div>
<div id="cloud_process_standards" style="display: none;">Standarddateien von {{standard_pk|length}} Standards werden neu zugewiesen...</div>
<div id="cloud_process_standards_error" style="display: none;">Standarddateien konnten nicht zugewiesen werden. Bitte manuell prüfen.</div>
</div>
<h5 id="migfinished" style="display: none;">Migration vollständig. Bitte diese Seite ausdrucken oder Speichern. Ein erneuter Import ist nicht möglich!</h5>
<script>
var userids = [{% for us in users %} "{{us.pk}}" {% if forloop.counter < users|length %}, {% endif %} {% endfor %}];
var groupids = [{% for g in groups %} "{{g.name}}" {% if forloop.counter < groups|length %}, {% endif %} {% endfor %}];
var files = [{% for f in files %} "{{f.pk}}" {% if forloop.counter < files|length %}, {% endif %} {% endfor %}];
var standard_files = [{% for f in standard_files %} "{{f.pk}}" {% if forloop.counter < standard_files|length %}, {% endif %} {% endfor %}];
var standards = [{% for s in standard_pk %} "{{s}}" {% if forloop.counter < standard_pk|length %}, {% endif %} {% endfor %}];
var dirids = [{% for d in dirs %} "{{d.pk}}" {% if forloop.counter < dirs|length %}, {% endif %} {% endfor %}];
$(document).ready(function(){
// FIRST CALL GROUPS, When Groups finished User will call by Groups
createAgencyGroups(groupids[0]);
//DEV
//rebuildingStandards(standards[0]);
//addGroupFolder();
//addDirs(dirids[0]);
})
var groupcounter = 0;
function createAgencyGroups(groupid){
$.ajax({
url: "{% url 'api:apiaddgroup' %}",
dataType: 'json',
data: {
'groupid' : groupid
},
success: function(data){
if(data['status'] == true){
console.log(data);
$("#groups_process_groups").append('<p>' + data['message'] + "</p>");
groupcounter += 1;
if(groupcounter < groupids.length){
createAgencyGroups(groupids[groupcounter]);
}
else {
createUsers(userids[0]);
}
}
},
error: function(e){
console.log(e);
}
});
}
var usercounter = 0;
function createUsers(userid){
$("#user_process").show();
$("#user_process_user").show();
$.ajax({
url: "{% url 'api:apiadduser' %}",
dataType: 'json',
data: {
'agencyid' : {{agency.pk}},
'userid' : userid
},
success: function(data){
if(data['status'] == true){
$("#user_process_user").append('<p>' + data['message'] + "</p>");
usercounter += 1;
if(usercounter < userids.length){
createUsers(userids[usercounter]);
}
else {
addGroupFolder();
}
}
},
error: function(e){
console.log(e);
}
});
}
var groupfolderid = "";
function addGroupFolder(){
$("#cloud_process").show();
$("#cloud_process_main").show();
$.ajax({
url: "{% url 'mig-groupfolder' agency.pk %}",
dataType: 'json',
success: function(data){
if(data['status'] == true){
$("#cloud_process_main").html("Ordner und Standardordner erfolgreich angelegt. Starte mit Dateiimport...");
if(files[0] != undefined){
addFiles(files[0]);
}
}
else{
console.log(data);
$("#cloud_process_main").html("FEHLER BEI GRUPPENORDNER! Import abgebrochen.");
}
},
error: function(e){
console.log(e);
}
});
}
filecounter = 0;
function addFiles(fileid){
$("#cloud_process_cloud").show();
$.ajax({
url: "{% url 'api:apiaddfile' %}",
dataType: 'json',
data: {
'agencyid' : {{agency.pk}},
'fileid' : fileid,
},
success: function(data){
if(data['status'] == true){
$("#cloud_process_cloud").append('<p>' + data['message'] + "</p>");
filecounter += 1;
if(filecounter < files.length){
addFiles(files[filecounter]);
}
else {
if(standard_files[0] != undefined){
console.log("start adding standard files...");
addStandardFilesFiles(standard_files[0]);
}
else {
if(dirids[0] != undefined){
addDirs(dirids[0]);
}
else {
$("#migfinished").show();
}
}
}
}
},
error: function(e){
console.log(e);
}
});
}
filecounters = 0;
function addStandardFilesFiles(fileid){
$("#cloud_process_cloud").show();
$.ajax({
url: "{% url 'api:apiaddstandardfile' %}",
dataType: 'json',
data: {
'agencyid' : {{agency.pk}},
'fileid' : fileid,
},
success: function(data){
if(data['status'] == true){
$("#cloud_process_cloud").append('<p>' + data['message'] + "</p>");
filecounters += 1;
if(filecounters < standard_files.length){
console.log("adding standard files...");
addStandardFilesFiles(standard_files[filecounters]);
}
else {
if(dirids[0] != undefined){
addDirs(dirids[0]);
}
}
}
},
error: function(e){
console.log(e);
}
});
}
dircounter = 0;
function addDirs(dirid){
$("#cloud_process_cloud").show();
$.ajax({
url: "{% url 'api:apiadddir' %}",
dataType: 'json',
data: {
'agencyid' : {{agency.pk}},
'dirid' : dirid,
},
success: function(data){
if(data['status'] == true){
$("#cloud_process_cloud").append('<p>' + data['message'] + "</p>");
dircounter += 1;
if(dircounter < dirids.length){
console.log(dircounter < dirids.length);
addDirs(dirids[dircounter]);
}
else {
if(standards[0] != undefined){
rebuildingStandards(standards[0]);
}
else{
$("#migfinished").show();
}
}
}
},
error: function(e){
console.log(e);
}
});
}
standardcounter = 0;
//Anlegen der Standarddateien
function rebuildingStandards(id){
$("#cloud_process_standards").show();
$.ajax({
url: "{% url 'api:apiswitchstandards' %}",
dataType: 'json',
data: {
'standardid' : id,
},
success: function(data){
if(data['status'] == "OK"){
standardcounter += 1;
if(standardcounter < standards.length){
console.log("STANDARD " + id + " OK");
rebuildingStandards(standards[standardcounter]);
}
else{
console.log("STANDARD " + id + " OK");
$("#migfinished").show();
}
}
else{
standardcounter += 1;
console.log("FEHLER BEI STANDARD " + data['status'] + " ID " + id);
if(standardcounter < standards.length){
rebuildingStandards(standards[standardcounter]);
}
else{
console.log("FEHLER BEI STANDARD " + data['status'] + " ID " + id);
$("#migfinished").show();
}
}
},
error: function(e){
console.log(e);
}
});
}
</script>
</div>
{% endblock content %}

View File

@ -0,0 +1,58 @@
{% extends "adm/adm_base.html" %}
{% block content %}
{% load adm_tags %}
<div class="content-section col-12">
<h4>Agenturimport</h4>
<small>Agenturen können hier importiert werden und erhalten einen detallierten Bericht. Bereits importierte Agenturen speichern ihre MainGroupID in Nextcloud</small>
<hr>
<table class="table table-hover" id="agdata" >
<thead>
<tr>
<th scope="col">Agenturname</th>
<th scope="col">Importierstatus</th>
<th scope="col">&nbsp;</th>
</tr>
</thead>
<tbody >
{% for ele in agencys %}
<tr>
<td><a href="{% url 'adm-agency-single' ele.pk %}">{{ele.name}}</a></td>
<td></td>
<td>
{% if ele.importid|length == 0 %}
<a href="{% url 'adm-import-flow' ele.pk %}" class="btn btn-danger btn-sm">Agentur jetzt zu Nextcloud migrieren</a>
{% else %}
Agentur importiert
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#agdata').DataTable({
order: [1, 'desc'],
"language": {
"search" : "Suche",
"info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
"lengthMenu": "Zeige _MENU_ Einträge",
"zeroRecords": "Nichts gefunden",
"infoEmpty": "Keine Einträge",
"paginate": {
"first": "Erste",
"last": "Letzte",
"next": "Nächste",
"previous": "Zurück"
},
},
"pageLength": 50,
"buttons" : {
"className" : "btn-danger"
}
});
})
</script>
</div>
{% endblock content %}

View File

@ -1,58 +0,0 @@
{% extends "adm/adm_base.html" %}
{% block content %}
{% load adm_tags %}
{% load mathfilters %}
{% load humanize %}
{% load counter_tag %}
<div class="content-section col-12">
<h4>Übersicht Arbeitstag und Abwesenheit
</h4>
<table class="table table-striped" id="wdabdays">
<thead>
<trd>
<td>Name</td>
<td>Relevante Arbeitstage OHNE FLAG</td>
<td>Relevante Arbeitstage MIT FLAG</td>
</trd>
</thead>
<tbody>
{% for user in users %}
{% getADMAbsenceWorkdays user as workdays %}
{% getADMAbsenceWorkdaysTrue user as workdaystrue %}
<tr>
<td>{{user.username}}</td>
<td>
{% for wd in workdays %} <a href="{% url 'adm-workday-update' wd.pk %}">{{wd.pk}}</a>, {% endfor %}
</td>
<td>
{% for wd in workdaystrue %} <a href="{% url 'adm-workday-update' wd.pk %}">{{wd.pk}}</a>, {% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<script>
$(document).ready(function(){
$('#wdabdays').DataTable({
order: [0, 'desc'],
"language": {
"search" : "Suche",
"info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
"lengthMenu": "Zeige _MENU_ Einträge",
"zeroRecords": "Nichts gefunden",
"infoEmpty": "Keine Einträge",
"paginate": {
"first": "Erste",
"last": "Letzte",
"next": "Nächste",
"previous": "Zurück"
},
},
"pageLength": 50,
"buttons" : {
"className" : "btn-danger"
}
});
})
</script>
{% endblock content %}

View File

@ -1,6 +1,5 @@
{% extends "adm/adm_base.html" %} {% extends "adm/adm_base.html" %}
{% block content %} {% block content %}
{% load counter_tag %}
{% load adm_tags %} {% load adm_tags %}
<!-- Mitarbeier ist immer der angemeledete!!! --> <!-- Mitarbeier ist immer der angemeledete!!! -->
<div class="content-section col-12"> <div class="content-section col-12">
@ -23,19 +22,6 @@
<td>Letzter Login</td> <td>Letzter Login</td>
<td>{{userdata.last_login|default:"-"}}</td> <td>{{userdata.last_login|default:"-"}}</td>
</tr> </tr>
{% if userdata.usertime.usetime %}
<tr>
<td>Gleitzeitkonto:</td>
<td>
{% loadaccounttime userdata as actualaccounttime %}
{% if actualaccounttime.1 == 0 %}
<b><span style="color: green">+{{actualaccounttime.0}}&nbsp;Stunden</span></b>
{% else %}
<b><span style="color: red">-{{actualaccounttime.0}}&nbsp;Stunden</span></b>
{% endif %}
</td>
</tr>
{% endif %}
</table> </table>
</div> </div>
</div> </div>

View File

@ -10,6 +10,8 @@ Permissions definiert in models.py bei USERS und dann hier vor die View geschrie
urlpatterns = [ urlpatterns = [
path('', AdmMain.as_view(), name='adm-main'), path('', AdmMain.as_view(), name='adm-main'),
path('ag/', AdmAgencys.as_view(), name="adm-agencys"), path('ag/', AdmAgencys.as_view(), name="adm-agencys"),
path('import/', AdmImport.as_view(), name="adm-import"),
path('doimport/<int:pk>', AdmImportFlow.as_view(), name="adm-import-flow"),
path('us/', AdmUsers.as_view(), name="adm-users"), path('us/', AdmUsers.as_view(), name="adm-users"),
path('agsingle/<int:agpk>', AdmAgencySingle.as_view(), name="adm-agency-single"), path('agsingle/<int:agpk>', AdmAgencySingle.as_view(), name="adm-agency-single"),
path('ad/del/<int:pk>', delAgency.as_view(), name='adm-agency-delete'), path('ad/del/<int:pk>', delAgency.as_view(), name='adm-agency-delete'),
@ -23,5 +25,6 @@ urlpatterns = [
path('wd/<int:pk>/delete', AdmWorkdayDelete.as_view(), name="adm-workday-delete"), path('wd/<int:pk>/delete', AdmWorkdayDelete.as_view(), name="adm-workday-delete"),
path('wd/break/<int:pk>/delete', AdmBreakDelete.as_view(), name="adm-break-delete"), path('wd/break/<int:pk>/delete', AdmBreakDelete.as_view(), name="adm-break-delete"),
path('wd/<int:pk>/break/add', AdmAddBreak.as_view(), name="adm-break-add"), path('wd/<int:pk>/break/add', AdmAddBreak.as_view(), name="adm-break-add"),
path('tmbug/', AdmTmWorkdayColl.as_view(), name="adm-tm-wd-bug"), # MIGRATION
path('mig/aggroupfolder/<int:agencypk>', createAgGroupFolder, name="mig-groupfolder"),
] ]

View File

@ -4,6 +4,7 @@ from django.shortcuts import render, redirect, reverse
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.conf import settings from django.conf import settings
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
from requests.api import head
from .models import MainStatistic, MainSalesMonth from .models import MainStatistic, MainSalesMonth
from django.contrib.auth.models import User from django.contrib.auth.models import User
from chat.models import ChatMessage from chat.models import ChatMessage
@ -29,20 +30,6 @@ from django.template.loader import render_to_string
from cloud.models import DataFile from cloud.models import DataFile
import math import math
import requests import requests
from digitaleagentur.timemanagement_utils import *
# TODO: ADM-Oberfläche Auswertung machen, an welchen Tagen eines Mitarbeiters auch eine Abwesenheit
class AdmTmWorkdayColl(TemplateView):
template_name = "adm/adm_tmworkday.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : "adm-tm-wd-bug"})
context.update({'users' : User.objects.all().order_by('username') })
return context
''' '''
Prüfung, ob angemeldeter User Mitarbeiterstatus hat. IMMER PER DISPATCH EINBAUEN! Prüfung, ob angemeldeter User Mitarbeiterstatus hat. IMMER PER DISPATCH EINBAUEN!
''' '''
@ -677,17 +664,94 @@ class AdmAddBreak(CreateView):
return reverse('adm-workday-update', kwargs={'pk': self.kwargs['pk']}) return reverse('adm-workday-update', kwargs={'pk': self.kwargs['pk']})
'''
IMPORT AGENCY
'''
class AdmImport(TemplateView):
template_name="adm/adm_import_overview.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'adm-import'})
context.update({'agencys' : Agency.objects.all()})
return context
from django.contrib.auth.models import Group
from cloud.models import *
class AdmImportFlow(TemplateView):
template_name="adm/adm_import_flow.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({'active_link' : 'adm-import'})
agency = Agency.objects.get(pk=kwargs.get("pk"))
# Agency itself
context.update({'agency' : agency})
# Users in that Agency
context.update({'users' : User.objects.filter(profile__agency=agency)})
# DataFiles
normal_files = []
for f in DataFile.objects.filter(agency=agency):
if(f.parent.name != "Standards Uploadbereich"):
normal_files.append(f)
context.update({'files' : normal_files})
# DataDirs
context.update({'dirs' : DataDir.objects.filter(agency=agency).exclude(is_root=True)})
# Groups of the Agency
groups = Group.objects.all()
ag_pk = str(agency.pk)
ag_groups = []
for g in groups:
if(ag_pk in g.name):
ag_groups.append(g)
context.update({'groups' : ag_groups})
# Loading Standard-Files
standards = Standards.objects.filter(agency=agency)
standard_files = []
for s in standards:
for f in s.addedfiles.all():
if(f.parent.name == "Standards Uploadbereich"):
standard_files.append(f)
context.update({'standard_files' : standard_files})
# Loading Standard-PKs
standard_pk = []
for s in standards:
standard_pk.append(str(s.pk))
context.update({'standard_pk' : standard_pk})
# LINK TO THE NC-INSTANCE
context.update({'nclink' : settings.NEXTCLOUD_URL})
context.update({'ncid' : self.request.user.profile.nc_sid})
context.update({'nc_url' : settings.NEXTCLOUD_URL})
return context
'''
Erstellt einen Gruppenordner
'''
def createAgGroupFolder(request, agencypk):
agency = Agency.objects.get(pk=agencypk)
data = {
"gid" : "agencymaingroupid_" + str(agency.pk),
"aid" : str(agency.pk),
}
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v2.php/apps/da_agency/api/v1/creategf?format=json", auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data)
r_2 = requests.request("MKCOL", settings.NEXTCLOUD_URL + "remote.php/dav/files/admin/Agenturdaten_" + str(agency.pk)+ '/Standards Uploadbereich', auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
json_response = json.loads(r.text)
response_status = json_response['ocs']['meta']['status']
if(response_status == "ok"):
return JsonResponse({'status' : True, 'message': 'Gruppenordner angelegt!'})
else:
return JsonResponse({'status' : False, 'message': 'Konnte nicht angelegt werden!', 'errormessage_r' : r.text})

View File

@ -11,4 +11,25 @@ urlpatterns = [
path('getchatrooms/', views.getchatrooms, name='api-getchatrooms'), path('getchatrooms/', views.getchatrooms, name='api-getchatrooms'),
path('getsinglechat/<int:pk>', views.getsinglechat, name='api-getsinglechat'), path('getsinglechat/<int:pk>', views.getsinglechat, name='api-getsinglechat'),
path('chatnewmessage/', views.savenewchatmessage, name='api-savechatmessage'), path('chatnewmessage/', views.savenewchatmessage, name='api-savechatmessage'),
# MIGRATION
path('migrateagencyusers/<int:pk>', views.migrateAgencyUsers, name="api-migrateagencyusers"),
path('addgroup/', views.NCAddGroup, name="apiaddgroup"),
path('adduser/', views.NCAddUser, name="apiadduser"),
path('addgf/', views.NCAddGroupFolder, name="apiaddgf"),
path('addfile/', views.NCAddFiles, name="apiaddfile"),
path('addstandardfile/', views.NCAddStandardFiles, name="apiaddstandardfile"),
path('adddir/', views.NCAddDirs, name="apiadddir"),
path('addswitchstandards/', views.NCSwitchStandardFiles, name="apiswitchstandards"),
path('setlog/', views.SetUserData, name="apisetlog"),
# EXTERNAL FROM NC
path('logout/<str:uid>', views.apilogout, name="api-logout"),
path('uschanged/<str:uid>/<str:sid>', views.userChangedInNc, name="api-userchanged"),
path('deletefile/<slug:fid>/<slug:secretkey>', views.deleteNCFile, name="api-deletencfile"),
path('tm/startday/<slug:uid>/<slug:secretkey>', views.startWorkDay, name="api-startday"),
path('tm/endday/<slug:uid>/<slug:secretkey>', views.endWorkDay, name="api-endday"),
path('tm/startbreak/<slug:uid>/<slug:secretkey>', views.startBreak, name="api-startbreak"),
path('tm/endbreak/<slug:uid>/<slug:secretkey>', views.endBreak, name="api-endbreak"),
path('tm/gettime/<slug:uid>/<slug:secretkey>', views.getTime, name="api-gettime"),
] ]

View File

@ -1,6 +1,9 @@
from django.views.decorators.csrf import ensure_csrf_cookie
from cloud.models import DataFile, DataDir
from django.shortcuts import redirect
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated # <-- Here #from rest_framework.permissions import IsAuthenticated # <-- Here
import json import json
from standards.models import Standards from standards.models import Standards
from rest_framework import serializers from rest_framework import serializers
@ -11,39 +14,44 @@ from rest_framework.authentication import SessionAuthentication, BasicAuthentica
from rest_framework.decorators import authentication_classes from rest_framework.decorators import authentication_classes
from chat.models import ChatRoom, ChatMessage from chat.models import ChatRoom, ChatMessage
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
from django.contrib.sessions.models import Session
from timemanagement.models import Absence from timemanagement.models import Absence
from django.conf import settings
from digitaleagentur.utils import *
from timemanagement.models import Workday, FreeDays, Absence
from standards.models import Standards, NCFile
from users.models import AgencyGroup, Agency, AgencyNetwork, AgencyNetworkPreperation, UserTime, UserYearAbsenceInfo, AgencyBills
from standards.templatetags import *
class GetUserId(APIView): class GetUserId(APIView):
permission_classes = (IsAuthenticated,) # <-- And here #permission_classes = (IsAuthenticated,) # <-- And here
def post(self, request): def post(self, request):
return Response({"userid" : self.request.user.pk}) return Response({"userid" : self.request.user.pk})
@api_view(['POST', ]) @api_view(['POST', ])
@permission_classes((IsAuthenticated,)) #@permission_classes((IsAuthenticated,))
def getStandardList(request): def getStandardList(request):
standards = Standards.objects.filter(agency=request.user.profile.agency) standards = Standards.objects.filter(agency=request.user.profile.agency)
ser = StandardsSerializer(standards, many=True) ser = StandardsSerializer(standards, many=True)
return Response(ser.data, status=status.HTTP_200_OK) return Response(ser.data, status=status.HTTP_200_OK)
@api_view(['POST', ]) @api_view(['POST', ])
@permission_classes((IsAuthenticated,)) #@permission_classes((IsAuthenticated,))
def getSingleStandard(request, pk): def getSingleStandard(request, pk):
standard = Standards.objects.get(pk=int(pk)) standard = Standards.objects.get(pk=int(pk))
ser = StandardsSerializer(standard, many=False) ser = StandardsSerializer(standard, many=False)
return Response(ser.data, status=status.HTTP_200_OK) return Response(ser.data, status=status.HTTP_200_OK)
@api_view(['POST', ]) @api_view(['POST', ])
@permission_classes((IsAuthenticated,)) #@permission_classes((IsAuthenticated,))
def logoutByToken(request): def logoutByToken(request):
print(request)
request.user.auth_token.delete() request.user.auth_token.delete()
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
@api_view(['POST', ]) @api_view(['POST', ])
@permission_classes((IsAuthenticated,)) #@permission_classes((IsAuthenticated,))
def getchatrooms(request): def getchatrooms(request):
chatrooms = ChatRoom.objects.filter(creator=request.user) | ChatRoom.objects.filter(chatmember_single=request.user) chatrooms = ChatRoom.objects.filter(creator=request.user) | ChatRoom.objects.filter(chatmember_single=request.user)
chatrooms_ser = ChatRoomSerializer(chatrooms, many=True) chatrooms_ser = ChatRoomSerializer(chatrooms, many=True)
@ -51,7 +59,7 @@ def getchatrooms(request):
@api_view(['POST', ]) @api_view(['POST', ])
@permission_classes((IsAuthenticated,)) #@permission_classes((IsAuthenticated,))
def getsinglechat(request, pk): def getsinglechat(request, pk):
chatroom = ChatRoom.objects.get(pk=pk) chatroom = ChatRoom.objects.get(pk=pk)
if chatroom.creator == request.user or chatroom.chatmember_single == request.user or (request.user in chatroom.chatmembers.all()): if chatroom.creator == request.user or chatroom.chatmember_single == request.user or (request.user in chatroom.chatmembers.all()):
@ -62,7 +70,7 @@ def getsinglechat(request, pk):
@api_view(['POST', ]) @api_view(['POST', ])
@permission_classes((IsAuthenticated,)) #@permission_classes((IsAuthenticated,))
def savenewchatmessage(request): def savenewchatmessage(request):
room = ChatRoom.objects.get(pk=request.POST["room"]) room = ChatRoom.objects.get(pk=request.POST["room"])
if(request.user == room.creator or request.user == room.chatmember_single): if(request.user == room.creator or request.user == room.chatmember_single):
@ -74,4 +82,668 @@ def savenewchatmessage(request):
else: else:
return Response(status=status.HTTP_403_FORBIDDEN) return Response(status=status.HTTP_403_FORBIDDEN)
# IMPORTED MODELS FOR MIGRATION
from users.models import Agency
from django.contrib.auth.models import User
@api_view(['GET', ])
def migrateAgencyUsers(request, pk):
datapackage = {}
Ag = Agency.objects.get(pk=pk)
for user in User.objects.filter(profile__agency=Ag):
if(len(user.email) > 0 and len(user.first_name) > 0 and len(user.last_name) > 0):
datapackage.update({str(user.pk) : {"userid" : user.email, "displayname" : user.first_name + " " + user.last_name}})
return JsonResponse(datapackage)
@api_view(['GET', ])
def apilogout(request, uid):
print("LOGOUT: " + str(uid))
user = User.objects.get(username=uid)
user.profile.nc_sid = ""
user.save()
[s.delete() for s in Session.objects.all() if s.get_decoded().get('_auth_user_hash') == user.get_session_auth_hash()]
return JsonResponse({'res' : 'ok'})
# This function change the Username of a user, when it was changed in NextCloud! Works only for the own user :) !
import xmltodict, json, requests
@api_view(['GET'], )
def userChangedInNc(request, uid, sid):
user = User.objects.get(username=uid)
print("SID: " + sid)
if(user.is_authenticated and getNCLoggedUserBySession(sid) == uid):
nc_login_headers = {'Authorization' : 'Bearer ' + sid}
r = requests.get(settings.NEXTCLOUD_URL + "ocs/v1.php/cloud/users/" + uid, headers=nc_login_headers)
xpars = xmltodict.parse(r.text)
js = json.dumps(xpars)
final_json = json.loads(js)
new_displayname = final_json['ocs']['data']['displayname'].split(" ")
new_email = final_json['ocs']['data']['email']
user.email = new_email
user.first_name = new_displayname[0]
new_last_name = ""
new_displayname.pop(0)
for ele in new_displayname:
new_last_name += " " + ele
user.last_name = new_last_name
user.save()
return JsonResponse({"status" : "ok!"})
return JsonResponse({"status" : "NO AUTH"})
from requests.auth import HTTPBasicAuth
import random
import string
from django.contrib.auth.models import Group
from users.models import AgencyGroup
def get_random_number(length = 6):
result_str = ''.join(random.choice("0123456789") for i in range(length))
return result_str
def get_random_password(length = 6):
result_str = ''.join(random.choice("!_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJLMNOPQRSTUVWXYZ0123456789") for i in range(length))
return result_str
# Returns a new groupID for NC by Groupname and Agency
def create_group_id(agencygroupname, agency):
newgroupid = ""
pregroupstr = "agencymaingroupid_"
if(agencygroupname == "Mitarbeiter"):
newgroupid = pregroupstr + str(agency.pk)
# NORMAL GROUOPS
elif(agencygroupname == "Administratoren"):
newgroupid = pregroupstr + str(agency.pk) + "_defaultadmingroup"
elif(agencygroupname == "Notfallhilfe"):
newgroupid = pregroupstr + str(agency.pk) + "_recover"
else:
newgroupid = pregroupstr + str(agency.pk) + "_subgroup_" + get_random_number()
return newgroupid
'''
Diese Methode erstellt die Gruppen in NC nach dem Schemata, wie sie auch bei einer Registrierung aufgebaut werden.
'''
@api_view(['GET'], )
def NCAddGroup(request):
if request.method == "GET":
group = Group.objects.get(name=request.GET.get('groupid'))
aggroup = AgencyGroup.objects.get(group=group)
agency = aggroup.agency
newgroupid = create_group_id(aggroup.agencygroupname, agency)
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
data = {
"groupid" : newgroupid
}
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v1.php/cloud/groups", data=data, headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
r_status = json.loads(r.text)
if(r_status['ocs']['meta']['statuscode'] == 100):
# Group created, save new group id in Django
aggroup.nc_name = newgroupid
aggroup.save()
# Group created, set display name in NC
data = {
"name": aggroup.agencygroupname,
"id" : newgroupid
}
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v2.php/apps/da_agency/api/v1/renameagg?format=json", auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data)
return JsonResponse({'status' : True, 'message': 'Gruppe ' + aggroup.agencygroupname + ' erzeugt - ID: ' + newgroupid})
elif(r_status['ocs']['meta']['statuscode'] == 102):
return JsonResponse({'status' : True, 'message': 'Gruppe ' + aggroup.agencygroupname + ' (ID '+aggroup.group.name+') existiert bereits. Wird übersprungen. Bitte Namen prüfen!'})
else:
return JsonResponse({'status' : True, 'message': 'Gruppe ' + aggroup.agencygroupname + ' (ID '+aggroup.group.name+') konnte nicht erzeugt werden. Bitte manuell prüfen'})
#except:
# return JsonResponse({'status' : True, 'message': 'Gruppe ' + aggroup.agencygroupname + ' (ID '+aggroup.group.name+') konnte nicht erzeugt werden. Bitte manuell prüfen' + r.text})
return JsonResponse({"status" : "NO AUTH"})
'''
Hier werden die Nutzer angelegt.
'''
@api_view(['GET'], )
def NCAddUser(request):
if request.method == "GET":
agency = Agency.objects.get(pk=request.GET.get('agencyid'))
user = User.objects.get(pk=request.GET['userid'])
# Check, that only users in the same agency can do that!
if(user.profile.agency == agency):
# Load all groups the User is in and get AgencyGroup for NC-Group-Name
groups = []
for g in user.groups.all():
groups.append(AgencyGroup.objects.get(group=g).nc_name)
#password = get_random_password(50)
password = ""
userid = user.username
displayName = user.first_name + " " + user.last_name
email = user.email
# Data for the new User
data = {
"userid": userid,
"password": password,
"displayName": displayName,
"email":email,
"groups[]":groups
}
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
# Request for adding the new User
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v1.php/cloud/users", data=data, headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
try:
r_status = json.loads(r.text)
if(r_status['ocs']['meta']['statuscode'] == 100):
return JsonResponse({'status' : True, 'message': 'Benutzer ' + user.first_name + " " + user.last_name + ' angelegt und in die Gruppen gepackt.'})
else:
return JsonResponse({'status' : True, 'message': 'Benutzer ' + user.first_name + " " + user.last_name + ' konnte nicht angelegt werden. Bitte manuell prüfen!', 'message' : r.text})
except:
return JsonResponse({'status' : True, 'message': 'Benutzer ' + user.first_name + " " + user.last_name + ' konnte nicht angelegt werden. Bitte manuell prüfen!', 'message' : r.text})
return JsonResponse({"status" : "NO AUTH"})
@api_view(['GET'],)
def getTMInfos(request, uid, secretkey):
if request.method == "GET":
return JsonResponse({"status" : "DATA " + uid + " " + secretkey})
return JsonResponse({"status" : "NO AUTH"})
from requests.auth import HTTPBasicAuth
'''
Anlegen des Gruppenordners der Agentur in NC
WIRD NICHT VERWENDET!!!
'''
@api_view(['POST'], )
def NCAddGroupFolder(request):
if request.method == "POST":
agency = Agency.objects.get(pk=request.POST.get('agencyid'))
data = {
"gid" : "agencymaingroupid_" + str(agency.pk),
"aid" : str(agency.pk),
"sk'" : settings.NC_SECRETKEY
}
headers = {
'Authorization': 'Bearer ' + request.user.profile.nc_sid
}
# Groupfolder
r = requests.post(settings.NEXTCLOUD_URL + "apps/agency/createagf", data=data, headers=headers)
# Standard Folder
r = requests.request("MKCOL", settings.NEXTCLOUD_URL + "remote.php/dav/files/" + settings.NEXTCLOUD_USER_API + "/Agenturdaten_" + str(agency.pk)+ '/Standards Uploadbereich/', auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
return JsonResponse({'status' : True, 'message': 'Gruppenordner und Standard-Ordner angelegt!' + r.text})
return JsonResponse({"status" : "NO AUTH"})
import os
'''
Hier werden die Dateien angelegt und entsprechende Zugriffsrechte der Gruppen gesetzt.
'''
@api_view(['GET'], )
def NCAddFiles(request):
if request.method == "GET":
agency = Agency.objects.get(pk=request.GET.get('agencyid'))
file_to_load = DataFile.objects.get(pk=request.GET.get('fileid'))
datadir_parent = None
datadir_parent_dirnames = []
if(file_to_load.parent != None):
datadir_parent = file_to_load.parent
datadir_parent_dirnames = [file_to_load.parent.name]
while(datadir_parent.parent != None):
datadir_parent_dirnames.append(datadir_parent.parent.name)
datadir_parent = datadir_parent.parent
## Popping last Element
d_prestring = ""
if(len(datadir_parent_dirnames) > 0):
datadir_parent_dirnames.pop(len(datadir_parent_dirnames)-1)
# Turning Array around
datadir_parent_dirnames = datadir_parent_dirnames[::-1]
# Dirs needed for the File
for d in datadir_parent_dirnames:
new_folder = d_prestring + "/" +d
r = requests.request("MKCOL", settings.NEXTCLOUD_URL + "remote.php/dav/files/admin/Agenturdaten_" + str(agency.pk)+ '/' + new_folder, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
d_prestring += "/" + d
# Uplod the file!
final_file_path = settings.NEXTCLOUD_URL + "remote.php/dav/files/admin/Agenturdaten_"+ str(agency.pk) + "/" + d_prestring + "/" + file_to_load.name
with open(file_to_load.file.path, 'rb') as f:
r = requests.put(final_file_path, data=f, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
if(len(r.text) == 0):
return JsonResponse({'status' : True, 'message': 'Datei ' + file_to_load.name + ' angelegt.'})
else:
return JsonResponse({'status' : True, 'message': 'Datei ' + file_to_load.name + ' konnte nicht angelegt. Bitte manuell prüfen!'})
return JsonResponse({"status" : "NO AUTH"})
'''
STANDARD FILES
'''
@api_view(['GET'], )
def NCAddStandardFiles(request):
if request.method == "GET":
agency = Agency.objects.get(pk=request.GET.get('agencyid'))
file_to_load = DataFile.objects.get(pk=request.GET.get('fileid'))
# Uplod the file!
final_file_path = settings.NEXTCLOUD_URL + "remote.php/dav/files/admin/Agenturdaten_"+ str(agency.pk) + "/Standards Uploadbereich/" + file_to_load.name
with open(file_to_load.file.path, 'rb') as f:
r = requests.put(final_file_path, data=f, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
if(len(r.text) == 0):
return JsonResponse({'status' : True, 'message': 'Datei ' + file_to_load.name + ' angelegt.'})
else:
return JsonResponse({'status' : True, 'message': 'Datei ' + file_to_load.name + ' konnte nicht angelegt. Bitte manuell prüfen!'})
return JsonResponse({"status" : "NO AUTH"})
'''
Hier werden die Dateien angelegt und entsprechende Zugriffsrechte der Gruppen gesetzt.
'''
@api_view(['GET'], )
def NCAddDirs(request):
if request.method == "GET":
agency = Agency.objects.get(pk=request.GET.get('agencyid'))
dir_to_create = DataDir.objects.get(pk=request.GET.get('dirid'))
sharestring = ""
if(dir_to_create.visibleby.all().count() > 0):
sharestring = " Ordner nur sichtbar durch: "
for cd in dir_to_create.visibleby.all():
sharestring += cd.agencygroupname + " (" + cd.nc_name + ")"
# Dir has no parent, create
if(len(dir_to_create.parent.name) == 0):
r = requests.request("MKCOL", settings.NEXTCLOUD_URL + "remote.php/dav/files/admin/Agenturdaten_" + str(agency.pk)+ '/' + dir_to_create.name, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
return JsonResponse({'status' : True, 'message': 'Ordner ' + dir_to_create.name + ' angelegt. ' + sharestring})
# Dir has parents, start thinking :)
else:
datadir_parent = None
datadir_parent_dirnames = []
if(dir_to_create.parent != None and len(dir_to_create.parent.name) > 0):
datadir_parent = dir_to_create.parent
datadir_parent_dirnames = [dir_to_create.parent.name]
if(datadir_parent.parent != None):
while(datadir_parent.parent != None and len(datadir_parent.parent.name) > 0):
datadir_parent_dirnames.append(datadir_parent.parent.name)
datadir_parent = datadir_parent.parent
if(len(datadir_parent_dirnames) > 0):
datadir_parent_dirnames = datadir_parent_dirnames[::-1]
d_prestring = ""
for d in datadir_parent_dirnames:
new_folder = d_prestring + "/" +d
r = requests.request("MKCOL", settings.NEXTCLOUD_URL + "remote.php/dav/files/admin/Agenturdaten_" + str(agency.pk)+ '/' + new_folder, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
d_prestring += "/" + d
r = requests.request("MKCOL", settings.NEXTCLOUD_URL + "remote.php/dav/files/admin/Agenturdaten_" + str(agency.pk)+ '/' + d_prestring + "/" + dir_to_create.name, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
return JsonResponse({'status' : True, 'message': 'Ordner ' + dir_to_create.name + ' angelegt.' + sharestring})
return JsonResponse({'status' : False, 'message': 'AUTH ERROR'})
@api_view(['GET'], )
def NCTest(request):
#print(request.headers)
return JsonResponse({'status' : False, 'message': 'AUTH ERROR'})
# Setting the Users Data for logging
@api_view(['POST'], )
def SetUserData(request):
try:
user = User.objects.get(username=request.POST.get('uid'))
user.profile.nc_sid = request.POST.get('sid')
user.save()
return JsonResponse({'message' : 'A user was found in request, sid set!'})
except:
return JsonResponse({'message' : 'USER NOT FOUND'})
def getFileIdFromXML(xmlresponse):
try:
split_response = xmlresponse.split("<oc:fileid>")
split_fileele = split_response[1].split("<")
return split_fileele[0]
except:
return None
'''
Standardateien neu zuweisen
Pro Datei in addedfiles wird ein neues NCFile-Objekt erstellt und in addedfiles_nc gespeichert. In den Ansichten der Standards werden dann nur noch die addedfiles_nc-Elemente gesehen und verändert.
'''
@api_view(['GET'], )
def NCSwitchStandardFiles(request):
if request.method == "GET":
#agency = Agency.objects.get(pk=request.GET.get('agencyid'))
standard = Standards.objects.get(pk=request.GET.get('standardid'))
response_status = "OK"
for f in standard.addedfiles.all():
filesearchdata = '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><oc:fileid/><d:displayname/></d:prop></d:select><d:from><d:scope><d:href>/files/' + settings.NEXTCLOUD_USER_API + '/Agenturdaten_' + str(standard.agency.pk) + '</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:like><d:prop><d:displayname/></d:prop><d:literal>' + f.name + '</d:literal></d:like></d:where></d:basicsearch></d:searchrequest>'
r = requests.request("SEARCH", settings.NEXTCLOUD_URL + "remote.php/dav", data=filesearchdata, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), headers={'Content-Type' : 'text/xml'})
fileid = getFileIdFromXML(r.text)
if(fileid == None):
response_status += " FEHLER BEI STANDARD " + str(standard.pk) + " "
else:
ncfile = NCFile.objects.create(agency=standard.agency, nc_id=fileid, file_id=f)
standard.addedfiles_nc.add(ncfile)
return JsonResponse({"status" : response_status})
return JsonResponse({"status" : "NO AUTH"})
@api_view(['GET'], )
def deleteNCFile(request, fid, secretkey):
if request.method == "GET":
if(secretkey == '87zuhjk87GHJ546tzgvhas76aaskbdhr45edfVHAKia87s6gbAVGFGSR3451627gBHAKJBN'):
try:
file_to_del = NCFile.objects.filter(nc_id=fid).first()
file_to_del.delete()
except:
pass
return JsonResponse({"status" : 'true'})
else:
return JsonResponse({"status" : "NO AUTH"})
else:
return JsonResponse({"status" : "NO AUTH"})
# APIs for TIMEMANAGEMENT
@api_view(['GET'], )
def startWorkDay(request, uid, secretkey):
if request.method == "GET" and secretkey == '87zuhjk87GHJ546tzgvhas76aaskbdhr45edfVHAKia87s6gbAVGFGSR3451627gBHAKJBN':
username_new = uid.replace("REPLACEDATAELEMENTVER0000000001", "@")
username_new = username_new.replace("POINTPOINTPOINTPOINTPOINTPOINT", ".")
user = User.objects.filter(username=username_new).first()
today = date.today()
targettime = 0.0
if(today.isoweekday() == 1):
targettime = user.usertime.wd_mo
elif(today.isoweekday() == 2):
targettime = user.usertime.wd_tu
elif(today.isoweekday() == 3):
targettime = user.usertime.wd_we
elif(today.isoweekday() == 4):
targettime = user.usertime.wd_th
elif(today.isoweekday() == 5):
targettime = user.usertime.wd_fr
elif(today.isoweekday() == 6):
targettime = user.usertime.wd_sa
elif(today.isoweekday() == 7):
targettime = user.usertime.wd_so
# Liegt eine halbe Abwesenheit vor, wird hier die Zielarbeitszeit halbiert
if(getAbsenceForOneDay(user, today) != False):
targettime = targettime / 2
# Prpfung, ob bereits Arbeitstage an diesem Tag vorliegen
tempworkday = Workday.objects.filter(agency=user.profile.agency, user=user, start__day=today.day, start__month=today.month, start__year=today.year, delflag = False)
user_has_workdays = False
if len(tempworkday) == 0:
# Noch kein Arbeitstag vorhanden, Zielarbeitszeit ganz normal
user_has_workdays = True
else:
# Es ist bereits ein ARbeitstag vorhanden, daher wird die Zielarbeitszeit des zweiten Teils auf 0 gesetzt
targettime=0.0
wd = Workday(user=user, agency=user.profile.agency, start=timezone.now(), target=targettime)
wd.save()
data = {
"success" : True,
"wd_starttime" : wd.start.strftime("%H:%M:%S"),
"wd_starttime_complete" : wd.start
}
return JsonResponse(data)
else:
return JsonResponse({"status" : "FALSE"})
# APIs for TIMEMANAGEMENT
import os
from django.conf import settings
from django.utils import timezone
from datetime import date
import datetime
# Ladet das aktuelle Gleitzeitkonto
'''
Es werden nur Tage berücksichtigt, die in der Vergangenheit liegen!
'''
def format_timedelta(td):
hours, remainder = divmod(td.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)
hours, minutes, seconds = int(hours), int(minutes), int(seconds)
if hours < 10:
hours = '0%s' % int(hours)
if minutes < 10:
minutes = '0%s' % minutes
if seconds < 10:
seconds = '0%s' % seconds
return '%s:%s:%s' % (hours, minutes, seconds)
def loadaccounttime(user):
status = 0
today = date.today()
workdays = Workday.objects.filter(user=user, start__lt=today, delflag = False).exclude(end=None)
finalaccounttimesum = datetime.timedelta(minutes=0) + datetime.timedelta(hours=UserTime.objects.get(user=user).startcount)
for workday in workdays:
# Zeit, die der Mitarbeiter gearbeitet haben MUSS
sum_break = 0
if(len(workday.breaks.all()) > 0):
for ele in workday.breaks.all():
if ele.end != None and ele.start != None:
sum_break += (ele.end - ele.start).seconds
finalsum = ((workday.end - workday.start).seconds - sum_break)
hastowork = datetime.timedelta(hours=workday.target)
final_info = (int(finalsum) - int(hastowork.total_seconds()))/60
if(final_info >= 0.0):
finalaccounttimesum += datetime.timedelta(minutes=final_info)
else:
final_info = final_info * -1
finalaccounttimesum -= datetime.timedelta(minutes=final_info)
# Gesamtgleitzeit einmal schick darstellen mit rot und grün
# Wenn GLeitzeit NEGATIV ist
if(finalaccounttimesum.total_seconds() < 0):
status = 1
final_info_data = format_timedelta(datetime.timedelta(seconds=finalaccounttimesum.total_seconds()*(-1)))
else:
status = 0
final_info_data = format_timedelta(datetime.timedelta(seconds=finalaccounttimesum.total_seconds()))
final_info_data_neu = final_info_data.split(":")[0] + ":" + final_info_data.split(":")[1]
#final_info = str(final_info_data[0]) + ":" + str(final_info_data[1])
return [final_info_data_neu, status]
'''
Gibt alle aktuellen Zeitdaten zurück:
- Aktuelles Gleitzeitkonto
- Ob ein aktueller Arbeitstag vorliegt (wenn ja, dann die entsprechenden Daten)
'''
@api_view(['GET'], )
def getTime(request, uid, secretkey):
if request.method == "GET" and secretkey == '87zuhjk87GHJ546tzgvhas76aaskbdhr45edfVHAKia87s6gbAVGFGSR3451627gBHAKJBN':
username_new = uid.replace("REPLACEDATAELEMENTVER0000000001", "@")
username_new = username_new.replace("POINTPOINTPOINTPOINTPOINTPOINT", ".")
user = User.objects.filter(username=username_new).first()
usetime = True
if(user.usertime!= None and user.usertime.usetime == False):
usetime = False
wd = Workday.objects.filter(user=user, agency=user.profile.agency, end=None, delflag = False)
workdaydata_workday = 0
workdaydata_starttime = 0
breakstatus = False
breaktimer = 0
breaksum = 0
if(len(wd) > 0):
wd_second = list(Workday.objects.filter(user=user, agency=user.profile.agency, end=None, delflag = False))[0]
workdaydata_workday = list(wd)[0].start
workdaydata_starttime = wd_second.start.strftime("%H:%M:%S")
for b in wd_second.breaks.all():
if(b.end != None):
breaksum += (b.end - b.start).seconds
breaksum = breaksum*1000
# Check for Breaks
if(len(wd_second.breaks.all()) > 0):
# Check if all Breaks ended
wdbreak = wd_second.breaks.filter(end=None)
if(len(wdbreak) > 0):
breakstatus = True
# Break Found, return actual breakcounter
if(breakstatus):
wdbreak = wd_second.breaks.filter(end=None)
if(len(wdbreak) > 0):
now = timezone.now()
breakstart = list(wdbreak)[0].start
breaktimer = (now - breakstart).seconds * 1000
return JsonResponse({'actualtime' : loadaccounttime(user)[0], 'workdaydata_workday' : workdaydata_workday, 'workdaydata_starttime' : workdaydata_starttime, 'breakstatus' : breakstatus, 'breaktimer' : breaktimer, 'breaksum' : breaksum, 'usetime' : usetime})
else:
return ({"status" : "FALSE"})
# APIs for TIMEMANAGEMENT
# End a WorkDay
@api_view(['GET'], )
def endWorkDay(request, uid, secretkey):
if request.method == "GET" and secretkey == '87zuhjk87GHJ546tzgvhas76aaskbdhr45edfVHAKia87s6gbAVGFGSR3451627gBHAKJBN':
username_new = uid.replace("REPLACEDATAELEMENTVER0000000001", "@")
username_new = username_new.replace("POINTPOINTPOINTPOINTPOINTPOINT", ".")
user = User.objects.filter(username=username_new).first()
wd = list(Workday.objects.filter(user=user, agency=user.profile.agency, end=None, delflag = False))[0]
# END ALL BREAKS
for b in wd.breaks.all():
if b.end == None:
b.end = timezone.now()
b.save()
wd.end = timezone.now()
wd.save()
breaksum = 0
for b in wd.breaks.all():
if(b.end != None):
breaksum += (b.end - b.start).seconds
data = {
"success" : True,
"wd_endtime" : wd.end.strftime("%H:%M:%S"),
"actualbreaktime" : breaksum*1000
}
return JsonResponse(data)
else:
return JsonResponse({"status" : "FALSE"})
# Start Break
@api_view(['GET'], )
def startBreak(request, uid, secretkey):
if request.method == "GET" and secretkey == '87zuhjk87GHJ546tzgvhas76aaskbdhr45edfVHAKia87s6gbAVGFGSR3451627gBHAKJBN':
username_new = uid.replace("REPLACEDATAELEMENTVER0000000001", "@")
username_new = username_new.replace("POINTPOINTPOINTPOINTPOINTPOINT", ".")
user = User.objects.filter(username=username_new).first()
wd = list(Workday.objects.filter(user=user, agency=user.profile.agency, end=None, delflag = False))[0]
newbreak = Breaks(workday=wd, user=user, agency=user.profile.agency, start=timezone.now())
newbreak.save()
wd.breaks.add(newbreak)
data = {
"success" : True,
"break_starttime" : newbreak.start,
}
return JsonResponse(data)
else:
return JsonResponse({"status" : "FALSE"})
# End Break
@api_view(['GET'], )
def endBreak(request, uid, secretkey):
if request.method == "GET" and secretkey == '87zuhjk87GHJ546tzgvhas76aaskbdhr45edfVHAKia87s6gbAVGFGSR3451627gBHAKJBN':
username_new = uid.replace("REPLACEDATAELEMENTVER0000000001", "@")
username_new = username_new.replace("POINTPOINTPOINTPOINTPOINTPOINT", ".")
user = User.objects.filter(username=username_new).first()
wd = list(Workday.objects.filter(user=user, agency=user.profile.agency, end=None, delflag = False))[0]
toendbreak = list(wd.breaks.filter(end=None))[0]
toendbreak.end = timezone.now()
toendbreak.save()
wd = list(Workday.objects.filter(user=user, agency=user.profile.agency, end=None, delflag = False))[0]
breaksum = 0
for b in wd.breaks.all():
if(b.end != None):
breaksum += (b.end - b.start).seconds
data = {
"success" : True,
"actualbreaktime" : breaksum*1000,
"wdtime" : wd.start
}
return JsonResponse(data)
else:
return JsonResponse({"status" : "FALSE"})

View File

@ -1,11 +1,11 @@
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from channels_presence.models import Presence #from channels_presence.models import Presence
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
from django.contrib.auth.models import User from django.contrib.auth.models import User
from channels_presence.models import Room #from channels_presence.models import Room
from channels_presence.models import Presence #from channels_presence.models import Presence
import channels.layers #import channels.layers
from django.utils import timezone from django.utils import timezone
from .models import ChatRoom, ChatMessage from .models import ChatRoom, ChatMessage
from .forms import ChatAddChatRoom, ChatUpdateChatRoom from .forms import ChatAddChatRoom, ChatUpdateChatRoom

View File

@ -162,11 +162,10 @@ def adddirbyajax(request, parent):
data = {'filename' : fileobj.name, 'linked_standards' : linked_standards_final} data = {'filename' : fileobj.name, 'linked_standards' : linked_standards_final}
# CHECK DOUBLE FILENAME # CHECK DOUBLE FILENAME
elif(request.GET.get("action") == "check_doublefile"): elif(request.GET.get("action") == "check_doublefile"):
fileobj = list(DataFile.objects.filter(name__icontains=request.GET.get('name'), agency=request.user.profile.agency)) #fileobj = list(DataFile.objects.filter(name__icontains=request.GET.get('name'), agency=request.user.profile.agency))
if len(fileobj) > 0: #if len(fileobj) > 0:
data = {"found" : True} #else:
else: data = {"found" : False}
data = {"found" : False}
# DELETE FILE # DELETE FILE
elif(request.GET.get("action") == "del_file"): elif(request.GET.get("action") == "del_file"):
DataFile.objects.filter(pk=request.GET.get('id'), agency=request.user.profile.agency).delete() DataFile.objects.filter(pk=request.GET.get('id'), agency=request.user.profile.agency).delete()
@ -243,8 +242,6 @@ def adddirbyajax(request, parent):
uploadsource = request.POST["uploadsource"] uploadsource = request.POST["uploadsource"]
replace = request.POST["replace"] replace = request.POST["replace"]
print(replace)
# DECODE # DECODE
request.decoding = 'utf-8' request.decoding = 'utf-8'

View File

@ -62,6 +62,7 @@
Die Gruppe Notfallhilfe ist für keine weiteren Rechte konfigurierbar. Die Gruppe Notfallhilfe ist für keine weiteren Rechte konfigurierbar.
<hr> <hr>
{% endif %} {% endif %}
{% if aggroup.agencygroupname != "Mitarbeiter" %}
<div col="10"> <div col="10">
<h6>Mitarbeiter zur Gruppe <b>{{aggroup.agencygroupname}}</b> hinzufügen</h6> <h6>Mitarbeiter zur Gruppe <b>{{aggroup.agencygroupname}}</b> hinzufügen</h6>
<div class="input-group mb-3 col-5"> <div class="input-group mb-3 col-5">
@ -78,7 +79,9 @@
</datalist> </datalist>
</datalist> </datalist>
</div> </div>
<hr> <hr>
{% endif %}
<h6>Gruppenmitglieder in <b>{{aggroup.agencygroupname}}</b></h6> <h6>Gruppenmitglieder in <b>{{aggroup.agencygroupname}}</b></h6>
{% if varcounter > 0 %} {% if varcounter > 0 %}
<span id="nogroupmember_{{aggroup.pk}}" style="display: none">Diese Gruppe hat noch keine Mitglieder.</span> <span id="nogroupmember_{{aggroup.pk}}" style="display: none">Diese Gruppe hat noch keine Mitglieder.</span>
@ -89,10 +92,11 @@
{% for user in usersofagency %} {% for user in usersofagency %}
{% for group in user.groups.all %} {% for group in user.groups.all %}
{% if group.name == aggroup.group.name %} {% if group.name == aggroup.group.name %}
{% if request.user == user and aggroup.is_admin %} {% if request.user == user and aggroup.is_admin or aggroup.agencygroupname == "Mitarbeiter" %}
<span class="badge badge-pill badge-primary mr-2 mt-2"><button class="btn btn-primary" disabled="true">{{ user.first_name }} {{ user.last_name }}</button></span> <span class="badge badge-pill badge-primary mr-2 mt-2"><button class="btn btn-primary" disabled="true">{{ user.first_name }} {{ user.last_name }}</button></span>
{% else %} {% else %}
<span id="span_btn_{{user.pk}}_{{aggroup.pk}}" class="badge badge-pill badge-primary mr-2 mt-2"><a class="btn btn-primary" onclick="javascript:removeUserFromGroup({{ user.pk }}, {{aggroup.pk}})">{{ user.first_name }} {{ user.last_name }}&nbsp;&nbsp;<i class="fas fa-times"></i></a > <span id="span_btn_{{user.pk}}_{{aggroup.pk}}" class="badge badge-pill badge-primary mr-2 mt-2">
<a class="btn btn-primary" onclick="javascript:removeUserFromGroup({{ user.pk }}, {{aggroup.pk}})">{{ user.first_name }} {{ user.last_name }}&nbsp;&nbsp;<i class="fas fa-times"></i></a >
</span> </span>
{% endif %} {% endif %}
{% endif %} {% endif %}
@ -352,9 +356,9 @@ function changeGroupName(groupid){
{ {
$("#newgroupname").val(data['data']['groupname']); $("#newgroupname").val(data['data']['groupname']);
$("#modTitle").html("Gruppenname ändern"); $("#modTitle").html("Gruppenname ändern");
$("#saveNewGroup").prop("disabled", false); $("#saveNewGroup").prop("disabled", false);
groupupdate_id = groupid; groupupdate_id = groupid;
groupaction = 1; groupaction = 1;
} }
}); });
} }
@ -387,15 +391,15 @@ function updateGroupName(){
}, },
success: function( data ) success: function( data )
{ {
if(data['success']){
if(data['success']){ window.location.href = window.location.href + "?showtoast=true";
window.location.href = window.location.href + "?showtoast=true"; $("#newGroup").modal("toggle");
} }
else{ else{
$("#newGroup").modal("toggle"); $("#newGroup").modal("toggle");
$('#notchange_err').toast('show'); $('#notchange_err').toast('show');
$("#toast_errcontent").html("Der Gruppenname ist in der Agentur bereits vorhanden!"); $("#toast_errcontent").html("Der Gruppenname ist in der Agentur bereits vorhanden!");
} }
} }
}); });
} }
@ -413,9 +417,9 @@ function updateGroupName(){
success: function( data ) success: function( data )
{ {
if(data['success']){ if(data['success']){
$("#newGroup").modal("toggle"); $("#newGroup").modal("hide");
$('#notchange_done').toast('show'); $('#notchange_done').toast('show');
$("#groupname_" + groupupdate_id).html("Gruppe <b>"+data['data']['newvalue']+"&nbsp;</b>"); $("#groupname_" + groupupdate_id).html("Gruppe <b>"+data['data']['newvalue']+"&nbsp;</b>");
} }
else{ else{
$('#notchange_err').toast('show'); $('#notchange_err').toast('show');

View File

@ -1,10 +1,10 @@
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
<div class="row">
<div class="col-6 mt-3"> <div class="col-6 mt-3">
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<tr> <tr>
<th scope="col">Modul</th> <th scope="col">Modul</th>
<th scope="col">Aktiviert</th>
<th scope="col">Einstellungen</th> <th scope="col">Einstellungen</th>
</tr> </tr>
</thead> </thead>
@ -14,9 +14,9 @@
<input type="hidden" name="form_type" value="agencymodform"> <input type="hidden" name="form_type" value="agencymodform">
<input type="hidden" name="settings_area" value="moduls"> <input type="hidden" name="settings_area" value="moduls">
{% for formfield in modulform %} {% for formfield in modulform %}
{% if formfield.name == 'module_organigramm' or formfield.name == 'module_timemanagement' %}
<tr> <tr>
<td>{{formfield.label_tag}}</td> <td>{{formfield.label_tag}}</td>
<td>{{formfield}}</td>
<td> <td>
{% if formfield.name == 'module_organigramm' and user.profile.agency.module_organigramm %} {% if formfield.name == 'module_organigramm' and user.profile.agency.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> <button type="button" class="btn btn-sm btn-primary" onclick="javascript:$('#modulesettings_{{formfield.name}}').modal('toggle');"><i class="fas fa-cog"></i></button>
@ -25,13 +25,13 @@
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
{% endif %}
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<button type="submit" class="btn btn-primary" data-toggle="tooltip" data-placement="top" title="Mit dem Speichern wird die Seite neu geladen, damit alle Einstellungen aktualisiert werden. Werden Module deaktiviert, gehen die Einstellungen und zugewiesenen Rechte nicht verloren.">Moduleinstellungen aktualisieren</button>
</form> </form>
</div> </div>
</div>
{% for formfield in modulform %} {% for formfield in modulform %}
<div class="modal fade" id="modulesettings_{{formfield.name}}" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="" aria-hidden="true"> <div class="modal fade" id="modulesettings_{{formfield.name}}" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="" aria-hidden="true">
<div class="modal-dialog modal-lg " role="document" > <div class="modal-dialog modal-lg " role="document" >

View File

@ -0,0 +1,82 @@
{% load crispy_forms_tags %}
<div class="col-6 mt-3">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Modul</th>
<th scope="col">Aktiviert</th>
<th scope="col">Einstellungen</th>
</tr>
</thead>
<tbody id="module_checkboxes">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input type="hidden" name="form_type" value="agencymodform">
<input type="hidden" name="settings_area" value="moduls">
{% for formfield in modulform %}
<tr>
<td>{{formfield.label_tag}}</td>
<td>{{formfield}}</td>
<td>
{% if formfield.name == 'module_organigramm' and user.profile.agency.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' and user.profile.agency.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>
</table>
<button type="submit" class="btn btn-primary" data-toggle="tooltip" data-placement="top" title="Mit dem Speichern wird die Seite neu geladen, damit alle Einstellungen aktualisiert werden. Werden Module deaktiviert, gehen die Einstellungen und zugewiesenen Rechte nicht verloren.">Moduleinstellungen aktualisieren</button>
</form>
</div>
{% 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 modal-lg " role="document" >
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Moduleinstellungen {{formfield.label_tag}}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
{% 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 %}
Keine Einstellungen vorhanden.
{% endif %}
{% if formfield.name == 'module_organigramm' and user.profile.agency.module_organigramm %}
<div class="modal-footer">
<button id="" type="button" onclick="javascript:updateOrganigrammSettings()" class="btn btn-primary" data-dismiss="modal" >Speichern</button>
&nbsp;
<button type="button" class="btn" data-dismiss="modal">Abbrechen</button>
</div>
{% elif formfield.name == 'module_timemanagement' and user.profile.agency.module_timemanagement %}
<div class="modal-footer">
<button id="" type="button " onclick="javascript:updateTmSettings()" class="btn btn-primary" data-dismiss="modal" >Speichern</button>
&nbsp;
<button type="button" class="btn" data-dismiss="modal">Abbrechen</button>
</div>
{% else %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Schließen</button>&nbsp;
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endfor %}

View File

@ -37,9 +37,11 @@
<h3>Einstellungen</i></b>{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Hier können Agenturweite Einstellungen (Mitarbeiter, Gruppen, Agenturinfos, Bereiche und Tätigkeiten, Abrechnung, Module usw.) verwaltet werden." class="far fa-question-circle"></i></small>{% endif %}</h3> <h3>Einstellungen</i></b>{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Hier können Agenturweite Einstellungen (Mitarbeiter, Gruppen, Agenturinfos, Bereiche und Tätigkeiten, Abrechnung, Module usw.) verwaltet werden." class="far fa-question-circle"></i></small>{% endif %}</h3>
<hr> <hr>
<ul class="nav nav-tabs" id="settingsTabs" role="tablist"> <ul class="nav nav-tabs" id="settingsTabs" role="tablist">
<!--
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" id="profil-tab" data-toggle="tab" href="#profil" role="tab" aria-controls="profil" aria-selected="false" ><i class="fas fa-user"></i>&nbsp;Profil</a> <a class="nav-link active" id="profil-tab" data-toggle="tab" href="#profil" role="tab" aria-controls="profil" aria-selected="false" ><i class="fas fa-user"></i>&nbsp;Profil</a>
</li> </li>
-->
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="notifications-tab" data-toggle="tab" href="#notifications" role="tab" aria-controls="notifications-tab" aria-selected="false"><i class="fas fa-bell"></i>&nbsp;Benachrichtigungen</a> <a class="nav-link" id="notifications-tab" data-toggle="tab" href="#notifications" role="tab" aria-controls="notifications-tab" aria-selected="false"><i class="fas fa-bell"></i>&nbsp;Benachrichtigungen</a>
</li> </li>
@ -79,14 +81,18 @@
</li> </li>
{% endif %} {% endif %}
</ul> </ul>
<div class="tab-content" id="settingsTabsContent"> <div class="tab-content" id="settingsTabsContent">
<!--
<div class="tab-pane fade show" id="profil" role="tabpanel" aria-labelledby="profil-tab"> <div class="tab-pane fade show" id="profil" role="tabpanel" aria-labelledby="profil-tab">
<h5 class="mt-3">Profileinstellungen{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Hier können Sie Einstellungen an ihrem Profil vornehmen (E-Mail, Passwort und, ob die Tooltips angezeigt werden sollen). Alle anderen Einstellungen werden von Mitarbeitern mit entsprechenden Gruppenrechten verwaltet." class="far fa-question-circle"></i></small>{% endif %}</h5> <h5 class="mt-3">Profileinstellungen{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Hier können Sie Einstellungen an ihrem Profil vornehmen (E-Mail, Passwort und, ob die Tooltips angezeigt werden sollen). Alle anderen Einstellungen werden von Mitarbeitern mit entsprechenden Gruppenrechten verwaltet." class="far fa-question-circle"></i></small>{% endif %}</h5>
<hr> <hr>
{% block profil_content %} WURDE AUSKOMMENTNTIERT, IST ABER DJANGO
{% include "dasettings/profil_content.html" %} block profil_content
{% endblock %} include "dasettings/profil_content.html"
endblock
</div> </div>
-->
<div class="tab-pane fade" id="notifications" role="tabpanel" aria-labelledby="notifications-tab"> <div class="tab-pane fade" id="notifications" role="tabpanel" aria-labelledby="notifications-tab">
<h5 class="mt-3">Benachrichtigungen{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Stellen Sie hier ein, welche Art der Benachrichtigung (E-Mail oder Push) Sie für welches Ereignis (Gruppenzuweisungen, Veröffentlichung eines Standards, neue Agenturnews usw.) erhalten möchten." class="far fa-question-circle"></i></small>{% endif %}</h5> <h5 class="mt-3">Benachrichtigungen{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Stellen Sie hier ein, welche Art der Benachrichtigung (E-Mail oder Push) Sie für welches Ereignis (Gruppenzuweisungen, Veröffentlichung eines Standards, neue Agenturnews usw.) erhalten möchten." class="far fa-question-circle"></i></small>{% endif %}</h5>
@ -170,7 +176,7 @@
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
var defaultsettingsview = "profil"; var defaultsettingsview = "notifications";
/* COOKIE FOR SAVING OPEN TAB */ /* COOKIE FOR SAVING OPEN TAB */
$(document).ready(function(){ $(document).ready(function(){
@ -192,14 +198,14 @@ var defaultsettingsview = "profil";
} }
else{ else{
$("#profil-tab").addClass("active"); $("#notifications-tab").addClass("active");
$('#profil').tab('show'); $('#notifications').tab('show');
} }
} }
else{ else{
$("#profil-tab").addClass("active"); $("#notifications-tab").addClass("active");
$('#profil').tab('show'); $('#notifications').tab('show');
} }
}); });

View File

@ -9,17 +9,17 @@
</div> </div>
<small>Legen Sie hier die Stammdaten des neuen Mitarbeiters fest.</small> <small>Legen Sie hier die Stammdaten des neuen Mitarbeiters fest.</small>
<form method="POST"> <form method="POST" id="new_user_form">
{% csrf_token %} {% csrf_token %}
{{ newuserform|crispy }} {{ newuserform|crispy }}
<div class="form-check"> <!--<div class="form-check">
<input class="form-check-input" type="checkbox" value="true" id="sendmailnewuser" name="sendmailnewuser"> <input class="form-check-input" type="checkbox" value="true" id="sendmailnewuser" name="sendmailnewuser">
<label class="form-check-label" for="sendmailnewuser" name="sendmailnewuser"> <label class="form-check-label" for="sendmailnewuser" name="sendmailnewuser">
E-Mailbenachrichtigung schicken E-Mailbenachrichtigung schicken
</label> </label>
</div> </div>-->
<small>*: Der Benutzer erhält direkt eine E-Mail mit einem Link zur Passworterstellung, wenn der Haken bei <i>E-Mailbenachrichtung schicken</i> gesetzt ist. Dies kann später auch wiederholt werden.</small> <small>*: Der Benutzer erhält direkt eine Willkommens-E-Mail mit einem Link zur Passworterstellung.</small>
{% if request.user.profile.agency.paymentplan != "0" %} {% if request.user.profile.agency.paymentplan != "0" %}
<hr> <hr>
@ -28,8 +28,14 @@
<hr> <hr>
<a class="btn" href="{% url 'dasettings' %} ">Abbrechen</a> <a class="btn" href="{% url 'dasettings' %} ">Abbrechen</a>
<button type="submit" class="btn btn-primary" style="float: right">Weiter zu Schritt 2</button> <button id="createbtn" type="submit" class="btn btn-primary" style="float: right">Weiter zu Schritt 2</button>
</form> </form>
</div> </div>
</div> </div>
<script>
/* Disable the button for submitting after click */
$("#new_user_form").submit(function(event){
$("#createbtn").prop("disabled", true);
})
</script>
{% endblock content %} {% endblock content %}

View File

@ -61,8 +61,8 @@
<span id="user_email">{{ mail }}</span>&nbsp;<button onclick="javascript:ChangeMail()" style="float: right" type="button" class="btn btn-secondary btn-sm" id="changemailbutton"><i class="fas fa-pen"></i></button> <span id="user_email">{{ mail }}</span>&nbsp;<button onclick="javascript:ChangeMail()" style="float: right" type="button" class="btn btn-secondary btn-sm" id="changemailbutton"><i class="fas fa-pen"></i></button>
</p> </p>
<div style="float: left"> <div style="float: left">
<button type="button" id="" onclick="javascript:sendPassMail({{vieweduser}})" class="btn btn-primary btn-sm active" >Passwort wiederherstellen</button>&nbsp;&nbsp; <!--<button type="button" id="" onclick="javascript:sendPassMail({{vieweduser}})" class="btn btn-primary btn-sm active" >Passwort wiederherstellen</button>&nbsp;&nbsp;
<br /><br /><span class="alert alert-success" id="mailsend" role="alert" style="display: none;">&nbsp;E-Mail gesendet!</span> <br /><br /><span class="alert alert-success" id="mailsend" role="alert" style="display: none;">&nbsp;E-Mail gesendet!</span>-->
</div> </div>
</div> </div>
</div> </div>

View File

@ -547,6 +547,7 @@ Hier werden die Profilinfos des User zurückgesetzt; Parameter kommen von Settin
- Passwort aktualisieren - Passwort aktualisieren
''' '''
import requests
@login_required @login_required
def SettingsProfilManagement(request, context): def SettingsProfilManagement(request, context):
# Check, which form # Check, which form
@ -590,6 +591,10 @@ def SettingsProfilManagement(request, context):
context['passwordform'] = passwordform context['passwordform'] = passwordform
return render(request, 'dasettings/settings.html', context) return render(request, 'dasettings/settings.html', context)
def get_random_number(length = 6):
result_str = ''.join(random.choice("0123456789") for i in range(length))
return result_str
@login_required @login_required
def SettingsAjaxRouter(request): def SettingsAjaxRouter(request):
success = False success = False
@ -645,7 +650,7 @@ def SettingsAjaxRouter(request):
tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency) tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency)
data = {"funcname" : tempjob.name} data = {"funcname" : tempjob.name}
success = True success = True
# DELETE FINAL AGECY JOB # DELETE FINAL AGENCY JOB
elif request.method == 'GET' and request.GET['action'] == "delete_agencyfunc" : elif request.method == 'GET' and request.GET['action'] == "delete_agencyfunc" :
job_id = request.GET['id'] job_id = request.GET['id']
tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency) tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency)
@ -663,7 +668,31 @@ def SettingsAjaxRouter(request):
group.agencygroupname = request.GET['newvalue'] group.agencygroupname = request.GET['newvalue']
group.save() group.save()
data = {"newvalue" : group.agencygroupname} data = {"newvalue" : group.agencygroupname}
# Update Groupname in NC
'''
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true',
}
'''
'''
data_nc = {
"groupid" : group.nc_name,
"newvalue" : request.GET['newvalue']
}
'''
#r = requests.post(settings.NEXTCLOUD_URL + "/apps/agency/updateagencygroup", data=data_nc, headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
data = {
"name": request.GET['newvalue'],
"id" : group.nc_name
}
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v2.php/apps/da_agency/api/v1/renameagg?format=json", auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data)
#r = requests.post(settings.NEXTCLOUD_URL + "/apps/agency/api/v1/renameagg", data=data_nc, headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
success = True success = True
data = {"newvalue" : request.GET['newvalue']}
else: else:
success = False success = False
# GRUPPENNAMEN HOLEN # GRUPPENNAMEN HOLEN
@ -671,21 +700,70 @@ def SettingsAjaxRouter(request):
group = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency) group = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency)
data = {"groupname" : group.agencygroupname} data = {"groupname" : group.agencygroupname}
success = True success = True
# SAVE NEW GROUP ADD GROUP
elif request.method == 'GET' and request.GET['action'] == "add_group" : elif request.method == 'GET' and request.GET['action'] == "add_group" :
if(checkForGroupName(request, request.GET['newvalue'])): if(checkForGroupName(request, request.GET['newvalue'])):
tempgroup = Group(name=str(request.user.profile.agency.pk) + "_" + randomString(8)) tempgroup = Group(name=str(request.user.profile.agency.pk) + "_" + randomString(8))
tempgroup.save() tempgroup.save()
tempgroup_ag = AgencyGroup(savefordel=False, group=tempgroup, agency=request.user.profile.agency, agencygroupname=request.GET['newvalue']) tempgroup_ag = AgencyGroup(savefordel=False, group=tempgroup, agency=request.user.profile.agency, agencygroupname=request.GET['newvalue'])
tempgroup_ag.save()
success = True success = True
data = {"group_id" : tempgroup_ag.pk, "group_name" : tempgroup_ag.agencygroupname} data = {"group_id" : tempgroup_ag.pk, "group_name" : tempgroup_ag.agencygroupname}
nc_groupid = "agencymaingroupid_" + str(tempgroup_ag.agency.pk) + "_subgroup_" + get_random_number()
tempgroup_ag.nc_name = nc_groupid
tempgroup_ag.save()
# ADD group in NC
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
data_nc = {
"groupid" : nc_groupid,
}
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v1.php/cloud/groups", data=data_nc, headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
# Group created, set display name in NC
data_nc = {
"name": tempgroup_ag.agencygroupname,
"id" : nc_groupid
}
r = requests.post(settings.NEXTCLOUD_URL + "apps/agency/regr", data=data_nc, headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
# Add current User to this Group
# TODO: Hier checken, ob das wirklich nötig ist...?
#data_nc = {
# "groupid" : nc_groupid
#}
data = {
"name": tempgroup_ag.agencygroupname,
"id" : nc_groupid
}
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v2.php/apps/da_agency/api/v1/renameagg?format=json", auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data)
#r = requests.post(settings.NEXTCLOUD_URL + "ocs/v1.php/cloud/users/" + request.user.username + "/groups", data=data_nc, headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
else: else:
success = False success = False
# DELETE A GROUP
elif request.method == 'GET' and request.GET['action'] == "delete_group" : elif request.method == 'GET' and request.GET['action'] == "delete_group" :
groupag = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency) groupag = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency)
# DELETE GROUP IN NC
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
data_nc = {
"groupid" : groupag.nc_name,
}
r = requests.request("DELETE", settings.NEXTCLOUD_URL + "/ocs/v1.php/cloud/groups/" + groupag.nc_name,headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
group_to_del = groupag.group group_to_del = groupag.group
group_to_del.delete() group_to_del.delete()
success = True success = True
# PERMISSIONS ON GROUP! # PERMISSIONS ON GROUP!
elif request.method == 'GET' and request.GET['action'] == "change_perm_group" : elif request.method == 'GET' and request.GET['action'] == "change_perm_group" :
success = True success = True
@ -716,6 +794,18 @@ def SettingsAjaxRouter(request):
aggroup.group.user_set.remove(usertoremove) aggroup.group.user_set.remove(usertoremove)
data = {"userid" : usertoremove.pk, "groupid" : aggroup.pk, "user_fname" : usertoremove.first_name, "user_lname" : usertoremove.last_name} data = {"userid" : usertoremove.pk, "groupid" : aggroup.pk, "user_fname" : usertoremove.first_name, "user_lname" : usertoremove.last_name}
# User add
# NC REMOVE USER FROM GROUP
# first_name and last_name CHANGE - Update in NC as DisplayName
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
data_nc = {
"groupid" : aggroup.nc_name,
}
r = requests.request("DELETE", settings.NEXTCLOUD_URL + "/ocs/v1.php/cloud/users/" + usertoremove.username + "/groups",headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data_nc)
else: else:
success = False success = False
# ADD USER TO GROUP # ADD USER TO GROUP
@ -729,6 +819,20 @@ def SettingsAjaxRouter(request):
if(request.user.profile.agency.pk == aggroup.agency.pk): if(request.user.profile.agency.pk == aggroup.agency.pk):
aggroup.group.user_set.add(usertoadd) aggroup.group.user_set.add(usertoadd)
data = {"userid" : usertoadd.pk, "groupid" : aggroup.pk, "user_fname" : usertoadd.first_name, "user_lname" : usertoadd.last_name} data = {"userid" : usertoadd.pk, "groupid" : aggroup.pk, "user_fname" : usertoadd.first_name, "user_lname" : usertoadd.last_name}
# User add
# NC ADD USER TO GROUP
# first_name and last_name CHANGE - Update in NC as DisplayName
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
data_nc = {
"groupid" : aggroup.nc_name,
}
r = requests.post(settings.NEXTCLOUD_URL + "/ocs/v1.php/cloud/users/" + usertoadd.username + "/groups",headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data_nc)
else: else:
success = False success = False
# AREA # AREA
@ -851,8 +955,19 @@ def SettingsAjaxRouter(request):
success = False success = False
else: else:
tempuser.email = newmail tempuser.email = newmail
tempuser.username = newmail #tempuser.username = newmail
tempuser.save() tempuser.save()
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
data_nc = {
"key" : "email",
"value" : newmail
}
r = requests.put(settings.NEXTCLOUD_URL + "/ocs/v1.php/cloud/users/" + tempuser.username,headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data_nc)
print(r.text)
success = True success = True
else: else:
data = {"mail" : tempmail} data = {"mail" : tempmail}
@ -870,6 +985,18 @@ def SettingsAjaxRouter(request):
tempuser.save() tempuser.save()
data = {"userfullname" : tempuser.first_name + " " + tempuser.last_name} data = {"userfullname" : tempuser.first_name + " " + tempuser.last_name}
success = True success = True
# first_name and last_name CHANGE - Update in NC as DisplayName
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
data_nc = {
"key" : "displayname",
"value" : tempuser.first_name + " " + tempuser.last_name
}
r = requests.put(settings.NEXTCLOUD_URL + "/ocs/v1.php/cloud/users/" + tempuser.username,headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data_nc)
else: else:
data = {"userfullname" : tempuser.first_name + " " + tempuser.last_name} data = {"userfullname" : tempuser.first_name + " " + tempuser.last_name}
success = False success = False
@ -1542,7 +1669,7 @@ def UserChangeMain(request, pk):
} }
return render(request, 'dasettings/user_changemaindata.html', context) return render(request, 'dasettings/user_changemaindata.html', context)
# Method for first User-Creation-Step # Method for first User-Creation-Step - NEW USER
@login_required @login_required
def NewUserFirstStep(request): def NewUserFirstStep(request):
context = { context = {
@ -1551,24 +1678,45 @@ def NewUserFirstStep(request):
if request.method == 'POST': if request.method == 'POST':
newuserform = UserNewUserForm(request.POST) newuserform = UserNewUserForm(request.POST)
if newuserform.is_valid(): if newuserform.is_valid():
if(request.POST.get("sendmailnewuser")): #if(request.POST.get("sendmailnewuser")):
msg_html = render_to_string('users/newusers_email.html', {'username': newuserform.cleaned_data.get('first_name') + " " + newuserform.cleaned_data.get('last_name')}) # msg_html = render_to_string('users/newusers_email.html', {'username': newuserform.cleaned_data.get('first_name') + " " + newuserform.cleaned_data.get('last_name')})
send_mail(request.user.profile.agency.name + ' Account', 'Hallo ' + newuserform.cleaned_data.get('first_name') + ' ' + newuserform.cleaned_data.get('last_name') + '! Bitte setzen sie sich auf https://app.digitale-agentur.com/password-reset/ ein Passwort.','noreply@digitale-agentur.com',[newuserform.cleaned_data.get('email')],html_message=msg_html,fail_silently=True) # send_mail(request.user.profile.agency.name + ' Account', 'Hallo ' + newuserform.cleaned_data.get('first_name') + ' ' + newuserform.cleaned_data.get('last_name') + '! Bitte setzen sie sich auf https://app.digitale-agentur.com/password-reset/ ein Passwort.','noreply@digitale-agentur.com',[newuserform.cleaned_data.get('email')],html_message=msg_html,fail_silently=True)
newuser = newuserform.save(commit=False) newuser = newuserform.save(commit=False)
newuser.username = newuser.email newuser.username = newuser.email
newprofile = Profile(agency=request.user.profile.agency, parent=None) newprofile = Profile(agency=request.user.profile.agency, parent=None)
newprofile.save() newprofile.save()
newuser.profile = newprofile newuser.profile = newprofile
newuser.save() newuser.save()
# NEW USER IN DJANGO - ADD USER TO NC
# Data for the new User
try:
data_nc = {
"userid": newuser.username,
"password": "",
"displayName": newuser.first_name + " " + newuser.last_name,
"email": newuser.email,
"groups[]": "agencymaingroupid_" + str(request.user.profile.agency.pk)
}
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
# Request for adding the new User
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v1.php/cloud/users", data=data_nc, headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
except:
pass
# USERTIME # USERTIME
user_time = UserTime(user=newuser) user_time = UserTime(user=newuser)
user_time.save() user_time.save()
# USER NOTIFICATIONS # USER NOTIFICATIONS
user_notifications = UserNotifications(user=newuser) #user_notifications = UserNotifications.objects.create(user=newuser)
user_notifications.save() #user_notifications.save()
#newuser.usernotifications = user_notifications
newuser.usernotifications = user_notifications
newuser.usertime = user_time newuser.usertime = user_time

View File

@ -2,11 +2,11 @@
ASGI entrypoint. Configures Django and then runs the application ASGI entrypoint. Configures Django and then runs the application
defined in the ASGI_APPLICATION setting. defined in the ASGI_APPLICATION setting.
""" """
'''
import os import os
import django import django
from channels.routing import get_default_application from channels.routing import get_default_application
'''
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "digitaleagentur.settings") #os.environ.setdefault("DJANGO_SETTINGS_MODULE", "digitaleagentur.settings")
django.setup() #django.setup()
application = get_default_application() #application = get_default_application()

View File

@ -1,7 +1,9 @@
'''
from channels.auth import AuthMiddlewareStack from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter from channels.routing import ProtocolTypeRouter, URLRouter
import users.routing import users.routing
application = ProtocolTypeRouter({ application = ProtocolTypeRouter({
# Empty for now (http->django views is added by default) # Empty for now (http->django views is added by default)
'websocket': AuthMiddlewareStack( 'websocket': AuthMiddlewareStack(
@ -9,4 +11,6 @@ application = ProtocolTypeRouter({
users.routing.websocket_urlpatterns users.routing.websocket_urlpatterns
) )
), ),
}) })
'''

View File

@ -25,14 +25,15 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Nach zehn Stunden läuft der Cookie ab! # Nach zehn Stunden läuft der Cookie ab!
# TASK: Zehn stunden auto-auslog einmal checken Sekunden! # TASK: Zehn stunden auto-auslog einmal checken Sekunden!
SESSION_COOKIE_AGE = 8*60*60 SESSION_COOKIE_AGE = 100*60*60
SESSION_COOKIE_SECURE = False
#CHANNELS_PRESENCE_MAX_AGE = 30
CHANNELS_PRESENCE_MAX_AGE = 30
# FOR SUMMERNOTE ORIGIN # FOR SUMMERNOTE ORIGIN
X_FRAME_OPTIONS = 'SAMEORIGIN' #X_FRAME_OPTIONS = 'SAMEORIGIN'
#X_FRAME_OPTIONS = 'ALLOWALL' #X_FRAME_OPTIONS = 'ALLOWALL'
X_FRAME_OPTIONS = 'allow-from *cloud.digitale-agentur.com'
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
@ -47,10 +48,8 @@ MAILINFOKEY = "jka7sd8iukashdna78skduJAHDsu6dilaksdjba65a68iadbhjak"
#ALTER ZUM TESTEN #ALTER ZUM TESTEN
#LEX_API = "8f9ba01f-9e84-42c7-9548-48c254f14c19" #LEX_API = "8f9ba01f-9e84-42c7-9548-48c254f14c19"
# Neuer KEY
LEX_API = "p6xxyzOul0BaLDr-xuhVNYNzZ5s"
# Gültig bis 17.10.2022 # Gültig bis 17.10.2022
#LEX_API = "8dcbd7a5-9447-417f-a4a4-989818742a36" LEX_API = "8dcbd7a5-9447-417f-a4a4-989818742a36"
# KEYS FOR ENCRYPTED FILE FIELDS # KEYS FOR ENCRYPTED FILE FIELDS
DEFF_SALT = 'A-!GDtuKp?H/H5-UUatEh6ZcG/6h-VQf1OkDORRkK0(:(qCf//' DEFF_SALT = 'A-!GDtuKp?H/H5-UUatEh6ZcG/6h-VQf1OkDORRkK0(:(qCf//'
@ -62,6 +61,8 @@ DEFF_FETCH_URL_NAME = 'getdoc'
USE_X_FORWARDED_HOST = True USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
NC_SECRETKEY = "lkjahstaszd76uhjNJABHM65rftzvb323ADSD567tzu9ztz"
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
'django.contrib.contenttypes', 'django.contrib.contenttypes',
@ -95,8 +96,8 @@ INSTALLED_APPS = [
'django_user_agents', 'django_user_agents',
'rest_framework', 'rest_framework',
'rest_framework.authtoken', 'rest_framework.authtoken',
'channels', #'channels',
'channels_presence', #'channels_presence',
'simple_history', 'simple_history',
'captcha', 'captcha',
'auditlog', 'auditlog',
@ -112,11 +113,14 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django_user_agents.middleware.UserAgentMiddleware', 'django_user_agents.middleware.UserAgentMiddleware',
'simple_history.middleware.HistoryRequestMiddleware', 'simple_history.middleware.HistoryRequestMiddleware',
'auditlog.middleware.AuditlogMiddleware' 'auditlog.middleware.AuditlogMiddleware',
#'users.middleware.oauth.OAuthMiddleware'
] ]
ROOT_URLCONF = 'digitaleagentur.urls' ROOT_URLCONF = 'digitaleagentur.urls'
#CSRF_COOKIE_SECURE = False
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
@ -134,16 +138,20 @@ TEMPLATES = [
] ]
REST_FRAMEWORK = { REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ( #'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication', #'rest_framework.authentication.TokenAuthentication',
), #'rest_framework.permissions.AllowAny',
'DEFAULT_PERMISSION_CLASSES': [ #),
'rest_framework.permissions.IsAuthenticated', #'DEFAULT_PERMISSION_CLASSES': [
], # 'rest_framework.permissions.IsAuthenticated',
#],
} }
#WSGI_APPLICATION = 'digitaleagentur.wsgi.application' WSGI_APPLICATION = 'digitaleagentur.wsgi.application'
ASGI_APPLICATION = "digitaleagentur.routing.application" ASGI_APPLICATION = "digitaleagentur.routing.application"
'''
CHANNEL_LAYERS = { CHANNEL_LAYERS = {
'default': { 'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer', 'BACKEND': 'channels_redis.core.RedisChannelLayer',
@ -152,6 +160,7 @@ CHANNEL_LAYERS = {
}, },
}, },
} }
'''
@ -205,11 +214,11 @@ LOGIN_REDIRECT_URL = 'users-dashboard'
# LOGIN PAGE FOR LOGIN-REDIRECT # LOGIN PAGE FOR LOGIN-REDIRECT
LOGIN_URL = 'login' LOGIN_URL = 'login'
# NC Default Login findet im Dashboard statt!
#LOGIN_URL = NEXTCLOUD_URL
STATIC_URL = '/static/' STATIC_URL = '/static/'
''' '''
SITE_ROOT = os.path.dirname(os.path.realpath(__file__)) + '/..' SITE_ROOT = os.path.dirname(os.path.realpath(__file__)) + '/..'

View File

@ -1,5 +1,7 @@
from timemanagement.models import * from timemanagement.models import *
from digitaleagentur.timemanagement_utils import * from digitaleagentur.timemanagement_utils import *
from django.conf import settings
from django.shortcuts import redirect
''' '''
Hier sind Funktion implementiert, die in verschiedenen Module benötigt werden Hier sind Funktion implementiert, die in verschiedenen Module benötigt werden
@ -44,6 +46,35 @@ def getAbsenceForOneDay(user, day):
- Abwesenheit ist der komplette Tag, dann wird dieser Arbeitstag gelöscht, wenn es is_time false ist, sprich die Zeiterfassung soll nicht angefasst werden - Abwesenheit ist der komplette Tag, dann wird dieser Arbeitstag gelöscht, wenn es is_time false ist, sprich die Zeiterfassung soll nicht angefasst werden
- Abwesenheit ist kompletter Tag und die Abwesenheit soll Zeiterfassung beeinflussen (z.B. Gleitzeit) dann wird der Arbeitstag nicht verändert. Ist die Gleitzeit ein halber Tag, wird die Zielarbeitszeit halbiert. - Abwesenheit ist kompletter Tag und die Abwesenheit soll Zeiterfassung beeinflussen (z.B. Gleitzeit) dann wird der Arbeitstag nicht verändert. Ist die Gleitzeit ein halber Tag, wird die Zielarbeitszeit halbiert.
''' '''
'''
def checkAbsenceWorkdayCollide(absence):
# Alle einzelnen Tage der Abwesenheit werden durchgegangen:
# TODO: Hier einmal testen ob das korrekto ist
for day in daterange(absence.start, absence.end):
# Arbeitstage an diesem Tag werden geladen
#workdays = Workday.objects.filter(user=absence.user, start__day=absence.start.day, start__month=absence.start.month, start__year=absence.start.year)
workdays = Workday.objects.filter(user=absence.user, start__day=day.day, start__month=day.month, start__year=day.year)
# Wenn es Arbeitstage gibt, dann wird geprüft, ob die Abwesenheit diesen verändert hat.
for workday in workdays:
# Arbeitstag in Tag ohne Zeit umwandeln
# Wenn die Abwesenheit die Zeiterfassung NICHT ändert, muss diese ggf. geändert werden. Ansonsten bleibt sie gleich.
#if absence.reason.is_time == False:
if absence.reason.is_time == True:
# Prüfung, ob der Tag halb ist oder nicht. Wenn ja, dann Zielarbeitszeit des Tages um die Hälfte reduzieren.
#if (workday.start.day == absence.start.day and workday.start.month == absence.start.month and workday.start.year == absence.start.year) or (workday.end.day == absence.end.day and workday.end.month == absence.end.month and workday.end.year == absence.end.year):
if(getIsAbsenceStartEndHalf(absence)):
workday.target = workday.target / 2
workday.save()
# Ganzer Tag vorhanden, Arbeitstag wird als löschen markiert, aber nicht gelöscht
else:
if workday.delflag == True:
workday.delflag = False
workday.save()
else:
workday.delflag = True
workday.save()
'''
def checkAbsenceWorkdayCollide(absence): def checkAbsenceWorkdayCollide(absence):
# Alle einzelnen Tage der Abwesenheit werden durchgegangen: # Alle einzelnen Tage der Abwesenheit werden durchgegangen:
for day in daterange(absence.start, absence.end): for day in daterange(absence.start, absence.end):
@ -68,6 +99,33 @@ def checkAbsenceWorkdayCollide(absence):
workday.delflag = True workday.delflag = True
workday.save() workday.save()
'''
def checkAbsenceWorkdayCollideDelete(absence):
# Alle einzelnen Tage der Abwesenheit werden durchgegangen:
for day in daterange(absence.start, absence.end):
# Arbeitstage an diesem Tag werden geladen
workdays = Workday.objects.filter(user=absence.user, start__day=absence.start.day, start__month=absence.start.month, start__year=absence.start.year)
# Wenn es Arbeitstage gibt, dann wird geprüft, ob die Abwesenheit diesen verändert hat.
for workday in workdays:
# Arbeitstag in Tag ohne Zeit umwandeln
# Wenn die Abwesenheit die Zeiterfassung NICHT ändert, muss diese ggf. geändert werden. Ansonsten bleibt sie gleich.
if absence.reason.is_time == False:
# Prüfung, ob der Tag halb ist oder nicht. Wenn ja, dann Zielarbeitszeit des Tages um die Hälfte reduzieren.
if (workday.start.day == absence.start.day and workday.start.month == absence.start.month and workday.start.year == absence.start.year) or (workday.end.day == absence.end.day and workday.end.month == absence.end.month and workday.end.year == absence.end.year):
if(getIsAbsenceStartEndHalf(absence)):
workday.target = workday.target / 2
workday.save()
# Ganzer Tag vorhanden, Arbeitstag wird als löschen markiert, aber nicht gelöscht
else:
workday.delflag = False
workday.save()
else:
# Sollte der ganze Tag mal als zu löschen markiert worden sein, wird dies hier zurückgenommen
if workday.delflag == True:
workday.delflag = False
workday.save()
'''
def checkAbsenceWorkdayCollideDelete(absence): def checkAbsenceWorkdayCollideDelete(absence):
# Alle einzelnen Tage der Abwesenheit werden durchgegangen: # Alle einzelnen Tage der Abwesenheit werden durchgegangen:
for day in daterange(absence.start, absence.end): for day in daterange(absence.start, absence.end):
@ -94,10 +152,38 @@ def checkAbsenceWorkdayCollideDelete(absence):
# NC LOGIN
'''
A User has to be logged in in NC. If yes, we check the user-status and retrieving the userId. If the logged user by this session is the same we want to see in Django, than the user will logged in.
Double-Check: Logged-Session from NC (session-id cannot be hacked cause it is serverside) and we check userId local, django and NC
'''
import xmltodict, json, requests
'''
getNCLoggedUserBySession
Returns the UserId of the user in the given session
@params:
- sid (string) from nc_session_id, saved in the server and cookie
'''
from django.core.mail import send_mail
def getNCLoggedUserBySession(sid):
nc_login_headers = {'Authorization' : 'Bearer ' + sid}
r = requests.get(settings.NEXTCLOUD_URL + "ocs/v2.php/apps/user_status/api/v1/user_status", headers=nc_login_headers)
xpars = xmltodict.parse(r.text)
js = json.dumps(xpars)
final_json = json.loads(js)
return final_json['ocs']['data']['userId']
#except:
# return redirect('users-dashboard')

View File

@ -1,6 +1,3 @@
from django.conf import settings
settings.configure()
from django.contrib.auth.models import User from django.contrib.auth.models import User
from users.models import Profile,Agency from users.models import Profile,Agency

View File

@ -17,5 +17,5 @@ urlpatterns = [
path('newsga/<int:pk>', permission_required('users.modulenews')(views.NewsGoToArchiv), name="news-gotoarchiv"), path('newsga/<int:pk>', permission_required('users.modulenews')(views.NewsGoToArchiv), name="news-gotoarchiv"),
#path('standard/<int:pk>/area', views.StandardArea, name="standard-area"), #path('standard/<int:pk>/area', views.StandardArea, name="standard-area"),
#path('standard/<int:pk>/task', views.StandardTask, name="standard-task") #path('standard/<int:pk>/task', views.StandardTask, name="standard-task")
] ]

View File

@ -1,3 +1,4 @@
from django.http.response import JsonResponse
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView
@ -17,6 +18,7 @@ class NewsManagement(LoginRequiredMixin, ListView):
# Loading only user same agency # Loading only user same agency
# Change context and return for template-data # Change context and return for template-data
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
filterdate = timezone.now() filterdate = timezone.now()
news = News.objects.filter(agency__pk=self.request.user.profile.agency.pk).filter(go_online_on__lt=filterdate).filter(go_offline_on__gt=filterdate).order_by('-created_date') | News.objects.filter(agency__pk=self.request.user.profile.agency.pk).filter(go_online_on__lt=filterdate).filter(go_offline_on__isnull=True).order_by('-created_date') news = News.objects.filter(agency__pk=self.request.user.profile.agency.pk).filter(go_online_on__lt=filterdate).filter(go_offline_on__gt=filterdate).order_by('-created_date') | News.objects.filter(agency__pk=self.request.user.profile.agency.pk).filter(go_online_on__lt=filterdate).filter(go_offline_on__isnull=True).order_by('-created_date')
@ -134,8 +136,3 @@ def NewsSingle(request, pk):
return render(request, 'news/news_single.html', context) return render(request, 'news/news_single.html', context)

View File

@ -465,7 +465,7 @@ class RecoverDirAddPL(CreateView):
template_name = "recoverdir/rd_pers_add.html" template_name = "recoverdir/rd_pers_add.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -513,7 +513,7 @@ class RDAoneAddDoc(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_1_adddoc.html" template_name = "recoverdir/rd_elements_forms/rd_area_1_adddoc.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -544,7 +544,7 @@ class RDAoneViewDoc(DetailView):
context_object_name = 'document' context_object_name = 'document'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -556,7 +556,7 @@ class RDAoneDelDoc(DeleteView):
context_object_name = 'document' context_object_name = 'document'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -573,7 +573,7 @@ class RDAoneUpdateDoc(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_1_adddoc.html" template_name = "recoverdir/rd_elements_forms/rd_area_1_adddoc.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -625,7 +625,7 @@ class RDAoneUpdateHL(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_1_addhl.html" template_name = "recoverdir/rd_elements_forms/rd_area_1_addhl.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -643,7 +643,7 @@ class RDAoneAddFC(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_1_addfc.html" template_name = "recoverdir/rd_elements_forms/rd_area_1_addfc.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -664,7 +664,7 @@ class RDAoneUpdateContact(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_1_addfc.html" template_name = "recoverdir/rd_elements_forms/rd_area_1_addfc.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -681,7 +681,7 @@ class RDAoneViewContact(DetailView):
context_object_name = 'contact' context_object_name = 'contact'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -693,7 +693,7 @@ class RDAoneDelContact(DeleteView):
context_object_name = 'contact' context_object_name = 'contact'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -711,7 +711,7 @@ class RDAoneViewTrust(DetailView):
context_object_name = 'contact' context_object_name = 'contact'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -723,7 +723,7 @@ class RDAoneDelTrust(DeleteView):
context_object_name = 'contact' context_object_name = 'contact'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -740,7 +740,7 @@ class RDAoneAddTrust(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_1_addtrust.html" template_name = "recoverdir/rd_elements_forms/rd_area_1_addtrust.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -761,7 +761,7 @@ class RDAoneUpdateTrust(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_1_addtrust.html" template_name = "recoverdir/rd_elements_forms/rd_area_1_addtrust.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -780,7 +780,7 @@ class RDAtwoAddHLFV(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_2_addhlvf.html" template_name = "recoverdir/rd_elements_forms/rd_area_2_addhlvf.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -801,7 +801,7 @@ class RDAtwoUpdateFV(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_2_addhlvf.html" template_name = "recoverdir/rd_elements_forms/rd_area_2_addhlvf.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -819,7 +819,7 @@ class RDAtwoViewdeposit(DetailView):
context_object_name = 'deposit' context_object_name = 'deposit'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -831,7 +831,7 @@ class RDAtwoDeldeposit(DeleteView):
context_object_name = 'deposit' context_object_name = 'deposit'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -848,7 +848,7 @@ class RDAtwoAdddeposit(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_2_adddeposit.html" template_name = "recoverdir/rd_elements_forms/rd_area_2_adddeposit.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -877,7 +877,7 @@ class RDAtwoUpdatedeposit(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_2_adddeposit.html" template_name = "recoverdir/rd_elements_forms/rd_area_2_adddeposit.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -899,7 +899,7 @@ class RDAtwoViewergo(DetailView):
context_object_name = 'ergo' context_object_name = 'ergo'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -911,7 +911,7 @@ class RDAtwoDelergo(DeleteView):
context_object_name = 'ergo' context_object_name = 'ergo'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -928,7 +928,7 @@ class RDAtwoAddergo(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_2_addergo.html" template_name = "recoverdir/rd_elements_forms/rd_area_2_addergo.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -949,7 +949,7 @@ class RDAtwoUpdateergo(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_2_addergo.html" template_name = "recoverdir/rd_elements_forms/rd_area_2_addergo.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -971,7 +971,7 @@ class RDAtwoViewonlinebank(DetailView):
context_object_name = 'onlinebank' context_object_name = 'onlinebank'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -983,7 +983,7 @@ class RDAtwoDelonlinebank(DeleteView):
context_object_name = 'onlinebank' context_object_name = 'onlinebank'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1000,7 +1000,7 @@ class RDAtwoAddonlinebank(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_2_addonlinebank.html" template_name = "recoverdir/rd_elements_forms/rd_area_2_addonlinebank.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1030,7 +1030,7 @@ class RDAtwoUpdateonlinebank(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_2_addonlinebank.html" template_name = "recoverdir/rd_elements_forms/rd_area_2_addonlinebank.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1059,7 +1059,7 @@ class RDAthreeViewstreaming(DetailView):
context_object_name = 'streaming' context_object_name = 'streaming'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1071,7 +1071,7 @@ class RDAthreeDelstreaming(DeleteView):
context_object_name = 'streaming' context_object_name = 'streaming'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1088,7 +1088,7 @@ class RDAthreeAddstreaming(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_3_addstreamingabo.html" template_name = "recoverdir/rd_elements_forms/rd_area_3_addstreamingabo.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1117,7 +1117,7 @@ class RDAthreeUpdatestreaming(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_3_addstreamingabo.html" template_name = "recoverdir/rd_elements_forms/rd_area_3_addstreamingabo.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1146,7 +1146,7 @@ class RDAfourViewdigitalaccount(DetailView):
context_object_name = 'account' context_object_name = 'account'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1159,7 +1159,7 @@ class RDAfourDeldigitalaccount(DeleteView):
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1176,7 +1176,7 @@ class RDAfourAdddigitalaccount(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_4_adddigitalaccount.html" template_name = "recoverdir/rd_elements_forms/rd_area_4_adddigitalaccount.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1206,7 +1206,7 @@ class RDAfourUpdatedigitalaccount(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_4_adddigitalaccount.html" template_name = "recoverdir/rd_elements_forms/rd_area_4_adddigitalaccount.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1235,7 +1235,7 @@ class RDAfiveViewpersonal(DetailView):
context_object_name = 'personal' context_object_name = 'personal'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1247,7 +1247,7 @@ class RDAfiveDelpersonal(DeleteView):
context_object_name = 'personal' context_object_name = 'personal'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1264,7 +1264,7 @@ class RDAfiveAddpersonal(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_5_addpersonal.html" template_name = "recoverdir/rd_elements_forms/rd_area_5_addpersonal.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1286,7 +1286,7 @@ class RDAfiveUpdatepersonal(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_5_addpersonal.html" template_name = "recoverdir/rd_elements_forms/rd_area_5_addpersonal.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1308,7 +1308,7 @@ class RDAnineViewelse(DetailView):
context_object_name = 'else' context_object_name = 'else'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1320,7 +1320,7 @@ class RDAnineDelelse(DeleteView):
context_object_name = 'ele' context_object_name = 'ele'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1337,7 +1337,7 @@ class RDAnineAddelse(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_9_addelse.html" template_name = "recoverdir/rd_elements_forms/rd_area_9_addelse.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1359,7 +1359,7 @@ class RDAnineUpdateelse(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_9_addelse.html" template_name = "recoverdir/rd_elements_forms/rd_area_9_addelse.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1381,7 +1381,7 @@ class RDAsevenViewcontract(DetailView):
context_object_name = 'contract' context_object_name = 'contract'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1393,7 +1393,7 @@ class RDAsevenDelcontract(DeleteView):
context_object_name = 'ele' context_object_name = 'ele'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1410,7 +1410,7 @@ class RDAsevenAddcontract(CreateView):
template_name = "recoverdir/rd_elements_forms/rd_area_7_addcontract.html" template_name = "recoverdir/rd_elements_forms/rd_area_7_addcontract.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self)): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1431,7 +1431,7 @@ class RDAsevenUpdatecontract(UpdateView):
template_name = "recoverdir/rd_elements_forms/rd_area_7_addcontract.html" template_name = "recoverdir/rd_elements_forms/rd_area_7_addcontract.html"
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1454,7 +1454,7 @@ class PLSingleHistory(DetailView):
context_object_name = 'persletter' context_object_name = 'persletter'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1481,7 +1481,7 @@ class HLSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_1_hl_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_1_hl_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1510,7 +1510,7 @@ class HLVFSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_2_hl_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_2_hl_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1539,7 +1539,7 @@ class ContactSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_1_contact_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_1_contact_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1568,7 +1568,7 @@ class TrustSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_1_trust_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_1_trust_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1597,7 +1597,7 @@ class DepositSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_2_deposit_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_2_deposit_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1626,7 +1626,7 @@ class DocumentSingleHistory(DetailView):
template_name = 'recoverdir/rd_doc_single.html' template_name = 'recoverdir/rd_doc_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1655,7 +1655,7 @@ class ErgoSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_2_ergo_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_2_ergo_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1684,7 +1684,7 @@ class OnlinebankSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_2_onlinebank_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_2_onlinebank_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1713,7 +1713,7 @@ class StreamingSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_3_streamingabo_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_3_streamingabo_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1742,7 +1742,7 @@ class DigitalAccountSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_4_digitalaccount_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_4_digitalaccount_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1771,7 +1771,7 @@ class PersonalSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_5_personal_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_5_personal_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1800,7 +1800,7 @@ class ContractSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_7_contract_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_7_contract_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')
@ -1829,7 +1829,7 @@ class ElseSingleHistory(DetailView):
template_name = 'recoverdir/rd_elements_forms/rd_area_9_else_single.html' template_name = 'recoverdir/rd_elements_forms/rd_area_9_else_single.html'
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
if(checkForLogin(self) and self.get_object().agency == self.request.user.profile.agency): if(checkForLogin(self) and self.instance.agency == self.request.user.profile.agency):
return super().dispatch(*args, **kwargs) return super().dispatch(*args, **kwargs)
else: else:
return redirect('recoverdir-login') return redirect('recoverdir-login')

View File

@ -36,3 +36,6 @@ xhtml2pdf==0.2.5
django-simple-captcha==0.5.13 django-simple-captcha==0.5.13
auditlog3==1.0.1 auditlog3==1.0.1
filetype==1.0.7 filetype==1.0.7
Authlib==0.15.3
xmltodict==0.12.0
django-user-sessions==1.7.1

View File

@ -22,7 +22,7 @@ class StandardComments(models.Model):
comment_by = models.ForeignKey(User, on_delete=models.CASCADE) comment_by = models.ForeignKey(User, on_delete=models.CASCADE)
comment_on = models.DateTimeField(default=timezone.now, blank=True) comment_on = models.DateTimeField(default=timezone.now, blank=True)
last_modified_on = models.DateTimeField(default=timezone.now, blank=True) last_modified_on = models.DateTimeField(default=timezone.now, blank=True)
class Standards(models.Model): class Standards(models.Model):
agency = models.ForeignKey(Agency, on_delete=models.CASCADE) agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
area = models.ForeignKey(Areas, on_delete=models.SET_NULL, blank=True, null=True) area = models.ForeignKey(Areas, on_delete=models.SET_NULL, blank=True, null=True)
@ -66,6 +66,8 @@ class Standards(models.Model):
# FILES # FILES
addedfiles = models.ManyToManyField(DataFile, blank=True) addedfiles = models.ManyToManyField(DataFile, blank=True)
addedfiles_nc = models.ManyToManyField('NCFile', blank=True)
# VERLINKTE STANDARDS # VERLINKTE STANDARDS
linked_standards = models.ManyToManyField('Standards', blank=True) linked_standards = models.ManyToManyField('Standards', blank=True)
# GORUPS # GORUPS
@ -94,3 +96,8 @@ class Standards(models.Model):
# Hier Path für Templates des Models mit Parametern # Hier Path für Templates des Models mit Parametern
def get_absolute_url(self): def get_absolute_url(self):
return reverse('standards-add', kwargs={'pk':self.pk}) return reverse('standards-add', kwargs={'pk':self.pk})
class NCFile(models.Model):
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
nc_id = models.IntegerField(default=0)
file_id = models.ForeignKey(DataFile, on_delete=models.CASCADE, null=True, blank=True, default=None)

View File

@ -0,0 +1,15 @@
var button = document.createElement("a");
button.innerHTML = '<image src="http://localhost:8080/svg/core/actions/user-admin?color=ebebec">';
// ICON
button.classList.add("header-menu");
var header = document.getElementsByClassName("header-right")[0];
header.prepend(button);
button.style.padding = "20px";
button.addEventListener ("click", function() {
alert("did something");
});

View File

@ -5,7 +5,7 @@
<div class="content-section col-12"> <div class="content-section col-12">
{% if update == True %} {% if update == True %}
<h3>Standard Bearbeiten{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Bearbeiten Sie hier einen bestehenden Standard." class="far fa-question-circle"></i></small>{% endif %}</h3> <h3>Standard Bearbeiten {% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Bearbeiten Sie hier einen bestehenden Standard." class="far fa-question-circle"></i></small>{% endif %}</h3>
{% else %} {% else %}
<h3>Neuen Standard anlegen{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Legen Sie hier einen neuen Standard an." class="far fa-question-circle"></i></small>{% endif %}</h3> <h3>Neuen Standard anlegen{% if request.user.profile.showtooltips %}&nbsp;<small><i data-toggle="tooltip" data-placement="top" title="Legen Sie hier einen neuen Standard an." class="far fa-question-circle"></i></small>{% endif %}</h3>
{% endif %} {% endif %}
@ -144,24 +144,29 @@
<button type="button" onclick="javascript:clearSearchField('files')" class="btn btn-secondary" ><i class="fas fa-times"></i></button> <button type="button" onclick="javascript:clearSearchField('files')" class="btn btn-secondary" ><i class="fas fa-times"></i></button>
</div> </div>
<datalist id="poss_files"> <datalist id="poss_files">
{% for f in files %} {% for f in files %}
<option id="files_{{f.pk}}" value="{{f.name}}">{{f.name}}</option> {% getNCFileInfos request f as filename %}
{% if filename != "FAIL_TO_LOAD_NC_FILE_DATA" %}
<option id="files_{{f}}" value="{{filename}}">{{filename}}</option>
{% endif %}
{% endfor %} {% endfor %}
</datalist> </datalist>
</div> </div>
Verlinkte Dateien: Verlinkte Dateien:
<table id="linked_files" class="table table-hover table-sm"> <table id="linked_files" class="table table-hover table-sm">
{% if update == True %} {% if update == True %}
{% for f in standard.addedfiles.all %} {% for f in standard.addedfiles_nc.all %}
<tr id="added_files_{{f.pk}}"><td>{{f.name}}</td><td><button type="button" class="btn btn-danger btn-sm" style="float: right;" onclick="javascript:remEle('files',{{f.pk}}, '{{f.name}}')"><i class="fas fa-trash"></i></button></td></tr> {% getNCFileInfos request f.nc_id as filename %}
<tr id="added_files_{{f.nc_id}}"><td>{{filename}}</td><td><button type="button" class="btn btn-danger btn-sm" style="float: right;" onclick="javascript:remEle('files',{{f.nc_id}}, '{{filename}}')"><i class="fas fa-trash"></i></button></td></tr>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</table> </table>
<!-- TODO: Upload ins richtige Verzeichnis-->
<input type="file" id="uploadedfile" name="uploadedfile" style="display:none"> <input type="file" id="uploadedfile" name="uploadedfile" style="display:none">
{% if user|usergperm:"filesmanager" %} {% if user|usergperm:"filesmanager" %}
<div class="alert alert-secondary text-center mt-5" id="directdiv" role="alert" style="line-height: 17px; text-align: center;"> <div class="alert alert-secondary text-center mt-5" id="directdiv" role="alert" style="line-height: 17px; text-align: center;">
<button type="button" class="btn btn-primary btn-sm" id="uploadButton" onclick="javascript:uploadButtonPush()"><i class="fas fa-plus"></i></button>&nbsp;&nbsp;<small>klicken/hineinziehen<p class="mt-2">Dateien werden im <b>Uploadordner für Standards</b> gespeichert. <button type="button" class="btn btn-primary btn-sm" id="uploadButton" onclick="javascript:uploadButtonPush()"><i class="fas fa-plus"></i></button>&nbsp;&nbsp;<small>klicken/hineinziehen<p class="mt-2">Dateien werden im Verzeichnis <b>Agenturdaten/Standards Uploadbereich </b> gespeichert.
</small></p> </small></p>
</div> </div>
{% endif %} {% endif %}
@ -717,8 +722,9 @@
var ua = window.navigator.userAgent; var ua = window.navigator.userAgent;
var isIE = /MSIE|Trident/.test(ua); var isIE = /MSIE|Trident/.test(ua);
var isSafari = /Safari/.test(ua); var isSafari = /Safari/.test(ua);
var isChrome = /Chrome/.test(ua);
if ( isIE || isSafari) { if ( isIE || (isSafari && !isChrome)) {
//IE specific code goes here //IE specific code goes here
setInterval(function() setInterval(function()
{ {
@ -762,7 +768,7 @@ function checkGroupVerant(){
$("#id_group_verant").val(act_verant_group); $("#id_group_verant").val(act_verant_group);
} }
console.log($("#id_group_verant").val()); //console.log($("#id_group_verant").val());
} }
function removeGroupFromVeran(id, name){ function removeGroupFromVeran(id, name){
@ -772,7 +778,7 @@ function removeGroupFromVeran(id, name){
$("#id_group_verant").val(act_verant_group); $("#id_group_verant").val(act_verant_group);
$("#span_btn_verant_group_" + id).remove(); $("#span_btn_verant_group_" + id).remove();
console.log($("#id_group_verant").val()); //console.log($("#id_group_verant").val());
} }
//AUSFÜHRENDER //AUSFÜHRENDER
@ -798,7 +804,7 @@ function checkGroupEx(){
$("#id_group_ex").val(act_ex_group); $("#id_group_ex").val(act_ex_group);
} }
console.log($("#id_group_ex").val()); //console.log($("#id_group_ex").val());
} }
function removeGroupFromEx(id, name){ function removeGroupFromEx(id, name){
@ -808,7 +814,7 @@ function removeGroupFromEx(id, name){
$("#id_group_ex").val(act_ex_group); $("#id_group_ex").val(act_ex_group);
$("#span_btn_ex_group_" + id).remove(); $("#span_btn_ex_group_" + id).remove();
console.log($("#id_group_ex").val()); //console.log($("#id_group_ex").val());
} }
//VERTRETER //VERTRETER
@ -1005,8 +1011,8 @@ actualStandards = [];
actualFiles = []; actualFiles = [];
{% if update == True %} {% if update == True %}
actualFiles = [ actualFiles = [
{% for f in standard.addedfiles.all %} {% for f in standard.addedfiles_nc.all %}
'{{f.pk}}', '{{f.nc_id}}',
{% endfor %} {% endfor %}
]; ];
$("#id_added_files").val(actualFiles); $("#id_added_files").val(actualFiles);
@ -1054,8 +1060,7 @@ function clearSearchField(type){
function updateLinkedElements(type){ function updateLinkedElements(type){
var g = $('#searchfield_' + type).val(); var g = $('#searchfield_' + type).val();
var id = $('#poss_' + type).find('option[value="' + g + '"]').attr('id'); var id = $('#poss_' + type).find('option[value="' + g + '"]').attr('id');
if((id != undefined || id != "undefined") && id.length > 0){
if(id != undefined && id.length > 0){
clearSearchField(type); clearSearchField(type);
tempid = id.split("_")[1]; tempid = id.split("_")[1];
@ -1100,6 +1105,7 @@ function remEle(type, id, name){
index_to_rem = actualFiles.indexOf(id); index_to_rem = actualFiles.indexOf(id);
actualFiles.splice(index_to_rem,1); actualFiles.splice(index_to_rem,1);
$("#id_added_" + type).val(actualFiles); $("#id_added_" + type).val(actualFiles);
} }
else if(type == 'quicklinks'){ else if(type == 'quicklinks'){
index_to_rem = actualQuicklinks.indexOf(id); index_to_rem = actualQuicklinks.indexOf(id);
@ -1176,6 +1182,7 @@ function replaceFileDirectChoice(filetodo, choice){
doUploadAction(filetodo_ex, choice); doUploadAction(filetodo_ex, choice);
} }
function uploadAction(filetodo){ function uploadAction(filetodo){
filetodo_ex = filetodo; filetodo_ex = filetodo;
@ -1183,7 +1190,7 @@ function uploadAction(filetodo){
$.ajax( $.ajax(
{ {
type: "GET", type: "GET",
url: "{% url 'cloud-adddir' parentid %}", url: "{% url 'cloud-adddir' 0 %}",
data:{ data:{
action : "check_doublefile", action : "check_doublefile",
name : filetodo.name name : filetodo.name
@ -1223,7 +1230,7 @@ function doUploadAction(filetodo, replacestat){
if(c && filetodo.type.length > 0){ if(c && filetodo.type.length > 0){
$.ajax({ $.ajax({
url: "{% url 'cloud-adddir' parentid %}", url: "{% url 'standard-uploadfile' %}",
headers: { headers: {
"X-CSRFTOKEN": "{{ csrf_token }}" "X-CSRFTOKEN": "{{ csrf_token }}"
}, },
@ -1246,6 +1253,7 @@ function doUploadAction(filetodo, replacestat){
return xhr; return xhr;
}, },
success: function(data) { success: function(data) {
console.log(data);
if(data["success"] == true){ if(data["success"] == true){
setTimeout(function(){ setTimeout(function(){
hideUpload(); hideUpload();

View File

@ -27,7 +27,7 @@
<hr> <hr>
<div class="row col"> <div class="row col">
{% if standard.addedfiles.all|length > 0 or standard.linked_standards.all|length > 0 or standard.authority.count > 0 or standard.executor.count > 0 or standard.representative.count > 0 or standard.addedfiles.all|length > 0 or standard.linked_standards.all|length > 0 or standard.freefield_title|length > 0 or standard.addedcontacts.all|length > 0 or standard.addedpasswords.all|length > 0 or standard.addedquicklinks.all|length > 0 or standard.authority_group.count > 0 or standard.executor_group.count > 0 or standard.representative_group.count > 0 %} {% if standard.addedfiles_nc.all|length > 0 or standard.linked_standards.all|length > 0 or standard.authority.count > 0 or standard.executor.count > 0 or standard.representative.count > 0 or standard.addedfiles_nc.all|length > 0 or standard.linked_standards.all|length > 0 or standard.freefield_title|length > 0 or standard.addedcontacts.all|length > 0 or standard.addedpasswords.all|length > 0 or standard.addedquicklinks.all|length > 0 or standard.authority_group.count > 0 or standard.executor_group.count > 0 or standard.representative_group.count > 0 %}
<div class="card col-9" style="min-height: 500px"> <div class="card col-9" style="min-height: 500px">
{% else %} {% else %}
<div class="card col-12" style="min-height: 500px"> <div class="card col-12" style="min-height: 500px">
@ -42,7 +42,7 @@
</div> </div>
<!-- PERSONEN --> <!-- PERSONEN -->
{% if standard.addedfiles.all|length > 0 or standard.linked_standards.all|length > 0 or standard.authority.count > 0 or standard.executor.count > 0 or standard.representative.count > 0 or standard.addedfiles.all|length > 0 or standard.linked_standards.all|length > 0 or standard.freefield_title|length > 0 or standard.addedcontacts.all|length > 0 or standard.addedpasswords.all|length > 0 or standard.addedquicklinks.all|length > 0 or standard.authority_group.count > 0 or standard.executor_group.count > 0 or standard.representative_group.count > 0 %} {% if standard.addedfiles_nc.all|length > 0 or standard.linked_standards.all|length > 0 or standard.authority.count > 0 or standard.executor.count > 0 or standard.representative.count > 0 or standard.addedfiles_nc.all|length > 0 or standard.linked_standards.all|length > 0 or standard.freefield_title|length > 0 or standard.addedcontacts.all|length > 0 or standard.addedpasswords.all|length > 0 or standard.addedquicklinks.all|length > 0 or standard.authority_group.count > 0 or standard.executor_group.count > 0 or standard.representative_group.count > 0 %}
<div class="col-3"> <div class="col-3">
@ -131,19 +131,26 @@
<!-- FILES --> <!-- FILES -->
{% if standard.addedfiles.all|length > 0 %} {% if standard.addedfiles_nc.all|length > 0 %}
<div class="card col-14 ml-1 mb-2" style="min-width: 110%"> <div class="card col-14 ml-1 mb-2" style="min-width: 110%">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Dateien</h5> <h5 class="card-title">Dateien</h5>
<p class="card-text"> <p class="card-text">
{% for files in standard.addedfiles.all %} {% for file in standard.addedfiles_nc.all %}
<a href="{% url 'cloud-td' files.pk %}" target="_blank">{{files.name|truncatechars:30}}</a><br /> {% getNCFileInfos request file.nc_id as filename %}
{% getNCFileInfosURL request file.nc_id as filelink %}
{% getNCDirInfosURL request file.nc_id as dirlink %}
{% getNextcloudURL as nc_url %}
<a href="{{nc_url}}apps/files/?dir=/{{dirlink}}&openfile={{file.nc_id}}" target="_blank">{{filename|truncatechars:30}}</a>
<br />
{% endfor %} {% endfor %}
</p> </p>
</div> </div>
</div> </div>
{% endif %} {% endif %}
<!-- Quicklinks --> <!-- Quicklinks -->
{% if standard.addedquicklinks.all|length > 0 %} {% if standard.addedquicklinks.all|length > 0 %}
<div class="card col-14 ml-1 mb-2" style="min-width: 110%"> <div class="card col-14 ml-1 mb-2" style="min-width: 110%">

View File

@ -72,13 +72,14 @@
<!-- FILES --> <!-- FILES -->
{% if standard.addedfiles.all|length > 0 %} {% if standard.addedfiles_nc.all|length > 0 %}
<div class="card col-14 ml-1 mb-2" style=""> <div class="card col-14 ml-1 mb-2" style="">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Dateien</h5> <h5 class="card-title">Dateien</h5>
<p class="card-text"> <p class="card-text">
{% for files in standard.addedfiles.all %} {% for files in standard.addedfiles_nc.all %}
{{files.name|truncatechars:30}}<br /> {% getNCFileInfos request files.nc_id as filename %}
{{filename|truncatechars:30}}<br />
{% endfor %} {% endfor %}
</p> </p>
</div> </div>

View File

@ -1110,30 +1110,70 @@ def getAbsenceLastHistory(absence):
return absence.history.first() return absence.history.first()
# Gibt die Arbeitstage zurück, an denen auch eine Abwesenheit liegt '''
from digitaleagentur.timemanagement_utils import * Dateinamen umbauen, damit im Standard die verlinkte Datei korrekt angezeigt wird.
@register.simple_tag
def getADMAbsenceWorkdays(user):
workdays_final = []
for absence in Absence.objects.filter(user=user):
for day in daterange(absence.start, absence.end):
# Arbeitstage an diesem Tag werden geladen
workdays = Workday.objects.filter(user=absence.user, start__day=day.day, start__month=day.month, start__year=day.year, delflag=False)
# Wenn es Arbeitstage gibt, dann wird geprüft, ob die Abwesenheit diesen verändert hat. TODO: Thread auf github beobachten, https://github.com/nextcloud/server/issues/17778 wenn dann displayname wieder bei WebDav geht!
for workday in workdays:
workdays_final.append(workday) Gibt den Dateinamen sauber als String zurück, wie sie in NC heißt!
return workdays_final '''
import urllib.parse
@register.simple_tag
def getNCFileInfos(request, ncid):
try:
filesearchdata = '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><d:displayname/></d:prop></d:select><d:from><d:scope><d:href>/files/' + request.user.username + '</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:eq><d:prop><oc:fileid/></d:prop><d:literal>' + str(ncid) + '</d:literal></d:eq></d:where></d:basicsearch></d:searchrequest>'
r = requests.request("SEARCH", settings.NEXTCLOUD_URL + "remote.php/dav/", data=filesearchdata, headers={'Content-Type' : 'text/xml', 'Authorization' : "Bearer " + request.user.profile.nc_sid})
split_response = r.text.split("<d:href>")
split_fileele = split_response[1].split("</d:href>")
split_filename = split_fileele[0].split("/")
split_filenameclear = split_filename[len(split_filename)-1]
return urllib.parse.unquote(split_filenameclear)
except:
return "FAIL_TO_LOAD_NC_FILE_DATA"
@register.simple_tag
def getNextcloudURL():
return settings.NEXTCLOUD_URL
@register.simple_tag @register.simple_tag
def getADMAbsenceWorkdaysTrue(user): def getNCFileInfosURL(request, ncid):
workdays_final = [] try:
for absence in Absence.objects.filter(user=user): filesearchdata = '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><d:displayname/></d:prop></d:select><d:from><d:scope><d:href>/files/' + request.user.username + '</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:eq><d:prop><oc:fileid/></d:prop><d:literal>' + str(ncid) + '</d:literal></d:eq></d:where></d:basicsearch></d:searchrequest>'
for day in daterange(absence.start, absence.end): r = requests.request("SEARCH", settings.NEXTCLOUD_URL + "remote.php/dav/", data=filesearchdata, headers={'Content-Type' : 'text/xml', 'Authorization' : "Bearer " + request.user.profile.nc_sid})
# Arbeitstage an diesem Tag werden geladen split_response = r.text.split("<d:href>")
workdays = Workday.objects.filter(user=absence.user, start__day=day.day, start__month=day.month, start__year=day.year, delflag=True) split_fileele = split_response[1].split("</d:href>")
# Return file-link except first slash in string
return split_fileele[0][1:]
#return urllib.parse.unquote(split_filenameclear)
except:
return ""
@register.simple_tag
def getNCDirInfosURL(request, ncid):
try:
filesearchdata = '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><d:displayname/></d:prop></d:select><d:from><d:scope><d:href>/files/' + request.user.username + '</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:eq><d:prop><oc:fileid/></d:prop><d:literal>' + str(ncid) + '</d:literal></d:eq></d:where></d:basicsearch></d:searchrequest>'
r = requests.request("SEARCH", settings.NEXTCLOUD_URL + "remote.php/dav/", data=filesearchdata, headers={'Content-Type' : 'text/xml', 'Authorization' : "Bearer " + request.user.profile.nc_sid})
split_response = r.text.split("<d:href>")
split_fileele = split_response[1].split("</d:href>")
# Generating Dir-Link
finaldirlink = ""
counter = 0
dirpre = split_fileele[0].split("/")
dirpre.pop(0)
dirpre.pop(0)
dirpre.pop(0)
dirpre.pop(0)
dirpre.pop(0)
for ele in dirpre:
if counter < len(dirpre) - 1:
finaldirlink += ele + "/"
counter += 1
# Return file-link except first slash in string
return finaldirlink[:-1]
#return urllib.parse.unquote(split_filenameclear)
except:
return ""
# Wenn es Arbeitstage gibt, dann wird geprüft, ob die Abwesenheit diesen verändert hat.
for workday in workdays:
workdays_final.append(workday)
return workdays_final

View File

@ -26,6 +26,8 @@ urlpatterns = [
path('standardsagn/<int:pk>', views.StandardFromAgn, name="standard-agn"), path('standardsagn/<int:pk>', views.StandardFromAgn, name="standard-agn"),
path('standardcopy/<int:pk>', views.CopyStandard, name="standard-copyagn"), path('standardcopy/<int:pk>', views.CopyStandard, name="standard-copyagn"),
path('loadaggroupm/', views.LoadAGGroupMembers, name="standard-loadaggroupmembers"), path('loadaggroupm/', views.LoadAGGroupMembers, name="standard-loadaggroupmembers"),
path('standard/update/', views.UpdateStandardBeforeUserDel, name="standard-update-before-user-del") path('standard/update/', views.UpdateStandardBeforeUserDel, name="standard-update-before-user-del"),
path('standard/download/<int:nc_id>', views.getFileFromStandard, name="standard-loadfile"),
path('standard/upload/', views.uploadFileFromStandard, name="standard-uploadfile")
] ]

View File

@ -1,8 +1,9 @@
from os import SEEK_CUR
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView, View from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView, View
from .models import Standards, StandardComments, StandardCommentRate from .models import NCFile, Standards, StandardComments, StandardCommentRate
from django.contrib import messages from django.contrib import messages
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse
from .forms import StandardAddStandard, StandardAddStandardEditor, StandardUpdateStandard, StandardUpdateStandardEditor from .forms import StandardAddStandard, StandardAddStandardEditor, StandardUpdateStandard, StandardUpdateStandardEditor
@ -77,6 +78,11 @@ class StandardsManagement(LoginRequiredMixin, ListView):
return context return context
@login_required
def getFileFromStandard(request, nc_id):
print(nc_id)
return JsonResponse({})
@login_required @login_required
def checkUserDirRights(request, startdir, userid): def checkUserDirRights(request, startdir, userid):
@ -109,6 +115,10 @@ def checkUserDirRights(request, startdir, userid):
canview = False canview = False
return canview return canview
# NEW FOR NC
import requests
from django.conf import settings
from digitaleagentur.utils import *
@login_required @login_required
def StandardAdd(request, id=False): def StandardAdd(request, id=False):
@ -203,11 +213,24 @@ def StandardAdd(request, id=False):
if(s.isdigit()): if(s.isdigit()):
new_standard.linked_standards.add(Standards.objects.get(pk=s)) new_standard.linked_standards.add(Standards.objects.get(pk=s))
# ADD FILES
#files = normalForm.cleaned_data['added_files'].split(",")
#for f in files:
# if(f.isdigit()):
# new_standard.addedfiles.add(DataFile.objects.get(pk=f))
# ADD FILES # ADD FILES
files = normalForm.cleaned_data['added_files'].split(",") files = normalForm.cleaned_data['added_files'].split(",")
for f in files: for f in files:
if(f.isdigit()): if(f.isdigit()):
new_standard.addedfiles.add(DataFile.objects.get(pk=f)) ncfile = NCFile.objects.filter(nc_id=f).first()
# Wenn die NC-File in Django nicht existiert, dann neu erstellen und hinzufügen. Trifft für Dateien zu, die zwar in den Dateien waren, aber noch nicht in der NC!
if(ncfile == None):
new_nc_file = NCFile(nc_id=f, agency=new_standard.agency)
new_nc_file.save()
new_standard.addedfiles_nc.add(new_nc_file)
else:
new_standard.addedfiles_nc.add(ncfile)
# ADD QUICKLINKS # ADD QUICKLINKS
quicklinks = normalForm.cleaned_data['added_quicklinks'].split(",") quicklinks = normalForm.cleaned_data['added_quicklinks'].split(",")
@ -240,19 +263,50 @@ def StandardAdd(request, id=False):
else: else:
normalForm = StandardAddStandard(instance=request.user) normalForm = StandardAddStandard(instance=request.user)
editorForm = StandardAddStandardEditor(instance=request.user) editorForm = StandardAddStandardEditor(instance=request.user)
possibleFilesByVisible = [] possibleFilesByVisible = []
# NC FILE
# Data for the new User
if(request.user.is_authenticated and getNCLoggedUserBySession(request.user.profile.nc_sid)):
allfiles = DataFile.objects.filter(agency=request.user.profile.agency) data_nc = {
"Depth" : 0
}
for f in allfiles: nc_login_headers = {'Authorization' : 'Bearer ' + request.user.profile.nc_sid}
actParent = DataDir.objects.get(pk=f.parent.pk) r = requests.request("PROPFIND", settings.NEXTCLOUD_URL + "remote.php/dav/files/" + request.user.username + "/Agenturdaten_1/", headers=nc_login_headers, data=data_nc)
if actParent.is_root: print(r.text)
possibleFilesByVisible.append(f)
else: #allfiles = DataFile.objects.filter(agency=request.user.profile.agency)
if(checkUserDirRights(request, actParent, request.user.pk)):
possibleFilesByVisible.append(f) #for f in allfiles:
# actParent = DataDir.objects.get(pk=f.parent.pk)
# if actParent.is_root:
# possibleFilesByVisible.append(f)
# else:
# if(checkUserDirRights(request, actParent, request.user.pk)):
# possibleFilesByVisible.append(f)
possibleFilesByVisible = []
filesearchdata = '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><oc:fileid/></d:prop></d:select><d:from><d:scope><d:href>/files/' + request.user.username + '/Agenturdaten/</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:gt><d:prop><oc:size/></d:prop><d:literal>1</d:literal></d:gt></d:where></d:basicsearch></d:searchrequest>'
#filesearchdata = '<?xml version="1.0" encoding="UTF-8"?><d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:prop><oc:fileid /></d:prop><d:depth>infinity</d:depth></d:propfind>'
r = requests.request("SEARCH", settings.NEXTCLOUD_URL + "remote.php/dav/", data=filesearchdata, headers={'Content-Type' : 'text/xml', 'Authorization' : "Bearer " + request.user.profile.nc_sid})
# IDs filtern aus XML-Response
try:
split_response = r.text.split("<oc:fileid>")
# Header des XML-Response entfernen
split_response.pop(0)
# IDs from the User
for ele in split_response:
new_id = ele.split("</oc:fileid>")[0]
possibleFilesByVisible.append(new_id)
except:
pass
context = { context = {
'normalForm' : normalForm, 'normalForm' : normalForm,
@ -261,7 +315,7 @@ def StandardAdd(request, id=False):
'agencygroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency), 'agencygroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency),
'usersofagency' : User.objects.filter(profile__agency=request.user.profile.agency), 'usersofagency' : User.objects.filter(profile__agency=request.user.profile.agency),
'files' : possibleFilesByVisible, 'files' : possibleFilesByVisible,
'parentid' : list(DataDir.objects.filter(agency=request.user.profile.agency, is_root=True))[0].pk, #'parentid' : list(DataDir.objects.filter(agency=request.user.profile.agency, is_root=True))[0].pk,
'standards' : Standards.objects.filter(agency=request.user.profile.agency, public=True), 'standards' : Standards.objects.filter(agency=request.user.profile.agency, public=True),
'quicklinks' : QuickLinks.objects.filter(agency=request.user.profile.agency), 'quicklinks' : QuickLinks.objects.filter(agency=request.user.profile.agency),
'contacts' : AGContacts.objects.filter(agency=request.user.profile.agency), 'contacts' : AGContacts.objects.filter(agency=request.user.profile.agency),
@ -271,14 +325,10 @@ def StandardAdd(request, id=False):
return render(request, 'standards/standards_add.html', context) return render(request, 'standards/standards_add.html', context)
# UPDATE A STANDARD # UPDATE A STANDARD
else: else:
standard = Standards.objects.get(pk=id, agency=request.user.profile.agency) standard = Standards.objects.get(pk=id, agency=request.user.profile.agency)
# SAVE UPDATED STANDARD # SAVE UPDATED STANDARD
if request.method == 'POST': if request.method == 'POST':
# CHECK IF USER HAS RIGHTS TO SEE THIS DIR # CHECK IF USER HAS RIGHTS TO SEE THIS DIR
groupsofstandard = standard groupsofstandard = standard
@ -320,7 +370,7 @@ def StandardAdd(request, id=False):
standard.visibleby.clear() standard.visibleby.clear()
standard.linked_standards.clear() standard.linked_standards.clear()
standard.addedfiles.clear() standard.addedfiles_nc.clear()
standard.addedquicklinks.clear() standard.addedquicklinks.clear()
standard.addedpasswords.clear() standard.addedpasswords.clear()
standard.addedcontacts.clear() standard.addedcontacts.clear()
@ -379,7 +429,14 @@ def StandardAdd(request, id=False):
files = normalForm.cleaned_data['added_files'].split(",") files = normalForm.cleaned_data['added_files'].split(",")
for f in files: for f in files:
if(f.isdigit()): if(f.isdigit()):
standard.addedfiles.add(DataFile.objects.get(pk=f)) ncfile = NCFile.objects.filter(nc_id=f).first()
# Wenn die NC-File in Django nicht existiert, dann neu erstellen und hinzufügen. Trifft für Dateien zu, die zwar in den Dateien waren, aber noch nicht in der NC!
if(ncfile == None):
new_nc_file = NCFile(nc_id=f, agency=standard.agency)
new_nc_file.save()
standard.addedfiles_nc.add(new_nc_file)
else:
standard.addedfiles_nc.add(ncfile)
# ADD QUICKLINKS # ADD QUICKLINKS
quicklinks = normalForm.cleaned_data['added_quicklinks'].split(",") quicklinks = normalForm.cleaned_data['added_quicklinks'].split(",")
@ -502,8 +559,6 @@ def StandardAdd(request, id=False):
return redirect('/standards') return redirect('/standards')
# SHOW EXISTING STANDARD # SHOW EXISTING STANDARD
else: else:
# CHECK IF USER HAS RIGHTS TO SEE THIS DIR # CHECK IF USER HAS RIGHTS TO SEE THIS DIR
groupsofstandard = standard groupsofstandard = standard
@ -518,33 +573,54 @@ def StandardAdd(request, id=False):
userisingroup = True userisingroup = True
if userisingroup: if userisingroup:
normalForm = StandardUpdateStandard(instance=standard) normalForm = StandardUpdateStandard(instance=standard)
editorForm = StandardUpdateStandardEditor(instance=standard) editorForm = StandardUpdateStandardEditor(instance=standard)
# TODO: Hier ändern, dass NC die Dateien anbietet!
# GET ALL DATAS FROM STANDARD # GET ALL DATAS FROM STANDARD
# FILES # FILES
possibleFilesByVisible = [] possibleFilesByVisible = []
allfiles = DataFile.objects.filter(agency=request.user.profile.agency) #allfiles = DataFile.objects.filter(agency=request.user.profile.agency)
# Get all files by view # Get all files by view
for f in allfiles: #for f in allfiles:
actParent = DataDir.objects.get(pk=f.parent.pk) # actParent = DataDir.objects.get(pk=f.parent.pk)
if actParent.is_root: # if actParent.is_root:
possibleFilesByVisible.append(f) # possibleFilesByVisible.append(f)
else: # else:
if(checkUserDirRights(request, actParent, request.user.pk)): # if(checkUserDirRights(request, actParent, request.user.pk)):
possibleFilesByVisible.append(f) # possibleFilesByVisible.append(f)
# Remove files which are in standard # Remove files which are in standard
for f in possibleFilesByVisible: #for f in possibleFilesByVisible:
if f in standard.addedfiles.all(): # if f in standard.addedfiles.all():
possibleFilesByVisible.remove(f) # possibleFilesByVisible.remove(f)
filesearchdata = '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><oc:fileid/></d:prop></d:select><d:from><d:scope><d:href>/files/' + request.user.username + '/Agenturdaten/</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:gt><d:prop><oc:size/></d:prop><d:literal>1</d:literal></d:gt></d:where></d:basicsearch></d:searchrequest>'
#filesearchdata = '<?xml version="1.0" encoding="UTF-8"?><d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:prop><oc:fileid /></d:prop><d:depth>infinity</d:depth></d:propfind>'
r = requests.request("SEARCH", settings.NEXTCLOUD_URL + "remote.php/dav/", data=filesearchdata, headers={'Content-Type' : 'text/xml', 'Authorization' : "Bearer " + request.user.profile.nc_sid})
# IDs filtern aus XML-Response
try:
split_response = r.text.split("<oc:fileid>")
# Header des XML-Response entfernen
split_response.pop(0)
# IDs from the User
for ele in split_response:
new_id = ele.split("</oc:fileid>")[0]
file_free = True
# Prüfen, dass diese IDs nicht im aktuellen Standard sind
for sf in standard.addedfiles_nc.all():
if str(sf.nc_id) == str(new_id):
file_free = False
if file_free == True:
possibleFilesByVisible.append(new_id)
except:
pass
# STANDARDS # STANDARDS
possible_standards = [] possible_standards = []
@ -652,7 +728,8 @@ def StandardAdd(request, id=False):
'possible_contacts' : possible_contacts, 'possible_contacts' : possible_contacts,
'agencynetworks' : agencynetworks, 'agencynetworks' : agencynetworks,
'agencygroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency), 'agencygroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency),
'parentid' : list(DataDir.objects.filter(agency=request.user.profile.agency, is_root=True))[0].pk, #'parentid' : list(DataDir.objects.filter(agency=request.user.profile.agency, is_root=True))[0].pk,
'parentid' : 0,
'active_link' : 'standards', 'active_link' : 'standards',
'update' : True, 'update' : True,
'aggroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency) 'aggroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency)
@ -748,6 +825,8 @@ def StandardChangePublic(request, pk):
standard.save() standard.save()
return redirect('standards') return redirect('standards')
# TODO: Upload der Standard-Dateien passt noch nicht, BUG!!!!
@login_required @login_required
def StandardSingle(request, pk): def StandardSingle(request, pk):
@ -811,13 +890,11 @@ def CopyStandard(request, pk):
new_standard.save() new_standard.save()
datadir_parentid = list(DataDir.objects.filter(is_defaultstandard=True, agency__pk=request.user.profile.agency.pk))[0] #datadir_parentid = list(DataDir.objects.filter(is_defaultstandard=True, agency__pk=request.user.profile.agency.pk))[0]
for f in sc.addedfiles_nc.all():
for f in sc.addedfiles.all(): tempdatafile = NCFile(agency=request.user.profile.agency, nc_id=f.nc_id)
tempdatafile = DataFile(file=f.file, name=f.name, owner=request.user, parent=datadir_parentid, agency=request.user.profile.agency)
tempdatafile.save() tempdatafile.save()
new_standard.addedfiles.add(tempdatafile) new_standard.addedfiles_nc.add(tempdatafile)
# TASK: Hier das kopieren der Dateien auf dem Server noch einfügen
# Sende Info, dass ein Standard übernommen wurde, an die Erstelleragentur # Sende Info, dass ein Standard übernommen wurde, an die Erstelleragentur
usersofagency = User.objects.filter(profile__agency=sc.agency) usersofagency = User.objects.filter(profile__agency=sc.agency)
@ -1115,3 +1192,50 @@ def UpdateStandardBeforeUserDel(request):
return JsonResponse({"success" : success}) return JsonResponse({"success" : success})
'''
UPLOADING A FILE
Replace the function in the App CLOUD
'''
@login_required
def uploadFileFromStandard(request):
success = True
if request.method == 'POST':
request.decoding = 'utf-8'
# VALIDATE FILE-TYPE
file_ext_arr = request.FILES['uploadedfile'].name.split(".")
file_ext = file_ext_arr[len(file_ext_arr)-1]
allowed_types = ["txt", "TXT", "png", "PNG", "jpeg", "JPEG", "jpg", "JPG", "PDF", "pdf", "csv", "CSV", "DOC", "doc", "DOCX", "docx", "ODT", "odt", "PPT", "ppt", "PPTX", "pptx", "XLS", "xls", "XLSX", "xlsx", "xlsm", "XLSM", "mov", "MOV", "SVG", "svg", "ZIP", "zip", "RAR", "rar", "EPS", "eps", "MP3", "mp3", "WAV", "wav", "avi", "AVI", "FLV", "flv", "MP4", "mp4", "PAGES", "pages", "NUMBERS", "numbers", "ics", "ICS"]
file_ok = False
for t in allowed_types:
if t == file_ext:
file_ok = True
if(file_ok):
final_file_path = settings.NEXTCLOUD_URL + "remote.php/dav/files/" + request.user.username + "/Agenturdaten/Standards Uploadbereich/" + request.FILES['uploadedfile'].name
r = requests.put(final_file_path, data=request.FILES['uploadedfile'], headers={'Content-Type' : 'text/xml;', 'Authorization' : "Bearer " + request.user.profile.nc_sid})
if(len(r.text) == 0):
try:
new_file_name = request.FILES['uploadedfile'].name
# Upload OK - get File-ID in NC
filesearchdata = '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><oc:fileid/></d:prop></d:select><d:from><d:scope><d:href>/files/' + request.user.username + '</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:like><d:prop><d:displayname/></d:prop><d:literal>' + new_file_name + '</d:literal></d:like></d:where></d:basicsearch></d:searchrequest>'
r = requests.request("SEARCH", settings.NEXTCLOUD_URL + "remote.php/dav/", data=filesearchdata, headers={'Content-Type' : 'text/xml;', 'Authorization' : "Bearer " + request.user.profile.nc_sid})
#print(r.text)
split_response = r.text.split("<oc:fileid>")
new_id = split_response[1].split("</oc:fileid>")[0]
tf = NCFile(agency=request.user.profile.agency, nc_id=new_id)
tf.save()
return JsonResponse({"success" : success, "data" : {'savedobj_id' : new_id, 'savedobj_name' : new_file_name}})
except:
success = True
return JsonResponse({"success" : success, "data" : {'savedobj_id' : None, 'savedobj_name' : 'Datei hochgeladen, enthält aber falsche Zeichen. Bitte Seite neu laden und anschließend über Suchfeld hinzufügen.'}})
return JsonResponse({"success" : success, "data" : "DONE!"})
return JsonResponse({"success" : success, "data" : "DONE!"})

View File

@ -0,0 +1,337 @@
<!-- TASK: Das Fenster soll nur einmal weggeklickt werden und dann nie wieder bis zum nächsten Login, wie bei der Erinnerung bzgl. der Vertretung -->
{% load counter_tag %}
{% load static %}
<link rel="canonical" href="https://app.digitale-agentur.com">
<script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
<link href="{%static 'users/vendor/fontawesome-free/css/all.min.css' %}" rel="stylesheet" type="text/css">
<link href="{%static 'users/css/google_font.css' %}" rel="stylesheet" type="text/css">
<link href="{%static 'users/css/google_swap.css' %}" rel="stylesheet" type="text/css">
<script src="{%static 'users/js/jquery_ui_min.js' %}" type="text/javascript"></script>
<link href="{% static 'users/css/cropper.min.css' %}" type="text/css" rel="stylesheet">
<!-- DATATABLES -->
<link href="{% static 'users/css/jquery_datatables.css' %}" type="text/css" rel="stylesheet">
<link href="{% static 'users/css/datatables_bs4.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 src="{%static 'users/js/bs4_summernote.js' %}" type="text/javascript"></script>
<link href="{% static 'users/css/bs4_summernote.css' %}" type="text/css" rel="stylesheet">
<script type="text/javascript" src="{% static 'summernote/lang/summernote-de-DE.min.js' %}"></script>
<!-- Bootstrap core JavaScript-->
<script type="text/javascript" src="{%static 'users/vendor/bootstrap/js/bootstrap.bundle.min.js' %}"></script>
<!-- Core plugin JavaScript-->
<script type="text/javascript" src="{%static 'users/vendor/jquery-easing/jquery.easing.min.js' %}"></script>
<!-- DATABLES JS -->
<script type="text/javascript" src="{%static 'users/js/jquery_dataTables.min.js' %}"></script>
<script type="text/javascript" src="https://cdn.datatables.net/plug-ins/1.10.22/dataRender/datetime.js"></script>
<script type="text/javascript" src="{%static 'users/js/bs4_dt.js' %}"></script>
<!-- Custom scripts for all pages-->
<script type="text/javascript" src="{%static 'users/js/sb-admin-2.js' %}"></script>
<link href="{% static 'users/css/custom.css' %}" type="text/css" rel="stylesheet">
<div class="mt-2 ml-2 text-center">
<div id="activeDay" style="display: none;">
<span id="worktime">
<h3>Heutiger Arbeitstag</h3>
<h2 id="realtimeclock">00:00</h2>
<hr>
</span>
<span id="breaktimeclock" style="display: none">
<h3>Aktuelle Pause</h3>
<h2 id="realtimeclock_break">00:00</h2>
<hr>
</span>
<span>
<button onclick="javascript:endBreak()" type="button" id="end_break" class="btn btn-success" style="display: none;"><i class="fas fa-play"></i></button>
<button onclick="javascript:startBreak()" type="button" id="start_break" class="btn btn-primary"><i class="fas fa-pause"></i></button>
<button onclick="javascript:endDay()" type="button" id="end_workday" class="btn btn-secondary">Arbeitstag beenden</button>
</span>
<hr>
</div>
<div>
Arbeitsbeginn: <span id="starttime">00:00:00</span><br />
Arbeitsende: <span id="endtime">00:00:00</span><br />
Pausenzeit: <span id="breaksum">00:00:00</span>
</div>
<div id="start_workday">
<hr>
<button onclick="javascript:startDay()" type="button" id="" class="btn btn-success">Arbeitstag starten</button>
</div>
<hr>
{% loadaccounttime request.user as actualaccounttime %}
Gleitzeitkonto:
{% if actualaccounttime.1 == 0 %}
<b><span style="color: green">+{{actualaccounttime.0}}&nbsp;Stunden</span></b>
{% else %}
<b><span style="color: red">-{{actualaccounttime.0}}&nbsp;Stunden</span></b>
{% endif %}
</div>
<script type="text/javascript">
console.log("COOKIES VON DJANGO");
console.log(document.cookie);
window.setInterval(function(){
if(starttime_view != false && isbreak == false){
realTimeClock();
}
else if(isbreak == true){
realTimeBreakClock();
}
}, 1000);
function convertMS(ms) {
var d, h, m, s;
s = Math.floor(ms / 1000);
m = Math.floor(s / 60);
s = s % 60;
h = Math.floor(m / 60);
m = m % 60;
d = Math.floor(h / 24);
h = h % 24;
h += d * 24;
if(s < 10){
s = "0" + s;
}
if(m < 10){
m = "0" + m;
}
if(h < 10){
h = "0" + h;
}
return h + ':' + m + ':' + s;
}
{% getactualworkingday request.user as starttime %}
//No day info
{% if starttime == 0 %}
var starttime_view = false;
var startbreaktime_view = false;
var isbreak = false;
var breaktime = 0;
{% getformattetstarttime_last_start request.user as formattetstarttime_last_start %}
{% getformattetstarttime_last_end request.user as formattetstarttime_last_end %}
$("#starttime").html("{{formattetstarttime_last_start}}");
$("#endtime").html("{{formattetstarttime_last_end}}");
$("#breaksum").html("00:00:00");
is_closed = localStorage.getItem("is_closed");
if (is_closed == null) {
$("#timemanagement_clock").toggle();
}
//day info
{% else %}
{% getdailybreaktime request.user as actbreaktime %}
$("#breaksum").html(convertMS({{actbreaktime}}));
var breaktime = {{actbreaktime}};
{% getformatedstarttime request.user as formattetstarttime %}
{% getactualbreak request.user as breakcounter %}
//BREAK CHECKEN!
{% if breakcounter %}
{% getactualbreakcounter request.user as breaktimer %}
var isbreak = true;
var startbreaktime_view = {{breaktimer}};
var starttime_view = Date.parse("{{starttime}}");
$("#start_workday").hide();
$("#activeDay").show();
$("#worktime").hide();
$("#breaktimeclock").show();
$("#end_break").show();
$("#start_break").hide();
$("#starttime").html("{{formattetstarttime}}");
{% else %}
var isbreak = false;
var startbreaktime_view = 0;
var starttime_view = parseDate("{{starttime}}");
$("#start_workday").hide();
$("#activeDay").show();
$("#starttime").html("{{formattetstarttime}}");
{% endif %}
{% endif %}
function parseDate(input) {
input_all = input.split(" ");
day = input_all[0].split(".")[0]
var today = new Date();
newdate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), parseInt(input_all[3].split(":")[0]), parseInt(input_all[3].split(":")[1]));
return newdate;
}
start = false;
function realTimeClock()
{
if(start != false){
startDate = Date.parse(start);
starttime_view = startDate;
start = false;
realTimeClock();
}
else{
now = new Date();
viewtime = now - starttime_view - breaktime;
$("#realtimeclock").html(convertMS(viewtime));
}
}
function realTimeBreakClock(){
breaktime = startbreaktime_view + 1000;
startbreaktime_view = startbreaktime_view + 1000;
$("#realtimeclock_break").html(convertMS(startbreaktime_view));
}
function startBreak(){
isbreak = true;
$("#timemanagement_clock").click(function(e){
e.stopPropagation();
})
$("#breaktimeclock").show();
$("#realtimeclock").hide();
$("#end_break").show();
$("#start_break").hide();
$("#worktime").hide();
$.ajax(
{
type: "GET",
url: "{% url 'tm-ajax' %}",
data:{
action : "start_break",
},
success: function( data )
{
startbreaktime_view = -1000;
realTimeBreakClock();
}
});
}
function endBreak()
{
isbreak = false;
$("#timemanagement_clock").click(function(e){
e.stopPropagation();
})
$("#breaktimeclock").hide();
$("#realtimeclock").show();
$("#end_break").hide();
$("#start_break").show();
$("#worktime").show();
$.ajax(
{
type: "GET",
url: "{% url 'tm-ajax' %}",
data:{
action : "end_break",
},
success: function( data )
{
breaktime = data["actualbreaktime"];
startbreaktime_view = data["actualbreaktime"];
starttime_view = Date.parse(data["wdtime"]);
$("#breaksum").html(convertMS(data["actualbreaktime"]));
}
});
}
function startDay()
{
$("#timemanagement_clock").click(function(e){
e.stopPropagation();
})
$("#start_workday").hide();
$("#activeDay").show();
$("#breaktimeclock").hide();
$.ajax(
{
type: "GET",
url: "{% url 'tm-ajax' %}",
data:{
action : "start_day",
},
success: function( data )
{
if(data["success"]){
$("#starttime").html(data["wd_starttime"])
$("#endtime").html("00:00:00");
$("#breaksum").html("00:00:00");
}
start = data["wd_starttime_complete"];
realTimeClock();
//location.href = location.href;
}
});
}
function endDay()
{
$("#timemanagement_clock").click(function(e){
e.stopPropagation();
})
$.ajax(
{
type: "GET",
url: "{% url 'tm-ajax' %}",
data:{
action : "end_day",
},
success: function( data )
{
if(data["success"]){
$("#breaktimeclock").hide();
$("#realtimeclock").show();
$("#end_break").hide();
$("#start_break").show();
$("#worktime").show();
$("#endtime").html(data["wd_endtime"]);
$("#activeDay").hide();
$("#start_workday").show();
$("#breaksum").html(convertMS(data["actualbreaktime"]));
starttime_view = false;
isbreak = false;
start = false;
breaktime = 0;
}
//start = data["wd_starttime_complete"]
realTimeClock();
}
});
}
</script>

View File

@ -315,7 +315,6 @@ document.getElementById("choosenyear").addEventListener("change", function(){
choosenyear = $('#choosenyear :selected').val(); choosenyear = $('#choosenyear :selected').val();
}) })
var selectedElements = []; var selectedElements = [];
var active_row = ""; var active_row = "";
var sameday = false; var sameday = false;
@ -689,7 +688,7 @@ $( function() {
/* /*
Functions for Kalendar Functions for Kalendar
*/ */
/*
function prevMonth(){ function prevMonth(){
$.ajax( $.ajax(
{ {
@ -751,7 +750,7 @@ function showNewAbsenceByUser(){
function goFastToMonth(month){ function goFastToMonth(month){
location.href = "/tm/abs/" + month +"/" + choosenyear location.href = "/tm/abs/" + month +"/" + choosenyear
} }
*/
</script> </script>

View File

@ -572,8 +572,7 @@ $('#absencetabs a').on('click', function (e) {
} }
localStorage.setItem('activeTabAbsence', lastview_name); localStorage.setItem('activeTabAbsence', lastview_name);
}); });
/*
function prevMonth(){ function prevMonth(){
$.ajax( $.ajax(
{ {
@ -589,6 +588,7 @@ $('#absencetabs a').on('click', function (e) {
request.setRequestHeader("X-Requested-With", "XMLHttpRequest"); request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
}, },
success : function(data){ success : function(data){
console.log(data);
$("#overlay").fadeOut(); $("#overlay").fadeOut();
$("#rendered_table").html(data); $("#rendered_table").html(data);
} }
@ -615,7 +615,7 @@ function nextMonth(){
} }
}); });
} }
*/
/* /*
Functions for Kalender Functions for Kalender

View File

@ -196,8 +196,10 @@
date_start = new Date(new_start[2], (parseInt(new_start[1])-1), new_start[0]); date_start = new Date(new_start[2], (parseInt(new_start[1])-1), new_start[0]);
date_end = new Date(new_end[2], (parseInt(new_end[1])-1), new_end[0]); date_end = new Date(new_end[2], (parseInt(new_end[1])-1), new_end[0]);
$("#id_start").data("DateTimePicker").date(date_start); if(date_start != undefined && date_end != undefined){
$("#id_end").data("DateTimePicker").date(date_end); $("#id_start").data("DateTimePicker").date(date_start);
$("#id_end").data("DateTimePicker").date(date_end);
}
if(+new_start == +new_end){ if(+new_start == +new_end){
sameday = true; sameday = true;

View File

@ -1,6 +1,6 @@
from django.urls import path from django.urls import path
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from .views import TimeManagement, TimeAjax, AbsenceManagmenet, AbsenceUpdate, TimeUpdate, AddBreak, TimeAdd, TimeManagementTeamSingle from .views import TimeManagement, TimeAjax, AbsenceManagmenet, AbsenceUpdate, TimeUpdate, AddBreak, TimeAdd, TimeManagementTeamSingle, GetRealtimeDropDown
''' '''
Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben! Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben!
''' '''
@ -20,5 +20,5 @@ urlpatterns = [
path('abs/<int:activemonth>/<int:activeyear>', AbsenceManagmenet, name='tma-management'), path('abs/<int:activemonth>/<int:activeyear>', AbsenceManagmenet, name='tma-management'),
path('ajax/', TimeAjax, name='tm-ajax'), path('ajax/', TimeAjax, name='tm-ajax'),
path('abs/update/<int:pk>/', AbsenceUpdate, name='tma-update'), path('abs/update/<int:pk>/', AbsenceUpdate, name='tma-update'),
path('abs/getncdd/<slug:uid>', GetRealtimeDropDown, name='tma-getrealtimedd'),
] ]

View File

@ -23,6 +23,14 @@ from django.template.loader import render_to_string
from django.core.mail import send_mail from django.core.mail import send_mail
from digitaleagentur.utils import * from digitaleagentur.utils import *
# LÖSCHEN?
from django.contrib.auth import login
def GetRealtimeDropDown(request, uid):
user = User.objects.get(username=uid)
if(getNCLoggedUserBySession(user.profile.nc_sid) == uid):
login(request, user)
return render(request, 'timemanagement/realtime_dropdown_nc_iframe.html', {})
# Load freedays # Load freedays
def loadingFreeDays(plz): def loadingFreeDays(plz):
# Getting land # Getting land
@ -414,7 +422,7 @@ def TimeManagement(request, activemonth=False, activeyear=False):
def TimeUpdate(request, pk, team=0): def TimeUpdate(request, pk, team=0):
workday = Workday.objects.get(pk=pk) workday = Workday.objects.get(pk=pk)
user = workday.user user = workday.user
if(request.user.profile.agency == workday.agency): if(request.user.profile.agency == workday.agency and request.user.has_perm('users.usermanager')):
if(request.method == "POST"): if(request.method == "POST"):
if(team == 0): if(team == 0):
form = UpdateWorkdayForm(request.POST, instance=request.user) form = UpdateWorkdayForm(request.POST, instance=request.user)
@ -786,6 +794,9 @@ def TimeAjax(request):
nextmonth = "" nextmonth = ""
activemonth = int(request.GET["activemonth"]) activemonth = int(request.GET["activemonth"])
activeyear = int(request.GET["activeyear"]) activeyear = int(request.GET["activeyear"])
print(activemonth)
print(activeyear)
#MONTH #MONTH
if(not activemonth or activemonth > 12 or activemonth < 1): if(not activemonth or activemonth > 12 or activemonth < 1):

View File

@ -1,10 +1,10 @@
from django.contrib import admin from django.contrib import admin
from .models import Profile, Agency, AgencyGroup, AgencyJob, AgencyNetwork, AgencyNetworkPreperation, UserTime, UserYearAbsenceInfo, UserNotifications, AgencyBills, RegNotfallhilfe from .models import Profile, Agency, AgencyGroup, AgencyJob, AgencyNetwork, AgencyNetworkPreperation, UserTime, UserYearAbsenceInfo, UserNotifications, AgencyBills, RegNotfallhilfe
from .priomodel import Prio from .priomodel import Prio
from standards.models import StandardCommentRate, StandardComments from standards.models import StandardCommentRate, StandardComments, NCFile
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from message.models import Message from message.models import Message
from cloud.models import DataFile from cloud.models import DataFile, DataDir
from organizer.models import AGContacts from organizer.models import AGContacts
from timemanagement.models import Workday, Breaks, AbsenceReason, FreeDays, Absence from timemanagement.models import Workday, Breaks, AbsenceReason, FreeDays, Absence
from chat.models import ChatRoom from chat.models import ChatRoom
@ -26,6 +26,7 @@ admin.site.register(AgencyNetwork)
admin.site.register(AGContacts) admin.site.register(AGContacts)
admin.site.register(AgencyNetworkPreperation) admin.site.register(AgencyNetworkPreperation)
admin.site.register(DataFile) admin.site.register(DataFile)
admin.site.register(DataDir)
admin.site.register(UserTime) admin.site.register(UserTime)
admin.site.register(Workday) admin.site.register(Workday)
admin.site.register(Breaks) admin.site.register(Breaks)
@ -43,4 +44,5 @@ admin.site.register(RDContact)
admin.site.register(RecoverDirSetting) admin.site.register(RecoverDirSetting)
admin.site.register(MainStatistic) admin.site.register(MainStatistic)
admin.site.register(RegNotfallhilfe) admin.site.register(RegNotfallhilfe)
admin.site.register(AGBLog) admin.site.register(AGBLog)
admin.site.register(NCFile)

View File

@ -1,3 +1,4 @@
import json import json
from channels.generic.websocket import WebsocketConsumer from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
@ -9,7 +10,7 @@ from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
class UsersConsumer(WebsocketConsumer): class UsersConsumer(WebsocketConsumer):
appconnect = False appconnect = False
''' '''

View File

Binary file not shown.

Binary file not shown.

116
users/middleware/oauth.py Normal file
View File

@ -0,0 +1,116 @@
import re
from requests.api import request
from authlib.integrations.base_client import OAuthError
from authlib.integrations.django_client import OAuth
from authlib.oauth2.rfc6749 import OAuth2Token
from django.shortcuts import redirect
from django.utils.deprecation import MiddlewareMixin
from users.models import Agency, Profile
from django.contrib.auth.models import User
from django.contrib.auth import login, logout
from digitaleagentur import settings
import requests, json
class OAuthMiddleware(MiddlewareMixin):
def __init__(self, get_response=None):
super().__init__(get_response)
self.oauth = OAuth()
def process_request(self, request):
if settings.OAUTH_URL_WHITELISTS is not None:
for w in settings.OAUTH_URL_WHITELISTS:
if request.path.startswith(w):
return self.get_response(request)
def update_token(token, refresh_token, access_token):
request.session['token'] = token
return None
# Check, if logged user is in Database - if not, create and save by SUB
def checkUserInDatabase(userdata):
# Get sub of current user
sub = userdata
activeuser = None
# Check in Database, if user exist - if not, create new user
if not User.objects.filter(username = sub).exists():
pr = Profile(user=None, agency=Agency.objects.get(pk=1))
pr.save()
activeuser = User.objects.create(username=sub, profile=pr)
pr.user = activeuser
pr.save()
else:
activeuser = User.objects.get(username=sub)
if activeuser is not None:
headers = {
'Authorization': 'Bearer ' + request.session.get('token').get('access_token'),
'Content-Type': 'application/json',
'Accept': 'application/json',
}
data = {}
#response = requests.get("http://localhost:8080/apps/agency/getcurrentuser", data=data, headers=headers)
#print(response.text)
login(request, activeuser)
sso_client = self.oauth.register(
settings.OAUTH_CLIENT_NAME, overwrite=True, **settings.OAUTH_CLIENT, update_token=update_token
)
if request.path.startswith('/oauth/callback'):
self.clear_session(request)
request.session['token'] = sso_client.authorize_access_token(request)
if self.get_current_user(sso_client, request) is not None:
redirect_uri = request.session.pop('redirect_uri', None)
if redirect_uri is not None:
return redirect(redirect_uri)
return redirect('users-dashboard')
if request.session.get('token', None) is not None:
#current_user = self.get_current_user(sso_client, request)
current_user = request.session.get('token').get('user_id')
if current_user is not None:
checkUserInDatabase(current_user)
return self.get_response(request)
# remember redirect URI for redirecting to the original URL.
request.session['redirect_uri'] = request.path
return sso_client.authorize_redirect(request, settings.OAUTH_CLIENT['redirect_uri'])
# fetch current login user info
# 1. check if it's in cache
# 2. fetch from remote API when it's not in cache
@staticmethod
def get_current_user(sso_client, request):
token = request.session.get('token', None)
if token is None or 'access_token' not in token:
return None
if not OAuth2Token.from_dict(token).is_expired() and 'user' in request.session:
return request.session['user']
try:
res = sso_client.get(settings.OAUTH_CLIENT['userinfo_endpoint'], token=OAuth2Token(token))
if res.ok:
#request.session['user'] = res.json()
#request.session['user'] = res
return True
#return res.json()
else:
print(res)
except OAuthError as e:
print(e)
return None
@staticmethod
def clear_session(request):
try:
del request.session['user']
del request.session['token']
except KeyError:
pass
def __del__(self):
print('destroyed')

View File

@ -139,7 +139,8 @@ class Agency(models.Model):
vve = models.CharField(default="", max_length=200, blank=True) vve = models.CharField(default="", max_length=200, blank=True)
# NC IMPORT
importid = models.CharField(default="", max_length=200, blank=True)
# RECOVERDIR # RECOVERDIR
module_recoverdir = models.BooleanField(default=False) module_recoverdir = models.BooleanField(default=False)
@ -214,6 +215,8 @@ class Profile(models.Model):
phonemobile = models.CharField(max_length=60, blank=True) phonemobile = models.CharField(max_length=60, blank=True)
phone_public = models.BooleanField(default=False) phone_public = models.BooleanField(default=False)
nc_sid = models.CharField(max_length=200, blank=True)
# Wenn die Funktion gelöscht wird, wird die FUNC auf NULL gesetzt # Wenn die Funktion gelöscht wird, wird die FUNC auf NULL gesetzt
func = models.ForeignKey("AgencyJob", blank=True, null=True, default=None, on_delete=models.SET_NULL) func = models.ForeignKey("AgencyJob", blank=True, null=True, default=None, on_delete=models.SET_NULL)
# Wenn dieses Profil gelöscht wird, wird NICHT die Agency geslöscht # Wenn dieses Profil gelöscht wird, wird NICHT die Agency geslöscht
@ -479,6 +482,7 @@ class AgencyGroup(models.Model):
group = models.OneToOneField(Group, on_delete=models.CASCADE) group = models.OneToOneField(Group, on_delete=models.CASCADE)
agency = models.ForeignKey(Agency, on_delete=models.CASCADE) agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
agencygroupname = models.CharField(max_length=60, blank=True) agencygroupname = models.CharField(max_length=60, blank=True)
nc_name = models.CharField(max_length=200, blank=True)
savefordel = models.BooleanField(default=False) savefordel = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False) is_admin = models.BooleanField(default=False)
@ -532,11 +536,11 @@ class UserFullName(User):
return f'{self.first_name + " " + self.last_name}' return f'{self.first_name + " " + self.last_name}'
# Hier Audit-Logeinträge einbauen für die versch. Models # Hier Audit-Logeinträge einbauen für die versch. Models
from django.utils.six import python_2_unicode_compatible #from django.utils.six import python_2_unicode_compatible
from auditlog.registry import auditlog #from auditlog.registry import auditlog
auditlog.register(User) #auditlog.register(User)
auditlog.register(Agency) #auditlog.register(Agency)

View File

@ -1,3 +1,4 @@
'''
from django.urls import re_path from django.urls import re_path
from . import mainwebsocket from . import mainwebsocket
@ -7,4 +8,5 @@ websocket_urlpatterns = [
re_path(r'ws/groupchat/(?P<chatid>\w+)/$', mainwebsocket.GroupChat, name="ws-groupchat"), re_path(r'ws/groupchat/(?P<chatid>\w+)/$', mainwebsocket.GroupChat, name="ws-groupchat"),
re_path(r'ws/appchat/(?P<creator>\w+)/(?P<single>\w+)/(?P<token>\w+)/$', mainwebsocket.UsersChat, name="ws-appchat"), re_path(r'ws/appchat/(?P<creator>\w+)/(?P<single>\w+)/(?P<token>\w+)/$', mainwebsocket.UsersChat, name="ws-appchat"),
re_path(r'ws/', mainwebsocket.UsersConsumer, name="ws-default"), re_path(r'ws/', mainwebsocket.UsersConsumer, name="ws-default"),
] ]
'''

View File

@ -27,14 +27,24 @@ from asgiref.sync import async_to_sync
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from datetime import timedelta from datetime import timedelta
from django.core.signals import request_started from django.core.signals import request_started
from channels_presence.models import Room #from channels_presence.models import Room
from channels_presence.models import Presence #from channels_presence.models import Presence
from channels_presence.signals import presence_changed #from channels_presence.signals import presence_changed
from organizer.models import * from organizer.models import *
from chat.models import ChatMessage from chat.models import ChatMessage
from digitaleagentur.utils import * from digitaleagentur.utils import *
from django.core.signals import request_finished
from django.dispatch import receiver
@receiver(request_finished)
def loginController(sender, **kwargs):
pass
def loadingFreeDays(plz, year): def loadingFreeDays(plz, year):
# Getting land # Getting land
file_path = os.path.join(settings.STATIC_ROOT, 'users/extra/plz_short.csv') file_path = os.path.join(settings.STATIC_ROOT, 'users/extra/plz_short.csv')
@ -177,6 +187,7 @@ def save_profile(sender, instance, **kwargs):
# SIGNALS FOR GROUPS # SIGNALS FOR GROUPS
# Signal für das Ändern von Gruppenrechten # Signal für das Ändern von Gruppenrechten
'''
@receiver(signal=m2m_changed, sender=Group.permissions.through) @receiver(signal=m2m_changed, sender=Group.permissions.through)
def adjust_group_notifications_permission(instance, action, reverse, model, pk_set, using, *args, **kwargs): def adjust_group_notifications_permission(instance, action, reverse, model, pk_set, using, *args, **kwargs):
group_touched = AgencyGroup.objects.get(group=instance) group_touched = AgencyGroup.objects.get(group=instance)
@ -191,8 +202,8 @@ def adjust_group_notifications_permission(instance, action, reverse, model, pk_s
newnotification = UserNotification(touser=user, notificationtext="Die Gruppe " + group_touched.agencygroupname + " hat neue Rechte erhalten.", notificationtype="groupchanges") newnotification = UserNotification(touser=user, notificationtext="Die Gruppe " + group_touched.agencygroupname + " hat neue Rechte erhalten.", notificationtype="groupchanges")
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Die Gruppe " + group_touched.agencygroupname + " hat neue Rechte erhalten."}) #async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Die Gruppe " + group_touched.agencygroupname + " hat neue Rechte erhalten."})
# Rechte wurden entfernt # Rechte wurden entfernt
elif(action == "post_remove"): elif(action == "post_remove"):
@ -205,12 +216,14 @@ def adjust_group_notifications_permission(instance, action, reverse, model, pk_s
newnotification = UserNotification(touser=user, notificationtext="Der Gruppe " + group_touched.agencygroupname + " wurden Rechte entzogen.", notificationtype="groupchanges") newnotification = UserNotification(touser=user, notificationtext="Der Gruppe " + group_touched.agencygroupname + " wurden Rechte entzogen.", notificationtype="groupchanges")
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Der Gruppe " + group_touched.agencygroupname + " wurden Rechte entzogen."}) #async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Der Gruppe " + group_touched.agencygroupname + " wurden Rechte entzogen."})
'''
# Signal, wenn ein Nutzer aus der Gruppe entfernt/hinzugefügt wird # Signal, wenn ein Nutzer aus der Gruppe entfernt/hinzugefügt wird
'''
@receiver(signal=m2m_changed, sender=User.groups.through) @receiver(signal=m2m_changed, sender=User.groups.through)
def adjust_group_notifications(instance, action, reverse, model, pk_set, using, *args, **kwargs): def adjust_group_notifications(instance, action, reverse, model, pk_set, using, *args, **kwargs):
if isinstance(instance, Group): if isinstance(instance, Group):
group_touched = AgencyGroup.objects.get(group=instance) group_touched = AgencyGroup.objects.get(group=instance)
userid = list(pk_set)[0] userid = list(pk_set)[0]
@ -221,8 +234,8 @@ def adjust_group_notifications(instance, action, reverse, model, pk_set, using,
newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden aus der Gruppe " + group_touched.agencygroupname + " entfernt.", notificationtype="groupchanges") newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden aus der Gruppe " + group_touched.agencygroupname + " entfernt.", notificationtype="groupchanges")
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Sie wurden aus der Gruppe " + group_touched.agencygroupname + " entfernt."}) #async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Sie wurden aus der Gruppe " + group_touched.agencygroupname + " entfernt."})
# A USER WAS ADDED TO A GROUP # A USER WAS ADDED TO A GROUP
elif(action == 'post_add'): elif(action == 'post_add'):
@ -230,8 +243,8 @@ def adjust_group_notifications(instance, action, reverse, model, pk_set, using,
newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden zur Gruppe " + group_touched.agencygroupname + " hinzugefügt.", notificationtype="groupchanges") newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden zur Gruppe " + group_touched.agencygroupname + " hinzugefügt.", notificationtype="groupchanges")
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Sie wurden zur Gruppe " + group_touched.agencygroupname + " hinzugefügt."}) #async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Gruppenaktivität | Sie wurden zur Gruppe " + group_touched.agencygroupname + " hinzugefügt."})
# E-MAILNOTIFICATIONS FOR GROUPCHANGES # E-MAILNOTIFICATIONS FOR GROUPCHANGES
if(user_touched.usernotifications.group_activity_mail): if(user_touched.usernotifications.group_activity_mail):
@ -265,7 +278,7 @@ def adjust_group_notifications(instance, action, reverse, model, pk_set, using,
html_message=msg_html, html_message=msg_html,
fail_silently=True fail_silently=True
) )
'''
# SIGNALS FOR STANDARDS # SIGNALS FOR STANDARDS
# DELETE # DELETE
@ -274,6 +287,7 @@ def delete_standard(sender, instance, **kwargs):
newNotifiyPush(2, instance, " es wurde ein neuer Agenturstandard gelöscht: ", "Agenturstandard gelöscht: ", "Standards | ", "", "") newNotifiyPush(2, instance, " es wurde ein neuer Agenturstandard gelöscht: ", "Agenturstandard gelöscht: ", "Standards | ", "", "")
# SAVE AND UPDATE # SAVE AND UPDATE
'''
@receiver(post_save, sender=Standards) @receiver(post_save, sender=Standards)
def save_standard(sender, instance, **kwargs): def save_standard(sender, instance, **kwargs):
targeturl = settings.BASE_URL + "standards/standard/" + str(instance.pk) + "/single" targeturl = settings.BASE_URL + "standards/standard/" + str(instance.pk) + "/single"
@ -290,8 +304,8 @@ def save_standard(sender, instance, **kwargs):
newnotification = UserNotification(touser=user, notificationtext="Neuer unveröffentlichter Agenturstandard: " + instance.name, notificationtype="newstandard", elementid=instance.pk) newnotification = UserNotification(touser=user, notificationtext="Neuer unveröffentlichter Agenturstandard: " + instance.name, notificationtype="newstandard", elementid=instance.pk)
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Standards | Neuer unveröffentlichter Agenturstandard: " + instance.name}) #async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Standards | Neuer unveröffentlichter Agenturstandard: " + instance.name})
if(user.has_perm("users.standardmanager") and user.usernotifications.standard_created_unpub_mail): if(user.has_perm("users.standardmanager") and user.usernotifications.standard_created_unpub_mail):
notificationtext = " es wurde ein neuer unveröffentlichter Agenturstandard erstellt: " + instance.name notificationtext = " es wurde ein neuer unveröffentlichter Agenturstandard erstellt: " + instance.name
@ -299,9 +313,10 @@ def save_standard(sender, instance, **kwargs):
# Standard wurde aktualisiert # Standard wurde aktualisiert
else: else:
newNotifiyPush(1, instance, " es wurde ein neuer Agenturstandard aktualisiert: ", "Agenturstandard aktualisiert: ", "Standards | ", "newstandard", targeturl) newNotifiyPush(1, instance, " es wurde ein neuer Agenturstandard aktualisiert: ", "Agenturstandard aktualisiert: ", "Standards | ", "newstandard", targeturl)
'''
# SIGNAL FOR NEWS # SIGNAL FOR NEWS
'''
@receiver(post_save, sender=News) @receiver(post_save, sender=News)
def save_news(sender, instance, **kwargs): def save_news(sender, instance, **kwargs):
if(kwargs["created"]): if(kwargs["created"]):
@ -313,9 +328,10 @@ def save_news(sender, instance, **kwargs):
else: else:
instance.agnotify = False instance.agnotify = False
instance.save() instance.save()
'''
# SIGNALS FOR TASK # SIGNALS FOR TASK
'''
@receiver(signal=m2m_changed, sender=Tasks.usersfield.through) @receiver(signal=m2m_changed, sender=Tasks.usersfield.through)
def adjust_group_notifications_task(instance, action, reverse, model, pk_set, using, *args, **kwargs): def adjust_group_notifications_task(instance, action, reverse, model, pk_set, using, *args, **kwargs):
@ -329,16 +345,16 @@ def adjust_group_notifications_task(instance, action, reverse, model, pk_set, us
newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden von der Tätigkeit " + taskname + " entfernt.", notificationtype="taskchange") newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden von der Tätigkeit " + taskname + " entfernt.", notificationtype="taskchange")
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Tätigkeitsbereich | Sie wurden von der Tätigkeitn " + instance.name + " entfernt."}) #async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Tätigkeitsbereich | Sie wurden von der Tätigkeitn " + instance.name + " entfernt."})
# A USER WAS ADDED TO A GROUP # A USER WAS ADDED TO A GROUP
elif(action == 'post_add'): elif(action == 'post_add'):
newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden der Tätigkeit " + taskname + " zugeordnet.", notificationtype="taskchange") newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden der Tätigkeit " + taskname + " zugeordnet.", notificationtype="taskchange")
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Tätigkeitsbereich | Sie wurden der Tätigkeitn " + instance.name + " zugeordnet."}) #async_to_sync(channel_layer.group_send)("user_" + str(user_touched.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Tätigkeitsbereich | Sie wurden der Tätigkeitn " + instance.name + " zugeordnet."})
# E-MAILNOTIFICATIONS FOR GROUPCHANGES # E-MAILNOTIFICATIONS FOR GROUPCHANGES
if(user_touched.usernotifications.task_activity_mail): if(user_touched.usernotifications.task_activity_mail):
@ -351,6 +367,7 @@ def adjust_group_notifications_task(instance, action, reverse, model, pk_set, us
elif(action == 'post_add'): elif(action == 'post_add'):
notificationtext = "Sie wurden der Tätigkeit " + taskname + " zugeordnet." notificationtext = "Sie wurden der Tätigkeit " + taskname + " zugeordnet."
sendMailNoti(notificationtext, user_touched) sendMailNoti(notificationtext, user_touched)
'''
@ -374,10 +391,9 @@ def adjust_group_notifications_task(instance, action, reverse, model, pk_set, us
''' '''
def newNotifiyPush(mode, instance, mailtext, notifytext, pushtext, notifytype, targeturl=""): def newNotifiyPush(mode, instance, mailtext, notifytext, pushtext, notifytype, targeturl=""):
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk) usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
'''
# CREATED # CREATED
for user in usersofagency: for user in usersofagency:
# LOAD USERNOTIFICATIONS # LOAD USERNOTIFICATIONS
created_mail = False created_mail = False
created_push = False created_push = False
@ -439,8 +455,8 @@ def newNotifiyPush(mode, instance, mailtext, notifytext, pushtext, notifytype, t
newnotification = UserNotification(touser=user, notificationtext=notifytext + instance.name, notificationtype="", elementid=instance.pk) newnotification = UserNotification(touser=user, notificationtext=notifytext + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__"+ pushtext + notifytext + instance.name}) #async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__"+ pushtext + notifytext + instance.name})
# UPDATED # UPDATED
elif(mode == 1): elif(mode == 1):
if(update_mail): if(update_mail):
@ -451,8 +467,8 @@ def newNotifiyPush(mode, instance, mailtext, notifytext, pushtext, notifytype, t
newnotification = UserNotification(touser=user, notificationtext=notifytext + instance.name, notificationtype="", elementid=instance.pk) newnotification = UserNotification(touser=user, notificationtext=notifytext + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__" + pushtext + notifytext + instance.name}) #async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__" + pushtext + notifytext + instance.name})
#DELETE #DELETE
elif(mode == 2): elif(mode == 2):
if(delete_mail): if(delete_mail):
@ -464,9 +480,9 @@ def newNotifiyPush(mode, instance, mailtext, notifytext, pushtext, notifytype, t
newnotification = UserNotification(touser=user, notificationtext=notifytext + instance.name, notificationtype="", elementid=instance.pk) newnotification = UserNotification(touser=user, notificationtext=notifytext + instance.name, notificationtype="", elementid=instance.pk)
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__" + pushtext + notifytext + instance.name}) #async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__" + pushtext + notifytext + instance.name})
'''
# DIRS # DIRS
@receiver(post_save, sender=DataDir) @receiver(post_save, sender=DataDir)
def save_dir(sender, instance, **kwargs): def save_dir(sender, instance, **kwargs):
@ -544,7 +560,7 @@ def save_agjoin_prep(sender, instance, **kwargs):
def receiver_function(sender, **kwargs): def receiver_function(sender, **kwargs):
# DELETES ALL PRESENCE-OBJECTS LOWER THAN 15 MINUTES # DELETES ALL PRESENCE-OBJECTS LOWER THAN 15 MINUTES
now_minus = datetime.datetime.now() - datetime.timedelta(minutes=2) now_minus = datetime.datetime.now() - datetime.timedelta(minutes=2)
Presence.objects.filter(last_seen__lt=now_minus).delete() #Presence.objects.filter(last_seen__lt=now_minus).delete()
users = User.objects.all() users = User.objects.all()
@ -559,17 +575,19 @@ def receiver_function(sender, **kwargs):
# PRESENCE CHANGED # PRESENCE CHANGED
'''
@receiver(signal=presence_changed) @receiver(signal=presence_changed)
def update_presence_live(sender, **kwargs): def update_presence_live(sender, **kwargs):
channel_layer = channels.layers.get_channel_layer() channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(str(kwargs["room"]), {'type' : 'update_presence_live'}) async_to_sync(channel_layer.group_send)(str(kwargs["room"]), {'type' : 'update_presence_live'})
'''
''' '''
ABWESENHEIT BERECHNUNG UND SPEICHERUNG DER NEUEN URLAUBSTAGE - VERWEIS AUF timemenagement.views ABWESENHEIT BERECHNUNG UND SPEICHERUNG DER NEUEN URLAUBSTAGE - VERWEIS AUF timemenagement.views
''' '''
@receiver(signal=post_save, sender=Absence) @receiver(signal=post_save, sender=Absence)
def save_newabsence(sender, instance, **kwargs): def save_newabsence(sender, instance, **kwargs):
post_save.disconnect(save_newabsence, sender=sender) post_save.disconnect(save_newabsence, sender=sender)
@ -665,8 +683,8 @@ def save_newabsence(sender, instance, **kwargs):
newnotification = UserNotification(touser=user, notificationtext="Neue Abwesenheit!", notificationtype="", elementid=instance.pk) newnotification = UserNotification(touser=user, notificationtext="Neue Abwesenheit!", notificationtype="", elementid=instance.pk)
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Neue Abwesenheit für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"}) #async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Neue Abwesenheit für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"})
# Benutzer ist Vertreter # Benutzer ist Vertreter
if(user == instance.representator): if(user == instance.representator):
if(user.usernotifications.absence_user_is_rep_mail): if(user.usernotifications.absence_user_is_rep_mail):
@ -676,8 +694,8 @@ def save_newabsence(sender, instance, **kwargs):
newnotification = UserNotification(touser=user, notificationtext="Neue Abwesenheitsvertretung!", notificationtype="", elementid=instance.pk) newnotification = UserNotification(touser=user, notificationtext="Neue Abwesenheitsvertretung!", notificationtype="", elementid=instance.pk)
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Sie wurden als Vertreter für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"}) #async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Sie wurden als Vertreter für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"})
# ABWESENHEIT GEÄNDERT # ABWESENHEIT GEÄNDERT
else: else:
@ -698,8 +716,8 @@ def save_newabsence(sender, instance, **kwargs):
newnotification = UserNotification(touser=user, notificationtext="Aktualisierte Abwesenheit!", notificationtype="", elementid=instance.pk) newnotification = UserNotification(touser=user, notificationtext="Aktualisierte Abwesenheit!", notificationtype="", elementid=instance.pk)
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Abwesenheit für " + instance.user.first_name + " " + instance.user.last_name + " wurde aktualisiert!"}) #async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Abwesenheit für " + instance.user.first_name + " " + instance.user.last_name + " wurde aktualisiert!"})
# Benutzer ist Vertreter # Benutzer ist Vertreter
if(user == instance.representator): if(user == instance.representator):
@ -710,8 +728,8 @@ def save_newabsence(sender, instance, **kwargs):
newnotification = UserNotification(touser=user, notificationtext="Neue Abwesenheitsvertretung!", notificationtype="", elementid=instance.pk) newnotification = UserNotification(touser=user, notificationtext="Neue Abwesenheitsvertretung!", notificationtype="", elementid=instance.pk)
newnotification.save() newnotification.save()
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Sie wurden als Vertreter für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"}) #async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Sie wurden als Vertreter für " + instance.user.first_name + " " + instance.user.last_name + " eingetragen!"})
else: else:
# Kein Urlaubsanspruch, dennoch prüfen ob bereits bestehende Arbeitstage involviert sind # Kein Urlaubsanspruch, dennoch prüfen ob bereits bestehende Arbeitstage involviert sind
@ -729,15 +747,15 @@ def new_chat_message(sender, instance, **kwargs):
for u in instance.room.chatmembers.all(): for u in instance.room.chatmembers.all():
if u != instance.author: if u != instance.author:
if u.usernotifications.chat_received_push and u not in sended_users: if u.usernotifications.chat_received_push and u not in sended_users:
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(u.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Chat | Neue Nachricht im Gruppenchat " + instance.room.roomname + " von " + instance.author.first_name + " " + instance.author.last_name + ": " + instance.content}) #async_to_sync(channel_layer.group_send)("user_" + str(u.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Chat | Neue Nachricht im Gruppenchat " + instance.room.roomname + " von " + instance.author.first_name + " " + instance.author.last_name + ": " + instance.content})
sended_users.append(u) sended_users.append(u)
for u in instance.room.chatmembers_admin.all(): for u in instance.room.chatmembers_admin.all():
if u != instance.author: if u != instance.author:
if u.usernotifications.chat_received_push and u not in sended_users: if u.usernotifications.chat_received_push and u not in sended_users:
channel_layer = channels.layers.get_channel_layer() #channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(u.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Chat | Neue Nachricht im Gruppenchat " + instance.room.roomname + " von " + instance.author.first_name + " " + instance.author.last_name + ": " + instance.content}) #async_to_sync(channel_layer.group_send)("user_" + str(u.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Chat | Neue Nachricht im Gruppenchat " + instance.room.roomname + " von " + instance.author.first_name + " " + instance.author.last_name + ": " + instance.content})
sended_users.append(u) sended_users.append(u)
@ -746,8 +764,9 @@ def new_chat_message(sender, instance, **kwargs):
u = instance.room.chatmember_single u = instance.room.chatmember_single
if u.usernotifications.chat_received_push and u != instance.author: if u.usernotifications.chat_received_push and u != instance.author:
channel_layer = channels.layers.get_channel_layer() pass
async_to_sync(channel_layer.group_send)("user_" + str(u.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Chat | Neue Nachricht von " + instance.author.first_name + " " + instance.author.last_name + ": " + instance.content}) #channel_layer = channels.layers.get_channel_layer()
#async_to_sync(channel_layer.group_send)("user_" + str(u.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Chat | Neue Nachricht von " + instance.author.first_name + " " + instance.author.last_name + ": " + instance.content})

View File

@ -52,7 +52,6 @@ html h1 {
} }
body{ body{
background-color: #f8f9fc; background-color: #f8f9fc;
padding-top: 70px;
} }
.modal-open {overflow-y: auto} .modal-open {overflow-y: auto}

View File

@ -0,0 +1,38 @@
window.onload = function () {
var button = document.createElement("a");
button.innerHTML = '<image src="http://localhost:8080/svg/core/actions/user-admin?color=ebebec">';
button.classList.add("header-menu");
// 2. Append somewhere
var header = document.getElementsByClassName("header-right")[0];
header.prepend(button);
button.style.padding = "20px";
// DIV
realtimediv = document.createElement("div");
realtimediv.style.width = "300px";
realtimediv.style.height = "250px";
realtimediv.style.border = "solid black 1px";
realtimediv.style.top = "50px";
realtimediv.style.right = "50px";
realtimediv.style.position = "fixed";
realtimediv.style.overflow = "hidden";
realtimediv.style.display = "none";
realtimediv.innerHTML = '<iframe src="http://localhost:8000/tm/abs/getncdd/" title="Zeiterfassung" width="300" height="250" style="overflow:hidden" scrolling="no"></iframe>';
header.appendChild(realtimediv);
button.addEventListener ("click", function() {
if(realtimediv.style.display == "none"){
realtimediv.style.display = "block";
}
else {
realtimediv.style.display = "none";
}
});
}

View File

@ -14,33 +14,20 @@
<!-- Custom fonts for this template--> <!-- Custom fonts for this template-->
<link rel="canonical" href="https://app.digitale-agentur.com"> <link rel="canonical" href="https://app.digitale-agentur.com">
<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.js" type="text/javascript"></script>-->
<script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script> <script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
<link href="{%static 'users/vendor/fontawesome-free/css/all.min.css' %}" rel="stylesheet" type="text/css"> <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/google_font.css' %}" rel="stylesheet" type="text/css"> <link href="{%static 'users/css/google_font.css' %}" rel="stylesheet" type="text/css">
<!--<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'>-->
<link href="{%static 'users/css/google_swap.css' %}" rel="stylesheet" type="text/css"> <link href="{%static 'users/css/google_swap.css' %}" 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="{%static 'users/js/jquery_ui_min.js' %}" type="text/javascript"></script> <script src="{%static 'users/js/jquery_ui_min.js' %}" type="text/javascript"></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"> <link href="{% static 'users/css/cropper.min.css' %}" type="text/css" rel="stylesheet">
<!-- DATATABLES --> <!-- DATATABLES -->
<!--<link href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css" type="text/css" rel="stylesheet">-->
<link href="{% static 'users/css/jquery_datatables.css' %}" type="text/css" rel="stylesheet"> <link href="{% static 'users/css/jquery_datatables.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">-->
<link href="{% static 'users/css/datatables_bs4.css' %}" type="text/css" rel="stylesheet"> <link href="{% static 'users/css/datatables_bs4.css' %}" type="text/css" rel="stylesheet">
<!-- Custom styles for this template--> <!-- Custom styles for this template-->
@ -50,63 +37,32 @@
<script src="{%static 'users/js/bs4_summernote.js' %}" type="text/javascript"></script> <script src="{%static 'users/js/bs4_summernote.js' %}" type="text/javascript"></script>
<!--<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/summernote@0.8.16/dist/summernote-bs4.js"></script>-->
<link href="{% static 'users/css/bs4_summernote.css' %}" type="text/css" rel="stylesheet"> <link href="{% static 'users/css/bs4_summernote.css' %}" type="text/css" rel="stylesheet">
<!--<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> <script type="text/javascript" src="{% static 'summernote/lang/summernote-de-DE.min.js' %}"></script>
<!-- Bootstrap core JavaScript--> <!-- Bootstrap core JavaScript-->
<!--<script src="{%static 'users/vendor/jquery/jquery.min.js' %}"></script>-->
<script type="text/javascript" src="{%static 'users/vendor/bootstrap/js/bootstrap.bundle.min.js' %}"></script> <script type="text/javascript" src="{%static 'users/vendor/bootstrap/js/bootstrap.bundle.min.js' %}"></script>
<!-- Core plugin JavaScript--> <!-- Core plugin JavaScript-->
<script type="text/javascript" src="{%static 'users/vendor/jquery-easing/jquery.easing.min.js' %}"></script> <script type="text/javascript" src="{%static 'users/vendor/jquery-easing/jquery.easing.min.js' %}"></script>
<!-- DATABLES JS --> <!-- 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="{%static 'users/js/jquery_dataTables.min.js' %}"></script> <script type="text/javascript" src="{%static 'users/js/jquery_dataTables.min.js' %}"></script>
<script type="text/javascript" src="https://cdn.datatables.net/plug-ins/1.10.22/dataRender/datetime.js"></script> <script type="text/javascript" src="https://cdn.datatables.net/plug-ins/1.10.22/dataRender/datetime.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="{%static 'users/js/bs4_dt.js' %}"></script> <script type="text/javascript" src="{%static 'users/js/bs4_dt.js' %}"></script>
<!-- Custom scripts for all pages--> <!-- Custom scripts for all pages-->
<script type="text/javascript" src="{%static 'users/js/sb-admin-2.js' %}"></script> <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>-->
<!-- Page level plugins -->
<!--<script src="vendor/chart.js/Chart.min.js"></script>-->
<!-- Page level custom scripts -->
<!--<script src="js/demo/chart-area-demo.js"></script>-->
<!--<script src="js/demo/chart-pie-demo.js"></script>-->
<link href="{% static 'users/css/custom.css' %}" type="text/css" rel="stylesheet">
<!-- -->
<link href="{% static 'users/css/custom.css' %}" type="text/css" rel="stylesheet">
</head> </head>
<body> <body>
<!-- Page Wrapper --> <!-- Page Wrapper -->
<div id="wrapper" > <div id="wrapper" >
<!-- Sidebar --> <!-- Sidebar -->
<ul class=" bg-gray-900 sidebar sidebar-dark accordion fixed-top " style="overflow: all; height: 100vh;"id="accordionSidebar"> <!--<ul class=" bg-gray-900 sidebar sidebar-dark accordion fixed-top " style="overflow: all; height: 100vh;"id="accordionSidebar">
-->
{% if request.user.profile.agency.paymentplan == 0 and request.user.profile.agency.paymentstatus == 0 %} {% if request.user.profile.agency.paymentplan == 0 and request.user.profile.agency.paymentstatus == 0 %}
<style type="text/css"> <style type="text/css">
.trail_arrow { .trail_arrow {
@ -128,231 +84,37 @@
} }
</style> </style>
<div class="trail_arrow"> <!-- <div class="trail_arrow">
{% getTrialDays request.user.profile.agency as trialdays %} {% getTrialDays request.user.profile.agency as trialdays %}
<span class="trail_font"><nobr><b>TRIAL ({{trialdays}})</b></nobr> <span class="trail_font"><nobr><b>TRIAL ({{trialdays}})</b></nobr>
</span> </span>
</div> </div>-->
{% endif %} {% endif %}
<!-- Sidebar - Brand --> <!-- Sidebar - Brand -->
<!--
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="{% url 'users-dashboard' %}"> <a class="sidebar-brand d-flex align-items-center justify-content-center" href="{% url 'users-dashboard' %}">
-->
<!--<i class="fas fa-laptop"></i> <!--<i class="fas fa-laptop"></i>
<div class="sidebar-brand-text mx-2" style="">Digitale Agentur</div>--> <div class="sidebar-brand-text mx-2" style="">Digitale Agentur</div>-->
<img src="{% static 'users/img/logo_neu.png' %}" width="100%"> <!--<img src="{% static 'users/img/logo_neu.png' %}" width="100%">-->
</a> <!--</a>-->
<!-- Divider --> <!-- Divider -->
<hr class="sidebar-divider my-0"> <!--<hr class="sidebar-divider my-0">-->
<!-- Nav Item - Dashboard --> <!-- Nav Item - Dashboard -->
{% if active_link == 'dashboard' %}
<li class="nav-item active">
{% else %}
<li class="nav-item">
{%endif%}
<a class="nav-link" href="{% url 'users-dashboard' %}">
<i class="fas fa-fw fa-tachometer-alt"></i>
<span>Dashboard</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- Heading -->
<div class="sidebar-heading">
Agentur
</div>
{% getUnpubStandards request.user as standardUnPubCount %}
{% if active_link == 'standards' %}
<li class="nav-item active">
{% else%}
<li class="nav-item">
{%endif%}
<a class="nav-link " href="{% url 'standards' %}" aria-expanded="true">
<i class="fas fa-fw fa-lightbulb"></i>
<span>Standards
{% if standardUnPubCount > 0 %}
<span class="badge badge-primary badge-counter" id="messcounter_badge" style="margin-right: 95px;"><span id="messcounter">{{standardUnPubCount}}</span></span>&nbsp;
{% endif %}
</span>
</a>
</li>
{% if active_link == 'orga' %}
<li class="nav-item active">
{% else%}
<li class="nav-item">
{%endif%}
<a class="nav-link " href="{% url 'orga-main' %}" aria-expanded="true">
<i class="fas fa-fw fa-sitemap"></i>
<span>Organigramm</span>
</a>
</li>
{% if request.user.profile.agency.module_organizer %}
{% if active_link == 'organizer' %}
<li class="nav-item active">
{% else%}
<li class="nav-item">
{%endif%}
<a class="nav-link " href="{% url 'organizer-management' %}" aria-expanded="true">
<i class="fas fa-address-book"></i>
<span>Organizer</span>
</a>
</li>
{% endif %}
{% if request.user.profile.agency.module_files and request.user|usergperm:"filesviewer" %}
{% if active_link == 'cloud' %}
<li class="nav-item active">
{% else%}
<li class="nav-item">
{%endif%}
<a class="nav-link " href="{% url 'cloud-main' 'first' %}" aria-expanded="true">
<i class="fas fa-file"></i>
<span>Dateien</span>
</a>
</li>
{% endif %}
{% if request.user.profile.agency.module_messages %}
{% if active_link == 'messages' %}
<li class="nav-item active">
{% else%}
<li class="nav-item">
{%endif%}
{% getmesscounter request.user as gs %}
<a class="nav-link " href="{% url 'messages' %}" aria-expanded="true">
<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>&nbsp;
{% endif %}
</span>
</a>
</li>
{% endif %}
{% if request.user.profile.agency.module_chat %}
<script type="text/javascript">preventUpdatePresLive = false;</script>
{% if active_link == 'chat' %}
<li class="nav-item active">
{% 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&nbsp;<sup>BETA</sup></span>
</a>
</li>
{% endif %}
<!--
TASK: Counter einfügen, der in der Navi zeigt, wie viele ausstehende Anträge es gibt
-->
{% if request.user.profile.agency.module_timemanagement %}
{% getAbsenceAsks request.user as ab_ask %}
{% 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>
<!-- TASK: Anzahl ausstehender Anträge hier rein -->
<span>Abwesenheiten&nbsp;
{% if ab_ask > 0 and request.user|usergperm:"absencemanager" %}
<span class="badge badge-primary badge-counter" id="messcounter_badge" style="margin-right: 62px;"><span id="messcounter">{{ab_ask}}</span></span>&nbsp;
{% endif %}
</span>
</a>
</li>
{% endif %}
{% if request.user.usertime.usetime or request.user|usergperm:"usermanager" and request.user.profile.agency.module_timemanagement %}
{% if active_link == 'timemanagement' %}
<li class="nav-item active">
{% else%}
<li class="nav-item">
{%endif%}
<a class="nav-link " href="{% url 'tm-management' %}" aria-expanded="true">
<i class="far fa-clock"></i>
<span>Zeiterfassung</span>
</a>
</li>
{% endif %}
{% if request.user.profile.agency.module_recoverdir and request.user|has_group_byname:"Notfallhilfe" %}
{% if active_link == 'recoverdir' %}
<li class="nav-item active">
{% else%}
<li class="nav-item">
{%endif%}
<a class="nav-link " href="{% url 'recoverdir' %}" aria-expanded="true">
<i class="fas fa-medkit"></i>
<span>Notfallhilfe</span>
</a>
</li>
{% endif %}
<!-- Sidebar Toggler (Sidebar) --> <!-- Sidebar Toggler (Sidebar) -->
<!-- <!--
<div class="text-center d-none d-md-inline"> <div class="text-center d-none d-md-inline">
<button class="rounded-circle border-0" id="sidebarToggle"></button> <button class="rounded-circle border-0" id="sidebarToggle"></button>
</div> </div>
--> -->
<style scoped>
#bottom_info {
bottom: 0;
}
</style>
<div id="bottom_info" style="z-index: -200">
<hr class="sidebar-divider d-none d-md-block"> <!--<div style="" class="sidebar-heading ">-->
{% if request.user.is_staff %}
<li class="nav-item">
<a class="nav-link " href="{% url 'adm-main' %}" aria-expanded="true" style="margin-top: -15px">
<i class="fas fa-user-shield"></i>
<span>Adminoberfläche</span>
</a>
</li>
{% endif %}
{% if active_link == 'dasettings' %}
<li class="nav-item active">
{% else%}
<li class="nav-item">
{%endif%}
<a class="nav-link " href="{% url 'dasettings' %}" aria-expanded="true" style="margin-top: -15px">
<i class="fas fa-cog"></i>
<span>Einstellungen</span>
</a>
</li>
{% if active_link == 'support' %}
<li class="nav-item active">
{% else%}
<li class="nav-item">
{%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&nbsp;</small><img src="{% static 'users/img/VVE-Logo.png' %}" width="27%" class="mb-2"></span>--> <!--<span style="float: left"><small>poweder by&nbsp;</small><img src="{% static 'users/img/VVE-Logo.png' %}" width="27%" class="mb-2"></span>-->
<a style="color: #999; text-decoration: none;" href="https://digitale-agentur.com/datenschutz" target="_blank">Datenschutz</a><br /> <!--<a style="color: #999; text-decoration: none;" href="https://digitale-agentur.com/datenschutz" target="_blank">Datenschutz</a><br />
<a style="color: #999; text-decoration: none;" href="https://digitale-agentur.com/impressum" target="_blank">Impressum</a> <a style="color: #999; text-decoration: none;" href="https://digitale-agentur.com/impressum" target="_blank">Impressum</a>
<br /> <br />
<br /> <br />
@ -362,12 +124,12 @@
<a href="https://www.myvve.de/" target="_blank"><img src="{% static 'users/img/VVE-Logo.png' %}" width="27%" class="mb-2"></a> <a href="https://www.myvve.de/" target="_blank"><img src="{% static 'users/img/VVE-Logo.png' %}" width="27%" class="mb-2"></a>
</div> </div>
</div> </div>
</ul> </ul>-->
<!-- End of Sidebar --> <!-- End of Sidebar -->
<!-- Content Wrapper --> <!-- Content Wrapper -->
<style scoped> <!--<style scoped>
.sidebar{ .sidebar{
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
@ -413,30 +175,31 @@
}*/ }*/
</style> </style>
<div id="content-wrapper"> <div id="content-wrapper">
-->
<!-- Main Content --> <!-- Main Content -->
<!-- Topbar --> <!-- 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="">-->
<!-- Sidebar Toggle (Topbar) --> <!-- Sidebar Toggle (Topbar) -->
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3" onclick="javascript:toggleSidebar()"> <!--<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3" onclick="javascript:toggleSidebar()">
<i class="fa fa-bars"></i> <i class="fa fa-bars"></i>
</button> </button>-->
<!-- Topbar Search --> <!-- 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"> <!--<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"> <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"> <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">
--> -->
<!--
<div class="input-group-append"> <div class="input-group-append">
<button class="btn btn-primary" type="button" onclick="javascript:clearSF()" id="agencysearch_button" disabled=""> <button class="btn btn-primary" type="button" onclick="javascript:clearSF()" id="agencysearch_button" disabled="">
<span id="agencysearch_icon"> <span id="agencysearch_icon">
<i class="fas fa-search"></i> <i class="fas fa-search"></i>
<!--<i class="fas fa-times fa-sm"></i>-->
</span> </span>
</button> </button>
</div> </div>
@ -447,7 +210,7 @@
background-color: #5a5c69 !important; background-color: #5a5c69 !important;
border-color: #5a5c69 !important; border-color: #5a5c69 !important;
} }
</style> </style>-->
{% getUserIsRep request.user as repstring %} {% getUserIsRep request.user as repstring %}
{% if repstring != False %} {% if repstring != False %}
@ -480,52 +243,31 @@
</script> </script>
<!-- Topbar Navbar --> <!-- Topbar Navbar -->
<ul class="navbar-nav ml-auto "> <!--<ul class="navbar-nav ml-auto ">-->
<!-- TASK: Hier Cookie mit einbauen --> <!-- TASK: Hier Cookie mit einbauen -->
{% getIsUserStartTime request.user as starttime %}
{% if request.user.usertime.usetime and starttime %}
<li class="nav-item dropdown no-arrow mx-1">
<a class="nav-link dropdown-toggle" id="timemanagement_realtime" role="button" data-toggle="dropdown" aria-haspopup="true" onclick="javascript:toggleDropDown()">
<i class="far fa-clock"></i>
</a>
<div class="dropdown-list dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="" id="timemanagement_clock" name="timemanagement_clock" aria-expanded="false" aria-role="static" style="display: none;">
<h6 class="dropdown-header text-white">
Zeiterfassung
<span style="float: right"><button onclick="javascript:toggleDropDown()" class="btn btn-small" style="margin-top: -15px; margin-right: -20px;">x</button></span>
</h6>
<div>
{% block timemanagement_content_realtime %}
{% include "timemanagement/realtime_dropdown.html" %}
{% endblock %}
</div>
<a class="dropdown-item text-center small text-gray-500" href="{% url 'tm-management' %}">Zur Zeiterfassung</a>
</div>
</li>
{% endif %}
<!-- ALERT_AREA --> <!-- ALERT_AREA -->
<!-- Nav Item - Alerts --> <!-- Nav Item - Alerts -->
<li class="nav-item dropdown no-arrow mx-1"> <!--<li class="nav-item dropdown no-arrow mx-1">
<a class="nav-link dropdown-toggle" onclick="changeNewNotToViewed()" id="alertsDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link dropdown-toggle" onclick="changeNewNotToViewed()" id="alertsDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-bell fa-fw"></i> <i class="fas fa-bell fa-fw"></i>-->
<!-- Counter - Alerts --> <!-- Counter - Alerts -->
<span class="badge badge-danger badge-counter" id="notificationcounter"></span> <!--<span class="badge badge-danger badge-counter" id="notificationcounter"></span>
</a> </a>-->
<!-- Dropdown - Alerts --> <!-- Dropdown - Alerts -->
<!--
<div class="dropdown-list dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="alertsDropdown" id="allnotificationsarea"> <div class="dropdown-list dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="alertsDropdown" id="allnotificationsarea">
<h6 class="dropdown-header bg-success text-white"> <h6 class="dropdown-header bg-success text-white">
Benachrichtigungen Benachrichtigungen
</h6> </h6>-->
<!-- ITEMS --> <!-- ITEMS -->
<span id="notification_items"></span> <!--<span id="notification_items"></span>-->
<!-- ITEMS END --> <!-- ITEMS END -->
<a class="dropdown-item text-center small text-gray-500" href="{% url 'showallnotificaions' %}">Alle Benachrichtigungen ansehen</a> <!--<a class="dropdown-item text-center small text-gray-500" href="{% url 'showallnotificaions' %}">Alle Benachrichtigungen ansehen</a>
</div> </div>-->
</li> <!--/li>-->
<style type="text/css"> <style type="text/css">
{% getonlinestatuscolor request.user as onlinecolor %} {% getonlinestatuscolor request.user as onlinecolor %}
.roundimg_base { .roundimg_base {
@ -535,16 +277,19 @@
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> <!--<div class="topbar-divider d-none d-sm-block"></div>-->
<!-- Nav Item - User Information --> <!-- Nav Item - User Information -->
<!--
<li class="nav-item dropdown no-arrow"> <li class="nav-item dropdown no-arrow">
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="mr-2 d-none d-lg-inline text-gray-600 small">{{request.user.first_name}} {{request.user.last_name}} <span class="mr-2 d-none d-lg-inline text-gray-600 small">{{request.user.first_name}} {{request.user.last_name}}
</span> </span>
<img id="userbaseprofilepicture" class="img-profile roundimg_base ml-2" src="{{ request.user.profile.get_photo_url }}"> <img id="userbaseprofilepicture" class="img-profile roundimg_base ml-2" src="{{ request.user.profile.get_photo_url }}">
</a> </a>-->
<!-- Dropdown - User Information --> <!-- Dropdown - User Information -->
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
<!--<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> <i class="fas fa-circle mr-2" style="color: green"></i>
Online Online
@ -561,13 +306,14 @@
<i class="fas fa-circle mr-2" style="color: grey"></i> <i class="fas fa-circle mr-2" style="color: grey"></i>
Offline anzeigen Offline anzeigen
</a> </a>
-->
<div class="dropdown-divider"></div> <!--<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({{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> <i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
Einstellungen Einstellungen
</a> </a>
<a class="dropdown-item" onclick="userGoToNotification()" href="#/"> <a class="dropdown-item" onclick="userGoToNotification()" href="#/">
<i class="fas fa-bell fa-sm fa-fw mr-2 text-gray-400"></i> <i class="fas fa-bell fa-sm fa-fw mr-2 text-gray-400"></i>
Benachrichtigungen Benachrichtigungen
@ -581,18 +327,18 @@
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i> <i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
Abmelden Abmelden
</a> </a>
</div> </div>-->
</li> <!--</li>-->
</ul> <!--</ul>-->
</nav> <!--</nav>-->
<!-- End of Topbar --> <!-- End of Topbar -->
<!-- Begin Page Content --> <!-- Begin Page Content -->
<div class="container-fluid" > <div class="container-fluid" style="padding-top: 10px !important;" >
<div id="searchcontent" style="min-height: 100%; margin-top: 85px;"> <div id="searchcontent" style="min-height: 100%; display: none;">
</div> </div>
<div id="maincontent" style="min-height: 100%; margin-top: 85px;" > <div id="maincontent" style="min-height: 100%; " >
<!-- MESSAGES --> <!-- MESSAGES -->
{% if messages %} {% if messages %}
{% for message in messages %} {% for message in messages %}
@ -610,26 +356,6 @@
<div style="height: 300px">&nbsp;</div> <div style="height: 300px">&nbsp;</div>
</div> <!-- End of Main Content CONTAINER FLUID--> </div> <!-- End of Main Content CONTAINER FLUID-->
<!-- End of Content Wrapper --> <!-- 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 -->
<div id="dynamicchatwindow" class="col-4" style="position: fixed; bottom: 30px; right: 23px; display: none;z-index: 999;">
<div class="card">
<div class="card-body">
<span id="dynamicchatwindow_content"></span>
</div>
</div>
</div>
<script type="text/javascript">
</script>
{% endif %}
<!-- CHATAREA END -->
{% endif %}
</div> </div>
</div> </div>
<!-- SUMMERNOTE ADDED CSS --> <!-- SUMMERNOTE ADDED CSS -->
@ -642,21 +368,7 @@
} }
</style> </style>
<!-- CHAT BUTTON -->
<!-- End of Page Wrapper -->
<!--
<footer class="sticky-footer bg-white" style="width: 86.2%;position: absolute;
bottom: 0; margin-top: 80px; padding-top: 20px; padding-bottom: 20px;
">
<div class="container my-auto">
<div class="copyright text-center my-auto">
<span>Copyright &copy; digitale-agentur.com für <b>{{ user.profile.agency.name }}</b></span><br /><small>Version 0.0.5</small>
</div>
</div>
</footer>
-->
<!-- Scroll to Top Button--> <!-- Scroll to Top Button-->
<a class="scroll-to-top rounded" href="#page-top"> <a class="scroll-to-top rounded" href="#page-top">
<i class="fas fa-angle-up"></i> <i class="fas fa-angle-up"></i>
@ -741,18 +453,11 @@ $(document).ready(function(){
if($( window ).width() < 768)
{
$("#accordionSidebar").addClass("toggled");
$("#content-wrapper").css("margin-left" , "0px");
$("#topnavbarmain").css("margin-left" , "0px");
sidebar_hidden = false;
}
}); });
// Toggle the side navigation // Toggle the side navigation
/*
function toggleSidebar(){ function toggleSidebar(){
if(sidebar_hidden == false){ if(sidebar_hidden == false){
$("#accordionSidebar").removeClass("toggled"); $("#accordionSidebar").removeClass("toggled");
@ -785,7 +490,7 @@ $( window ).resize(function() {
$("#topnavbarmain").css("margin-left" , "224px"); $("#topnavbarmain").css("margin-left" , "224px");
sidebar_hidden = true; sidebar_hidden = true;
} }
}); });*/
/* /*
AJAX CALL FOR NOTIFICATIONS AJAX CALL FOR NOTIFICATIONS
@ -875,7 +580,7 @@ $(document).on('click', function (e) {
<!-- WEBSOCKETS --> <!-- WEBSOCKETS -->
<script type="text/javascript"> <script type="text/javascript">
/*
$(document).ready(function(){ $(document).ready(function(){
$("#chat_alluserscontent").hide(); $("#chat_alluserscontent").hide();
@ -897,10 +602,7 @@ $(document).ready(function(){
//HANDLER FOR ALL PUSHNOTIFICATIONS //HANDLER FOR ALL PUSHNOTIFICATIONS
if(e["data"].split("__")[0] == "pushnotification"){ if(e["data"].split("__")[0] == "pushnotification"){
/* tempsplit = e["data"].split("__");
Check for Chat-Message in CHatview or invisible-Browser
*/
tempsplit = e["data"].split("__");
finalsplit = tempsplit[1].split(" "); finalsplit = tempsplit[1].split(" ");
if(finalsplit[0] != "Chat"){ if(finalsplit[0] != "Chat"){
@ -1048,7 +750,7 @@ $("#chatButton").click(function(){
} }
}); });
}); });
*/
</script> </script>
<!-- Billstatus --> <!-- Billstatus -->

View File

@ -204,6 +204,4 @@ $(document).ready(function(){
</div> </div>
</div> </div>
<!-- YOUTUBE PART ENDE --> <!-- YOUTUBE PART ENDE -->
{% endblock content %} {% endblock content %}

View File

@ -1,56 +1,14 @@
{% extends "users/publicbase.html" %} {% load static %}
<!-- CRISPY --> <html>
{% load crispy_forms_tags %} <body>
{% block content %} <h4>Sie werden gleich zur neuen Login-Seite der Digitalen Agentur weitergeleitet. Sollte dies nicht gehen, klicken Sie auf folgenden Link:</h4>
<style type="text/css"> <a href="https://cloud.digitale-agentur.com/">https://cloud.digitale-agentur.com/</a>
#logincard { </body>
width: 25%; </html>
margin-top: 7%; <script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
} <script>
</style> $(document).ready(function(){
<div class="card mx-auto" id="logincard"> window.location.replace("https://cloud.digitale-agentur.com/external/1");
<div class="card-body">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group" >
<legend class="border-bottom mb-4" style="text-align: center;">
<i class="fas fa-laptop"></i>
<h3>Digitale Agentur Login</h3>
</legend>
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert" id="message_{{forloop.counter}}">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endfor %}
{% endif %}
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-primary">Anmelden</button>
<small class="text-muted ml-2">
<a href="{% url 'password-reset' %}" class="">Passwort vergessen?</a><br />
</small>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted ml-2">
<a href="mailto:support@digitale-agentur.com" class="">Probleme beim anmelden?</a>
</small>
<small class="text-muted">
<a class="ml-2" href="{% url 'register' %}">Agentur registrieren</a>
</small>
</div>
</div>
</div>
<script type="text/javascript">
$("label[for*='username']").html("E-Mail-Adresse*");
$(document).ready(function(){
localStorage.clear(); localStorage.clear();
}) })
</script> </script>
{% endblock content %}

View File

@ -0,0 +1,56 @@
{% extends "users/publicbase.html" %}
<!-- CRISPY -->
{% load crispy_forms_tags %}
{% block content %}
<style type="text/css">
#logincard {
width: 25%;
margin-top: 7%;
}
</style>
<div class="card mx-auto" id="logincard">
<div class="card-body">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group" >
<legend class="border-bottom mb-4" style="text-align: center;">
<i class="fas fa-laptop"></i>
<h3>Digitale Agentur Login</h3>
</legend>
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert" id="message_{{forloop.counter}}">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endfor %}
{% endif %}
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-primary">Anmelden</button>
<small class="text-muted ml-2">
<a href="{% url 'password-reset' %}" class="">Passwort vergessen?</a><br />
</small>
</div>
</form>
<div class="border-top pt-3">
<small class="text-muted ml-2">
<a href="mailto:support@digitale-agentur.com" class="">Probleme beim anmelden?</a>
</small>
<small class="text-muted">
<a class="ml-2" href="{% url 'register' %}">Agentur registrieren</a>
</small>
</div>
</div>
</div>
<script type="text/javascript">
$("label[for*='username']").html("E-Mail-Adresse*");
$(document).ready(function(){
localStorage.clear();
})
</script>
{% endblock content %}

View File

@ -0,0 +1 @@
<h3>{{error}}</h3>

View File

@ -1,25 +1,8 @@
{% extends "users/publicbase.html" %} {% load static %}
{% load crispy_forms_tags %} <script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
{% block content %} <script>
<style type="text/css"> $(document).ready(function(){
#logincard { window.location.replace("cloud.digitale-agentur.com/external/1");
width: 35%; localStorage.clear();
margin-top: 4%; })
} </script>
</style>
<div class="card mx-auto" id="logincard">
<div class="card-body">
<legend class="border-bottom mb-4" style="text-align: center;">
<i class="fas fa-laptop"></i>
<h3>Passwort anfordern</h3>
</legend>
<p>Bitte geben Sie ihre E-Mailadresse ein, mit der Sie sich bei der Digitalen Agentur registriert haben.</p>
<form method="POST">
{% csrf_token %}
{{ form|crispy }}
<hr>
<button type="submit" class="btn btn-primary">Passwort anfordern</button>&nbsp;
</form>
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,25 @@
{% extends "users/publicbase.html" %}
{% load crispy_forms_tags %}
{% block content %}
<style type="text/css">
#logincard {
width: 35%;
margin-top: 4%;
}
</style>
<div class="card mx-auto" id="logincard">
<div class="card-body">
<legend class="border-bottom mb-4" style="text-align: center;">
<i class="fas fa-laptop"></i>
<h3>Passwort anfordern</h3>
</legend>
<p>Bitte geben Sie ihre E-Mailadresse ein, mit der Sie sich bei der Digitalen Agentur registriert haben.</p>
<form method="POST">
{% csrf_token %}
{{ form|crispy }}
<hr>
<button type="submit" class="btn btn-primary">Passwort anfordern</button>&nbsp;
</form>
</div>
</div>
{% endblock content %}

View File

@ -1,67 +1,8 @@
<!-- Base-Template einbinden --> {% load static %}
{% extends "users/publicbase.html" %} <script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
<!-- CRISPY --> <script>
{% load crispy_forms_tags %} $(document).ready(function(){
<!-- BLOCK NAME START --> window.location.replace("cloud.digitale-agentur.com/external/1");
{% block content %} localStorage.clear();
<div class="card mx-auto" id="logincard"> })
<div class="card-body"> </script>
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show " role="alert" id="message_{{forloop.counter}}">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close" onclick='javascript:$("#message_{{forloop.counter}}").fadeOut()'>
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endfor %}
{% endif %}
<form method="POST">
{% csrf_token %}
<fieldset class="form-group" >
<legend class="border-bottom mb-4" style="text-align: center;">
<i class="fas fa-laptop"></i>
<h3>Registrieren Sie Ihre Agentur</h3>
</legend>
{% for field in form %}
{% if field.name != 'captcha' %}
{{field.field_name}}
{% if field.name == 'agb' %}
{{field}}&nbsp;&nbsp;<a style="" href="https://digitale-agentur.com/agb" target="_blank">AGB's*</a><br />
{% elif field.name == 'av' %}
{{field}}&nbsp;&nbsp;<a style="" href="https://digitale-agentur.com/agb" target="_blank">AV-Vertrag*</a>
{% else %}
{{field|as_crispy_field}}
{% endif %}
{% endif %}
{% endfor %}
<!--form.captcha|as_crispy_field-->
<!--<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="isvve" onclick="javascript:changeVVE()">
<label class="form-check-label" for="isvve">
VVE-Mitglied
</label>
</div>-->
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-lg" style="float: right;">Registrieren</button>
</div>
</form>
</div>
</div>
<script type="text/javascript">
/*$(document).ready(function(){
$("#div_id_vve").hide();
});
function changeVVE(){
var checkBox = document.getElementById("isvve");
if (checkBox.checked == true)
{
$("#div_id_vve").show();
} else {
$("#div_id_vve").hide();
}
}*/
</script>
{% endblock content %}

View File

@ -0,0 +1,67 @@
<!-- Base-Template einbinden -->
{% extends "users/publicbase.html" %}
<!-- CRISPY -->
{% load crispy_forms_tags %}
<!-- BLOCK NAME START -->
{% block content %}
<div class="card mx-auto" id="logincard">
<div class="card-body">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show " role="alert" id="message_{{forloop.counter}}">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close" onclick='javascript:$("#message_{{forloop.counter}}").fadeOut()'>
<span aria-hidden="true">&times;</span>
</button>
</div>
{% endfor %}
{% endif %}
<form method="POST">
{% csrf_token %}
<fieldset class="form-group" >
<legend class="border-bottom mb-4" style="text-align: center;">
<i class="fas fa-laptop"></i>
<h3>Registrieren Sie Ihre Agentur</h3>
</legend>
{% for field in form %}
{% if field.name != 'captcha' %}
{{field.field_name}}
{% if field.name == 'agb' %}
{{field}}&nbsp;&nbsp;<a style="" href="https://digitale-agentur.com/agb" target="_blank">AGB's*</a><br />
{% elif field.name == 'av' %}
{{field}}&nbsp;&nbsp;<a style="" href="https://digitale-agentur.com/agb" target="_blank">AV-Vertrag*</a>
{% else %}
{{field|as_crispy_field}}
{% endif %}
{% endif %}
{% endfor %}
<!--form.captcha|as_crispy_field-->
<!--<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="isvve" onclick="javascript:changeVVE()">
<label class="form-check-label" for="isvve">
VVE-Mitglied
</label>
</div>-->
</fieldset>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-lg" style="float: right;">Registrieren</button>
</div>
</form>
</div>
</div>
<script type="text/javascript">
/*$(document).ready(function(){
$("#div_id_vve").hide();
});
function changeVVE(){
var checkBox = document.getElementById("isvve");
if (checkBox.checked == true)
{
$("#div_id_vve").show();
} else {
$("#div_id_vve").hide();
}
}*/
</script>
{% endblock content %}

View File

@ -1,24 +1,8 @@
<!-- Base-Template einbinden --> {% load static %}
{% extends "users/publicbase.html" %} <script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
<script>
{% load crispy_forms_tags %} $(document).ready(function(){
<!-- BLOCK NAME START --> window.location.replace("cloud.digitale-agentur.com/external/1");
{% block content %} localStorage.clear();
})
<style type="text/css"> </script>
#logincard {
width: 35%;
margin-top: 4%;
}
</style>
<div class="card mx-auto" id="logincard">
<div class="card-body">
<legend class="border-bottom mb-4" style="text-align: center;">
<i class="fas fa-laptop"></i>
<h3>Registrierung abgeschlossen</h3>
</legend>
<p>Ihre Agentur wurde erfolgreich angelegt! Bitte prüfen Sie Ihre E-Mails, um sich ein Passwort für Ihren Account zu erstellen. Anschließend können Sie sich in Ihrer Agentur anmelden.
</p>
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,24 @@
<!-- Base-Template einbinden -->
{% extends "users/publicbase.html" %}
{% load crispy_forms_tags %}
<!-- BLOCK NAME START -->
{% block content %}
<style type="text/css">
#logincard {
width: 35%;
margin-top: 4%;
}
</style>
<div class="card mx-auto" id="logincard">
<div class="card-body">
<legend class="border-bottom mb-4" style="text-align: center;">
<i class="fas fa-laptop"></i>
<h3>Registrierung abgeschlossen</h3>
</legend>
<p>Ihre Agentur wurde erfolgreich angelegt! Bitte prüfen Sie Ihre E-Mails, um sich ein Passwort für Ihren Account zu erstellen. Anschließend können Sie sich in Ihrer Agentur anmelden.
</p>
</div>
</div>
{% endblock content %}

View File

@ -14,21 +14,16 @@ Permissions definiert in models.py bei USERS und dann hier vor die View geschrie
''' '''
urlpatterns = [ urlpatterns = [
path('nclog/<str:uid>', views.ncLogin, name='nclog'),
path('', views.dashboard, name='users-dashboard'), path('', views.dashboard, name='users-dashboard'),
path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='users-logout'), path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='users-logout'),
path('usersman/', permission_required('users.usermanager')(UsersManagement.as_view(template_name="users/users_management.html")), name='users-management'), path('usersman/', permission_required('users.usermanager')(UsersManagement.as_view(template_name="users/users_management.html")), name='users-management'),
path('usersman/adduser/', permission_required('users.usermanager')(UsersCreateUser.as_view(template_name="users/users_adduser.html")), name='users-adduser'), path('usersman/adduser/', permission_required('users.usermanager')(UsersCreateUser.as_view(template_name="users/users_adduser.html")), name='users-adduser'),
#path('usersman/profile/', views.profile, name='users-profile'),
#path('usersman/<int:pk>/', views.ProfileUpdateView, name='users-update'),
#path('usersman/<int:pk>/', permission_required('users.usermanager')(ProfileUpdateView.as_view()), name='users-update'),
path('usersman/<int:pk>/perms', permission_required('users.usermanager')(UsersPermUpdateView.as_view()), name='users-perm-update'), path('usersman/<int:pk>/perms', permission_required('users.usermanager')(UsersPermUpdateView.as_view()), name='users-perm-update'),
path('usersman/<int:pk>/delete', permission_required('users.usermanager')(ProfileDeleteView.as_view()), name='users-delete'), path('usersman/<int:pk>/delete', permission_required('users.usermanager')(ProfileDeleteView.as_view()), name='users-delete'),
path('usersman/gd/<int:pk>', views.getDataFromToDelUser, name="users-delete-getdata"), path('usersman/gd/<int:pk>', views.getDataFromToDelUser, name="users-delete-getdata"),
path('userlog/<int:pk>', views.showUserLog, name="users-log"), path('userlog/<int:pk>', views.showUserLog, name="users-log"),
#path('agencyinfo/', views.agency, name='agencyinfo'),
#path('agencyinfo/<int:pk>/', permission_required('users.agency_change')(AgencyUpdateView.as_view()), name='agency-manage'),
path('usersman/<int:pk>/prio', views.UsersPrio, name='users-prio'), path('usersman/<int:pk>/prio', views.UsersPrio, name='users-prio'),
#path('prioupdate/', views.UsersPrioUpdate, name="users-prioupdate"),
path('areataskupdate/<int:pk>/', views.UsersAreaTaskUpdate, name="users-areataskupdate"), path('areataskupdate/<int:pk>/', views.UsersAreaTaskUpdate, name="users-areataskupdate"),
path('globalsearch/', views.GlobalSearch, name="globalsearch"), path('globalsearch/', views.GlobalSearch, name="globalsearch"),
path('standardrout/', views.searchStandardRouter, name="standardrouter"), path('standardrout/', views.searchStandardRouter, name="standardrouter"),
@ -46,9 +41,9 @@ urlpatterns = [
path('icsall/<int:ag>', views.getICSFileAll, name="geticsall"), path('icsall/<int:ag>', views.getICSFileAll, name="geticsall"),
path('icspublic/<slug:code>/<int:ag>', views.getICSFileEx, name="getics"), path('icspublic/<slug:code>/<int:ag>', views.getICSFileEx, name="getics"),
path('icspublicall/<slug:code>/<int:ag>', views.getICSFileExAll, name="geticsall"), path('icspublicall/<slug:code>/<int:ag>', views.getICSFileExAll, name="geticsall"),
path('updateuserorga/', views.UpdateUserOrga, name="update-user-orga") path('updateuserorga/', views.UpdateUserOrga, name="update-user-orga"),
#path('recalculateabsence/<slug:code>', views.recalculateAbsence, name="recalculateabsence"), # OAUTH
#path('oauth/callback/', views.oauthCallBack, name="oauthcallback"),
] ]

View File

@ -36,17 +36,17 @@ from message.models import Message
from notificsys.models import UserNotification from notificsys.models import UserNotification
from organizer.models import AGContacts, AGPassword from organizer.models import AGContacts, AGPassword
import sys, os import sys, os
from asgiref.sync import async_to_sync #from asgiref.sync import async_to_sync
from channels_presence.models import Room #from channels_presence.models import Room
from channels_presence.models import Presence #from channels_presence.models import Presence
import channels.layers #import channels.layers
from datetime import date, timedelta from datetime import date, timedelta
from timemanagement.models import Workday, Absence, Breaks from timemanagement.models import Workday, Absence, Breaks
import base64 import base64
import filetype import filetype
from django.db.models.signals import m2m_changed from django.db.models.signals import m2m_changed
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from users.signals import adjust_group_notifications_permission #from users.signals import adjust_group_notifications_permission
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from digitaleagentur.utils import * from digitaleagentur.utils import *
from digitaleagentur.timemanagement_utils import * from digitaleagentur.timemanagement_utils import *
@ -67,6 +67,175 @@ import base64
from django.http import HttpResponse from django.http import HttpResponse
# NC LOGIN
'''
A User has to be logged in in NC. If yes, we check the user-status and retrieving the userId. If the logged user by this session is the same we want to see in Django, than the user will logged in.
Double-Check: Logged-Session from NC (session-id cannot be hacked cause it is serverside) and we check userId local, django and NC
'''
import xmltodict, json
import urllib.request as urllib2
from django.contrib.auth import login, logout
from django.core.mail import send_mail
from django.views.generic import TemplateView
def get_random_number(length = 6):
result_str = ''.join(random.choice("0123456789") for i in range(length))
return result_str
def create_group_id(agencygroupname, agency):
newgroupid = ""
pregroupstr = "agencymaingroupid_"
if(agencygroupname == "Mitarbeiter"):
newgroupid = pregroupstr + str(agency.pk)
# NORMAL GROUOPS
elif(agencygroupname == "Administratoren"):
newgroupid = pregroupstr + str(agency.pk) + "_defaultadmingroup"
elif(agencygroupname == "Notfallhilfe"):
newgroupid = pregroupstr + str(agency.pk) + "_recover"
else:
newgroupid = pregroupstr + str(agency.pk) + "_subgroup_" + get_random_number()
return newgroupid
def createNewAgencyByNC(request, uid):
print("CREATE NEW AGENCY")
# Creating Agency and prepare basic-Structure
email = uid
agency = Agency()
agency.name = email + "'s Agentur"
agency.vve = ""
agency.save()
pr=Profile()
pr.agency=agency
# Create new User
try:
print("CREATE NEW USER IN DJANGO")
user=User.objects.create_user(email, email, randomString(30))
except:
print("PREDICTED EXCEPT - CONTINUE")
user = User.objects.get(username=email)
user.first_name = email
user.last_name = email
user.usernotification = UserNotification()
#user.usertime = UserTime()
pr.user=user
pr.save()
user.profile = pr
user.save()
print("USER DONE")
request.user = user
# Creating all Standard-Django-Stuff
toUpdate(request)
loadPreStructure(agency)
# Creating all NC-Stuff
# Agency-Groupfolder and Standard-Folder
data = {
"gid" : "agencymaingroupid_" + str(agency.pk),
"aid" : str(agency.pk),
"newagency" : True
}
print("CREATING GROUPFOLDER")
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v2.php/apps/da_agency/api/v1/creategf?format=json", auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data)
print(r.text)
print("CREATING GROUPS IN NC FROM DJANGO")
groups = AgencyGroup.objects.filter(agency=agency)
for g in groups:
newgroupid = create_group_id(g.agencygroupname, agency)
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
data = {
"groupid" : newgroupid
}
print("CREATE GROUP " + g.agencygroupname)
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v1.php/cloud/groups", data=data, headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
print(r.text)
r_status = json.loads(r.text)
if(r_status['ocs']['meta']['statuscode'] == 100):
# Group created, save new group id in Django
g.nc_name = newgroupid
g.save()
# Group created, set display name in NC
data = {
"name": g.agencygroupname,
"id" : newgroupid
}
print("GROUP OK - CHANGE DISPLAY NAME")
r = requests.post(settings.NEXTCLOUD_URL + "ocs/v2.php/apps/da_agency/api/v1/renameagg?format=json", auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data)
print(r.text)
# Add current user to all Groups!
print("ADDING CURRENT USER TO ALL GROUPS")
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
data_nc = {
"groupid" : g.nc_name,
}
r = requests.post(settings.NEXTCLOUD_URL + "/ocs/v1.php/cloud/users/" + user.username + "/groups",headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API), data=data_nc)
print(r.text)
print("CREATING STANDARDFOLDER")
r_2 = requests.request("MKCOL", settings.NEXTCLOUD_URL + "remote.php/dav/files/" + user.username + "/Agenturdaten/Standards Uploadbereich", auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
print(r_2.text)
print("DONE! Redirecting to nclogin")
#return redirect(settings.NEXTCLOUD_URL)
#return redirect('nclog', uid)
# Entry-Point for NC
def ncLogin(request, uid):
logout(request)
#print(uid)
if(User.objects.filter(username=uid).exists()):
user = User.objects.get(username=uid)
if(len(user.profile.nc_sid) > 0 and getNCLoggedUserBySession(user.profile.nc_sid) == uid):
# Checking, if all necessary folders are created
#r = requests.request("MKCOL", settings.NEXTCLOUD_URL + "remote.php/dav/files/" + user.username + '/Agenturdaten/Standards Uploadbereich/', auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
headers = {
'Authorization': 'Bearer ' + user.profile.nc_sid
}
# Groupfolder for Standards
r = requests.request("MKCOL", settings.NEXTCLOUD_URL + "remote.php/dav/files/" + user.username + '/Agenturdaten/Standards Uploadbereich/', headers=headers)
login(request, user)
return redirect('users-dashboard')
else:
return render(request, 'users/nclog.html',{'error' : "Die Agenturdaten wurden aktualisiert. Bitte melden Sie sich ab und wieder an. Sollten Sie diese Meldung weiterhin sehen, kontaktieren Sie den Support."})
else:
print("NO USER FOUND - NEW AGENCY REGISTRATION!")
createNewAgencyByNC(request, uid)
return render(request, 'users/nclog.html',{'error' : "Die Agenturdaten wurden aktualisiert. Bitte melden Sie sich ab und wieder an. Sollten Sie diese Meldung weiterhin sehen, kontaktieren Sie den Support."})
#return render(request, 'users/nclog.html',{'error' : "Die Agenturdaten wurden aktualisiert. Bitte melden Sie sich ab und wieder an. Sollten Sie diese Meldung weiterhin sehen, kontaktieren Sie den Support."})
#except:
#
# try:
# except:
# return render(request, 'users/nclog.html',{'error' : "Die Agenturdaten wurden aktualisiert. Bitte melden Sie sich ab und wieder an. Sollten Sie diese Meldung weiterhin sehen, kontaktieren Sie den Support."})
#return render(request, 'users/nclog.html',{'error' : "Die Agenturdaten wurden aktualisiert. Bitte melden Sie sich ab und wieder an. Sollten Sie diese Meldung weiterhin sehen, kontaktieren Sie den Support."})
def getICSFile(request, ag): def getICSFile(request, ag):
if 'HTTP_AUTHORIZATION' in request.META: if 'HTTP_AUTHORIZATION' in request.META:
auth = request.META['HTTP_AUTHORIZATION'].split() auth = request.META['HTTP_AUTHORIZATION'].split()
@ -222,45 +391,6 @@ def getICSFileExAll(request, code, ag):
response.status_code = 404 response.status_code = 404
return response return response
'''
def getICSFileExAll(request, code, ag):
if(request.method == "GET"):
#try:
agency = Agency.objects.get(pk=ag)
if agency != None and agency.agencycal_publicstatus == 1 and str(code) == str(agency.agencycalurl_all):
c = Calendar()
absencedays = Absence.objects.filter(agency=ag).exclude(confirm_status=2)
for ab in absencedays:
if ab.start != None and ab.end != None:
e = Event()
e.name = ab.user.first_name + " " + ab.user.last_name + " | " + ab.reason.name
e.uid = "da-ab-" + str(ab.pk)
if ab.start < ab.end:
e.begin = ab.start
e.end = ab.end
else:
e.begin = ab.start
e.end = ab.start + timedelta(minutes=1)
e.allday = True
c.events.add(e)
return HttpResponse(c, content_type='text/calendar')
else:
realm = ""
response = HttpResponse()
response.status_code = 400
return response
except:
realm = ""
response = HttpResponse()
response.status_code = 403
return response
else:
realm = ""
response = HttpResponse()
response.status_code = 404
return response
'''
''' '''
@ -391,6 +521,14 @@ def toUpdate(request):
temgroup_verwaltung_ag = AgencyGroup(savefordel=True, is_admin=True, group=temgroup_verwaltung, agency=request.user.profile.agency, agencygroupname="Administratoren") temgroup_verwaltung_ag = AgencyGroup(savefordel=True, is_admin=True, group=temgroup_verwaltung, agency=request.user.profile.agency, agencygroupname="Administratoren")
temgroup_verwaltung_ag.save() temgroup_verwaltung_ag.save()
temgroup_Notfallhilfe = Group(name=str(request.user.profile.agency.pk) + "_" + randomString(8))
temgroup_Notfallhilfe.save()
temgroup_Notfallhilfe_ag = AgencyGroup(savefordel=True, group=temgroup_Notfallhilfe, agency=request.user.profile.agency, agencygroupname="Notfallhilfe")
temgroup_Notfallhilfe_ag.save()
recoverdirmanagingperm = Permission.objects.get(codename='recoverdirmanager')
temgroup_Notfallhilfe_ag.group.permissions.add(recoverdirmanagingperm)
#print("default groups created...adding users...") #print("default groups created...adding users...")
users_of_agency = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk) users_of_agency = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk)
for user in users_of_agency: for user in users_of_agency:
@ -425,7 +563,7 @@ def toUpdate(request):
#print("recoverdirgroup added and perms set") #print("recoverdirgroup added and perms set")
# CHECK FOR ALL POSSIBLE RIGHTS ON ADMINGROUP # CHECK FOR ALL POSSIBLE RIGHTS ON ADMINGROUP
m2m_changed.disconnect(adjust_group_notifications_permission, sender=Group.permissions.through) #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] ag_admingroup = list(AgencyGroup.objects.filter(agency=request.user.profile.agency, is_admin=True))[0]
perms = AgencyGroup._meta.permissions perms = AgencyGroup._meta.permissions
@ -434,7 +572,7 @@ def toUpdate(request):
ag_admingroup.group.permissions.add(tempperm) ag_admingroup.group.permissions.add(tempperm)
'''
# INITIAL ROOT DIR # INITIAL ROOT DIR
rootdir = DataDir.objects.filter(is_root=True, agency__pk=request.user.profile.agency.pk) rootdir = DataDir.objects.filter(is_root=True, agency__pk=request.user.profile.agency.pk)
@ -470,7 +608,7 @@ def toUpdate(request):
#print("AGENCY DEF STANDARD DIR - FILESMODULE READY") #print("AGENCY DEF STANDARD DIR - FILESMODULE READY")
pass pass
'''
# CHANGE RIGHTS ORGNAIZER # CHANGE RIGHTS ORGNAIZER
admingroups = AgencyGroup.objects.filter(is_admin=True) admingroups = AgencyGroup.objects.filter(is_admin=True)
for a in admingroups: for a in admingroups:
@ -478,7 +616,7 @@ def toUpdate(request):
a.group.permissions.add(Permission.objects.get(codename="agencynetwork")) a.group.permissions.add(Permission.objects.get(codename="agencynetwork"))
m2m_changed.connect(adjust_group_notifications_permission, sender=Group.permissions.through) #m2m_changed.connect(adjust_group_notifications_permission, sender=Group.permissions.through)
# USER TIME MODEL # USER TIME MODEL
usersofagency = User.objects.filter(profile__agency=request.user.profile.agency) usersofagency = User.objects.filter(profile__agency=request.user.profile.agency)
@ -757,6 +895,7 @@ def showUserLog(request, pk):
context = {} context = {}
return render(request, 'users/userlog_forbidden.html', context) return render(request, 'users/userlog_forbidden.html', context)
@login_required @login_required
def dashboard(request): def dashboard(request):
# UPDATE FUNCTIONS BY NEW MODEL-CHANGES FOR COPIEN SOME DATA # UPDATE FUNCTIONS BY NEW MODEL-CHANGES FOR COPIEN SOME DATA
@ -1119,10 +1258,19 @@ class ProfileDeleteView(LoginRequiredMixin, DeleteView):
a.published_by = logged_user a.published_by = logged_user
a.save() a.save()
''' '''
# NC DELETE USER IN NC TOO!
headers = {
'Accept' : 'application/json',
'Access-Control-Allow-Headers' : 'OCS-APIRequest',
'OCS-APIRequest' : 'true'
}
r = requests.request("DELETE", settings.NEXTCLOUD_URL + "/ocs/v1.php/cloud/users/" + user.username,headers=headers, auth=(settings.NEXTCLOUD_USER_API, settings.NEXTCLOUD_PW_API))
response = super(ProfileDeleteView, self).delete(request, *args, **kwargs) response = super(ProfileDeleteView, self).delete(request, *args, **kwargs)
name = user.first_name + " " + user.last_name name = user.first_name + " " + user.last_name
messages.success(request, f'Benutzer ' +name+ ' wurde gelöscht!') messages.success(request, f'Benutzer ' +name+ ' wurde gelöscht!')
return response return response
# Saves a new User in parent of others Users. # Saves a new User in parent of others Users.