#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 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 from api.views.views import InterventionCheckAPIView, InterventionAPIShareView, EcoAccountAPIShareView, EmaAPIShareView
app_name = "v1" app_name = "v1"
@ -24,6 +25,9 @@ urlpatterns = [
path("ecoaccount/<id>", EcoAccountAPIViewV1.as_view(), name="ecoaccount"), path("ecoaccount/<id>", EcoAccountAPIViewV1.as_view(), name="ecoaccount"),
path("ecoaccount/", 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>/share", EmaAPIShareView.as_view(), name="ema-share"),
path("ema/<id>", EmaAPIViewV1.as_view(), name="ema"), path("ema/<id>", EmaAPIViewV1.as_view(), name="ema"),
path("ema/", 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,17 +132,16 @@ class DeductableAPISerializerV1Mixin:
class Meta: class Meta:
abstract = True abstract = True
def _deductions_to_json(self, qs: QuerySet): def _single_deduction_to_json(self, entry):
""" Serializes eco account deductions into json """ Serializes a single eco account deduction into json
Args: Args:
qs (QuerySet): A queryset of EcoAccountDeduction entries entry (EcoAccountDeduction): An EcoAccountDeduction
Returns: Returns:
serialized_json (list) serialized_json (dict)
""" """
return [ return {
{
"id": entry.pk, "id": entry.pk,
"eco_account": { "eco_account": {
"id": entry.account.pk, "id": entry.account.pk,
@ -156,6 +155,18 @@ class DeductableAPISerializerV1Mixin:
"title": entry.intervention.title, "title": entry.intervention.title,
} }
} }
def _deductions_to_json(self, qs: QuerySet):
""" Serializes eco account deductions into json
Args:
qs (QuerySet): A queryset of EcoAccountDeduction entries
Returns:
serialized_json (list)
"""
return [
self._single_deduction_to_json(entry)
for entry in qs for entry in qs
] ]

View File

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