DocManagerBackend/docmanager_backend/document_requests/serializers.py

196 lines
6.2 KiB
Python

from rest_framework import serializers
from documents.models import Document
from documents.serializers import DocumentSerializer, DocumentFileSerializer
from questionnaires.models import Questionnaire
from accounts.models import CustomUser
from emails.templates import RequestUpdateEmail
from .models import DocumentRequest, DocumentRequestUnit
class DocumentRequestUnitCreationSerializer(serializers.ModelSerializer):
document = serializers.SlugRelatedField(
many=False, slug_field="id", queryset=Document.objects.all(), required=True
)
copies = serializers.IntegerField(min_value=1)
class Meta:
model = DocumentRequestUnit
fields = ["document", "copies"]
class DocumentRequestCreationSerializer(serializers.ModelSerializer):
requester = serializers.SlugRelatedField(
many=False, slug_field="id", queryset=CustomUser.objects.all(), required=False
)
documents = DocumentRequestUnitCreationSerializer(many=True, required=True)
college = serializers.CharField(max_length=64)
purpose = serializers.CharField(max_length=512)
type = serializers.ChoiceField(
choices=DocumentRequest.TYPE_CHOICES, required=True)
class Meta:
model = DocumentRequest
fields = ["requester", "college", "type", "purpose", "documents"]
def create(self, validated_data):
user = self.context["request"].user
documents_data = validated_data.pop("documents")
# Set requester to user who sent HTTP request to prevent spoofing
validated_data["requester"] = user
DOCUMENT_REQUEST = DocumentRequest.objects.create(**validated_data)
DOCUMENT_REQUEST_UNITS = []
for DOCUMENT_REQUEST_UNIT in documents_data:
DOCUMENT_REQUEST_UNIT = DocumentRequestUnit.objects.create(
document_request=DOCUMENT_REQUEST,
document=DOCUMENT_REQUEST_UNIT["document"],
copies=DOCUMENT_REQUEST_UNIT["copies"],
)
DOCUMENT_REQUEST_UNITS.append(DOCUMENT_REQUEST_UNIT)
DOCUMENT_REQUEST.documents.set(DOCUMENT_REQUEST_UNITS)
DOCUMENT_REQUEST.save()
return DOCUMENT_REQUEST
class DocumentRequestUnitSerializer(serializers.ModelSerializer):
document = DocumentSerializer(many=False)
class Meta:
model = DocumentRequestUnit
fields = ["id", "document", "copies"]
read_only_fields = ["id", "document", "copies"]
class DocumentRequestUnitWithFileSerializer(serializers.ModelSerializer):
document = DocumentFileSerializer(many=False)
class Meta:
model = DocumentRequestUnit
fields = ["id", "document", "copies"]
read_only_fields = ["id", "document", "copies"]
class DocumentRequestSerializer(serializers.ModelSerializer):
documents = serializers.SerializerMethodField()
questionnaire = serializers.SlugRelatedField(
many=False,
slug_field="id",
queryset=Questionnaire.objects.all(),
)
requester = serializers.SlugRelatedField(
many=False,
slug_field="email",
queryset=CustomUser.objects.all(),
)
purpose = serializers.CharField(max_length=512)
date_requested = serializers.DateTimeField(
format="%m-%d-%Y %I:%M %p", read_only=True
)
class Meta:
model = DocumentRequest
fields = [
"id",
"questionnaire",
"requester",
"college",
"type",
"purpose",
"date_requested",
"documents",
"status",
]
read_only_fields = [
"id",
"questionnaire",
"requester",
"college",
"type",
"purpose",
"date_requested",
"documents",
"status",
]
def get_documents(self, obj):
if obj.questionnaire and obj.status == "approved":
serializer_class = DocumentRequestUnitWithFileSerializer
else:
serializer_class = DocumentRequestUnitSerializer
return serializer_class(obj.documents, many=True).data
class FullDocumentRequestSerializer(serializers.ModelSerializer):
documents = DocumentRequestUnitWithFileSerializer()
requester = serializers.SlugRelatedField(
many=False,
slug_field="email",
queryset=CustomUser.objects.all(),
required=False,
)
purpose = serializers.CharField(max_length=512)
date_requested = serializers.DateTimeField(
format="%m-%d-%Y %I:%M %p", read_only=True
)
class Meta:
model = DocumentRequest
fields = [
"id",
"requester",
"college",
"type",
"purpose",
"date_requested",
"documents",
"status",
]
read_only_fields = [
"id",
"requester",
"college",
"type",
"purpose",
"date_requested",
"documents",
"status",
]
class DocumentRequestUpdateSerializer(serializers.ModelSerializer):
status = serializers.ChoiceField(
choices=DocumentRequest.STATUS_CHOICES, required=True
)
class Meta:
model = DocumentRequest
fields = ["id", "status"]
read_only_fields = ["id", "status"]
def update(self, instance, validated_data):
if instance.status == "denied" or instance.status == "approved":
raise serializers.ValidationError(
{
"error": "Already approved/denied requests cannot be updated. You should instead create a new request and approve it from there"
}
)
elif validated_data["status"] == instance.status:
raise serializers.ValidationError(
{"error": "Request form status provided is the same as current status"}
)
representation = super().update(instance, validated_data)
# Send an email on request status update
try:
email = RequestUpdateEmail()
email.context = {"request_status": instance.status}
email.send(to=[instance.requester.email])
except:
# Silence out errors if email sending fails
pass
return representation