128 lines
5.0 KiB
Python
128 lines
5.0 KiB
Python
import uuid
|
|
from typing import cast
|
|
|
|
from django_core.mixins import BaseViewSetMixin # type: ignore
|
|
from django.utils.translation import gettext as _
|
|
from drf_spectacular.utils import extend_schema
|
|
from rest_framework.exceptions import PermissionDenied # type: ignore
|
|
from rest_framework.permissions import AllowAny, IsAdminUser # type: ignore
|
|
from rest_framework.viewsets import ModelViewSet # type: ignore
|
|
from rest_framework.request import HttpRequest # type: ignore
|
|
from rest_framework.response import Response # type: ignore
|
|
from rest_framework import status # type: ignore
|
|
from rest_framework.generics import GenericAPIView # type: ignore
|
|
from rest_framework.parsers import MultiPartParser, FormParser # type: ignore
|
|
from rest_framework.generics import get_object_or_404 # type: ignore
|
|
|
|
from core.utils.views import BaseApiViewMixin
|
|
from core.apps.contracts.models import (
|
|
ContractOwnerModel,
|
|
ContractAttachedFileModel,
|
|
)
|
|
from core.apps.contracts.serializers import (
|
|
CreateContractOwnerSerializer,
|
|
ListContractOwnerSerializer,
|
|
RetrieveContractOwnerSerializer,
|
|
UpdateContractOwnerSerializer,
|
|
DestroyContractOwnerSerializer,
|
|
|
|
CreateContractFileContentFromOwnerSerializer,
|
|
)
|
|
|
|
|
|
###################################################################################
|
|
# @view-set | ALL - /contract-owners
|
|
###################################################################################
|
|
@extend_schema(tags=["Contract Owners"])
|
|
class ContractOwnerViewSet(BaseViewSetMixin, ModelViewSet):
|
|
queryset = ContractOwnerModel.objects.all()
|
|
serializer_class = ListContractOwnerSerializer
|
|
permission_classes = [AllowAny]
|
|
|
|
action_permission_classes = {
|
|
"list": [IsAdminUser],
|
|
"retrieve": [IsAdminUser],
|
|
"create": [IsAdminUser],
|
|
"update": [IsAdminUser],
|
|
"destroy": [IsAdminUser],
|
|
}
|
|
action_serializer_class = { # type: ignore
|
|
"list": ListContractOwnerSerializer,
|
|
"retrieve": RetrieveContractOwnerSerializer,
|
|
"create": CreateContractOwnerSerializer,
|
|
"update": UpdateContractOwnerSerializer,
|
|
"destroy": DestroyContractOwnerSerializer,
|
|
}
|
|
|
|
|
|
###################################################################################
|
|
# @api-view | DELETE - /contract-owners/{owner_id}/files/{file_id}
|
|
###################################################################################
|
|
@extend_schema(tags=["Contract Files"])
|
|
class ContractOwnerAttachedFileApiView(BaseApiViewMixin, GenericAPIView): # type: ignore
|
|
permission_classes = [AllowAny]
|
|
serializer_class = ListContractOwnerSerializer
|
|
queryset = ContractOwnerModel.objects.all()
|
|
|
|
method_permission_classes = {"delete": [AllowAny]}
|
|
method_serializer_class = {}
|
|
|
|
@extend_schema(
|
|
summary="Delete a file from contract",
|
|
description="Deletes a contract-attached file if contract allows file deletion.",
|
|
)
|
|
def delete(
|
|
self,
|
|
request: HttpRequest,
|
|
owner_id: uuid.UUID,
|
|
file_id: uuid.UUID,
|
|
*args: object,
|
|
**kwargs: object
|
|
) -> Response:
|
|
owner = get_object_or_404(
|
|
ContractOwnerModel.objects.all().select_related("contract"), pk=owner_id
|
|
)
|
|
if not owner.contract.allow_delete_files:
|
|
raise PermissionDenied(_("Deleting attached files was restricted for this contract"))
|
|
|
|
file = get_object_or_404(
|
|
ContractAttachedFileModel.objects.all().select_related("contract"), pk=file_id
|
|
)
|
|
if owner.contract.pk != file.contract.pk:
|
|
raise PermissionDenied(_("Contract have no such file attached"))
|
|
file.delete()
|
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
|
|
|
|
|
###################################################################################
|
|
# @api-view | POST - /contract-owners/{owner_id}/files/{file_id}/upload
|
|
###################################################################################
|
|
@extend_schema(tags=["Contract File contents"])
|
|
class UploadFileContentApiView(BaseApiViewMixin, GenericAPIView): # type: ignore
|
|
permission_classes = [AllowAny]
|
|
parser_classes = [MultiPartParser, FormParser] # type: ignore
|
|
|
|
method_permission_classes = {"post": [AllowAny]}
|
|
method_serializer_class = {"post": CreateContractFileContentFromOwnerSerializer}
|
|
|
|
@extend_schema(
|
|
summary="Uploads a file for contract attached files",
|
|
description="Creates a file for contract attached files.",
|
|
)
|
|
def post(
|
|
self,
|
|
request: HttpRequest,
|
|
owner_id: uuid.UUID,
|
|
file_id: uuid.UUID,
|
|
*args: object,
|
|
**kwargs: object
|
|
) -> Response:
|
|
serializer_context = dict(file_id=file_id, contract_owner_id=owner_id)
|
|
serializer = cast(
|
|
CreateContractFileContentFromOwnerSerializer,
|
|
self.get_serializer(data=request.data, context=serializer_context) # type: ignore
|
|
)
|
|
serializer.is_valid(raise_exception=True)
|
|
serializer.save()
|
|
return Response(serializer.data, status=status.HTTP_201_CREATED)
|