diff --git a/.DS_Store b/.DS_Store index c945451..ed20b16 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/digitaleagentur/__pycache__/settings.cpython-38.pyc b/digitaleagentur/__pycache__/settings.cpython-38.pyc index ee9c2b4..48a02aa 100644 Binary files a/digitaleagentur/__pycache__/settings.cpython-38.pyc and b/digitaleagentur/__pycache__/settings.cpython-38.pyc differ diff --git a/digitaleagentur/__pycache__/urls.cpython-38.pyc b/digitaleagentur/__pycache__/urls.cpython-38.pyc index 6ac02f8..1bcbb61 100644 Binary files a/digitaleagentur/__pycache__/urls.cpython-38.pyc and b/digitaleagentur/__pycache__/urls.cpython-38.pyc differ diff --git a/digitaleagentur/__pycache__/views.cpython-38.pyc b/digitaleagentur/__pycache__/views.cpython-38.pyc index 952c571..a8d9815 100644 Binary files a/digitaleagentur/__pycache__/views.cpython-38.pyc and b/digitaleagentur/__pycache__/views.cpython-38.pyc differ diff --git a/digitaleagentur/settings.py b/digitaleagentur/settings.py index bdb6542..22a4d84 100644 --- a/digitaleagentur/settings.py +++ b/digitaleagentur/settings.py @@ -42,6 +42,10 @@ MAILINFOKEY = "jka7sd8iukashdna78skduJAHDsu6dilaksdjba65a68iadbhjak" # API KEY LEXOFFICE LEX_API = "8f9ba01f-9e84-42c7-9548-48c254f14c19" +# KEYS FOR ENCRYPTED FILE FIELDS +DEFF_SALT = 'A-!GDtuKp?H/H5-UUatEh6ZcG/6h-VQf1OkDORRkK0(:(qCf//' +DEFF_PASSWORD = 'i8#vKXbrgHfdrPGns+O1n!s15bAF(3SE8tFNXuAGC0INHRo+EI' +DEFF_FETCH_URL_NAME = 'getdoc' #ALLOWED_HOSTS = ['digitale-agentur.com', 'www.digitale-agentur.com', '127.0.0.1', '192.168.178.101','localhost', 'dev01.digitale-agentur.com', '10.0.2.2'] # FORWARD HEADERS @@ -204,9 +208,6 @@ MEDIA_URL = '/media/' # CRISPY CRISPY_TEMPLATE_PACK = 'bootstrap4' -# Bildspeicherpfad -MEDIA_ROOT = os.path.join(BASE_DIR, 'media') -MEDIA_URL = '/media/' # FOR COLORFIELD GRAPPELLI_CLEAN_INPUT_TYPES = False diff --git a/digitaleagentur/urls.py b/digitaleagentur/urls.py index 65b6711..2ae371b 100644 --- a/digitaleagentur/urls.py +++ b/digitaleagentur/urls.py @@ -5,8 +5,12 @@ from django.conf import settings from django.conf.urls.static import static from users.views import AgencyCreateView, registerNewAgency from . import views +from .views import GetCryptFile from django.contrib.auth.decorators import login_required from rest_framework.authtoken.views import obtain_auth_token +from django_encrypted_filefield.constants import FETCH_URL_NAME +from django.conf.urls import url + urlpatterns = [ path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'), @@ -35,6 +39,8 @@ urlpatterns = [ path('api/', include('api.urls', namespace='api')), path('chat/', include('chat.urls'), name='chat'), path('api-token-auth/', obtain_auth_token, name='api-token-auth'), + path('getdoc/', GetCryptFile.as_view(), name=FETCH_URL_NAME), + ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/digitaleagentur/views.py b/digitaleagentur/views.py index 0875363..83565ff 100644 --- a/digitaleagentur/views.py +++ b/digitaleagentur/views.py @@ -1,4 +1,106 @@ from django.shortcuts import render +from django.contrib.auth.mixins import AccessMixin +from django.views.generic import CreateView, ListView, UpdateView, DetailView, DeleteView +import requests +import magic +from django.conf import settings +from django.core.validators import URLValidator, ValidationError +from django.http import Http404, HttpResponse +from django.views.generic import View +import base64 +from cryptography.fernet import Fernet +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC +import os, six + + +def _get_setting(name): + setting_name = "DEFF_{}".format(name) + return os.getenv(setting_name, getattr(settings, setting_name, None)) + + +def get_bytes(v): + + if isinstance(v, six.string_types): + return bytes(v.encode("utf-8")) + + if isinstance(v, bytes): + return v + + raise TypeError( + "SALT & PASSWORD must be specified as strings that convert nicely to " + "bytes." + ) + + +SALT = get_bytes(_get_setting("SALT")) +PASSWORD = get_bytes(_get_setting("PASSWORD")) +FETCH_URL_NAME = _get_setting("FETCH_URL_NAME") + +class Cryptographer(object): + + _fernet = Fernet(base64.urlsafe_b64encode(PBKDF2HMAC( + algorithm=hashes.SHA256(), + length=32, + salt=SALT, + iterations=100000, + backend=default_backend() + ).derive(PASSWORD))) + + @classmethod + def encrypted(cls, content): + return cls._fernet.encrypt(content) + + @classmethod + def decrypted(cls, content): + return cls._fernet.decrypt(content) def registerdone(request): - return render (request, 'users/registercomplete.html') \ No newline at end of file + return render (request, 'users/registercomplete.html') + + + +class GetCryptFile(DetailView): + + def get(self, request, *args, **kwargs): + + if(self.request.user.has_perm("users.recoverdirmanager")): + + path = kwargs.get("path") + + # No path? You're boned. Move along. + if not path: + raise Http404 + + if self._is_url(path): + content = requests.get(path, stream=True).raw.read() + + else: + # Normalise the path to strip out naughty attempts + path = os.path.normpath(path).replace(settings.MEDIA_URL, settings.MEDIA_ROOT, 1) + path = "media/" + path + # Evil path request! + #if not path.startswith(settings.MEDIA_ROOT): + # print("404 startswith") + # raise Http404 + + # The file requested doesn't exist locally. A legit 404 + if not os.path.exists(path): + raise Http404 + + with open(path, "rb") as f: + content = f.read() + + content = Cryptographer.decrypted(content) + return HttpResponse(content, content_type=magic.Magic(mime=True).from_buffer(content)) + else: + return render(request, 'cloud/noentrie.html') + + @staticmethod + def _is_url(path): + try: + URLValidator()(path) + return True + except ValidationError: + return False diff --git a/media/.DS_Store b/media/.DS_Store new file mode 100644 index 0000000..d809409 Binary files /dev/null and b/media/.DS_Store differ diff --git a/recoverdir/forms.py b/recoverdir/forms.py index 5c77f37..025ee80 100644 --- a/recoverdir/forms.py +++ b/recoverdir/forms.py @@ -1,6 +1,7 @@ from django import forms from django.forms import ModelForm -from .models import PersLetter +from .models import * +from bootstrap_datepicker_plus import DatePickerInput class PersLetterForm(forms.ModelForm): @@ -16,4 +17,79 @@ class PersLetterForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(PersLetterForm, self).__init__(*args, **kwargs) self.fields['text'] = forms.CharField(label="Ihr persönlicher Text", widget=forms.Textarea(attrs={"rows":15, "cols":35})) - \ No newline at end of file + + +# NOTFALLORDNER FORMS +# 1 Handlungsleitfaden +class HLForm(forms.ModelForm): + + class Meta: + model = Handlungsleitfaden + fields = ['rd_main','rd_prename','rd_postname','rd_street','rd_plz','rd_city','rd_tel','rd_mail','bvk_number','rv_name','rv_number','rv_tel_1','rv_tel_2'] + + labels = { + 'rd_main' : "Zuständige RD", + 'rd_prename': "Vorname RD Leiter", + 'rd_postname' : "Nachname RD Leiter", + 'rd_street' : "RD Straße", + 'rd_plz' : "RD PLZ", + 'rd_city' : "RD Stadt", + 'rd_tel' : "RD Telefon", + 'rd_mail' : "RD E-Mail", + 'bvk_number' : "BVK Nummer", + 'rv_name' : "Rechtsschutzversicherer", + 'rv_number' : "Versicherungsnummer", + 'rv_tel_1' : "Telefon 1", + 'rv_tel_2' : "Telefon 2" + } + +class RDContactF(forms.ModelForm): + + class Meta: + model = RDContact + + fields = ['rd_prename','rd_postname','rd_rel','rd_adresse','rd_tel'] + + labels = { + 'rd_prename' : "Vorname", + 'rd_postname' : "Nachname", + 'rd_rel' : "Beziehung", + 'rd_adresse' : "Adresse", + 'rd_tel' : "Telefon" + } + +class RDTrustPersonF(forms.ModelForm): + + class Meta: + model = RDTrustPerson + + fields = ['rd_prename','rd_postname','rd_company','rd_adresse','rd_tel'] + + labels = { + 'rd_prename' : "Vorname", + 'rd_postname' : "Nachname", + 'rd_company' : "Firma", + 'rd_adresse' : "Adresse", + 'rd_tel' : "Telefon" + } + + + +# DOCUMENTS +class DocumentForm(forms.ModelForm): + + class Meta: + model = Documents + fields = ['document_desc', 'document_date', 'document_name','document', 'area'] + labels = { + 'document_desc' : "Dokumentbeschreibung", + 'document_date' : "Datum", + "document_name" : "Dateiname", + 'document' : "Dokument" + } + widgets = { + 'document_date': DatePickerInput(options={"format":'DD.MM.YYYY', "locale":'de'}) + } + def __init__(self, *args, **kwargs): + super(DocumentForm, self).__init__(*args, **kwargs) + self.fields['area'] = forms.CharField(initial="", required=False, widget=forms.HiddenInput()) \ No newline at end of file diff --git a/recoverdir/models.py b/recoverdir/models.py index ee4fd6e..296e962 100644 --- a/recoverdir/models.py +++ b/recoverdir/models.py @@ -7,6 +7,17 @@ from django_cryptography.fields import encrypt # HISTORY from simple_history.models import HistoricalRecords +from django_encrypted_filefield.fields import ( + EncryptedFileField, + EncryptedImageField +) + +# PATH FOR AGENCYPIC +def rd_path_agency(instance, filename): + # file will be uploaded to MEDIA_URL/agency_// + return 'agencydata/agency_{0}/rd/{1}'.format(instance.agency.pk, filename) + + # Create your models here. class PersLetter(models.Model): @@ -15,3 +26,52 @@ class PersLetter(models.Model): text = encrypt(models.CharField(max_length=100000, blank=True, default="", null=True)) history = HistoricalRecords() +# Notfallordner Datenfelder +# Handlungsleitfaden +class Handlungsleitfaden(models.Model): + agency = models.ForeignKey(Agency, on_delete=models.CASCADE, null=True) + rd_main = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_prename = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_postname = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_street = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_plz = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_city = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_tel = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_mail = encrypt(models.EmailField(max_length=500, blank=True, default="", null=True)) + bvk_number = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rv_name = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rv_number = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rv_tel_1 = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rv_tel_2 = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + history = HistoricalRecords() + +# Contacts +class RDContact(models.Model): + agency = models.ForeignKey(Agency, on_delete=models.CASCADE, null=True) + rd_prename = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_postname = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_rel = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_adresse = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_tel = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + history = HistoricalRecords() + +class RDTrustPerson(models.Model): + agency = models.ForeignKey(Agency, on_delete=models.CASCADE, null=True) + rd_prename = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_postname = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_company = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_adresse = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + rd_tel = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + history = HistoricalRecords() + +class Documents(models.Model): + agency = models.ForeignKey(Agency, on_delete=models.CASCADE, null=True) + area = models.IntegerField(default=0) + document_desc = encrypt(models.CharField(max_length=500, blank=True, default="", null=True)) + document_name = encrypt(models.CharField(max_length=500, blank=False, default="", null=False)) + document_date = encrypt(models.DateField(default=timezone.now, blank=True, null=True)) + document = EncryptedFileField(upload_to=rd_path_agency, blank=True) + history = HistoricalRecords() + + + diff --git a/recoverdir/templates/recoverdir/rd_areas/rd_area_1.html b/recoverdir/templates/recoverdir/rd_areas/rd_area_1.html new file mode 100644 index 0000000..aee45f5 --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_areas/rd_area_1.html @@ -0,0 +1,157 @@ + +{% if area_1_hl == None %} + Handlungsleitfaden +{% else %} +

Handlungsleitfaden bearbeiten

+{% endif %} + +
+

Familie und Freunde + Kontakt +

+ + + + + + + + + + + + {% for familyc in area_1_fc %} + + + + + + + + {% endfor %} + +
NameBeziehungAdresseTelefon 
{{familyc.rd_prename}} {{familyc.rd_postname}}{{familyc.rd_rel}}{{familyc.rd_adresse}}{{familyc.rd_tel}} 
+ +
+

Vertrauensperson + Vertrauensperson +

+ + + + + + + + + + + + {% for familyc in area_1_trust %} + + + + + + + + {% endfor %} + +
NameFirmaAdresseTelefon 
{{familyc.rd_prename}} {{familyc.rd_postname}}{{familyc.rd_company}}{{familyc.rd_adresse}}{{familyc.rd_tel}} 
+ +
+

Vorsorgedokumente + Vorsorgedokument +

+ + + + + + + + + + + {% for doc in area_1_doc %} + + + + + + + {% endfor %} + +
NameDatumBeschreibung 
{{doc.document_name}}{{doc.document_date|date:"d.m.Y"}}{{doc.document_desc}} +   +   + +
+ + + \ No newline at end of file diff --git a/recoverdir/templates/recoverdir/rd_areas/rd_area_2.html b/recoverdir/templates/recoverdir/rd_areas/rd_area_2.html new file mode 100644 index 0000000..db79ceb --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_areas/rd_area_2.html @@ -0,0 +1 @@ +ZWEITE \ No newline at end of file diff --git a/recoverdir/templates/recoverdir/rd_areas/rd_area_3.html b/recoverdir/templates/recoverdir/rd_areas/rd_area_3.html new file mode 100644 index 0000000..39e684b --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_areas/rd_area_3.html @@ -0,0 +1 @@ +DRIITTE \ No newline at end of file diff --git a/recoverdir/templates/recoverdir/rd_areas/rd_area_4.html b/recoverdir/templates/recoverdir/rd_areas/rd_area_4.html new file mode 100644 index 0000000..4413e6a --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_areas/rd_area_4.html @@ -0,0 +1 @@ +VIERTE \ No newline at end of file diff --git a/recoverdir/templates/recoverdir/rd_areas/rd_area_5.html b/recoverdir/templates/recoverdir/rd_areas/rd_area_5.html new file mode 100644 index 0000000..38b3d8d --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_areas/rd_area_5.html @@ -0,0 +1 @@ +FÜNFTE \ No newline at end of file diff --git a/recoverdir/templates/recoverdir/rd_areas/rd_area_6.html b/recoverdir/templates/recoverdir/rd_areas/rd_area_6.html new file mode 100644 index 0000000..a79236c --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_areas/rd_area_6.html @@ -0,0 +1 @@ +SECHSTE \ No newline at end of file diff --git a/recoverdir/templates/recoverdir/rd_areas/rd_area_7.html b/recoverdir/templates/recoverdir/rd_areas/rd_area_7.html new file mode 100644 index 0000000..163172b --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_areas/rd_area_7.html @@ -0,0 +1 @@ +SIEBTE \ No newline at end of file diff --git a/recoverdir/templates/recoverdir/rd_areas/rd_area_8.html b/recoverdir/templates/recoverdir/rd_areas/rd_area_8.html new file mode 100644 index 0000000..c9a0ad1 --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_areas/rd_area_8.html @@ -0,0 +1 @@ +ACHTE \ No newline at end of file diff --git a/recoverdir/templates/recoverdir/rd_areas/rd_area_9.html b/recoverdir/templates/recoverdir/rd_areas/rd_area_9.html new file mode 100644 index 0000000..2cd0d2f --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_areas/rd_area_9.html @@ -0,0 +1 @@ +NEUNTE \ No newline at end of file diff --git a/recoverdir/templates/recoverdir/rd_doc_single.html b/recoverdir/templates/recoverdir/rd_doc_single.html new file mode 100644 index 0000000..b570e62 --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_doc_single.html @@ -0,0 +1,21 @@ +{% extends "users/base.html" %} +{% block content %} +{% if request.user.profile.agency.module_recoverdir %} +
+

Dokumentenansicht + + + +

+
+

Beschreibung

+

{{document.document_desc}}

+

Datum: {{document.document_date}}

+
+ Datei herunterladen +
+
+{% else %} +

Auf dieses Modul haben Sie keinen Zugriff!

+{% endif %} +{% endblock content %} \ No newline at end of file diff --git a/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_adddoc.html b/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_adddoc.html new file mode 100644 index 0000000..0cf9db5 --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_adddoc.html @@ -0,0 +1,27 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +{% if request.user.profile.agency.module_recoverdir %} +
+

Vorsorgedokument hinzufügen

+
+
+ {% csrf_token %} + {{form.media}} + {{ form|crispy }} +
+ Abbrechen +   +
+
+ +{% else %} +

Das Modul Notfallordner wurden in ihrer Agentur deaktiviert.

+{% endif %} +{% endblock content %} diff --git a/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_addfc.html b/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_addfc.html new file mode 100644 index 0000000..f018363 --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_addfc.html @@ -0,0 +1,20 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +{% if request.user.profile.agency.module_recoverdir %} +
+

Familien/Freundekontakt bearbeiten

+
+
+ {% csrf_token %} + {{form.media}} + {{form|crispy}} +
+ Abbrechen +   +
+
+{% else %} +

Das Modul Notfallordner wurden in ihrer Agentur deaktiviert.

+{% endif %} +{% endblock content %} diff --git a/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_addhl.html b/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_addhl.html new file mode 100644 index 0000000..04b341a --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_addhl.html @@ -0,0 +1,38 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +{% if request.user.profile.agency.module_recoverdir %} +
+

Handlungsleitfaden bearbeiten

+
+
+ {% csrf_token %} + {{form.media}} + +

Daten der Regionaldirektion

+ {{form.rd_main|as_crispy_field}} + {{form.rd_prename|as_crispy_field}} + {{form.rd_postname|as_crispy_field}} + {{form.rd_street|as_crispy_field}} + {{form.rd_plz|as_crispy_field}} + {{form.rd_city|as_crispy_field}} + {{form.rd_tel|as_crispy_field}} + {{form.rd_mail|as_crispy_field}} +
+

BVK Mitgliedsnummer

+ {{form.bvk_number|as_crispy_field}} +
+

Rechtsschutzersicherungsdaten

+ {{form.rv_name|as_crispy_field}} + {{form.rv_number|as_crispy_field}} + {{form.rv_tel_1|as_crispy_field}} + {{form.rv_tel_2|as_crispy_field}} +
+ Abbrechen +   +
+
+{% else %} +

Das Modul Notfallordner wurden in ihrer Agentur deaktiviert.

+{% endif %} +{% endblock content %} diff --git a/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_addtrust.html b/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_addtrust.html new file mode 100644 index 0000000..ecd0607 --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_elements_forms/rd_area_1_addtrust.html @@ -0,0 +1,20 @@ +{% extends "users/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +{% if request.user.profile.agency.module_recoverdir %} +
+

Vertraunsperson bearbeiten

+
+
+ {% csrf_token %} + {{form.media}} + {{form|crispy}} +
+ Abbrechen +   +
+
+{% else %} +

Das Modul Notfallordner wurden in ihrer Agentur deaktiviert.

+{% endif %} +{% endblock content %} diff --git a/recoverdir/templates/recoverdir/rd_management.html b/recoverdir/templates/recoverdir/rd_management.html index 16d0e74..483b275 100644 --- a/recoverdir/templates/recoverdir/rd_management.html +++ b/recoverdir/templates/recoverdir/rd_management.html @@ -33,7 +33,11 @@
- Notfallordner +
Notfallordner{% if request.user.profile.showtooltips %} {% endif %}
+
+ {% block rd_content %} + {% include "recoverdir/rd_rd.html" %} + {% endblock %}
diff --git a/recoverdir/templates/recoverdir/rd_rd.html b/recoverdir/templates/recoverdir/rd_rd.html new file mode 100644 index 0000000..76bc076 --- /dev/null +++ b/recoverdir/templates/recoverdir/rd_rd.html @@ -0,0 +1,257 @@ + +
+ +
+
+
+ + +

#1

+
+
+
+ +
+
+ {% block rd_area_1 %} + {% include "recoverdir/rd_areas/rd_area_1.html" %} + {% endblock %} +
+
+
+ + + +
+
+
+ + +

#2

+
+
+
+ +
+
+ {% block rd_area_2 %} + {% include "recoverdir/rd_areas/rd_area_2.html" %} + {% endblock %} +
+
+
+ + +
+
+
+ + +

#3

+
+
+
+ +
+
+ {% block rd_area_3 %} + {% include "recoverdir/rd_areas/rd_area_3.html" %} + {% endblock %} +
+
+
+ + +
+
+
+ + +

#4

+
+
+
+ +
+
+ {% block rd_area_4 %} + {% include "recoverdir/rd_areas/rd_area_4.html" %} + {% endblock %} +
+
+
+ + + + +
+
+
+ + +

#5

+
+
+
+ +
+
+ {% block rd_area_5 %} + {% include "recoverdir/rd_areas/rd_area_5.html" %} + {% endblock %} +
+
+
+ + +
+
+
+ + +

#6

+
+
+
+ +
+
+ {% block rd_area_6 %} + {% include "recoverdir/rd_areas/rd_area_6.html" %} + {% endblock %} +
+
+
+ + +
+
+
+ + +

#7

+
+
+
+ +
+
+ {% block rd_area_7 %} + {% include "recoverdir/rd_areas/rd_area_7.html" %} + {% endblock %} +
+
+
+ + +
+
+
+ + +

#8

+
+
+
+ +
+
+ {% block rd_area_8 %} + {% include "recoverdir/rd_areas/rd_area_8.html" %} + {% endblock %} +
+
+
+ + +
+
+
+ + +

#9

+
+
+
+ +
+
+ {% block rd_area_9 %} + {% include "recoverdir/rd_areas/rd_area_9.html" %} + {% endblock %} +
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/recoverdir/templates/recoverdir/rd_updates.html b/recoverdir/templates/recoverdir/rd_updates.html index bbb00c4..7489dbc 100644 --- a/recoverdir/templates/recoverdir/rd_updates.html +++ b/recoverdir/templates/recoverdir/rd_updates.html @@ -9,10 +9,13 @@ - {% for plver in persletter.history.all %} + {% for ele in history %} + {% for plver in ele.history.all %} - Persönlicher Brief - {{plver.history_date|date:"d.m.Y H:i"}} + + {% getClassOfObject plver as plver_typ %} + {{plver}} {{plver_typ}} + {{plver.history_date|date:"d.m.Y H:i"}} {% gethistoryuser plver.history_user_id as history_user %} @@ -24,6 +27,7 @@ {% if plver.history_type == "~" %} Geändert {% elif plver.history_type == "+" %} Erstellt {% elif plver.history_type == "-"%} Gelöscht {% endif %} + {% endfor %} {% endfor %} @@ -48,7 +52,8 @@ "pageLength": 50, "buttons" : { "className" : "btn-danger" - } + }, + "order": [[ 1, "desc" ]] }); diff --git a/recoverdir/urls.py b/recoverdir/urls.py index 06b9203..27d296f 100644 --- a/recoverdir/urls.py +++ b/recoverdir/urls.py @@ -1,6 +1,9 @@ from django.urls import path from django.contrib.auth import views as auth_views from django.contrib.auth.decorators import login_required, permission_required + +from django_encrypted_filefield.constants import FETCH_URL_NAME + from .views import * ''' Permissions definiert in models.py bei USERS und dann hier vor die View geschrieben! @@ -11,7 +14,10 @@ urlpatterns = [ path('addpl/', permission_required('users.recoverdirmanager')(RecoverDirAddPL.as_view(template_name="recoverdir/rd_pers_add.html")), name='recoverdir-addpl'), path('updatepl/', permission_required('users.recoverdirmanager')(RecoverDirUpdatePL.as_view(template_name="recoverdir/rd_pers_update.html")), name='recoverdir-updatepl'), path('pl/ver//', permission_required('users.recoverdirmanager')(PLSingle.as_view(template_name="recoverdir/rd_persletter_single.html")), name='recoverdir-plsingle'), - - - + path('aone/doc/add', permission_required('users.recoverdirmanager')(RDAoneAddDoc.as_view()), name='rd-a1-adddoc'), + path('aone/doc/', permission_required('users.recoverdirmanager')(RDAoneViewDoc.as_view()), name='rd-a1-viewdoc'), + path('aone/hl/add', permission_required('users.recoverdirmanager')(RDAoneAddHL.as_view()), name='rd-a1-hl'), + path('aone/hl/update/', permission_required('users.recoverdirmanager')(RDAoneUpdateHL.as_view()), name='rd-a1-hl-update'), + path('aone/fc/add', permission_required('users.recoverdirmanager')(RDAoneAddFC.as_view()), name='rd-a1-addfamily'), + path('aone/trust/add', permission_required('users.recoverdirmanager')(RDAoneAddTrust.as_view()), name='rd-a1-addtrust'), ] \ No newline at end of file diff --git a/recoverdir/views.py b/recoverdir/views.py index 4cfe626..ae6c77b 100644 --- a/recoverdir/views.py +++ b/recoverdir/views.py @@ -4,6 +4,14 @@ from django.views.generic import CreateView, ListView, UpdateView, DetailView, D from .models import * from .forms import * from django.urls import reverse_lazy +from django.contrib.auth.decorators import login_required +import os +import sys +from django.conf import settings +from django.http import JsonResponse, HttpResponse, Http404 +from django_encrypted_filefield.views import FetchView +import string, random +from itertools import chain # Create your views here. class RecoverDirManagement(LoginRequiredMixin, ListView): @@ -19,6 +27,38 @@ class RecoverDirManagement(LoginRequiredMixin, ListView): persletter = PersLetter.objects.filter(agency=self.request.user.profile.agency)[0] context.update({'persletter' : persletter}) + # Load Update-Historys + persletters = PersLetter.objects.filter(agency=self.request.user.profile.agency) + handlungsleitfaden = Handlungsleitfaden.objects.filter(agency=self.request.user.profile.agency) + contactfc = RDContact.objects.filter(agency=self.request.user.profile.agency) + contactstrust = RDTrustPerson.objects.filter(agency=self.request.user.profile.agency) + documents = Documents.objects.filter(agency=self.request.user.profile.agency, area=1) + + finalupdatelist = chain(persletters, handlungsleitfaden, contactfc, contactstrust, documents) + context.update({"history" : finalupdatelist}) + + print(finalupdatelist) + + # Bereich 1 - Handlungsleitfaden ########## ########## ########## ########## ########## ########## + # Handlungsleitfaden + hl = Handlungsleitfaden.objects.filter(agency=self.request.user.profile.agency) + if(len(hl) == 1): + hl = Handlungsleitfaden.objects.filter(agency=self.request.user.profile.agency)[0] + else: + hl = None + context.update({'area_1_hl' : hl}) + + # Familien-Freunde + context.update({'area_1_fc' : RDContact.objects.filter(agency=self.request.user.profile.agency)}) + + # Vertrauensperson + context.update({'area_1_trust' : RDTrustPerson.objects.filter(agency=self.request.user.profile.agency)}) + + + # Dokumente + context.update({'area_1_doc' : Documents.objects.filter(agency=self.request.user.profile.agency, area=1).order_by('-document_date')}) + + return context @@ -63,6 +103,7 @@ class RecoverDirAddPL(CreateView): # TASK: Hier Aktualisierung hinzufügen! return super().form_valid(form) + class RecoverDirUpdatePL(UpdateView): model = PersLetter success_url = reverse_lazy('recoverdir') @@ -79,3 +120,108 @@ class RecoverDirUpdatePL(UpdateView): return super().form_valid(form) +def randomString(stringLength=40): + """Generate a random string of fixed length """ + letters = string.ascii_lowercase + return ''.join(random.choice(letters) for i in range(stringLength)) + +# NOTFALLORDNER ELEMENTE + +# ABNSCHNITT 1 +class RDAoneAddDoc(CreateView): + model = Documents + success_url = reverse_lazy('recoverdir') + form_class = DocumentForm + template_name = "recoverdir/rd_elements_forms/rd_area_1_adddoc.html" + + def form_valid(self, form): + form.instance.agency = self.request.user.profile.agency + form.instance.area = 1 + + # Randomize File-Name keeping extension + file = self.request.FILES['document'] + file_ext_arr = file.name.split(".") + file_ext = file_ext_arr[len(file_ext_arr)-1] + file.name = randomString() + "." + file_ext + form.instance.document = file + return super().form_valid(form) + + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context.update({'active_link' : 'recoverdir'}) + return context + +# Einzeldokumentenanzeige +class RDAoneViewDoc(DetailView): + model = Documents + success_url = reverse_lazy('recoverdir') + template_name = 'recoverdir/rd_doc_single.html' + context_object_name = 'document' + +# Handlungsleitfaden +# ABNSCHNITT 1 +class RDAoneAddHL(CreateView): + model = Handlungsleitfaden + success_url = reverse_lazy('recoverdir') + form_class = HLForm + template_name = "recoverdir/rd_elements_forms/rd_area_1_addhl.html" + + def form_valid(self, form): + form.instance.agency = self.request.user.profile.agency + return super().form_valid(form) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context.update({'active_link' : 'recoverdir'}) + return context + +class RDAoneUpdateHL(UpdateView): + model = Handlungsleitfaden + success_url = reverse_lazy('recoverdir') + form_class = HLForm + template_name = "recoverdir/rd_elements_forms/rd_area_1_addhl.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context.update({'active_link' : 'recoverdir'}) + return context + + +class RDAoneAddFC(CreateView): + model = RDContact + success_url = reverse_lazy('recoverdir') + form_class = RDContactF + template_name = "recoverdir/rd_elements_forms/rd_area_1_addfc.html" + + def form_valid(self, form): + form.instance.agency = self.request.user.profile.agency + return super().form_valid(form) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context.update({'active_link' : 'recoverdir'}) + return context + + + + +class RDAoneAddTrust(CreateView): + model = RDTrustPerson + success_url = reverse_lazy('recoverdir') + form_class = RDTrustPersonF + template_name = "recoverdir/rd_elements_forms/rd_area_1_addtrust.html" + + def form_valid(self, form): + form.instance.agency = self.request.user.profile.agency + return super().form_valid(form) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context.update({'active_link' : 'recoverdir'}) + return context + + + + + diff --git a/requirements.txt b/requirements.txt index 50f0ffd..810c5d6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -28,4 +28,6 @@ django-cryptography==1.0 channels-redis==3.0.1 filetype==1.0.7 python-dateutil==2.8.1 -django-simple-history==2.11.0 \ No newline at end of file +django-simple-history==2.11.0 +django-encrypted-filefield==0.2.2 +more-itertools==8.5.0 diff --git a/standards/templatetags/__pycache__/counter_tag.cpython-38.pyc b/standards/templatetags/__pycache__/counter_tag.cpython-38.pyc index c4a6978..ba12a7b 100644 Binary files a/standards/templatetags/__pycache__/counter_tag.cpython-38.pyc and b/standards/templatetags/__pycache__/counter_tag.cpython-38.pyc differ diff --git a/standards/templatetags/counter_tag.py b/standards/templatetags/counter_tag.py index a78f947..566146e 100644 --- a/standards/templatetags/counter_tag.py +++ b/standards/templatetags/counter_tag.py @@ -742,6 +742,10 @@ def gethistoryuser(userid): last_user = None return last_user +@register.simple_tag +def getClassOfObject(value): + return value.__class__.__name__ + diff --git a/timemanagement/templates/timemanagement/realtime_dropdown.html b/timemanagement/templates/timemanagement/realtime_dropdown.html index f85c479..a9b8304 100644 --- a/timemanagement/templates/timemanagement/realtime_dropdown.html +++ b/timemanagement/templates/timemanagement/realtime_dropdown.html @@ -239,7 +239,7 @@ Gleitzeitkonto: } start = data["wd_starttime_complete"]; realTimeClock(); - location.href = location.href; + //location.href = location.href; } }); diff --git a/users/admin.py b/users/admin.py index b10c8d7..cd584c2 100644 --- a/users/admin.py +++ b/users/admin.py @@ -8,7 +8,7 @@ from cloud.models import DataFile from organizer.models import AGContacts from timemanagement.models import Workday, Breaks, AbsenceReason, FreeDays, Absence from chat.models import ChatRoom -from recoverdir.models import PersLetter +from recoverdir.models import PersLetter, Documents, Handlungsleitfaden, RDContact from simple_history.admin import SimpleHistoryAdmin @@ -37,4 +37,6 @@ admin.site.register(ChatRoom) admin.site.register(UserNotifications) admin.site.register(AgencyBills) admin.site.register(PersLetter, SimpleHistoryAdmin) - +admin.site.register(Documents, SimpleHistoryAdmin) +admin.site.register(Handlungsleitfaden) +admin.site.register(RDContact) \ No newline at end of file diff --git a/users/templates/users/dashboard.html b/users/templates/users/dashboard.html index a2bdf63..5841003 100644 --- a/users/templates/users/dashboard.html +++ b/users/templates/users/dashboard.html @@ -55,7 +55,7 @@ Titel Bearbeitet von - Zuletzt bearbeitet am + Bearbeitet am {% for standard in standards_of_agency %} diff --git a/users/usersforms.py b/users/usersforms.py index cdac851..f437cc3 100644 --- a/users/usersforms.py +++ b/users/usersforms.py @@ -156,8 +156,7 @@ SUPPORT_DEP = ( ('12', 'Technischer Support'), ('13', 'Abrechnung'), ('14', 'Lob, Kritik und Anregung'), - - ) +) class SupportForm(forms.Form): def __init__(self, user, *args, **kwargs):