""" 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 api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin, \ LegalAPISerializerV1Mixin, ResponsibilityAPISerializerV1Mixin, DeductableAPISerializerV1Mixin from codelist.settings import CODELIST_CONSERVATION_OFFICE_ID, CODELIST_HANDLER_ID from compensation.models import EcoAccount from intervention.models import Legal, Responsibility, Handler from konova.models import Geometry from konova.tasks import celery_update_parcels from user.models import UserActionLogEntry class EcoAccountAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin, LegalAPISerializerV1Mixin, ResponsibilityAPISerializerV1Mixin, DeductableAPISerializerV1Mixin): model = EcoAccount def _extend_properties_data(self, entry): self.properties_data["is_pik"] = entry.is_pik self.properties_data["deductable_surface"] = entry.deductable_surface self.properties_data["deductable_surface_available"] = entry.deductable_surface - entry.get_deductions_surface() self.properties_data["responsible"] = self._responsible_to_json(entry.responsible) self.properties_data["legal"] = self._legal_to_json(entry.legal) 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()) self.properties_data["deductions"] = self._deductions_to_json(entry.deductions.all()) def _legal_to_json(self, legal: Legal): return { "agreement_date": legal.registration_date, } def _responsible_to_json(self, responsible: Responsibility): return { "conservation_office": self._konova_code_to_json(responsible.conservation_office), "conservation_file_number": responsible.conservation_file_number, "handler": self._handler_to_json(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.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.type = self._konova_code_from_json( responsibility_data["handler"]["type"], CODELIST_HANDLER_ID, ) obj.responsible.handler.detail = responsibility_data["handler"]["detail"] return obj 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( handler=Handler() ) 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.is_pik = properties.get("is_pik", False) try: obj.deductable_surface = float(properties["deductable_surface"]) except TypeError: raise ValueError("Deductable surface (m²) must be a number >= 0") if obj.deductable_surface < 0: raise ValueError("Deductable surface (m²) must be greater or equal 0") obj = self._set_responsibility(obj, properties["responsible"]) obj = self._set_legal(obj, properties["legal"]) obj.geometry.save() obj.responsible.handler.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.is_pik = properties.get("is_pik", False) 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.handler.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