diff --git a/api/utils/serializer/v1/compensation.py b/api/utils/serializer/v1/compensation.py index 6fb8486d..05787795 100644 --- a/api/utils/serializer/v1/compensation.py +++ b/api/utils/serializer/v1/compensation.py @@ -7,16 +7,15 @@ Created on: 24.01.22 """ from django.db import transaction -from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1 -from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID -from compensation.models import Compensation, CompensationAction, CompensationState, UnitChoices +from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin +from compensation.models import Compensation from intervention.models import Intervention -from konova.models import Geometry, Deadline, DeadlineType +from konova.models import Geometry from konova.tasks import celery_update_parcels from user.models import UserActionLogEntry -class CompensationAPISerializerV1(AbstractModelAPISerializerV1): +class CompensationAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin): model = Compensation def prepare_lookup(self, id, user): @@ -88,122 +87,6 @@ class CompensationAPISerializerV1(AbstractModelAPISerializerV1): obj.intervention = intervention return obj - 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) - """ - found_deadlines = [] - for entry in deadline_data: - deadline_type = entry["type"] - date = entry["date"] - comment = entry["comment"] - - if deadline_type not in DeadlineType: - raise ValueError(f"Invalid deadline type. Choices are {DeadlineType.values}") - - pre_existing_deadlines = obj.deadlines.filter( - type=deadline_type, - date=date, - comment=comment, - ).exclude( - id__in=found_deadlines - ) - if pre_existing_deadlines.count() > 0: - found_deadlines += pre_existing_deadlines.values_list("id", flat=True) - else: - # Create! - new_deadline = Deadline.objects.create( - type=deadline_type, - date=date, - comment=comment, - ) - obj.deadlines.add(new_deadline) - 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) - """ - found_states = [] - for entry in states_data: - biotope_type = entry["biotope"] - surface = float(entry["surface"]) - if surface <= 0: - raise ValueError("State surfaces must be > 0") - pre_existing_states = states_manager.filter( - biotope_type__atom_id=biotope_type, - surface=surface, - ).exclude( - id__in=found_states - ) - if pre_existing_states.count() > 0: - found_states += pre_existing_states.values_list("id", flat=True) - else: - # Create! - new_state = CompensationState.objects.create( - biotope_type=self.konova_code_from_json(biotope_type, CODELIST_BIOTOPES_ID), - surface=surface - ) - states_manager.add(new_state) - 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) - """ - found_actions = [] - for entry in actions_data: - action = entry["action"] - amount = float(entry["amount"]) - unit = entry["unit"] - comment = entry["comment"] - - if amount <= 0: - raise ValueError("Action amount must be > 0") - if unit not in UnitChoices: - raise ValueError(f"Invalid unit. Choices are {UnitChoices.values}") - pre_existing_actions = obj.actions.filter( - action_type__atom_id=action, - amount=amount, - unit=unit, - comment=comment, - ).exclude( - id__in=found_actions - ) - if pre_existing_actions.count() > 0: - found_actions += pre_existing_actions.values_list("id", flat=True) - else: - # Create! - new_action = CompensationAction.objects.create( - action_type=self.konova_code_from_json(action, CODELIST_COMPENSATION_ACTION_ID), - amount=amount, - unit=unit, - comment=comment, - ) - obj.actions.add(new_action) - 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 diff --git a/api/utils/serializer/v1/ecoaccount.py b/api/utils/serializer/v1/ecoaccount.py index 2491eb11..5ddbffd7 100644 --- a/api/utils/serializer/v1/ecoaccount.py +++ b/api/utils/serializer/v1/ecoaccount.py @@ -5,12 +5,17 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 24.01.22 """ -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 intervention.models import Legal, Responsibility -class EcoAccountAPISerializerV1(AbstractModelAPISerializerV1): +class EcoAccountAPISerializerV1(AbstractModelAPISerializerV1, + AbstractCompensationAPISerializerV1Mixin, + LegalAPISerializerV1Mixin, + ResponsibilityAPISerializerV1Mixin, + DeductableAPISerializerV1Mixin): model = EcoAccount def extend_properties_data(self, entry): diff --git a/api/utils/serializer/v1/ema.py b/api/utils/serializer/v1/ema.py index e8f2228e..a2e0bc1f 100644 --- a/api/utils/serializer/v1/ema.py +++ b/api/utils/serializer/v1/ema.py @@ -5,12 +5,13 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 24.01.22 """ -from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1 +from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin, \ + ResponsibilityAPISerializerV1Mixin from ema.models import Ema from intervention.models import Responsibility -class EmaAPISerializerV1(AbstractModelAPISerializerV1): +class EmaAPISerializerV1(AbstractModelAPISerializerV1, AbstractCompensationAPISerializerV1Mixin, ResponsibilityAPISerializerV1Mixin): model = Ema def responsible_to_json(self, responsible: Responsibility): diff --git a/api/utils/serializer/v1/intervention.py b/api/utils/serializer/v1/intervention.py index 82644083..1b91a6cb 100644 --- a/api/utils/serializer/v1/intervention.py +++ b/api/utils/serializer/v1/intervention.py @@ -8,7 +8,8 @@ Created on: 24.01.22 from django.db import transaction from django.db.models import QuerySet -from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1 +from api.utils.serializer.v1.serializer import AbstractModelAPISerializerV1, \ + ResponsibilityAPISerializerV1Mixin, LegalAPISerializerV1Mixin from codelist.settings import CODELIST_CONSERVATION_OFFICE_ID, CODELIST_REGISTRATION_OFFICE_ID, \ CODELIST_PROCESS_TYPE_ID, CODELIST_LAW_ID from intervention.models import Intervention, Responsibility, Legal @@ -17,7 +18,7 @@ from konova.tasks import celery_update_parcels from user.models import UserActionLogEntry -class InterventionAPISerializerV1(AbstractModelAPISerializerV1): +class InterventionAPISerializerV1(AbstractModelAPISerializerV1, ResponsibilityAPISerializerV1Mixin, LegalAPISerializerV1Mixin): model = Intervention def compensations_to_json(self, qs: QuerySet): @@ -27,6 +28,17 @@ 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): self.properties_data["responsible"] = self.responsible_to_json(entry.responsible) self.properties_data["legal"] = self.legal_to_json(entry.legal) diff --git a/api/utils/serializer/v1/serializer.py b/api/utils/serializer/v1/serializer.py index 63c71827..f60428b7 100644 --- a/api/utils/serializer/v1/serializer.py +++ b/api/utils/serializer/v1/serializer.py @@ -12,7 +12,10 @@ from django.db.models import QuerySet from api.utils.serializer.serializer import AbstractModelAPISerializer from codelist.models import KonovaCode +from codelist.settings import CODELIST_COMPENSATION_ACTION_ID, CODELIST_BIOTOPES_ID +from compensation.models import CompensationAction, UnitChoices, CompensationState from intervention.models import Responsibility, Legal +from konova.models import Deadline, DeadlineType class AbstractModelAPISerializerV1(AbstractModelAPISerializer): @@ -71,49 +74,34 @@ class AbstractModelAPISerializerV1(AbstractModelAPISerializer): ) return code - def responsible_to_json(self, responsible: Responsibility): - """ Serializes Responsibility model into json + def created_on_to_json(self, entry): + """ Serializes the created_on into json Args: - responsible (Responsibility): The Responsibility entry + entry (BaseObject): The entry Returns: - serialized_json (dict) + created_on (timestamp) """ - 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, - } + return entry.created.timestamp - def legal_to_json(self, legal: Legal): - """ Serializes Legal model into json + def modified_on_to_json(self, entry): + """ Serializes the modified_on into json Args: - legal (Legal): The Legal entry + entry (BaseObject): The entry Returns: - serialized_json (dict) + modified_on (timestamp) """ - 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()], - } + modified_on = entry.modified or entry.created + modified_on = modified_on.timestamp + return modified_on - 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")) +class DeductableAPISerializerV1Mixin: + class Meta: + abstract = True def deductions_to_json(self, qs: QuerySet): """ Serializes eco account deductions into json @@ -142,6 +130,171 @@ class AbstractModelAPISerializerV1(AbstractModelAPISerializer): 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, + } + + +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()], + } + + +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) + """ + found_deadlines = [] + for entry in deadline_data: + deadline_type = entry["type"] + date = entry["date"] + comment = entry["comment"] + + if deadline_type not in DeadlineType: + raise ValueError(f"Invalid deadline type. Choices are {DeadlineType.values}") + + pre_existing_deadlines = obj.deadlines.filter( + type=deadline_type, + date=date, + comment=comment, + ).exclude( + id__in=found_deadlines + ) + if pre_existing_deadlines.count() > 0: + found_deadlines += pre_existing_deadlines.values_list("id", flat=True) + else: + # Create! + new_deadline = Deadline.objects.create( + type=deadline_type, + date=date, + comment=comment, + ) + obj.deadlines.add(new_deadline) + 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) + """ + found_states = [] + for entry in states_data: + biotope_type = entry["biotope"] + surface = float(entry["surface"]) + if surface <= 0: + raise ValueError("State surfaces must be > 0") + pre_existing_states = states_manager.filter( + biotope_type__atom_id=biotope_type, + surface=surface, + ).exclude( + id__in=found_states + ) + if pre_existing_states.count() > 0: + found_states += pre_existing_states.values_list("id", flat=True) + else: + # Create! + new_state = CompensationState.objects.create( + biotope_type=self.konova_code_from_json(biotope_type, CODELIST_BIOTOPES_ID), + surface=surface + ) + states_manager.add(new_state) + 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) + """ + found_actions = [] + for entry in actions_data: + action = entry["action"] + amount = float(entry["amount"]) + unit = entry["unit"] + comment = entry["comment"] + + if amount <= 0: + raise ValueError("Action amount must be > 0") + if unit not in UnitChoices: + raise ValueError(f"Invalid unit. Choices are {UnitChoices.values}") + pre_existing_actions = obj.actions.filter( + action_type__atom_id=action, + amount=amount, + unit=unit, + comment=comment, + ).exclude( + id__in=found_actions + ) + if pre_existing_actions.count() > 0: + found_actions += pre_existing_actions.values_list("id", flat=True) + else: + # Create! + new_action = CompensationAction.objects.create( + action_type=self.konova_code_from_json(action, CODELIST_COMPENSATION_ACTION_ID), + amount=amount, + unit=unit, + comment=comment, + ) + obj.actions.add(new_action) + return obj + def compensation_state_to_json(self, qs: QuerySet): """ Serializes compensation states into json @@ -191,28 +344,4 @@ class AbstractModelAPISerializerV1(AbstractModelAPISerializer): "type", "date", "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 + )) \ No newline at end of file