* adds support for sending "external_identifier" in POST and PUT requests * if an external identifier already exists on the database, the client will be informed that the entry should not be POSTed again but rather an update via PUT should be performed
186 lines
7.0 KiB
Python
186 lines
7.0 KiB
Python
"""
|
|
Author: Michel Peltriaux
|
|
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
|
Contact: michel.peltriaux@sgdnord.rlp.de
|
|
Created on: 24.01.22
|
|
|
|
"""
|
|
from django.db import transaction
|
|
from django.db.models import Q
|
|
|
|
from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin
|
|
from compensation.models import Compensation
|
|
from intervention.models import Intervention
|
|
from konova.models import Geometry
|
|
from konova.tasks import celery_update_parcels, celery_check_for_geometry_conflicts
|
|
from konova.utils.message_templates import DATA_UNSHARED
|
|
from user.models import UserActionLogEntry
|
|
|
|
|
|
class CompensationAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin):
|
|
model = Compensation
|
|
|
|
def prepare_lookup(self, id, user):
|
|
super().prepare_lookup(id, user)
|
|
self.shared_lookup = Q(
|
|
Q(intervention__users__in=[user]) |
|
|
Q(intervention__teams__in=user.shared_teams)
|
|
)
|
|
|
|
def intervention_to_json(self, entry):
|
|
return {
|
|
"id": entry.pk,
|
|
"identifier": entry.identifier,
|
|
"title": entry.title,
|
|
}
|
|
|
|
def _extend_properties_data(self, entry):
|
|
self.properties_data["is_cef"] = entry.is_cef
|
|
self.properties_data["is_coherence_keeping"] = entry.is_coherence_keeping
|
|
self.properties_data["is_pik"] = entry.is_pik
|
|
self.properties_data["intervention"] = self.intervention_to_json(entry.intervention)
|
|
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["actions"] = self._compensation_actions_to_json(entry.actions.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.modified = 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 is not None and 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(DATA_UNSHARED)
|
|
|
|
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.get("properties", None)
|
|
if not properties:
|
|
raise AssertionError("No 'properties' found in payload!")
|
|
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.is_pik = properties.get("is_pik", False)
|
|
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"])
|
|
|
|
self._set_external_identifier(obj, properties.get("external_identifier", None))
|
|
obj.log.add(obj.created)
|
|
|
|
celery_update_parcels.delay(obj.geometry.id)
|
|
celery_check_for_geometry_conflicts.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 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"]
|
|
|
|
external_identifier = properties.get("external_identifier", None)
|
|
self._check_external_identifier_on_entry_creation(external_identifier)
|
|
|
|
obj.title = properties["title"]
|
|
obj.is_cef = properties["is_cef"]
|
|
obj.is_coherence_keeping = properties["is_coherence_keeping"]
|
|
obj.is_pik = properties.get("is_pik", False)
|
|
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"])
|
|
|
|
self._set_external_identifier(obj, properties.get("external_identifier", None))
|
|
obj.log.add(update_action)
|
|
|
|
celery_update_parcels.delay(obj.geometry.id)
|
|
|
|
return obj.id
|