mpeltriaux
36f0603a3b
* removes fundings from all models, except the EMA model for migration compatibility (some old data may have fundings data)
145 lines
4.7 KiB
Python
145 lines
4.7 KiB
Python
import shutil
|
|
|
|
from django.db import models
|
|
from django.db.models import QuerySet
|
|
|
|
from codelist.models import KonovaCode
|
|
from codelist.settings import CODELIST_COMPENSATION_FUNDING_ID
|
|
from compensation.models import AbstractCompensation
|
|
from ema.managers import EmaManager
|
|
from ema.utils.quality import EmaQualityChecker
|
|
from konova.models import AbstractDocument, generate_document_file_upload_path, RecordableObject, ShareableObject
|
|
from konova.settings import DEFAULT_SRID_RLP, LANIS_LINK_TEMPLATE
|
|
|
|
|
|
class Ema(AbstractCompensation, ShareableObject, RecordableObject):
|
|
"""
|
|
EMA = Ersatzzahlungsmaßnahme
|
|
(compensation actions from payments)
|
|
|
|
Until 2015 the EMA was the data object to keep track of any compensation, which has been funded by payments
|
|
previously paid. In 2015 another organization got in charge of this, which led to the creation of the data object
|
|
MAE (which is basically the same, just renamed in their system) to differ between the 'old' payment funded ones and
|
|
the new. For historical reasons, we need to keep EMAs in our system, since there are still entries done to this day,
|
|
which have been performed somewhere before 2015 and therefore needs to be entered.
|
|
Further information:
|
|
https://snu.rlp.de/de/foerderungen/massnahmen-aus-ersatzzahlungen/uebersicht-mae/
|
|
|
|
EMA therefore holds data like a compensation: actions, before-/after-states, deadlines, ...
|
|
|
|
"""
|
|
fundings = models.ManyToManyField(
|
|
KonovaCode,
|
|
blank=True,
|
|
limit_choices_to={
|
|
"code_lists__in": [CODELIST_COMPENSATION_FUNDING_ID],
|
|
"is_selectable": True,
|
|
"is_archived": False,
|
|
},
|
|
help_text="List of funding project codes",
|
|
)
|
|
objects = EmaManager()
|
|
|
|
def __str__(self):
|
|
return "{}".format(self.identifier)
|
|
|
|
def save(self, *args, **kwargs):
|
|
if self.identifier is None or len(self.identifier) == 0:
|
|
# Create new identifier
|
|
new_id = self.generate_new_identifier()
|
|
while Ema.objects.filter(identifier=new_id).exists():
|
|
new_id = self.generate_new_identifier()
|
|
self.identifier = new_id
|
|
super().save(*args, **kwargs)
|
|
|
|
def get_LANIS_link(self) -> str:
|
|
""" Generates a link for LANIS depending on the geometry
|
|
|
|
Returns:
|
|
|
|
"""
|
|
try:
|
|
geom = self.geometry.geom.transform(DEFAULT_SRID_RLP, clone=True)
|
|
x = geom.centroid.x
|
|
y = geom.centroid.y
|
|
zoom_lvl = 16
|
|
except AttributeError:
|
|
# If no geometry has been added, yet.
|
|
x = 1
|
|
y = 1
|
|
zoom_lvl = 6
|
|
return LANIS_LINK_TEMPLATE.format(
|
|
zoom_lvl,
|
|
x,
|
|
y,
|
|
)
|
|
|
|
def quality_check(self) -> EmaQualityChecker:
|
|
""" Quality check
|
|
|
|
Returns:
|
|
ret_msgs (EmaQualityChecker): Holds validity error messages
|
|
"""
|
|
checker = EmaQualityChecker(self)
|
|
checker.run_check()
|
|
return checker
|
|
|
|
def get_documents(self) -> QuerySet:
|
|
""" Getter for all documents of an EMA
|
|
|
|
Returns:
|
|
docs (QuerySet): The queryset of all documents
|
|
"""
|
|
docs = EmaDocument.objects.filter(
|
|
instance=self
|
|
)
|
|
return docs
|
|
|
|
|
|
class EmaDocument(AbstractDocument):
|
|
"""
|
|
Specializes document upload for ema with certain path
|
|
"""
|
|
instance = models.ForeignKey(
|
|
Ema,
|
|
on_delete=models.CASCADE,
|
|
related_name="documents",
|
|
)
|
|
file = models.FileField(
|
|
upload_to=generate_document_file_upload_path,
|
|
max_length=1000,
|
|
)
|
|
|
|
def delete(self, *args, **kwargs):
|
|
"""
|
|
Custom delete functionality for EcoAccountDocuments.
|
|
Removes the folder from the file system if there are no further documents for this entry.
|
|
|
|
Args:
|
|
*args ():
|
|
**kwargs ():
|
|
|
|
Returns:
|
|
|
|
"""
|
|
ema_docs = self.instance.get_documents()
|
|
|
|
folder_path = None
|
|
if ema_docs.count() == 1:
|
|
# The only file left for this EMA is the one which is currently processed and will be deleted
|
|
# Make sure that the compensation folder itself is deleted as well, not only the file
|
|
# Therefore take the folder path from the file path
|
|
folder_path = self.file.path.split("/")[:-1]
|
|
folder_path = "/".join(folder_path)
|
|
|
|
# Remove the file itself
|
|
super().delete(*args, **kwargs)
|
|
|
|
# If a folder path has been set, we need to delete the whole folder!
|
|
if folder_path is not None:
|
|
try:
|
|
shutil.rmtree(folder_path)
|
|
except FileNotFoundError:
|
|
# Folder seems to be missing already...
|
|
pass
|