diff --git a/ema/models/__init__.py b/ema/models/__init__.py new file mode 100644 index 0000000..77fe9d7 --- /dev/null +++ b/ema/models/__init__.py @@ -0,0 +1,9 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" + +from .ema import * diff --git a/ema/models.py b/ema/models/ema.py similarity index 96% rename from ema/models.py rename to ema/models/ema.py index b35cda3..5c7e9fc 100644 --- a/ema/models.py +++ b/ema/models/ema.py @@ -1,3 +1,10 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" import shutil from django.db import models diff --git a/konova/models/__init__.py b/konova/models/__init__.py new file mode 100644 index 0000000..c60ecaa --- /dev/null +++ b/konova/models/__init__.py @@ -0,0 +1,11 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" +from .object import * +from .deadline import * +from .document import * +from .geometry import * diff --git a/konova/models/deadline.py b/konova/models/deadline.py new file mode 100644 index 0000000..7cad8a6 --- /dev/null +++ b/konova/models/deadline.py @@ -0,0 +1,49 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from konova.models import BaseResource + + +class DeadlineType(models.TextChoices): + """ + Django 3.x way of handling enums for models + """ + FINISHED = "finished", _("Finished") + MAINTAIN = "maintain", _("Maintain") + CONTROL = "control", _("Control") + OTHER = "other", _("Other") + + +class Deadline(BaseResource): + """ + Defines a deadline, which can be used to define dates with a semantic meaning + """ + + type = models.CharField(max_length=255, null=True, blank=True, choices=DeadlineType.choices) + date = models.DateField(null=True, blank=True) + comment = models.TextField(null=True, blank=True) + + def __str__(self): + return self.type + + @property + def type_humanized(self): + """ Returns humanized version of enum + + Used for template rendering + + Returns: + + """ + choices = DeadlineType.choices + for choice in choices: + if choice[0] == self.type: + return choice[1] + return None diff --git a/konova/models/document.py b/konova/models/document.py new file mode 100644 index 0000000..11b6c06 --- /dev/null +++ b/konova/models/document.py @@ -0,0 +1,84 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" +import os + +from django.db import models + +from konova.models import BaseResource +from konova.settings import INTERVENTION_REVOCATION_DOC_PATH + + +def generate_document_file_upload_path(instance, filename): + """ Generates the file upload path for certain document instances + + Documents derived from AbstractDocument need specific upload paths for their related models. + + Args: + instance (): The document instance + filename (): The filename + + Returns: + + """ + from compensation.models import CompensationDocument, EcoAccountDocument + from ema.models import EmaDocument + from intervention.models import InterventionDocument, RevocationDocument + from konova.settings import ECO_ACCOUNT_DOC_PATH, EMA_DOC_PATH, \ + COMPENSATION_DOC_PATH, \ + INTERVENTION_DOC_PATH + + # Map document types to paths on the hard drive + path_map = { + InterventionDocument: INTERVENTION_DOC_PATH, + CompensationDocument: COMPENSATION_DOC_PATH, + EmaDocument: EMA_DOC_PATH, + RevocationDocument: INTERVENTION_REVOCATION_DOC_PATH, + EcoAccountDocument: ECO_ACCOUNT_DOC_PATH, + } + path = path_map.get(instance.__class__, None) + if path is None: + raise NotImplementedError("Unidentified document type: {}".format(instance.__class__)) + + # RevocationDocument needs special treatment, since these files need to be stored in a subfolder of the related + # instance's (Revocation) legaldata interventions folder + if instance.__class__ is RevocationDocument: + path = path.format(instance.intervention.id) + else: + path = path.format(instance.instance.id) + return path + filename + + +class AbstractDocument(BaseResource): + """ + Documents can be attached to compensation or intervention for uploading legal documents or pictures. + """ + title = models.CharField(max_length=500, null=True, blank=True) + date_of_creation = models.DateField() + file = models.FileField() + comment = models.TextField() + + class Meta: + abstract = True + + def delete(self, using=None, keep_parents=False): + """ Custom delete function to remove the real file from the hard drive + + Args: + using (): + keep_parents (): + + Returns: + + """ + try: + os.remove(self.file.file.name) + except FileNotFoundError: + # File seems to missing anyway - continue! + pass + super().delete(using=using, keep_parents=keep_parents) + diff --git a/konova/models/geometry.py b/konova/models/geometry.py new file mode 100644 index 0000000..736e1b3 --- /dev/null +++ b/konova/models/geometry.py @@ -0,0 +1,18 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" +from django.contrib.gis.db.models import MultiPolygonField + +from konova.models import BaseResource + + +class Geometry(BaseResource): + """ + Outsourced geometry model so multiple versions of the same object can refer to the same geometry if it is not changed + """ + from konova.settings import DEFAULT_SRID + geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID) \ No newline at end of file diff --git a/konova/models.py b/konova/models/object.py similarity index 75% rename from konova/models.py rename to konova/models/object.py index 7dbe4f7..7546e70 100644 --- a/konova/models.py +++ b/konova/models/object.py @@ -2,25 +2,21 @@ Author: Michel Peltriaux Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany Contact: michel.peltriaux@sgdnord.rlp.de -Created on: 17.11.20 +Created on: 15.11.21 """ -import os + import uuid from django.contrib.auth.models import User from django.core.exceptions import ObjectDoesNotExist from django.utils import timezone from django.utils.timezone import now -from django.utils.translation import gettext_lazy as _ -from django.contrib.gis.db.models import MultiPolygonField from django.db import models, transaction - from compensation.settings import COMPENSATION_IDENTIFIER_TEMPLATE, COMPENSATION_IDENTIFIER_LENGTH, \ ECO_ACCOUNT_IDENTIFIER_TEMPLATE, ECO_ACCOUNT_IDENTIFIER_LENGTH from ema.settings import EMA_ACCOUNT_IDENTIFIER_LENGTH, EMA_ACCOUNT_IDENTIFIER_TEMPLATE from intervention.settings import INTERVENTION_IDENTIFIER_LENGTH, INTERVENTION_IDENTIFIER_TEMPLATE -from konova.settings import INTERVENTION_REVOCATION_DOC_PATH from konova.utils import generators from konova.utils.generators import generate_random_string from user.models import UserActionLogEntry, UserAction @@ -224,122 +220,6 @@ class BaseObject(BaseResource): return definitions[self.__class__]["template"].format(_str) -class DeadlineType(models.TextChoices): - """ - Django 3.x way of handling enums for models - """ - FINISHED = "finished", _("Finished") - MAINTAIN = "maintain", _("Maintain") - CONTROL = "control", _("Control") - OTHER = "other", _("Other") - - -class Deadline(BaseResource): - """ - Defines a deadline, which can be used to define dates with a semantic meaning - """ - - type = models.CharField(max_length=255, null=True, blank=True, choices=DeadlineType.choices) - date = models.DateField(null=True, blank=True) - comment = models.TextField(null=True, blank=True) - - def __str__(self): - return self.type - - @property - def type_humanized(self): - """ Returns humanized version of enum - - Used for template rendering - - Returns: - - """ - choices = DeadlineType.choices - for choice in choices: - if choice[0] == self.type: - return choice[1] - return None - - -def generate_document_file_upload_path(instance, filename): - """ Generates the file upload path for certain document instances - - Documents derived from AbstractDocument need specific upload paths for their related models. - - Args: - instance (): The document instance - filename (): The filename - - Returns: - - """ - from compensation.models import CompensationDocument, EcoAccountDocument - from ema.models import EmaDocument - from intervention.models import InterventionDocument, RevocationDocument - from konova.settings import ECO_ACCOUNT_DOC_PATH, EMA_DOC_PATH, \ - COMPENSATION_DOC_PATH, \ - INTERVENTION_DOC_PATH - - # Map document types to paths on the hard drive - path_map = { - InterventionDocument: INTERVENTION_DOC_PATH, - CompensationDocument: COMPENSATION_DOC_PATH, - EmaDocument: EMA_DOC_PATH, - RevocationDocument: INTERVENTION_REVOCATION_DOC_PATH, - EcoAccountDocument: ECO_ACCOUNT_DOC_PATH, - } - path = path_map.get(instance.__class__, None) - if path is None: - raise NotImplementedError("Unidentified document type: {}".format(instance.__class__)) - - # RevocationDocument needs special treatment, since these files need to be stored in a subfolder of the related - # instance's (Revocation) legaldata interventions folder - if instance.__class__ is RevocationDocument: - path = path.format(instance.intervention.id) - else: - path = path.format(instance.instance.id) - return path + filename - - -class AbstractDocument(BaseResource): - """ - Documents can be attached to compensation or intervention for uploading legal documents or pictures. - """ - title = models.CharField(max_length=500, null=True, blank=True) - date_of_creation = models.DateField() - file = models.FileField() - comment = models.TextField() - - class Meta: - abstract = True - - def delete(self, using=None, keep_parents=False): - """ Custom delete function to remove the real file from the hard drive - - Args: - using (): - keep_parents (): - - Returns: - - """ - try: - os.remove(self.file.file.name) - except FileNotFoundError: - # File seems to missing anyway - continue! - pass - super().delete(using=using, keep_parents=keep_parents) - - -class Geometry(BaseResource): - """ - Outsourced geometry model so multiple versions of the same object can refer to the same geometry if it is not changed - """ - from konova.settings import DEFAULT_SRID - geom = MultiPolygonField(null=True, blank=True, srid=DEFAULT_SRID) - - class RecordableObject(models.Model): """ Wraps record related fields and functionality @@ -518,4 +398,4 @@ class ShareableObject(models.Model): self.generate_access_token(make_unique, rec_depth) else: self.access_token = token - self.save() + self.save() \ No newline at end of file diff --git a/user/models/__init__.py b/user/models/__init__.py new file mode 100644 index 0000000..85a98b6 --- /dev/null +++ b/user/models/__init__.py @@ -0,0 +1,10 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" +from .user_action import * +from .konova_user import * +from .notification import * diff --git a/user/models/konova_user.py b/user/models/konova_user.py new file mode 100644 index 0000000..b100e02 --- /dev/null +++ b/user/models/konova_user.py @@ -0,0 +1,19 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" +from django.contrib.auth.models import User +from django.db import models + + +class KonovaUserExtension(models.Model): + """ Extension model for additional ksp features + + Extends the default user model for some extras + + """ + user = models.OneToOneField(User, on_delete=models.CASCADE) + notifications = models.ManyToManyField("user.UserNotification", related_name="+") diff --git a/user/models/notification.py b/user/models/notification.py new file mode 100644 index 0000000..c86b84b --- /dev/null +++ b/user/models/notification.py @@ -0,0 +1,34 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" +from django.db import models + +from user.enums import UserNotificationEnum + + +class UserNotification(models.Model): + """ Notifications for users + + """ + id = models.CharField( + max_length=500, + null=False, + blank=False, + choices=UserNotificationEnum.as_choices(drop_empty_choice=True), + primary_key=True, + ) + name = models.CharField( + max_length=500, + null=False, + blank=False, + unique=True, + help_text="Human readable name" + ) + is_active = models.BooleanField(default=True, help_text="Can be toggle to enable/disable this notification for all users") + + def __str__(self): + return self.name \ No newline at end of file diff --git a/user/models.py b/user/models/user_action.py similarity index 65% rename from user/models.py rename to user/models/user_action.py index a85159f..a37aab5 100644 --- a/user/models.py +++ b/user/models/user_action.py @@ -1,44 +1,15 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" import uuid -from django.utils.translation import gettext_lazy as _ from django.contrib.auth.models import User from django.db import models - -from user.enums import UserNotificationEnum - - -class UserNotification(models.Model): - """ Notifications for users - - """ - id = models.CharField( - max_length=500, - null=False, - blank=False, - choices=UserNotificationEnum.as_choices(drop_empty_choice=True), - primary_key=True, - ) - name = models.CharField( - max_length=500, - null=False, - blank=False, - unique=True, - help_text="Human readable name" - ) - is_active = models.BooleanField(default=True, help_text="Can be toggle to enable/disable this notification for all users") - - def __str__(self): - return self.name - - -class KonovaUserExtension(models.Model): - """ Extension model for additional ksp features - - Extends the default user model for some extras - - """ - user = models.OneToOneField(User, on_delete=models.CASCADE) - notifications = models.ManyToManyField(UserNotification, related_name="+") +from django.utils.translation import gettext_lazy as _ class UserAction(models.TextChoices):