Compare commits

..

No commits in common. "617d969a10fe26d22ae9ef1d9c928a06ef1d37f2" and "314879a1fe985fdbf31891856bd9cf275d0b4beb" have entirely different histories.

12 changed files with 123 additions and 790 deletions

View File

@ -52,6 +52,7 @@ class AbstractModelAPISerializer:
""" """
raise NotImplementedError("Must be implemented in subclasses") raise NotImplementedError("Must be implemented in subclasses")
@abstractmethod
def prepare_lookup(self, _id, user): def prepare_lookup(self, _id, user):
""" Updates lookup dict for db fetching """ Updates lookup dict for db fetching
@ -62,12 +63,7 @@ class AbstractModelAPISerializer:
Returns: Returns:
""" """
if _id is None: self.lookup["id"] = _id
# Return all objects
del self.lookup["id"]
else:
# Return certain objects
self.lookup["id"] = _id
self.lookup["users__in"] = [user] self.lookup["users__in"] = [user]
def fetch_and_serialize(self): def fetch_and_serialize(self):
@ -78,10 +74,8 @@ class AbstractModelAPISerializer:
Returns: Returns:
serialized_data (dict) serialized_data (dict)
""" """
entries = self.model.objects.filter(**self.lookup) entry = self.model.objects.get(**self.lookup)
serialized_data = {} serialized_data = self.model_to_geo_json(entry)
for entry in entries:
serialized_data[str(entry.id)] = self.model_to_geo_json(entry)
return serialized_data return serialized_data
@abstractmethod @abstractmethod
@ -140,19 +134,4 @@ class AbstractModelAPISerializer:
return self.model.objects.get( return self.model.objects.get(
id=id, id=id,
users__in=[user] users__in=[user]
) )
@abstractmethod
def initialize_objects(self, json_model, user):
""" Initializes all needed objects from the json_model data
Does not persist data to the DB!
Args:
json_model (dict): The json data
user (User): The API user
Returns:
obj (Intervention)
"""
raise NotImplementedError("Must be implemented in subclasses")

View File

@ -5,21 +5,15 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 24.01.22 Created on: 24.01.22
""" """
from django.db import transaction from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1
from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin
from compensation.models import Compensation from compensation.models import Compensation
from intervention.models import Intervention
from konova.models import Geometry
from konova.tasks import celery_update_parcels
from user.models import UserActionLogEntry
class CompensationAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin): class CompensationAPISerializerV1(AbstractModelAPISerializerV1):
model = Compensation model = Compensation
def prepare_lookup(self, id, user): def prepare_lookup(self, id, user):
super().prepare_lookup(id, user) self.lookup["id"] = id
del self.lookup["users__in"] del self.lookup["users__in"]
self.lookup["intervention__users__in"] = [user] self.lookup["intervention__users__in"] = [user]
@ -37,149 +31,4 @@ class CompensationAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensa
self.properties_data["before_states"] = self.compensation_state_to_json(entry.before_states.all()) self.properties_data["before_states"] = self.compensation_state_to_json(entry.before_states.all())
self.properties_data["after_states"] = self.compensation_state_to_json(entry.after_states.all()) self.properties_data["after_states"] = self.compensation_state_to_json(entry.after_states.all())
self.properties_data["actions"] = self.compensation_actions_to_json(entry.actions.all()) self.properties_data["actions"] = self.compensation_actions_to_json(entry.actions.all())
self.properties_data["deadlines"] = self.deadlines_to_json(entry.deadlines.all()) self.properties_data["deadlines"] = self.deadlines_to_json(entry.deadlines.all())
def initialize_objects(self, json_model, user):
""" Initializes all needed objects from the json_model data
Does not persist data to the DB!
Args:
json_model (dict): The json data
user (User): The API user
Returns:
obj (Compensation)
"""
create_action = UserActionLogEntry.get_created_action(user, comment="API Import")
# Create geometry
json_geom = self.create_geometry_from_json(json_model)
geometry = Geometry()
geometry.geom = json_geom
geometry.created = create_action
# Create linked objects
obj = Compensation()
created = create_action
obj.created = created
obj.geometry = geometry
return obj
def set_intervention(self, obj, intervention_id, user):
""" Sets the linked compensation according to the given id
Fails if no such intervention found or user has no shared access
Args:
obj (Compensation): The Compensation object
intervention_id (str): The intervention's id
user (User): The API user
Returns:
obj (Compensation)
"""
if obj.intervention.id == intervention_id:
# Nothing to do here
return obj
intervention = Intervention.objects.get(
id=intervention_id,
)
is_shared = intervention.is_shared_with(user)
if not is_shared:
raise PermissionError("Intervention not shared with user")
obj.intervention = intervention
return obj
def create_model_from_json(self, json_model, user):
""" Creates a new entry for the model based on the contents of json_model
Args:
json_model (dict): The json containing data
user (User): The API user
Returns:
created_id (str): The id of the newly created Compensation entry
"""
with transaction.atomic():
obj = self.initialize_objects(json_model, user)
# Fill in data to objects
properties = json_model["properties"]
obj.identifier = obj.generate_new_identifier()
obj.title = properties["title"]
obj.is_cef = properties["is_cef"]
obj.is_coherence_keeping = properties["is_coherence_keeping"]
obj = self.set_intervention(obj, properties["intervention"], user)
obj.geometry.save()
obj.save()
obj = self.set_compensation_actions(obj, properties["actions"])
obj = self.set_compensation_states(obj, properties["before_states"], obj.before_states)
obj = self.set_compensation_states(obj, properties["after_states"], obj.after_states)
obj = self.set_deadlines(obj, properties["deadlines"])
obj.log.add(obj.created)
celery_update_parcels.delay(obj.geometry.id)
return obj.id
def get_obj_from_db(self, id, user):
""" Returns the object from database
Fails if id not found or user does not have shared access
Args:
id (str): The object's id
user (User): The API user
Returns:
"""
return self.model.objects.get(
id=id,
intervention__users__in=[user]
)
def update_model_from_json(self, id, json_model, user):
""" Updates an entry for the model based on the contents of json_model
Args:
id (str): The object's id
json_model (dict): The json containing data
user (User): The API user
Returns:
created_id (str): The id of the newly created Compensation entry
"""
with transaction.atomic():
update_action = UserActionLogEntry.get_edited_action(user, "API update")
obj = self.get_obj_from_db(id, user)
# Fill in data to objects
properties = json_model["properties"]
obj.title = properties["title"]
obj.is_cef = properties["is_cef"]
obj.is_coherence_keeping = properties["is_coherence_keeping"]
obj.modified = update_action
obj.geometry.geom = self.create_geometry_from_json(json_model)
obj.geometry.modified = update_action
obj = self.set_intervention(obj, properties["intervention"], user)
obj.geometry.save()
obj.save()
obj = self.set_compensation_actions(obj, properties["actions"])
obj = self.set_compensation_states(obj, properties["before_states"], obj.before_states)
obj = self.set_compensation_states(obj, properties["after_states"], obj.after_states)
obj = self.set_deadlines(obj, properties["deadlines"])
obj.log.add(update_action)
celery_update_parcels.delay(obj.geometry.id)
return obj.id

View File

@ -5,22 +5,12 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 24.01.22 Created on: 24.01.22
""" """
from django.db import transaction from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1
from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin, \
LegalAPISerializerV1Mixin, ResponsibilityAPISerializerV1Mixin, DeductableAPISerializerV1Mixin
from compensation.models import EcoAccount from compensation.models import EcoAccount
from intervention.models import Legal, Responsibility from intervention.models import Legal, Responsibility
from konova.models import Geometry
from konova.tasks import celery_update_parcels
from user.models import UserActionLogEntry
class EcoAccountAPISerializerV1(AbstractModelAPISerializerV1, class EcoAccountAPISerializerV1(AbstractModelAPISerializerV1):
AbstractCompensationAPISerializerV1Mixin,
LegalAPISerializerV1Mixin,
ResponsibilityAPISerializerV1Mixin,
DeductableAPISerializerV1Mixin):
model = EcoAccount model = EcoAccount
def extend_properties_data(self, entry): def extend_properties_data(self, entry):
@ -44,115 +34,4 @@ class EcoAccountAPISerializerV1(AbstractModelAPISerializerV1,
"conservation_office": self.konova_code_to_json(responsible.conservation_office), "conservation_office": self.konova_code_to_json(responsible.conservation_office),
"conservation_file_number": responsible.conservation_file_number, "conservation_file_number": responsible.conservation_file_number,
"handler": responsible.handler, "handler": responsible.handler,
} }
def set_legal(self, obj, legal_data):
obj.legal.registration_date = legal_data.get("agreement_date", None)
return obj
def initialize_objects(self, json_model, user):
""" Initializes all needed objects from the json_model data
Does not persist data to the DB!
Args:
json_model (dict): The json data
user (User): The API user
Returns:
obj (Compensation)
"""
create_action = UserActionLogEntry.get_created_action(user, comment="API Import")
# Create geometry
json_geom = self.create_geometry_from_json(json_model)
geometry = Geometry()
geometry.geom = json_geom
geometry.created = create_action
# Create linked objects
obj = EcoAccount()
obj.responsible = Responsibility()
obj.legal = Legal()
created = create_action
obj.created = created
obj.geometry = geometry
return obj
def create_model_from_json(self, json_model, user):
""" Creates a new entry for the model based on the contents of json_model
Args:
json_model (dict): The json containing data
user (User): The API user
Returns:
created_id (str): The id of the newly created EcoAccount entry
"""
with transaction.atomic():
obj = self.initialize_objects(json_model, user)
# Fill in data to objects
properties = json_model["properties"]
obj.identifier = obj.generate_new_identifier()
obj.title = properties["title"]
obj.deductable_surface = float(properties["deductable_surface"])
obj = self.set_responsibility(obj, properties["responsible"])
obj = self.set_legal(obj, properties["legal"])
obj.geometry.save()
obj.responsible.save()
obj.legal.save()
obj.save()
obj = self.set_compensation_actions(obj, properties["actions"])
obj = self.set_compensation_states(obj, properties["before_states"], obj.before_states)
obj = self.set_compensation_states(obj, properties["after_states"], obj.after_states)
obj = self.set_deadlines(obj, properties["deadlines"])
obj.log.add(obj.created)
obj.users.add(user)
celery_update_parcels.delay(obj.geometry.id)
return obj.id
def update_model_from_json(self, id, json_model, user):
""" Updates an entry for the model based on the contents of json_model
Args:
id (str): The object's id
json_model (dict): The json containing data
user (User): The API user
Returns:
created_id (str): The id of the newly created EcoAccount entry
"""
with transaction.atomic():
update_action = UserActionLogEntry.get_edited_action(user, "API update")
obj = self.get_obj_from_db(id, user)
# Fill in data to objects
properties = json_model["properties"]
obj.title = properties["title"]
obj.deductable_surface = float(properties["deductable_surface"])
obj.modified = update_action
obj.geometry.geom = self.create_geometry_from_json(json_model)
obj.geometry.modified = update_action
obj = self.set_responsibility(obj, properties["responsible"])
obj = self.set_legal(obj, properties["legal"])
obj.geometry.save()
obj.responsible.save()
obj.legal.save()
obj.save()
obj = self.set_compensation_actions(obj, properties["actions"])
obj = self.set_compensation_states(obj, properties["before_states"], obj.before_states)
obj = self.set_compensation_states(obj, properties["after_states"], obj.after_states)
obj = self.set_deadlines(obj, properties["deadlines"])
obj.log.add(update_action)
celery_update_parcels.delay(obj.geometry.id)
return obj.id

View File

@ -5,18 +5,12 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 24.01.22 Created on: 24.01.22
""" """
from django.db import transaction from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1
from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin, \
ResponsibilityAPISerializerV1Mixin
from ema.models import Ema from ema.models import Ema
from intervention.models import Responsibility from intervention.models import Responsibility
from konova.models import Geometry
from konova.tasks import celery_update_parcels
from user.models import UserActionLogEntry
class EmaAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin, ResponsibilityAPISerializerV1Mixin): class EmaAPISerializerV1(AbstractModelAPISerializerV1):
model = Ema model = Ema
def responsible_to_json(self, responsible: Responsibility): def responsible_to_json(self, responsible: Responsibility):
@ -32,103 +26,3 @@ class EmaAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensationAPISe
self.properties_data["after_states"] = self.compensation_state_to_json(entry.after_states.all()) self.properties_data["after_states"] = self.compensation_state_to_json(entry.after_states.all())
self.properties_data["actions"] = self.compensation_actions_to_json(entry.actions.all()) self.properties_data["actions"] = self.compensation_actions_to_json(entry.actions.all())
self.properties_data["deadlines"] = self.deadlines_to_json(entry.deadlines.all()) self.properties_data["deadlines"] = self.deadlines_to_json(entry.deadlines.all())
def initialize_objects(self, json_model, user):
""" Initializes all needed objects from the json_model data
Does not persist data to the DB!
Args:
json_model (dict): The json data
user (User): The API user
Returns:
obj (Compensation)
"""
create_action = UserActionLogEntry.get_created_action(user, comment="API Import")
# Create geometry
json_geom = self.create_geometry_from_json(json_model)
geometry = Geometry()
geometry.geom = json_geom
geometry.created = create_action
# Create linked objects
obj = Ema()
obj.responsible = Responsibility()
created = create_action
obj.created = created
obj.geometry = geometry
return obj
def create_model_from_json(self, json_model, user):
""" Creates a new entry for the model based on the contents of json_model
Args:
json_model (dict): The json containing data
user (User): The API user
Returns:
created_id (str): The id of the newly created Ema entry
"""
with transaction.atomic():
obj = self.initialize_objects(json_model, user)
# Fill in data to objects
properties = json_model["properties"]
obj.identifier = obj.generate_new_identifier()
obj.title = properties["title"]
obj = self.set_responsibility(obj, properties["responsible"])
obj.geometry.save()
obj.responsible.save()
obj.save()
obj = self.set_compensation_actions(obj, properties["actions"])
obj = self.set_compensation_states(obj, properties["before_states"], obj.before_states)
obj = self.set_compensation_states(obj, properties["after_states"], obj.after_states)
obj = self.set_deadlines(obj, properties["deadlines"])
obj.log.add(obj.created)
obj.users.add(user)
celery_update_parcels.delay(obj.geometry.id)
return obj.id
def update_model_from_json(self, id, json_model, user):
""" Updates an entry for the model based on the contents of json_model
Args:
id (str): The object's id
json_model (dict): The json containing data
user (User): The API user
Returns:
created_id (str): The id of the newly created Ema entry
"""
with transaction.atomic():
update_action = UserActionLogEntry.get_edited_action(user, "API update")
obj = self.get_obj_from_db(id, user)
# Fill in data to objects
properties = json_model["properties"]
obj.title = properties["title"]
obj.modified = update_action
obj.geometry.geom = self.create_geometry_from_json(json_model)
obj.geometry.modified = update_action
obj = self.set_responsibility(obj, properties["responsible"])
obj.geometry.save()
obj.responsible.save()
obj.save()
obj = self.set_compensation_actions(obj, properties["actions"])
obj = self.set_compensation_states(obj, properties["before_states"], obj.before_states)
obj = self.set_compensation_states(obj, properties["after_states"], obj.after_states)
obj = self.set_deadlines(obj, properties["deadlines"])
obj.log.add(update_action)
celery_update_parcels.delay(obj.geometry.id)
return obj.id

View File

@ -8,19 +8,16 @@ Created on: 24.01.22
from django.db import transaction from django.db import transaction
from django.db.models import QuerySet from django.db.models import QuerySet
from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, \ from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1
ResponsibilityAPISerializerV1Mixin, LegalAPISerializerV1Mixin, DeductableAPISerializerV1Mixin from codelist.settings import CODELIST_CONSERVATION_OFFICE_ID, CODELIST_REGISTRATION_OFFICE_ID, \
from compensation.models import Payment CODELIST_PROCESS_TYPE_ID, CODELIST_LAW_ID
from intervention.models import Intervention, Responsibility, Legal from intervention.models import Intervention, Responsibility, Legal
from konova.models import Geometry from konova.models import Geometry
from konova.tasks import celery_update_parcels from konova.tasks import celery_update_parcels
from user.models import UserActionLogEntry from user.models import UserActionLogEntry
class InterventionAPISerializerV1(AbstractModelAPISerializerV1, class InterventionAPISerializerV1(AbstractModelAPISerializerV1):
ResponsibilityAPISerializerV1Mixin,
LegalAPISerializerV1Mixin,
DeductableAPISerializerV1Mixin):
model = Intervention model = Intervention
def compensations_to_json(self, qs: QuerySet): def compensations_to_json(self, qs: QuerySet):
@ -30,17 +27,6 @@ class InterventionAPISerializerV1(AbstractModelAPISerializerV1,
) )
) )
def payments_to_json(self, qs: QuerySet):
""" Serializes payments into json
Args:
qs (QuerySet): A queryset of Payment entries
Returns:
serialized_json (list)
"""
return list(qs.values("amount", "due_on", "comment"))
def extend_properties_data(self, entry): def extend_properties_data(self, entry):
self.properties_data["responsible"] = self.responsible_to_json(entry.responsible) self.properties_data["responsible"] = self.responsible_to_json(entry.responsible)
self.properties_data["legal"] = self.legal_to_json(entry.legal) self.properties_data["legal"] = self.legal_to_json(entry.legal)
@ -60,76 +46,63 @@ class InterventionAPISerializerV1(AbstractModelAPISerializerV1,
Returns: Returns:
obj (Intervention) obj (Intervention)
""" """
create_action = UserActionLogEntry.get_created_action(user, comment="API Import")
# Create geometry # Create geometry
json_geom = self.create_geometry_from_json(json_model) json_geom = self.create_geometry_from_json(json_model)
geometry = Geometry() geometry = Geometry()
geometry.geom = json_geom geometry.geom = json_geom
geometry.created = create_action
# Create linked objects # Create linked objects
obj = Intervention() obj = Intervention()
resp = Responsibility() resp = Responsibility()
legal = Legal() legal = Legal()
created = create_action created = UserActionLogEntry.get_created_action(user, comment="API Import")
obj.legal = legal obj.legal = legal
obj.created = created obj.created = created
obj.geometry = geometry obj.geometry = geometry
obj.responsible = resp obj.responsible = resp
return obj return obj
def set_payments(self, obj, payment_data): def set_legal(self, obj, legal_data):
""" Sets the linked Payment data according to the given payment_data """ Sets the legal data contents to the provided legal_data dict
Args: Args:
obj (Compensation): The Compensation object obj (Intervention): The intervention object
payment_data (dict): The posted payment_data legal_data (dict): The new data
Returns: Returns:
obj (intervention) obj
""" """
if payment_data is None: obj.legal.registration_date = legal_data["registration_date"]
return obj obj.legal.binding_date = legal_data["binding_date"]
payments = [] obj.legal.process_type = self.konova_code_from_json(
for entry in payment_data: legal_data["process_type"],
due_on = entry["due_on"] CODELIST_PROCESS_TYPE_ID,
amount = float(entry["amount"])
comment = entry["comment"]
# Check on validity
if amount <= 0:
raise ValueError("Payment amount must be > 0")
no_due_on = due_on is None or len(due_on) == 0
no_comment = comment is None or len(comment) == 0
if no_due_on and no_comment:
raise ValueError("If no due_on can be provided, you need to explain why using the comment")
# If this exact data is already existing, we do not create it new. Instead put it's id in the list of
# entries, we will use to set the new actions
pre_existing_payment = obj.payments.filter(
amount=amount,
due_on=due_on,
comment=comment,
).exclude(
id__in=payments
).first()
if pre_existing_payment is not None:
payments.append(pre_existing_payment.id)
else:
# Create and add id to list
new_payment = Payment.objects.create(
amount=amount,
due_on=due_on,
comment=comment,
)
payments.append(new_payment.id)
payments = Payment.objects.filter(
id__in=payments
) )
obj.payments.set(payments) laws = [self.konova_code_from_json(law, CODELIST_LAW_ID) for law in legal_data["laws"]]
obj.legal.laws.set(laws)
return obj
def set_responsibility(self, obj, responsibility_data: dict):
""" Sets the responsible data contents to the provided responsibility_data dict
Args:
obj (Intervention): The intervention object
responsibility_data (dict): The new data
Returns:
obj
"""
obj.responsible.registration_office = self.konova_code_from_json(
responsibility_data["registration_office"],
CODELIST_REGISTRATION_OFFICE_ID
)
obj.responsible.registration_file_number = responsibility_data["registration_file_number"]
obj.responsible.conservation_office = self.konova_code_from_json(
responsibility_data["conservation_office"],
CODELIST_CONSERVATION_OFFICE_ID,
)
obj.responsible.conservation_file_number = responsibility_data["conservation_file_number"]
obj.responsible.handler = responsibility_data["handler"]
return obj return obj
def create_model_from_json(self, json_model, user): def create_model_from_json(self, json_model, user):
@ -158,7 +131,6 @@ class InterventionAPISerializerV1(AbstractModelAPISerializerV1,
obj.save() obj.save()
obj.users.add(user) obj.users.add(user)
obj.log.add(obj.created)
celery_update_parcels.delay(obj.geometry.id) celery_update_parcels.delay(obj.geometry.id)
@ -176,25 +148,21 @@ class InterventionAPISerializerV1(AbstractModelAPISerializerV1,
created_id (str): The id of the newly created Intervention entry created_id (str): The id of the newly created Intervention entry
""" """
with transaction.atomic(): with transaction.atomic():
update_action = UserActionLogEntry.get_edited_action(user, "API update")
obj = self.get_obj_from_db(id, user) obj = self.get_obj_from_db(id, user)
# Fill in data to objects # Fill in data to objects
properties = json_model["properties"] properties = json_model["properties"]
obj.title = properties["title"] obj.title = properties["title"]
obj.modified = update_action self.set_responsibility(obj, properties["responsible"])
self.set_responsibility(obj, properties.get("responsible", None)) self.set_legal(obj, properties["legal"])
self.set_legal(obj, properties.get("legal", None))
self.set_payments(obj, properties.get("payments", None))
obj.geometry.geom = self.create_geometry_from_json(json_model) obj.geometry.geom = self.create_geometry_from_json(json_model)
obj.geometry.modified = update_action
obj.responsible.save() obj.responsible.save()
obj.geometry.save() obj.geometry.save()
obj.legal.save() obj.legal.save()
obj.save() obj.save()
obj.log.add(update_action) obj.users.add(user)
celery_update_parcels.delay(obj.geometry.id) celery_update_parcels.delay(obj.geometry.id)

View File

@ -12,11 +12,7 @@ from django.db.models import QuerySet
from api.utils.serializer.serializer import AbstractModelAPISerializer from api.utils.serializer.serializer import AbstractModelAPISerializer
from codelist.models import KonovaCode from codelist.models import KonovaCode
from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID, CODELIST_PROCESS_TYPE_ID, \
CODELIST_LAW_ID, CODELIST_REGISTRATION_OFFICE_ID, CODELIST_CONSERVATION_OFFICE_ID
from compensation.models import CompensationAction, UnitChoices, CompensationState
from intervention.models import Responsibility, Legal from intervention.models import Responsibility, Legal
from konova.models import Deadline, DeadlineType
class AbstractModelAPISerializerV1(AbstractModelAPISerializer): class AbstractModelAPISerializerV1(AbstractModelAPISerializer):
@ -51,8 +47,6 @@ class AbstractModelAPISerializerV1(AbstractModelAPISerializer):
Returns: Returns:
serialized_json (dict) serialized_json (dict)
""" """
if konova_code is None:
return None
return { return {
"atom_id": konova_code.atom_id, "atom_id": konova_code.atom_id,
"long_name": konova_code.long_name, "long_name": konova_code.long_name,
@ -77,34 +71,49 @@ class AbstractModelAPISerializerV1(AbstractModelAPISerializer):
) )
return code return code
def created_on_to_json(self, entry): def responsible_to_json(self, responsible: Responsibility):
""" Serializes the created_on into json """ Serializes Responsibility model into json
Args: Args:
entry (BaseObject): The entry responsible (Responsibility): The Responsibility entry
Returns: Returns:
created_on (timestamp) serialized_json (dict)
""" """
return entry.created.timestamp if entry.created is not None else None return {
"registration_office": self.konova_code_to_json(responsible.registration_office),
"registration_file_number": responsible.registration_file_number,
"conservation_office": self.konova_code_to_json(responsible.conservation_office),
"conservation_file_number": responsible.conservation_file_number,
"handler": responsible.handler,
}
def modified_on_to_json(self, entry): def legal_to_json(self, legal: Legal):
""" Serializes the modified_on into json """ Serializes Legal model into json
Args: Args:
entry (BaseObject): The entry legal (Legal): The Legal entry
Returns: Returns:
modified_on (timestamp) serialized_json (dict)
""" """
modified_on = entry.modified or entry.created return {
modified_on = modified_on.timestamp if modified_on is not None else None "registration_date": legal.registration_date,
return modified_on "binding_date": legal.binding_date,
"process_type": self.konova_code_to_json(legal.process_type),
"laws": [self.konova_code_to_json(law) for law in legal.laws.all()],
}
def payments_to_json(self, qs: QuerySet):
""" Serializes payments into json
class DeductableAPISerializerV1Mixin: Args:
class Meta: qs (QuerySet): A queryset of Payment entries
abstract = True
Returns:
serialized_json (list)
"""
return list(qs.values("amount", "due_on", "comment"))
def deductions_to_json(self, qs: QuerySet): def deductions_to_json(self, qs: QuerySet):
""" Serializes eco account deductions into json """ Serializes eco account deductions into json
@ -133,234 +142,6 @@ class DeductableAPISerializerV1Mixin:
for entry in qs for entry in qs
] ]
class ResponsibilityAPISerializerV1Mixin:
class Meta:
abstract = True
def responsible_to_json(self, responsible: Responsibility):
""" Serializes Responsibility model into json
Args:
responsible (Responsibility): The Responsibility entry
Returns:
serialized_json (dict)
"""
return {
"registration_office": self.konova_code_to_json(responsible.registration_office),
"registration_file_number": responsible.registration_file_number,
"conservation_office": self.konova_code_to_json(responsible.conservation_office),
"conservation_file_number": responsible.conservation_file_number,
"handler": responsible.handler,
}
def set_responsibility(self, obj, responsibility_data: dict):
""" Sets the responsible data contents to the provided responsibility_data dict
Args:
obj (Intervention): The intervention object
responsibility_data (dict): The new data
Returns:
obj
"""
if responsibility_data is None:
return obj
obj.responsible.registration_office = self.konova_code_from_json(
responsibility_data.get("registration_office", None),
CODELIST_REGISTRATION_OFFICE_ID
)
obj.responsible.registration_file_number = responsibility_data.get("registration_file_number", None)
obj.responsible.conservation_office = self.konova_code_from_json(
responsibility_data.get("conservation_office", None),
CODELIST_CONSERVATION_OFFICE_ID,
)
obj.responsible.conservation_file_number = responsibility_data.get("conservation_file_number", None)
obj.responsible.handler = responsibility_data.get("handler", None)
return obj
class LegalAPISerializerV1Mixin:
class Meta:
abstract = True
def legal_to_json(self, legal: Legal):
""" Serializes Legal model into json
Args:
legal (Legal): The Legal entry
Returns:
serialized_json (dict)
"""
return {
"registration_date": legal.registration_date,
"binding_date": legal.binding_date,
"process_type": self.konova_code_to_json(legal.process_type),
"laws": [self.konova_code_to_json(law) for law in legal.laws.all()],
}
def set_legal(self, obj, legal_data):
""" Sets the legal data contents to the provided legal_data dict
Args:
obj (Intervention): The intervention object
legal_data (dict): The new data
Returns:
obj
"""
if legal_data is None:
return obj
obj.legal.registration_date = legal_data.get("registration_date", None)
obj.legal.binding_date = legal_data.get("binding_date", None)
obj.legal.process_type = self.konova_code_from_json(
legal_data.get("process_type", None),
CODELIST_PROCESS_TYPE_ID,
)
laws = [self.konova_code_from_json(law, CODELIST_LAW_ID) for law in legal_data.get("laws", [])]
obj.legal.laws.set(laws)
return obj
class AbstractCompensationAPISerializerV1Mixin:
class Meta:
abstract = True
def set_deadlines(self, obj, deadline_data):
""" Sets the linked deadline data according to the given deadline_data
Args:
obj (Compensation): The Compensation object
deadline_data (dict): The posted deadline_data
Returns:
obj (Compensation)
"""
deadlines = []
for entry in deadline_data:
deadline_type = entry["type"]
date = entry["date"]
comment = entry["comment"]
# Check on validity
if deadline_type not in DeadlineType:
raise ValueError(f"Invalid deadline type. Choices are {DeadlineType.values}")
# If this exact data is already existing, we do not create it new. Instead put it's id in the list of
# entries, we will use to set the new actions
pre_existing_deadline = obj.deadlines.filter(
type=deadline_type,
date=date,
comment=comment,
).exclude(
id__in=deadlines
).first()
if pre_existing_deadline is not None:
deadlines.append(pre_existing_deadline.id)
else:
# Create and add id to list
new_deadline = Deadline.objects.create(
type=deadline_type,
date=date,
comment=comment,
)
deadlines.append(new_deadline.id)
obj.deadlines.set(deadlines)
return obj
def set_compensation_states(self, obj, states_data, states_manager):
""" Sets the linked compensation state data according to the given states_data
Args:
obj (Compensation): The Compensation object
states_data (dict): The posted states_data
states_manager (Manager): The before_states or after_states manager
Returns:
obj (Compensation)
"""
states = []
for entry in states_data:
biotope_type = entry["biotope"]
surface = float(entry["surface"])
# Check on validity
if surface <= 0:
raise ValueError("State surfaces must be > 0")
# If this exact data is already existing, we do not create it new. Instead put it's id in the list of
# entries, we will use to set the new actions
pre_existing_state = states_manager.filter(
biotope_type__atom_id=biotope_type,
surface=surface,
).exclude(
id__in=states
).first()
if pre_existing_state is not None:
states.append(pre_existing_state.id)
else:
# Create and add id to list
new_state = CompensationState.objects.create(
biotope_type=self.konova_code_from_json(biotope_type, CODELIST_BIOTOPES_ID),
surface=surface
)
states.append(new_state.id)
states_manager.set(states)
return obj
def set_compensation_actions(self, obj, actions_data):
""" Sets the linked compensation action data according to the given actions_data
Args:
obj (Compensation): The Compensation object
actions_data (dict): The posted actions_data
Returns:
obj (Compensation)
"""
actions = []
for entry in actions_data:
action = entry["action"]
amount = float(entry["amount"])
unit = entry["unit"]
comment = entry["comment"]
# Check on validity
if amount <= 0:
raise ValueError("Action amount must be > 0")
if unit not in UnitChoices:
raise ValueError(f"Invalid unit. Choices are {UnitChoices.values}")
# If this exact data is already existing, we do not create it new. Instead put it's id in the list of
# entries, we will use to set the new actions
pre_existing_action = obj.actions.filter(
action_type__atom_id=action,
amount=amount,
unit=unit,
comment=comment,
).exclude(
id__in=actions
).first()
if pre_existing_action is not None:
actions.append(pre_existing_action.id)
else:
# Create and add id to list
new_action = CompensationAction.objects.create(
action_type=self.konova_code_from_json(action, CODELIST_COMPENSATION_ACTION_ID),
amount=amount,
unit=unit,
comment=comment,
)
actions.append(new_action.id)
obj.actions.set(actions)
return obj
def compensation_state_to_json(self, qs: QuerySet): def compensation_state_to_json(self, qs: QuerySet):
""" Serializes compensation states into json """ Serializes compensation states into json
@ -410,4 +191,28 @@ class AbstractCompensationAPISerializerV1Mixin:
"type", "type",
"date", "date",
"comment", "comment",
)) ))
def created_on_to_json(self, entry):
""" Serializes the created_on into json
Args:
entry (BaseObject): The entry
Returns:
created_on (timestamp)
"""
return entry.created.timestamp
def modified_on_to_json(self, entry):
""" Serializes the modified_on into json
Args:
entry (BaseObject): The entry
Returns:
modified_on (timestamp)
"""
modified_on = entry.modified or entry.created
modified_on = modified_on.timestamp
return modified_on

View File

@ -28,29 +28,21 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
Args: Args:
request (HttpRequest): The incoming request request (HttpRequest): The incoming request
id (str): The entries id (optional) id (str): The entries id
Returns: Returns:
response (JsonResponse)
""" """
try: try:
if id is None:
raise AttributeError("No id provided")
self.serializer.prepare_lookup(id, self.user) self.serializer.prepare_lookup(id, self.user)
data = self.serializer.fetch_and_serialize() data = self.serializer.fetch_and_serialize()
except Exception as e: except Exception as e:
return self.return_error_response(e, 500) return self.return_error_response(e, 500)
return JsonResponse(data) return JsonResponse(data)
def post(self, request: HttpRequest): def post(self, request: HttpRequest, id=None):
""" Handles the POST request
Performs creation of new data
Args:
request (HttpRequest): The incoming request
Returns:
response (JsonResponse)
"""
try: try:
body = request.body.decode("utf-8") body = request.body.decode("utf-8")
body = json.loads(body) body = json.loads(body)
@ -60,17 +52,6 @@ class AbstractModelAPIViewV1(AbstractModelAPIView):
return JsonResponse({"id": created_id}) return JsonResponse({"id": created_id})
def put(self, request: HttpRequest, id=None): def put(self, request: HttpRequest, id=None):
""" Handles the PUT request
Performs updating
Args:
request (HttpRequest): The incoming request
id (str): The entries id
Returns:
"""
try: try:
body = request.body.decode("utf-8") body = request.body.decode("utf-8")
body = json.loads(body) body = json.loads(body)

View File

@ -29,7 +29,6 @@ class CompensationAdmin(BaseObjectAdmin):
"identifier", "identifier",
"title", "title",
"created", "created",
"deleted",
] ]

View File

@ -35,7 +35,9 @@ class CompensationManager(models.Manager):
""" """
def get_queryset(self): def get_queryset(self):
return super().get_queryset().select_related( return super().get_queryset().filter(
deleted__isnull=True,
).select_related(
"modified", "modified",
"intervention", "intervention",
"intervention__recorded", "intervention__recorded",

View File

@ -245,15 +245,6 @@ class Compensation(AbstractCompensation, CEFMixin, CoherenceMixin):
# Compensations inherit their shared state from the interventions # Compensations inherit their shared state from the interventions
return self.intervention.is_shared_with(user) return self.intervention.is_shared_with(user)
@property
def shared_users(self) -> QuerySet:
""" Shortcut for fetching the users which have shared access on this object
Returns:
users (QuerySet)
"""
return self.intervention.users.all()
def get_LANIS_link(self) -> str: def get_LANIS_link(self) -> str:
""" Generates a link for LANIS depending on the geometry """ Generates a link for LANIS depending on the geometry

View File

@ -10,7 +10,7 @@ from ema.models import Ema
from intervention.models import Intervention from intervention.models import Intervention
from konova.management.commands.setup import BaseKonovaCommand from konova.management.commands.setup import BaseKonovaCommand
from konova.models import Deadline, Geometry, Parcel, District from konova.models import Deadline, Geometry, Parcel, District
from user.models import UserActionLogEntry, UserAction from user.models import UserActionLogEntry
class Command(BaseKonovaCommand): class Command(BaseKonovaCommand):
@ -55,11 +55,7 @@ class Command(BaseKonovaCommand):
""" """
self._write_warning("=== Sanitize log entries ===") self._write_warning("=== Sanitize log entries ===")
# Exclude created log entries from being cleaned, since they can be part of objects which do not have logs all_log_entries = UserActionLogEntry.objects.all()
# Being in a log (or not) is essential for this cleanup
all_log_entries = UserActionLogEntry.objects.all().exclude(
action=UserAction.CREATED
)
intervention_log_entries_ids = self.get_all_log_entries_ids(Intervention) intervention_log_entries_ids = self.get_all_log_entries_ids(Intervention)
attached_log_entries_id = intervention_log_entries_ids.union( attached_log_entries_id = intervention_log_entries_ids.union(

View File

@ -10,7 +10,6 @@ import uuid
from abc import abstractmethod from abc import abstractmethod
from django.contrib import messages from django.contrib import messages
from django.db.models import QuerySet
from konova.tasks import celery_send_mail_shared_access_removed, celery_send_mail_shared_access_given, \ from konova.tasks import celery_send_mail_shared_access_removed, celery_send_mail_shared_access_given, \
celery_send_mail_shared_data_recorded, celery_send_mail_shared_data_unrecorded, \ celery_send_mail_shared_data_recorded, celery_send_mail_shared_data_unrecorded, \
@ -125,7 +124,7 @@ class BaseObject(BaseResource):
self.log.add(action) self.log.add(action)
# Send mail # Send mail
shared_users = self.shared_users.values_list("id", flat=True) shared_users = self.users.all().values_list("id", flat=True)
for user_id in shared_users: for user_id in shared_users:
celery_send_mail_shared_data_deleted.delay(self.identifier, user_id) celery_send_mail_shared_data_deleted.delay(self.identifier, user_id)
@ -465,15 +464,6 @@ class ShareableObjectMixin(models.Model):
# Set new shared users # Set new shared users
self.share_with_list(users) self.share_with_list(users)
@property
def shared_users(self) -> QuerySet:
""" Shortcut for fetching the users which have shared access on this object
Returns:
users (QuerySet)
"""
return self.users.all()
class GeoReferencedMixin(models.Model): class GeoReferencedMixin(models.Model):
geometry = models.ForeignKey("konova.Geometry", null=True, blank=True, on_delete=models.SET_NULL) geometry = models.ForeignKey("konova.Geometry", null=True, blank=True, on_delete=models.SET_NULL)