#31 API Deductions

* adds GET/POST/PUT/DELETE support for EcoAccountDeductions
This commit is contained in:
mpeltriaux 2022-01-28 15:44:09 +01:00
parent 5dc1b11ca1
commit c3a8631f03
4 changed files with 198 additions and 15 deletions

View File

@ -7,7 +7,8 @@ Created on: 21.01.22
"""
from django.urls import path
from api.views.v1.views import EmaAPIViewV1, EcoAccountAPIViewV1, CompensationAPIViewV1, InterventionAPIViewV1
from api.views.v1.views import EmaAPIViewV1, EcoAccountAPIViewV1, CompensationAPIViewV1, InterventionAPIViewV1, \
DeductionAPIViewV1
from api.views.views import InterventionCheckAPIView, InterventionAPIShareView, EcoAccountAPIShareView, EmaAPIShareView
app_name = "v1"
@ -24,6 +25,9 @@ urlpatterns = [
path("ecoaccount/<id>", EcoAccountAPIViewV1.as_view(), name="ecoaccount"),
path("ecoaccount/", EcoAccountAPIViewV1.as_view(), name="ecoaccount"),
path("deduction/<id>", DeductionAPIViewV1.as_view(), name="deduction"),
path("deduction/", DeductionAPIViewV1.as_view(), name="deduction"),
path("ema/<id>/share", EmaAPIShareView.as_view(), name="ema-share"),
path("ema/<id>", EmaAPIViewV1.as_view(), name="ema"),
path("ema/", EmaAPIViewV1.as_view(), name="ema"),

View File

@ -0,0 +1,163 @@
"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 28.01.22
"""
from django.core.exceptions import ObjectDoesNotExist
from api.utils.serializer.v1.serializer import DeductableAPISerializerV1Mixin, AbstractModelAPISerializerV1
from compensation.models import EcoAccountDeduction, EcoAccount
from intervention.models import Intervention
from konova.utils.message_templates import DATA_UNSHARED
class DeductionAPISerializerV1(AbstractModelAPISerializerV1,
DeductableAPISerializerV1Mixin):
model = EcoAccountDeduction
def prepare_lookup(self, _id, user):
""" Updates lookup dict for db fetching
Args:
_id (str): The object's id
user (User): The user requesting for
Returns:
"""
super().prepare_lookup(_id, user)
del self.lookup["users__in"]
del self.lookup["deleted__isnull"]
self.lookup["intervention__users__in"] = [user]
def _model_to_geo_json(self, entry):
""" Adds the basic data
Args:
entry (): The data entry
Returns:
"""
return self._single_deduction_to_json(entry)
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 Intervention entry
"""
acc_id = json_model["eco_account"]
intervention_id = json_model["intervention"]
surface = float(json_model["surface"])
if surface <= 0:
raise ValueError("Surface must be > 0 m²")
acc = EcoAccount.objects.get(
id=acc_id,
deleted__isnull=True,
)
intervention = Intervention.objects.get(
id=intervention_id,
deleted__isnull=True,
)
acc_shared = acc.is_shared_with(user)
intervention_shared = intervention.is_shared_with(user)
if not acc_shared:
raise PermissionError(f"Account: {DATA_UNSHARED}")
if not intervention_shared:
raise PermissionError(f"Intervention: {DATA_UNSHARED}")
deduction = self.model.objects.create(
intervention=intervention,
account=acc,
surface=surface
)
return str(deduction.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:
"""
obj = self.model.objects.get(
id=id,
)
shared_with = obj.intervention.is_shared_with(user)
if not shared_with:
raise PermissionError(f"Intervention: {DATA_UNSHARED}")
return obj
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 Intervention entry
"""
deduction = self._get_obj_from_db(id, user)
acc_id = json_model["eco_account"]
intervention_id = json_model["intervention"]
surface = float(json_model["surface"])
if surface <= 0:
raise ValueError("Surface must be > 0 m²")
acc = EcoAccount.objects.get(
id=acc_id,
deleted__isnull=True,
)
intervention = Intervention.objects.get(
id=intervention_id,
deleted__isnull=True,
)
acc_shared = acc.is_shared_with(user)
intervention_shared = intervention.is_shared_with(user)
if not acc_shared:
raise PermissionError(f"Account: {DATA_UNSHARED}")
if not intervention_shared:
raise PermissionError(f"Intervention: {DATA_UNSHARED}")
deduction.intervention = intervention
deduction.account = acc
deduction.surface = surface
deduction.save()
return str(deduction.id)
def delete_entry(self, id, user):
""" Deletes the entry
Args:
id (str): The entry's id
user (User): The API user
Returns:
"""
entry = self._get_obj_from_db(id, user)
entry.intervention.mark_as_edited(user)
entry.delete()
try:
entry.refresh_from_db()
success = False
except ObjectDoesNotExist:
success = True
return success

View File

@ -132,6 +132,30 @@ class DeductableAPISerializerV1Mixin:
class Meta:
abstract = True
def _single_deduction_to_json(self, entry):
""" Serializes a single eco account deduction into json
Args:
entry (EcoAccountDeduction): An EcoAccountDeduction
Returns:
serialized_json (dict)
"""
return {
"id": entry.pk,
"eco_account": {
"id": entry.account.pk,
"identifier": entry.account.identifier,
"title": entry.account.title,
},
"surface": entry.surface,
"intervention": {
"id": entry.intervention.pk,
"identifier": entry.intervention.identifier,
"title": entry.intervention.title,
}
}
def _deductions_to_json(self, qs: QuerySet):
""" Serializes eco account deductions into json
@ -142,20 +166,7 @@ class DeductableAPISerializerV1Mixin:
serialized_json (list)
"""
return [
{
"id": entry.pk,
"eco_account": {
"id": entry.account.pk,
"identifier": entry.account.identifier,
"title": entry.account.title,
},
"surface": entry.surface,
"intervention": {
"id": entry.intervention.pk,
"identifier": entry.intervention.identifier,
"title": entry.intervention.title,
}
}
self._single_deduction_to_json(entry)
for entry in qs
]

View File

@ -10,6 +10,7 @@ import json
from django.http import JsonResponse, HttpRequest
from api.utils.serializer.v1.compensation import CompensationAPISerializerV1
from api.utils.serializer.v1.deduction import DeductionAPISerializerV1
from api.utils.serializer.v1.ecoaccount import EcoAccountAPISerializerV1
from api.utils.serializer.v1.ema import EmaAPISerializerV1
from api.utils.serializer.v1.intervention import InterventionAPISerializerV1
@ -125,3 +126,7 @@ class EcoAccountAPIViewV1(AbstractAPIViewV1):
class EmaAPIViewV1(AbstractAPIViewV1):
serializer = EmaAPISerializerV1
class DeductionAPIViewV1(AbstractAPIViewV1):
serializer = DeductionAPISerializerV1