#31 API code cleaning

* splits large AbstractModelAPISerializer into different reusable Mixins to increase reusability of code for similar models
This commit is contained in:
2022-01-24 15:20:23 +01:00
parent b3b9bfca09
commit 59c5caf8ac
5 changed files with 212 additions and 182 deletions

View File

@@ -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
))