#31 API Deductions
* adds GET/POST/PUT/DELETE support for EcoAccountDeductions
This commit is contained in:
		
							parent
							
								
									5dc1b11ca1
								
							
						
					
					
						commit
						c3a8631f03
					
				@ -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"),
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										163
									
								
								api/utils/serializer/v1/deduction.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								api/utils/serializer/v1/deduction.py
									
									
									
									
									
										Normal 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
 | 
			
		||||
@ -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
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user