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
Quellcode für Prod aktuell
Aktuelle Version für die Prod!
Agenturstand zur Migration in Nextcloud.

View File

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

View File

@ -97,6 +97,16 @@
<span>Agenturen</span></a>
</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' %}
<li class="nav-item active">
{% else %}
@ -118,17 +128,6 @@
<span>Benutzer</span></a>
</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">
<li class="nav-item">
@ -296,7 +295,7 @@
<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 -->
{% if messages %}
{% for message in messages %}
@ -543,7 +542,7 @@ function removeNotification(notifyid){
}
/*
$(document).on('click', function (e) {
if(e.target["id"] != 'chatButton'){
@ -551,13 +550,13 @@ $(document).on('click', function (e) {
$("#chat_alluserscontent").fadeOut();
}
}
});
});*/
</script>
<!-- WEBSOCKETS -->
<script type="text/javascript">
/*
$(document).ready(function(){
$("#chat_alluserscontent").hide();
@ -579,9 +578,7 @@ $(document).ready(function(){
//HANDLER FOR ALL PUSHNOTIFICATIONS
if(e["data"].split("__")[0] == "pushnotification"){
/*
Check for Chat-Message in CHatview or invisible-Browser
*/
tempsplit = e["data"].split("__");
finalsplit = tempsplit[1].split(" ");
@ -731,5 +728,5 @@ $("#chatButton").click(function(){
});
});
*/
</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" %}
{% block content %}
{% load counter_tag %}
{% load adm_tags %}
<!-- Mitarbeier ist immer der angemeledete!!! -->
<div class="content-section col-12">
@ -23,19 +22,6 @@
<td>Letzter Login</td>
<td>{{userdata.last_login|default:"-"}}</td>
</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>
</div>
</div>

View File

@ -10,6 +10,8 @@ Permissions definiert in models.py bei USERS und dann hier vor die View geschrie
urlpatterns = [
path('', AdmMain.as_view(), name='adm-main'),
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('agsingle/<int:agpk>', AdmAgencySingle.as_view(), name="adm-agency-single"),
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/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('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.conf import settings
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
from requests.api import head
from .models import MainStatistic, MainSalesMonth
from django.contrib.auth.models import User
from chat.models import ChatMessage
@ -29,20 +30,6 @@ from django.template.loader import render_to_string
from cloud.models import DataFile
import math
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!
'''
@ -677,17 +664,94 @@ class AdmAddBreak(CreateView):
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('getsinglechat/<int:pk>', views.getsinglechat, name='api-getsinglechat'),
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.response import Response
from rest_framework.permissions import IsAuthenticated # <-- Here
#from rest_framework.permissions import IsAuthenticated # <-- Here
import json
from standards.models import Standards
from rest_framework import serializers
@ -11,39 +14,44 @@ from rest_framework.authentication import SessionAuthentication, BasicAuthentica
from rest_framework.decorators import authentication_classes
from chat.models import ChatRoom, ChatMessage
from django.http import HttpResponseRedirect,HttpResponse, JsonResponse
from django.contrib.sessions.models import Session
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):
permission_classes = (IsAuthenticated,) # <-- And here
#permission_classes = (IsAuthenticated,) # <-- And here
def post(self, request):
return Response({"userid" : self.request.user.pk})
@api_view(['POST', ])
@permission_classes((IsAuthenticated,))
#@permission_classes((IsAuthenticated,))
def getStandardList(request):
standards = Standards.objects.filter(agency=request.user.profile.agency)
ser = StandardsSerializer(standards, many=True)
return Response(ser.data, status=status.HTTP_200_OK)
@api_view(['POST', ])
@permission_classes((IsAuthenticated,))
#@permission_classes((IsAuthenticated,))
def getSingleStandard(request, pk):
standard = Standards.objects.get(pk=int(pk))
ser = StandardsSerializer(standard, many=False)
return Response(ser.data, status=status.HTTP_200_OK)
@api_view(['POST', ])
@permission_classes((IsAuthenticated,))
#@permission_classes((IsAuthenticated,))
def logoutByToken(request):
print(request)
request.user.auth_token.delete()
return Response(status=status.HTTP_200_OK)
@api_view(['POST', ])
@permission_classes((IsAuthenticated,))
#@permission_classes((IsAuthenticated,))
def getchatrooms(request):
chatrooms = ChatRoom.objects.filter(creator=request.user) | ChatRoom.objects.filter(chatmember_single=request.user)
chatrooms_ser = ChatRoomSerializer(chatrooms, many=True)
@ -51,7 +59,7 @@ def getchatrooms(request):
@api_view(['POST', ])
@permission_classes((IsAuthenticated,))
#@permission_classes((IsAuthenticated,))
def getsinglechat(request, 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()):
@ -62,7 +70,7 @@ def getsinglechat(request, pk):
@api_view(['POST', ])
@permission_classes((IsAuthenticated,))
#@permission_classes((IsAuthenticated,))
def savenewchatmessage(request):
room = ChatRoom.objects.get(pk=request.POST["room"])
if(request.user == room.creator or request.user == room.chatmember_single):
@ -74,4 +82,668 @@ def savenewchatmessage(request):
else:
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.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.contrib.auth.models import User
from channels_presence.models import Room
from channels_presence.models import Presence
import channels.layers
#from channels_presence.models import Room
#from channels_presence.models import Presence
#import channels.layers
from django.utils import timezone
from .models import ChatRoom, ChatMessage
from .forms import ChatAddChatRoom, ChatUpdateChatRoom

View File

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

View File

@ -62,6 +62,7 @@
Die Gruppe Notfallhilfe ist für keine weiteren Rechte konfigurierbar.
<hr>
{% endif %}
{% if aggroup.agencygroupname != "Mitarbeiter" %}
<div col="10">
<h6>Mitarbeiter zur Gruppe <b>{{aggroup.agencygroupname}}</b> hinzufügen</h6>
<div class="input-group mb-3 col-5">
@ -78,7 +79,9 @@
</datalist>
</datalist>
</div>
<hr>
<hr>
{% endif %}
<h6>Gruppenmitglieder in <b>{{aggroup.agencygroupname}}</b></h6>
{% if varcounter > 0 %}
<span id="nogroupmember_{{aggroup.pk}}" style="display: none">Diese Gruppe hat noch keine Mitglieder.</span>
@ -89,10 +92,11 @@
{% for user in usersofagency %}
{% for group in user.groups.all %}
{% 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>
{% 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>
{% endif %}
{% endif %}
@ -352,9 +356,9 @@ function changeGroupName(groupid){
{
$("#newgroupname").val(data['data']['groupname']);
$("#modTitle").html("Gruppenname ändern");
$("#saveNewGroup").prop("disabled", false);
groupupdate_id = groupid;
groupaction = 1;
$("#saveNewGroup").prop("disabled", false);
groupupdate_id = groupid;
groupaction = 1;
}
});
}
@ -387,15 +391,15 @@ function updateGroupName(){
},
success: function( data )
{
if(data['success']){
window.location.href = window.location.href + "?showtoast=true";
}
else{
$("#newGroup").modal("toggle");
$('#notchange_err').toast('show');
$("#toast_errcontent").html("Der Gruppenname ist in der Agentur bereits vorhanden!");
}
if(data['success']){
window.location.href = window.location.href + "?showtoast=true";
$("#newGroup").modal("toggle");
}
else{
$("#newGroup").modal("toggle");
$('#notchange_err').toast('show');
$("#toast_errcontent").html("Der Gruppenname ist in der Agentur bereits vorhanden!");
}
}
});
}
@ -413,9 +417,9 @@ function updateGroupName(){
success: function( data )
{
if(data['success']){
$("#newGroup").modal("toggle");
$("#newGroup").modal("hide");
$('#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{
$('#notchange_err').toast('show');

View File

@ -1,10 +1,10 @@
{% load crispy_forms_tags %}
<div class="row">
<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>
@ -14,9 +14,9 @@
<input type="hidden" name="form_type" value="agencymodform">
<input type="hidden" name="settings_area" value="moduls">
{% for formfield in modulform %}
{% if formfield.name == 'module_organigramm' or formfield.name == 'module_timemanagement' %}
<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>
@ -25,13 +25,13 @@
{% endif %}
</td>
</tr>
{% endif %}
{% 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>
</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" >

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>
<hr>
<ul class="nav nav-tabs" id="settingsTabs" role="tablist">
<!--
<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>
</li>
-->
<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>
</li>
@ -79,14 +81,18 @@
</li>
{% endif %}
</ul>
<div class="tab-content" id="settingsTabsContent">
<!--
<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>
<hr>
{% block profil_content %}
{% include "dasettings/profil_content.html" %}
{% endblock %}
WURDE AUSKOMMENTNTIERT, IST ABER DJANGO
block profil_content
include "dasettings/profil_content.html"
endblock
</div>
-->
<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>
@ -170,7 +176,7 @@
</div>
<script type="text/javascript">
var defaultsettingsview = "profil";
var defaultsettingsview = "notifications";
/* COOKIE FOR SAVING OPEN TAB */
$(document).ready(function(){
@ -192,14 +198,14 @@ var defaultsettingsview = "profil";
}
else{
$("#profil-tab").addClass("active");
$('#profil').tab('show');
$("#notifications-tab").addClass("active");
$('#notifications').tab('show');
}
}
else{
$("#profil-tab").addClass("active");
$('#profil').tab('show');
$("#notifications-tab").addClass("active");
$('#notifications').tab('show');
}
});

View File

@ -9,17 +9,17 @@
</div>
<small>Legen Sie hier die Stammdaten des neuen Mitarbeiters fest.</small>
<form method="POST">
<form method="POST" id="new_user_form">
{% csrf_token %}
{{ newuserform|crispy }}
<div class="form-check">
<!--<div class="form-check">
<input class="form-check-input" type="checkbox" value="true" id="sendmailnewuser" name="sendmailnewuser">
<label class="form-check-label" for="sendmailnewuser" name="sendmailnewuser">
E-Mailbenachrichtigung schicken
</label>
</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>
</div>-->
<small>*: Der Benutzer erhält direkt eine Willkommens-E-Mail mit einem Link zur Passworterstellung.</small>
{% if request.user.profile.agency.paymentplan != "0" %}
<hr>
@ -28,8 +28,14 @@
<hr>
<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>
</div>
</div>
<script>
/* Disable the button for submitting after click */
$("#new_user_form").submit(function(event){
$("#createbtn").prop("disabled", true);
})
</script>
{% 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>
</p>
<div style="float: left">
<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>
<!--<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>-->
</div>
</div>
</div>

View File

@ -547,6 +547,7 @@ Hier werden die Profilinfos des User zurückgesetzt; Parameter kommen von Settin
- Passwort aktualisieren
'''
import requests
@login_required
def SettingsProfilManagement(request, context):
# Check, which form
@ -590,6 +591,10 @@ def SettingsProfilManagement(request, context):
context['passwordform'] = passwordform
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
def SettingsAjaxRouter(request):
success = False
@ -645,7 +650,7 @@ def SettingsAjaxRouter(request):
tempjob = AgencyJob.objects.get(pk=job_id, agency=request.user.profile.agency)
data = {"funcname" : tempjob.name}
success = True
# DELETE FINAL AGECY JOB
# DELETE FINAL AGENCY JOB
elif request.method == 'GET' and request.GET['action'] == "delete_agencyfunc" :
job_id = request.GET['id']
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.save()
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
data = {"newvalue" : request.GET['newvalue']}
else:
success = False
# GRUPPENNAMEN HOLEN
@ -671,21 +700,70 @@ def SettingsAjaxRouter(request):
group = AgencyGroup.objects.get(pk=request.GET['id'], agency=request.user.profile.agency)
data = {"groupname" : group.agencygroupname}
success = True
# SAVE NEW GROUP ADD GROUP
elif request.method == 'GET' and request.GET['action'] == "add_group" :
if(checkForGroupName(request, request.GET['newvalue'])):
tempgroup = Group(name=str(request.user.profile.agency.pk) + "_" + randomString(8))
tempgroup.save()
tempgroup_ag = AgencyGroup(savefordel=False, group=tempgroup, agency=request.user.profile.agency, agencygroupname=request.GET['newvalue'])
tempgroup_ag.save()
success = True
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:
success = False
# DELETE A GROUP
elif request.method == 'GET' and request.GET['action'] == "delete_group" :
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.delete()
success = True
# PERMISSIONS ON GROUP!
elif request.method == 'GET' and request.GET['action'] == "change_perm_group" :
success = True
@ -716,6 +794,18 @@ def SettingsAjaxRouter(request):
aggroup.group.user_set.remove(usertoremove)
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:
success = False
# ADD USER TO GROUP
@ -729,6 +819,20 @@ def SettingsAjaxRouter(request):
if(request.user.profile.agency.pk == aggroup.agency.pk):
aggroup.group.user_set.add(usertoadd)
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:
success = False
# AREA
@ -851,8 +955,19 @@ def SettingsAjaxRouter(request):
success = False
else:
tempuser.email = newmail
tempuser.username = newmail
#tempuser.username = newmail
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
else:
data = {"mail" : tempmail}
@ -870,6 +985,18 @@ def SettingsAjaxRouter(request):
tempuser.save()
data = {"userfullname" : tempuser.first_name + " " + tempuser.last_name}
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:
data = {"userfullname" : tempuser.first_name + " " + tempuser.last_name}
success = False
@ -1542,7 +1669,7 @@ def UserChangeMain(request, pk):
}
return render(request, 'dasettings/user_changemaindata.html', context)
# Method for first User-Creation-Step
# Method for first User-Creation-Step - NEW USER
@login_required
def NewUserFirstStep(request):
context = {
@ -1551,24 +1678,45 @@ def NewUserFirstStep(request):
if request.method == 'POST':
newuserform = UserNewUserForm(request.POST)
if newuserform.is_valid():
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')})
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)
#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')})
# 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.username = newuser.email
newprofile = Profile(agency=request.user.profile.agency, parent=None)
newprofile.save()
newuser.profile = newprofile
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
user_time = UserTime(user=newuser)
user_time.save()
# USER NOTIFICATIONS
user_notifications = UserNotifications(user=newuser)
user_notifications.save()
newuser.usernotifications = user_notifications
#user_notifications = UserNotifications.objects.create(user=newuser)
#user_notifications.save()
#newuser.usernotifications = user_notifications
newuser.usertime = user_time

View File

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

View File

@ -1,7 +1,9 @@
'''
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import users.routing
application = ProtocolTypeRouter({
# Empty for now (http->django views is added by default)
'websocket': AuthMiddlewareStack(
@ -9,4 +11,6 @@ application = ProtocolTypeRouter({
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!
# 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
X_FRAME_OPTIONS = 'SAMEORIGIN'
#X_FRAME_OPTIONS = 'SAMEORIGIN'
#X_FRAME_OPTIONS = 'ALLOWALL'
X_FRAME_OPTIONS = 'allow-from *cloud.digitale-agentur.com'
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
@ -47,10 +48,8 @@ MAILINFOKEY = "jka7sd8iukashdna78skduJAHDsu6dilaksdjba65a68iadbhjak"
#ALTER ZUM TESTEN
#LEX_API = "8f9ba01f-9e84-42c7-9548-48c254f14c19"
# Neuer KEY
LEX_API = "p6xxyzOul0BaLDr-xuhVNYNzZ5s"
# 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
DEFF_SALT = 'A-!GDtuKp?H/H5-UUatEh6ZcG/6h-VQf1OkDORRkK0(:(qCf//'
@ -62,6 +61,8 @@ DEFF_FETCH_URL_NAME = 'getdoc'
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
NC_SECRETKEY = "lkjahstaszd76uhjNJABHM65rftzvb323ADSD567tzu9ztz"
# Application definition
INSTALLED_APPS = [
'django.contrib.contenttypes',
@ -95,8 +96,8 @@ INSTALLED_APPS = [
'django_user_agents',
'rest_framework',
'rest_framework.authtoken',
'channels',
'channels_presence',
#'channels',
#'channels_presence',
'simple_history',
'captcha',
'auditlog',
@ -112,11 +113,14 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django_user_agents.middleware.UserAgentMiddleware',
'simple_history.middleware.HistoryRequestMiddleware',
'auditlog.middleware.AuditlogMiddleware'
'auditlog.middleware.AuditlogMiddleware',
#'users.middleware.oauth.OAuthMiddleware'
]
ROOT_URLCONF = 'digitaleagentur.urls'
#CSRF_COOKIE_SECURE = False
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
@ -134,16 +138,20 @@ TEMPLATES = [
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
#'DEFAULT_AUTHENTICATION_CLASSES': (
#'rest_framework.authentication.TokenAuthentication',
#'rest_framework.permissions.AllowAny',
#),
#'DEFAULT_PERMISSION_CLASSES': [
# 'rest_framework.permissions.IsAuthenticated',
#],
}
#WSGI_APPLICATION = 'digitaleagentur.wsgi.application'
WSGI_APPLICATION = 'digitaleagentur.wsgi.application'
ASGI_APPLICATION = "digitaleagentur.routing.application"
'''
CHANNEL_LAYERS = {
'default': {
'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_URL = 'login'
# NC Default Login findet im Dashboard statt!
#LOGIN_URL = NEXTCLOUD_URL
STATIC_URL = '/static/'
'''
SITE_ROOT = os.path.dirname(os.path.realpath(__file__)) + '/..'

View File

@ -1,5 +1,7 @@
from timemanagement.models 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
@ -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 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):
# Alle einzelnen Tage der Abwesenheit werden durchgegangen:
for day in daterange(absence.start, absence.end):
@ -68,6 +99,33 @@ def checkAbsenceWorkdayCollide(absence):
workday.delflag = True
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):
# Alle einzelnen Tage der Abwesenheit werden durchgegangen:
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 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('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.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView
@ -17,6 +18,7 @@ class NewsManagement(LoginRequiredMixin, ListView):
# Loading only user same agency
# Change context and return for template-data
def get_context_data(self, **kwargs):
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')
@ -134,8 +136,3 @@ def NewsSingle(request, pk):
return render(request, 'news/news_single.html', context)

View File

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

View File

@ -36,3 +36,6 @@ xhtml2pdf==0.2.5
django-simple-captcha==0.5.13
auditlog3==1.0.1
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_on = models.DateTimeField(default=timezone.now, blank=True)
last_modified_on = models.DateTimeField(default=timezone.now, blank=True)
class Standards(models.Model):
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
area = models.ForeignKey(Areas, on_delete=models.SET_NULL, blank=True, null=True)
@ -66,6 +66,8 @@ class Standards(models.Model):
# FILES
addedfiles = models.ManyToManyField(DataFile, blank=True)
addedfiles_nc = models.ManyToManyField('NCFile', blank=True)
# VERLINKTE STANDARDS
linked_standards = models.ManyToManyField('Standards', blank=True)
# GORUPS
@ -94,3 +96,8 @@ class Standards(models.Model):
# Hier Path für Templates des Models mit Parametern
def get_absolute_url(self):
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">
{% 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 %}
<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 %}
@ -144,24 +144,29 @@
<button type="button" onclick="javascript:clearSearchField('files')" class="btn btn-secondary" ><i class="fas fa-times"></i></button>
</div>
<datalist id="poss_files">
{% for f in files %}
<option id="files_{{f.pk}}" value="{{f.name}}">{{f.name}}</option>
{% for f in files %}
{% getNCFileInfos request f as filename %}
{% if filename != "FAIL_TO_LOAD_NC_FILE_DATA" %}
<option id="files_{{f}}" value="{{filename}}">{{filename}}</option>
{% endif %}
{% endfor %}
</datalist>
</div>
Verlinkte Dateien:
<table id="linked_files" class="table table-hover table-sm">
{% if update == True %}
{% for f in standard.addedfiles.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>
{% for f in standard.addedfiles_nc.all %}
{% 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 %}
{% endif %}
</table>
<!-- TODO: Upload ins richtige Verzeichnis-->
<input type="file" id="uploadedfile" name="uploadedfile" style="display:none">
{% if user|usergperm:"filesmanager" %}
<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>
</div>
{% endif %}
@ -717,8 +722,9 @@
var ua = window.navigator.userAgent;
var isIE = /MSIE|Trident/.test(ua);
var isSafari = /Safari/.test(ua);
if ( isIE || isSafari) {
var isChrome = /Chrome/.test(ua);
if ( isIE || (isSafari && !isChrome)) {
//IE specific code goes here
setInterval(function()
{
@ -762,7 +768,7 @@ function checkGroupVerant(){
$("#id_group_verant").val(act_verant_group);
}
console.log($("#id_group_verant").val());
//console.log($("#id_group_verant").val());
}
function removeGroupFromVeran(id, name){
@ -772,7 +778,7 @@ function removeGroupFromVeran(id, name){
$("#id_group_verant").val(act_verant_group);
$("#span_btn_verant_group_" + id).remove();
console.log($("#id_group_verant").val());
//console.log($("#id_group_verant").val());
}
//AUSFÜHRENDER
@ -798,7 +804,7 @@ function checkGroupEx(){
$("#id_group_ex").val(act_ex_group);
}
console.log($("#id_group_ex").val());
//console.log($("#id_group_ex").val());
}
function removeGroupFromEx(id, name){
@ -808,7 +814,7 @@ function removeGroupFromEx(id, name){
$("#id_group_ex").val(act_ex_group);
$("#span_btn_ex_group_" + id).remove();
console.log($("#id_group_ex").val());
//console.log($("#id_group_ex").val());
}
//VERTRETER
@ -1005,8 +1011,8 @@ actualStandards = [];
actualFiles = [];
{% if update == True %}
actualFiles = [
{% for f in standard.addedfiles.all %}
'{{f.pk}}',
{% for f in standard.addedfiles_nc.all %}
'{{f.nc_id}}',
{% endfor %}
];
$("#id_added_files").val(actualFiles);
@ -1054,8 +1060,7 @@ function clearSearchField(type){
function updateLinkedElements(type){
var g = $('#searchfield_' + type).val();
var id = $('#poss_' + type).find('option[value="' + g + '"]').attr('id');
if(id != undefined && id.length > 0){
if((id != undefined || id != "undefined") && id.length > 0){
clearSearchField(type);
tempid = id.split("_")[1];
@ -1100,6 +1105,7 @@ function remEle(type, id, name){
index_to_rem = actualFiles.indexOf(id);
actualFiles.splice(index_to_rem,1);
$("#id_added_" + type).val(actualFiles);
}
else if(type == 'quicklinks'){
index_to_rem = actualQuicklinks.indexOf(id);
@ -1176,6 +1182,7 @@ function replaceFileDirectChoice(filetodo, choice){
doUploadAction(filetodo_ex, choice);
}
function uploadAction(filetodo){
filetodo_ex = filetodo;
@ -1183,7 +1190,7 @@ function uploadAction(filetodo){
$.ajax(
{
type: "GET",
url: "{% url 'cloud-adddir' parentid %}",
url: "{% url 'cloud-adddir' 0 %}",
data:{
action : "check_doublefile",
name : filetodo.name
@ -1223,7 +1230,7 @@ function doUploadAction(filetodo, replacestat){
if(c && filetodo.type.length > 0){
$.ajax({
url: "{% url 'cloud-adddir' parentid %}",
url: "{% url 'standard-uploadfile' %}",
headers: {
"X-CSRFTOKEN": "{{ csrf_token }}"
},
@ -1246,6 +1253,7 @@ function doUploadAction(filetodo, replacestat){
return xhr;
},
success: function(data) {
console.log(data);
if(data["success"] == true){
setTimeout(function(){
hideUpload();

View File

@ -27,7 +27,7 @@
<hr>
<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">
{% else %}
<div class="card col-12" style="min-height: 500px">
@ -42,7 +42,7 @@
</div>
<!-- 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">
@ -131,19 +131,26 @@
<!-- 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-body">
<h5 class="card-title">Dateien</h5>
<p class="card-text">
{% for files in standard.addedfiles.all %}
<a href="{% url 'cloud-td' files.pk %}" target="_blank">{{files.name|truncatechars:30}}</a><br />
{% for file in standard.addedfiles_nc.all %}
{% 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 %}
</p>
</div>
</div>
{% endif %}
<!-- Quicklinks -->
{% if standard.addedquicklinks.all|length > 0 %}
<div class="card col-14 ml-1 mb-2" style="min-width: 110%">

View File

@ -72,13 +72,14 @@
<!-- 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-body">
<h5 class="card-title">Dateien</h5>
<p class="card-text">
{% for files in standard.addedfiles.all %}
{{files.name|truncatechars:30}}<br />
{% for files in standard.addedfiles_nc.all %}
{% getNCFileInfos request files.nc_id as filename %}
{{filename|truncatechars:30}}<br />
{% endfor %}
</p>
</div>

View File

@ -1110,30 +1110,70 @@ def getAbsenceLastHistory(absence):
return absence.history.first()
# Gibt die Arbeitstage zurück, an denen auch eine Abwesenheit liegt
from digitaleagentur.timemanagement_utils import *
@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)
'''
Dateinamen umbauen, damit im Standard die verlinkte Datei korrekt angezeigt wird.
# 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
TODO: Thread auf github beobachten, https://github.com/nextcloud/server/issues/17778 wenn dann displayname wieder bei WebDav geht!
Gibt den Dateinamen sauber als String zurück, wie sie in NC heißt!
'''
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
def getADMAbsenceWorkdaysTrue(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=True)
def getNCFileInfosURL(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>")
# 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('standardcopy/<int:pk>', views.CopyStandard, name="standard-copyagn"),
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.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
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.http import HttpResponse, JsonResponse
from .forms import StandardAddStandard, StandardAddStandardEditor, StandardUpdateStandard, StandardUpdateStandardEditor
@ -77,6 +78,11 @@ class StandardsManagement(LoginRequiredMixin, ListView):
return context
@login_required
def getFileFromStandard(request, nc_id):
print(nc_id)
return JsonResponse({})
@login_required
def checkUserDirRights(request, startdir, userid):
@ -109,6 +115,10 @@ def checkUserDirRights(request, startdir, userid):
canview = False
return canview
# NEW FOR NC
import requests
from django.conf import settings
from digitaleagentur.utils import *
@login_required
def StandardAdd(request, id=False):
@ -203,11 +213,24 @@ def StandardAdd(request, id=False):
if(s.isdigit()):
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
files = normalForm.cleaned_data['added_files'].split(",")
for f in files:
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
quicklinks = normalForm.cleaned_data['added_quicklinks'].split(",")
@ -240,19 +263,50 @@ def StandardAdd(request, id=False):
else:
normalForm = StandardAddStandard(instance=request.user)
editorForm = StandardAddStandardEditor(instance=request.user)
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:
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)
nc_login_headers = {'Authorization' : 'Bearer ' + request.user.profile.nc_sid}
r = requests.request("PROPFIND", settings.NEXTCLOUD_URL + "remote.php/dav/files/" + request.user.username + "/Agenturdaten_1/", headers=nc_login_headers, data=data_nc)
print(r.text)
#allfiles = DataFile.objects.filter(agency=request.user.profile.agency)
#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 = {
'normalForm' : normalForm,
@ -261,7 +315,7 @@ def StandardAdd(request, id=False):
'agencygroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency),
'usersofagency' : User.objects.filter(profile__agency=request.user.profile.agency),
'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),
'quicklinks' : QuickLinks.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)
# UPDATE A STANDARD
else:
standard = Standards.objects.get(pk=id, agency=request.user.profile.agency)
# SAVE UPDATED STANDARD
if request.method == 'POST':
# CHECK IF USER HAS RIGHTS TO SEE THIS DIR
groupsofstandard = standard
@ -320,7 +370,7 @@ def StandardAdd(request, id=False):
standard.visibleby.clear()
standard.linked_standards.clear()
standard.addedfiles.clear()
standard.addedfiles_nc.clear()
standard.addedquicklinks.clear()
standard.addedpasswords.clear()
standard.addedcontacts.clear()
@ -379,7 +429,14 @@ def StandardAdd(request, id=False):
files = normalForm.cleaned_data['added_files'].split(",")
for f in files:
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
quicklinks = normalForm.cleaned_data['added_quicklinks'].split(",")
@ -502,8 +559,6 @@ def StandardAdd(request, id=False):
return redirect('/standards')
# SHOW EXISTING STANDARD
else:
# CHECK IF USER HAS RIGHTS TO SEE THIS DIR
groupsofstandard = standard
@ -518,33 +573,54 @@ def StandardAdd(request, id=False):
userisingroup = True
if userisingroup:
normalForm = StandardUpdateStandard(instance=standard)
editorForm = StandardUpdateStandardEditor(instance=standard)
# TODO: Hier ändern, dass NC die Dateien anbietet!
# GET ALL DATAS FROM STANDARD
# FILES
possibleFilesByVisible = []
allfiles = DataFile.objects.filter(agency=request.user.profile.agency)
#allfiles = DataFile.objects.filter(agency=request.user.profile.agency)
# Get all files by view
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)
#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)
# Remove files which are in standard
for f in possibleFilesByVisible:
if f in standard.addedfiles.all():
possibleFilesByVisible.remove(f)
#for f in possibleFilesByVisible:
# if f in standard.addedfiles.all():
# 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
possible_standards = []
@ -652,7 +728,8 @@ def StandardAdd(request, id=False):
'possible_contacts' : possible_contacts,
'agencynetworks' : agencynetworks,
'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',
'update' : True,
'aggroups' : AgencyGroup.objects.filter(agency=request.user.profile.agency)
@ -748,6 +825,8 @@ def StandardChangePublic(request, pk):
standard.save()
return redirect('standards')
# TODO: Upload der Standard-Dateien passt noch nicht, BUG!!!!
@login_required
def StandardSingle(request, pk):
@ -811,13 +890,11 @@ def CopyStandard(request, pk):
new_standard.save()
datadir_parentid = list(DataDir.objects.filter(is_defaultstandard=True, agency__pk=request.user.profile.agency.pk))[0]
for f in sc.addedfiles.all():
tempdatafile = DataFile(file=f.file, name=f.name, owner=request.user, parent=datadir_parentid, agency=request.user.profile.agency)
#datadir_parentid = list(DataDir.objects.filter(is_defaultstandard=True, agency__pk=request.user.profile.agency.pk))[0]
for f in sc.addedfiles_nc.all():
tempdatafile = NCFile(agency=request.user.profile.agency, nc_id=f.nc_id)
tempdatafile.save()
new_standard.addedfiles.add(tempdatafile)
# TASK: Hier das kopieren der Dateien auf dem Server noch einfügen
new_standard.addedfiles_nc.add(tempdatafile)
# Sende Info, dass ein Standard übernommen wurde, an die Erstelleragentur
usersofagency = User.objects.filter(profile__agency=sc.agency)
@ -1115,3 +1192,50 @@ def UpdateStandardBeforeUserDel(request):
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();
})
var selectedElements = [];
var active_row = "";
var sameday = false;
@ -689,7 +688,7 @@ $( function() {
/*
Functions for Kalendar
*/
/*
function prevMonth(){
$.ajax(
{
@ -751,7 +750,7 @@ function showNewAbsenceByUser(){
function goFastToMonth(month){
location.href = "/tm/abs/" + month +"/" + choosenyear
}
*/
</script>

View File

@ -572,8 +572,7 @@ $('#absencetabs a').on('click', function (e) {
}
localStorage.setItem('activeTabAbsence', lastview_name);
});
/*
function prevMonth(){
$.ajax(
{
@ -589,6 +588,7 @@ $('#absencetabs a').on('click', function (e) {
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
},
success : function(data){
console.log(data);
$("#overlay").fadeOut();
$("#rendered_table").html(data);
}
@ -615,7 +615,7 @@ function nextMonth(){
}
});
}
*/
/*
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_end = new Date(new_end[2], (parseInt(new_end[1])-1), new_end[0]);
$("#id_start").data("DateTimePicker").date(date_start);
$("#id_end").data("DateTimePicker").date(date_end);
if(date_start != undefined && date_end != undefined){
$("#id_start").data("DateTimePicker").date(date_start);
$("#id_end").data("DateTimePicker").date(date_end);
}
if(+new_start == +new_end){
sameday = true;

View File

@ -1,6 +1,6 @@
from django.urls import path
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!
'''
@ -20,5 +20,5 @@ urlpatterns = [
path('abs/<int:activemonth>/<int:activeyear>', AbsenceManagmenet, name='tma-management'),
path('ajax/', TimeAjax, name='tm-ajax'),
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 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
def loadingFreeDays(plz):
# Getting land
@ -414,7 +422,7 @@ def TimeManagement(request, activemonth=False, activeyear=False):
def TimeUpdate(request, pk, team=0):
workday = Workday.objects.get(pk=pk)
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(team == 0):
form = UpdateWorkdayForm(request.POST, instance=request.user)
@ -786,6 +794,9 @@ def TimeAjax(request):
nextmonth = ""
activemonth = int(request.GET["activemonth"])
activeyear = int(request.GET["activeyear"])
print(activemonth)
print(activeyear)
#MONTH
if(not activemonth or activemonth > 12 or activemonth < 1):

View File

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

View File

@ -1,3 +1,4 @@
import json
from channels.generic.websocket import WebsocketConsumer
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
class UsersConsumer(WebsocketConsumer):
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)
# NC IMPORT
importid = models.CharField(default="", max_length=200, blank=True)
# RECOVERDIR
module_recoverdir = models.BooleanField(default=False)
@ -214,6 +215,8 @@ class Profile(models.Model):
phonemobile = models.CharField(max_length=60, blank=True)
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
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
@ -479,6 +482,7 @@ class AgencyGroup(models.Model):
group = models.OneToOneField(Group, on_delete=models.CASCADE)
agency = models.ForeignKey(Agency, on_delete=models.CASCADE)
agencygroupname = models.CharField(max_length=60, blank=True)
nc_name = models.CharField(max_length=200, blank=True)
savefordel = 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}'
# Hier Audit-Logeinträge einbauen für die versch. Models
from django.utils.six import python_2_unicode_compatible
from auditlog.registry import auditlog
#from django.utils.six import python_2_unicode_compatible
#from auditlog.registry import auditlog
auditlog.register(User)
auditlog.register(Agency)
#auditlog.register(User)
#auditlog.register(Agency)

View File

@ -1,3 +1,4 @@
'''
from django.urls import re_path
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/appchat/(?P<creator>\w+)/(?P<single>\w+)/(?P<token>\w+)/$', mainwebsocket.UsersChat, name="ws-appchat"),
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 datetime import timedelta
from django.core.signals import request_started
from channels_presence.models import Room
from channels_presence.models import Presence
from channels_presence.signals import presence_changed
#from channels_presence.models import Room
#from channels_presence.models import Presence
#from channels_presence.signals import presence_changed
from organizer.models import *
from chat.models import ChatMessage
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):
# Getting land
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
# Signal für das Ändern von Gruppenrechten
'''
@receiver(signal=m2m_changed, sender=Group.permissions.through)
def adjust_group_notifications_permission(instance, action, reverse, model, pk_set, using, *args, **kwargs):
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.save()
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."})
#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."})
# Rechte wurden entfernt
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.save()
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."})
#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."})
'''
# Signal, wenn ein Nutzer aus der Gruppe entfernt/hinzugefügt wird
'''
@receiver(signal=m2m_changed, sender=User.groups.through)
def adjust_group_notifications(instance, action, reverse, model, pk_set, using, *args, **kwargs):
if isinstance(instance, Group):
group_touched = AgencyGroup.objects.get(group=instance)
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.save()
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."})
#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."})
# A USER WAS ADDED TO A GROUP
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.save()
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."})
#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."})
# E-MAILNOTIFICATIONS FOR GROUPCHANGES
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,
fail_silently=True
)
'''
# SIGNALS FOR STANDARDS
# 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 | ", "", "")
# SAVE AND UPDATE
'''
@receiver(post_save, sender=Standards)
def save_standard(sender, instance, **kwargs):
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.save()
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})
#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})
if(user.has_perm("users.standardmanager") and user.usernotifications.standard_created_unpub_mail):
notificationtext = " es wurde ein neuer unveröffentlichter Agenturstandard erstellt: " + instance.name
@ -299,9 +313,10 @@ def save_standard(sender, instance, **kwargs):
# Standard wurde aktualisiert
else:
newNotifiyPush(1, instance, " es wurde ein neuer Agenturstandard aktualisiert: ", "Agenturstandard aktualisiert: ", "Standards | ", "newstandard", targeturl)
'''
# SIGNAL FOR NEWS
'''
@receiver(post_save, sender=News)
def save_news(sender, instance, **kwargs):
if(kwargs["created"]):
@ -313,9 +328,10 @@ def save_news(sender, instance, **kwargs):
else:
instance.agnotify = False
instance.save()
'''
# SIGNALS FOR TASK
'''
@receiver(signal=m2m_changed, sender=Tasks.usersfield.through)
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.save()
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."})
#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."})
# A USER WAS ADDED TO A GROUP
elif(action == 'post_add'):
newnotification = UserNotification(touser=user_touched, notificationtext="Sie wurden der Tätigkeit " + taskname + " zugeordnet.", notificationtype="taskchange")
newnotification.save()
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."})
#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."})
# E-MAILNOTIFICATIONS FOR GROUPCHANGES
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'):
notificationtext = "Sie wurden der Tätigkeit " + taskname + " zugeordnet."
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=""):
usersofagency = User.objects.filter(profile__agency__pk=instance.agency.pk)
'''
# CREATED
for user in usersofagency:
# LOAD USERNOTIFICATIONS
created_mail = 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.save()
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})
#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})
# UPDATED
elif(mode == 1):
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.save()
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})
#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})
#DELETE
elif(mode == 2):
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.save()
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})
#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})
'''
# DIRS
@receiver(post_save, sender=DataDir)
def save_dir(sender, instance, **kwargs):
@ -544,7 +560,7 @@ def save_agjoin_prep(sender, instance, **kwargs):
def receiver_function(sender, **kwargs):
# DELETES ALL PRESENCE-OBJECTS LOWER THAN 15 MINUTES
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()
@ -559,17 +575,19 @@ def receiver_function(sender, **kwargs):
# PRESENCE CHANGED
'''
@receiver(signal=presence_changed)
def update_presence_live(sender, **kwargs):
channel_layer = channels.layers.get_channel_layer()
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
'''
@receiver(signal=post_save, sender=Absence)
def save_newabsence(sender, instance, **kwargs):
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.save()
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!"})
#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!"})
# Benutzer ist Vertreter
if(user == instance.representator):
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.save()
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!"})
#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!"})
# ABWESENHEIT GEÄNDERT
else:
@ -698,8 +716,8 @@ def save_newabsence(sender, instance, **kwargs):
newnotification = UserNotification(touser=user, notificationtext="Aktualisierte Abwesenheit!", notificationtype="", elementid=instance.pk)
newnotification.save()
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)("user_" + str(user.pk), {'type' : 'pushhandler', 'pushtext' : "pushnotification__Abwesenheit | Abwesenheit für " + instance.user.first_name + " " + instance.user.last_name + " wurde aktualisiert!"})
#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!"})
# Benutzer ist Vertreter
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.save()
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!"})
#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!"})
else:
# 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():
if u != instance.author:
if u.usernotifications.chat_received_push and u not in sended_users:
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})
#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})
sended_users.append(u)
for u in instance.room.chatmembers_admin.all():
if u != instance.author:
if u.usernotifications.chat_received_push and u not in sended_users:
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})
#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})
sended_users.append(u)
@ -746,8 +764,9 @@ def new_chat_message(sender, instance, **kwargs):
u = instance.room.chatmember_single
if u.usernotifications.chat_received_push and u != instance.author:
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})
pass
#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{
background-color: #f8f9fc;
padding-top: 70px;
}
.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-->
<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>
<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/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">
<!-- 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="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>-->
<!-- CROPPER -->
<link href="{% static 'users/css/cropper.min.css' %}" type="text/css" rel="stylesheet">
<!-- DATATABLES -->
<!--<link href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css" type="text/css" rel="stylesheet">-->
<link href="{% 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">
<!-- Custom styles for this template-->
@ -50,63 +37,32 @@
<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="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>
<!-- 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>
<!-- 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="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="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>
<!-- Custom scripts for all pages-->
<script type="text/javascript" src="{%static 'users/js/sb-admin-2.js' %}"></script>
<!-- CUSTOM FONT -->
<!--<link href="{% static 'users/css/custom.css' %}" rel="stylesheet">-->
<!-- TABLE SORT -->
<!--<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>-->
<!-- 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>
<body>
<!-- Page Wrapper -->
<div id="wrapper" >
<!-- 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 %}
<style type="text/css">
.trail_arrow {
@ -128,231 +84,37 @@
}
</style>
<div class="trail_arrow">
<!-- <div class="trail_arrow">
{% getTrialDays request.user.profile.agency as trialdays %}
<span class="trail_font"><nobr><b>TRIAL ({{trialdays}})</b></nobr>
</span>
</div>
</div>-->
{% endif %}
<!-- Sidebar - Brand -->
<!--
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="{% url 'users-dashboard' %}">
-->
<!--<i class="fas fa-laptop"></i>
<div class="sidebar-brand-text mx-2" style="">Digitale Agentur</div>-->
<img src="{% static 'users/img/logo_neu.png' %}" width="100%">
</a>
<!--<img src="{% static 'users/img/logo_neu.png' %}" width="100%">-->
<!--</a>-->
<!-- Divider -->
<hr class="sidebar-divider my-0">
<!--<hr class="sidebar-divider my-0">-->
<!-- 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) -->
<!--
<div class="text-center d-none d-md-inline">
<button class="rounded-circle border-0" id="sidebarToggle"></button>
</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">
{% 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 ">
<!--<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>-->
<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>
<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>
</div>
</div>
</ul>
</ul>-->
<!-- End of Sidebar -->
<!-- Content Wrapper -->
<style scoped>
<!--<style scoped>
.sidebar{
overflow-y: auto;
overflow-x: hidden;
@ -413,30 +175,31 @@
}*/
</style>
<div id="content-wrapper">
-->
<!-- Main Content -->
<!-- Topbar -->
<nav id="topnavbarmain" class="navbar navbar-expand navbar-light bg-white topbar fixed-top mb-4 static-top shadow" style="margin-left: 224px;">
<!--<nav id="topnavbarmain" class="navbar navbar-expand navbar-light bg-white topbar fixed-top mb-4 static-top shadow" style="">-->
<!-- 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>
</button>
</button>-->
<!-- 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">
<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">
-->
<!--
<div class="input-group-append">
<button class="btn btn-primary" type="button" onclick="javascript:clearSF()" id="agencysearch_button" disabled="">
<span id="agencysearch_icon">
<i class="fas fa-search"></i>
<!--<i class="fas fa-times fa-sm"></i>-->
</span>
</button>
</div>
@ -447,7 +210,7 @@
background-color: #5a5c69 !important;
border-color: #5a5c69 !important;
}
</style>
</style>-->
{% getUserIsRep request.user as repstring %}
{% if repstring != False %}
@ -480,52 +243,31 @@
</script>
<!-- Topbar Navbar -->
<ul class="navbar-nav ml-auto ">
<!--<ul class="navbar-nav ml-auto ">-->
<!-- 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 -->
<!-- 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">
<i class="fas fa-bell fa-fw"></i>
<i class="fas fa-bell fa-fw"></i>-->
<!-- Counter - Alerts -->
<span class="badge badge-danger badge-counter" id="notificationcounter"></span>
</a>
<!--<span class="badge badge-danger badge-counter" id="notificationcounter"></span>
</a>-->
<!-- Dropdown - Alerts -->
<!--
<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">
Benachrichtigungen
</h6>
</h6>-->
<!-- ITEMS -->
<span id="notification_items"></span>
<!--<span id="notification_items"></span>-->
<!-- ITEMS END -->
<a class="dropdown-item text-center small text-gray-500" href="{% url 'showallnotificaions' %}">Alle Benachrichtigungen ansehen</a>
</div>
</li>
<!--<a class="dropdown-item text-center small text-gray-500" href="{% url 'showallnotificaions' %}">Alle Benachrichtigungen ansehen</a>
</div>-->
<!--/li>-->
<style type="text/css">
{% getonlinestatuscolor request.user as onlinecolor %}
.roundimg_base {
@ -535,16 +277,19 @@
box-shadow: 0px 0px 4px 5px {{onlinecolor}};
}
</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 -->
<!--
<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">
<span class="mr-2 d-none d-lg-inline text-gray-600 small">{{request.user.first_name}} {{request.user.last_name}}
</span>
<img id="userbaseprofilepicture" class="img-profile roundimg_base ml-2" src="{{ request.user.profile.get_photo_url }}">
</a>
</a>-->
<!-- 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="#/">
<i class="fas fa-circle mr-2" style="color: green"></i>
Online
@ -561,13 +306,14 @@
<i class="fas fa-circle mr-2" style="color: grey"></i>
Offline anzeigen
</a>
<div class="dropdown-divider"></div>
<!--<a class="dropdown-item" onclick="userGoToSettings({{user.pk}})" href="{% url 'orga-single' user.pk %}">-->
-->
<!--<div class="dropdown-divider"></div>-->
<!--<a class="dropdown-item" onclick="userGoToSettings({{user.pk}})" href="{% url 'orga-single' user.pk %}">
<a class="dropdown-item" onclick="userGoToSettings()" href="#/">
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
Einstellungen
</a>
<a class="dropdown-item" onclick="userGoToNotification()" href="#/">
<i class="fas fa-bell fa-sm fa-fw mr-2 text-gray-400"></i>
Benachrichtigungen
@ -581,18 +327,18 @@
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
Abmelden
</a>
</div>
</li>
</ul>
</nav>
</div>-->
<!--</li>-->
<!--</ul>-->
<!--</nav>-->
<!-- End of Topbar -->
<!-- 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 id="maincontent" style="min-height: 100%; margin-top: 85px;" >
<div id="maincontent" style="min-height: 100%; " >
<!-- MESSAGES -->
{% if messages %}
{% for message in messages %}
@ -610,26 +356,6 @@
<div style="height: 300px">&nbsp;</div>
</div> <!-- End of Main Content CONTAINER FLUID-->
<!-- End of Content Wrapper -->
{% if active_link != 'chat' %}
{% if request.user.profile.agency.module_chat %}
<div id="chat_alluserscontent" style="position: fixed; bottom: 75px; right: 36px; z-index: 999;"></div>
<button id="chatButton" class="btn btn-primary" style="position: fixed; right: 36px; bottom: 30px;"><i class="far fa-comments"></i></button>
<!-- CHATAREA -->
<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>
<!-- SUMMERNOTE ADDED CSS -->
@ -642,21 +368,7 @@
}
</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-->
<a class="scroll-to-top rounded" href="#page-top">
<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
/*
function toggleSidebar(){
if(sidebar_hidden == false){
$("#accordionSidebar").removeClass("toggled");
@ -785,7 +490,7 @@ $( window ).resize(function() {
$("#topnavbarmain").css("margin-left" , "224px");
sidebar_hidden = true;
}
});
});*/
/*
AJAX CALL FOR NOTIFICATIONS
@ -875,7 +580,7 @@ $(document).on('click', function (e) {
<!-- WEBSOCKETS -->
<script type="text/javascript">
/*
$(document).ready(function(){
$("#chat_alluserscontent").hide();
@ -897,10 +602,7 @@ $(document).ready(function(){
//HANDLER FOR ALL PUSHNOTIFICATIONS
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(" ");
if(finalsplit[0] != "Chat"){
@ -1048,7 +750,7 @@ $("#chatButton").click(function(){
}
});
});
*/
</script>
<!-- Billstatus -->

View File

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

View File

@ -1,56 +1,14 @@
{% 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(){
{% load static %}
<html>
<body>
<h4>Sie werden gleich zur neuen Login-Seite der Digitalen Agentur weitergeleitet. Sollte dies nicht gehen, klicken Sie auf folgenden Link:</h4>
<a href="https://cloud.digitale-agentur.com/">https://cloud.digitale-agentur.com/</a>
</body>
</html>
<script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
<script>
$(document).ready(function(){
window.location.replace("https://cloud.digitale-agentur.com/external/1");
localStorage.clear();
})
</script>
{% endblock content %}
</script>

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 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 %}
{% load static %}
<script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
<script>
$(document).ready(function(){
window.location.replace("cloud.digitale-agentur.com/external/1");
localStorage.clear();
})
</script>

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 -->
{% 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 %}
{% load static %}
<script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
<script>
$(document).ready(function(){
window.location.replace("cloud.digitale-agentur.com/external/1");
localStorage.clear();
})
</script>

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 -->
{% 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 %}
{% load static %}
<script src="{%static 'users/js/jquery.js' %}" type="text/javascript"></script>
<script>
$(document).ready(function(){
window.location.replace("cloud.digitale-agentur.com/external/1");
localStorage.clear();
})
</script>

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 = [
path('nclog/<str:uid>', views.ncLogin, name='nclog'),
path('', views.dashboard, name='users-dashboard'),
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/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>/delete', permission_required('users.usermanager')(ProfileDeleteView.as_view()), name='users-delete'),
path('usersman/gd/<int:pk>', views.getDataFromToDelUser, name="users-delete-getdata"),
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('prioupdate/', views.UsersPrioUpdate, name="users-prioupdate"),
path('areataskupdate/<int:pk>/', views.UsersAreaTaskUpdate, name="users-areataskupdate"),
path('globalsearch/', views.GlobalSearch, name="globalsearch"),
path('standardrout/', views.searchStandardRouter, name="standardrouter"),
@ -46,9 +41,9 @@ urlpatterns = [
path('icsall/<int:ag>', views.getICSFileAll, name="geticsall"),
path('icspublic/<slug:code>/<int:ag>', views.getICSFileEx, name="getics"),
path('icspublicall/<slug:code>/<int:ag>', views.getICSFileExAll, name="geticsall"),
path('updateuserorga/', views.UpdateUserOrga, name="update-user-orga")
#path('recalculateabsence/<slug:code>', views.recalculateAbsence, name="recalculateabsence"),
path('updateuserorga/', views.UpdateUserOrga, name="update-user-orga"),
# 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 organizer.models import AGContacts, AGPassword
import sys, os
from asgiref.sync import async_to_sync
from channels_presence.models import Room
from channels_presence.models import Presence
import channels.layers
#from asgiref.sync import async_to_sync
#from channels_presence.models import Room
#from channels_presence.models import Presence
#import channels.layers
from datetime import date, timedelta
from timemanagement.models import Workday, Absence, Breaks
import base64
import filetype
from django.db.models.signals import m2m_changed
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 digitaleagentur.utils import *
from digitaleagentur.timemanagement_utils import *
@ -67,6 +67,175 @@ import base64
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):
if 'HTTP_AUTHORIZATION' in request.META:
auth = request.META['HTTP_AUTHORIZATION'].split()
@ -222,45 +391,6 @@ def getICSFileExAll(request, code, ag):
response.status_code = 404
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.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...")
users_of_agency = User.objects.filter(profile__agency__pk=request.user.profile.agency.pk)
for user in users_of_agency:
@ -425,7 +563,7 @@ def toUpdate(request):
#print("recoverdirgroup added and perms set")
# 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]
perms = AgencyGroup._meta.permissions
@ -434,7 +572,7 @@ def toUpdate(request):
ag_admingroup.group.permissions.add(tempperm)
'''
# INITIAL ROOT DIR
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")
pass
'''
# CHANGE RIGHTS ORGNAIZER
admingroups = AgencyGroup.objects.filter(is_admin=True)
for a in admingroups:
@ -478,7 +616,7 @@ def toUpdate(request):
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
usersofagency = User.objects.filter(profile__agency=request.user.profile.agency)
@ -757,6 +895,7 @@ def showUserLog(request, pk):
context = {}
return render(request, 'users/userlog_forbidden.html', context)
@login_required
def dashboard(request):
# UPDATE FUNCTIONS BY NEW MODEL-CHANGES FOR COPIEN SOME DATA
@ -1119,10 +1258,19 @@ class ProfileDeleteView(LoginRequiredMixin, DeleteView):
a.published_by = logged_user
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)
name = user.first_name + " " + user.last_name
messages.success(request, f'Benutzer ' +name+ ' wurde gelöscht!')
return response
# Saves a new User in parent of others Users.