160 lines
5.7 KiB
Python
Executable File
160 lines
5.7 KiB
Python
Executable File
from typing import TYPE_CHECKING
|
|
|
|
from rest_framework import serializers
|
|
from rest_framework.exceptions import PermissionDenied
|
|
|
|
from outbo.apps.photobriefing.enums import ChoiceRole
|
|
from outbo.apps.photobriefing.models import Brief, BriefItemChoice
|
|
from outbo.apps.photobriefing.rules import can_complete_brief, can_publish_brief
|
|
from outbo.apps.photobriefing.serializers import (
|
|
BriefItemSerializer,
|
|
BriefItemChoiceSerializer,
|
|
)
|
|
|
|
if TYPE_CHECKING:
|
|
from outbo.apps.authentication.models import User
|
|
|
|
|
|
class BaseBriefSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Brief
|
|
|
|
def get_editable(self, instance: Brief):
|
|
current_user = self.context["request"].user
|
|
return instance.editable_for_user(user=current_user)
|
|
|
|
def get_acceptable(self, instance: Brief):
|
|
current_user = self.context["request"].user
|
|
return instance.acceptable_for_user(user=current_user)
|
|
|
|
def get_publishable(self, instance: Brief):
|
|
current_user = self.context["request"].user
|
|
return instance.publishable_for_user(user=current_user)
|
|
|
|
def get_completable(self, instance: Brief):
|
|
current_user = self.context["request"].user
|
|
return instance.completable_for_user(user=current_user)
|
|
|
|
|
|
class BriefSerializer:
|
|
class Retrieve(BaseBriefSerializer):
|
|
items = BriefItemSerializer.List(many=True)
|
|
choices = BriefItemChoiceSerializer.List(many=True)
|
|
editable = serializers.SerializerMethodField()
|
|
acceptable = serializers.SerializerMethodField()
|
|
publishable = serializers.SerializerMethodField()
|
|
completable = serializers.SerializerMethodField()
|
|
|
|
class Meta(BaseBriefSerializer.Meta):
|
|
fields = [
|
|
"stage",
|
|
"session_date",
|
|
"concept_description",
|
|
"items",
|
|
"choices",
|
|
"created_at",
|
|
"updated_at",
|
|
"editable",
|
|
"acceptable",
|
|
"publishable",
|
|
"completable",
|
|
]
|
|
|
|
class Update(BaseBriefSerializer):
|
|
publish = serializers.BooleanField()
|
|
complete = serializers.BooleanField()
|
|
choice = BriefItemChoiceSerializer.Update(partial=False)
|
|
items = BriefItemSerializer.Create(many=True)
|
|
|
|
class Meta(BaseBriefSerializer.Meta):
|
|
fields = [
|
|
"session_date",
|
|
"concept_description",
|
|
"items",
|
|
"choice",
|
|
"publish",
|
|
"complete",
|
|
]
|
|
|
|
def update(self, instance, validated_data):
|
|
if validated_data.get("choice", None) is not None:
|
|
serializer = BriefSerializer.ChoiceUpdate(context=self.context)
|
|
return serializer.update(instance, {"choice": validated_data["choice"]})
|
|
if validated_data.get("publish", None) is not None:
|
|
serializer = BriefSerializer.Publish(context=self.context)
|
|
return serializer.update(
|
|
instance, {"publish": validated_data["publish"]}
|
|
)
|
|
if validated_data.get("complete", None) is not None:
|
|
serializer = BriefSerializer.Complete(context=self.context)
|
|
return serializer.update(
|
|
instance, {"complete": validated_data["complete"]}
|
|
)
|
|
items = validated_data.pop("items", None)
|
|
if items:
|
|
for item in items:
|
|
item["brief"] = instance
|
|
BriefItemSerializer.Create(context=self.context).create(item)
|
|
|
|
return super().update(instance=instance, validated_data=validated_data)
|
|
|
|
class Publish(BaseBriefSerializer):
|
|
publish = serializers.BooleanField()
|
|
|
|
class Meta(BaseBriefSerializer.Meta):
|
|
fields = ["publish"]
|
|
|
|
def update(self, instance, validated_data):
|
|
publish = validated_data["publish"]
|
|
current_user = self.context["request"].user
|
|
if not can_publish_brief.test(current_user, instance):
|
|
raise PermissionDenied()
|
|
if publish:
|
|
instance.publish_as_user(user=current_user)
|
|
instance.save()
|
|
return instance
|
|
|
|
class Complete(BaseBriefSerializer):
|
|
complete = serializers.BooleanField()
|
|
|
|
class Meta(BaseBriefSerializer.Meta):
|
|
fields = ["complete"]
|
|
|
|
def update(self, instance: Brief, validated_data):
|
|
complete = validated_data["complete"]
|
|
current_user = self.context["request"].user
|
|
if not can_complete_brief.test(current_user, instance):
|
|
raise PermissionDenied()
|
|
if complete:
|
|
instance.complete_as_user(user=current_user)
|
|
instance.save()
|
|
return instance
|
|
|
|
class ChoiceUpdate(BaseBriefSerializer):
|
|
choice = BriefItemChoiceSerializer.Update()
|
|
|
|
class Meta(BaseBriefSerializer.Meta):
|
|
fields = ["choice"]
|
|
|
|
def update(self, instance, validated_data):
|
|
choice = validated_data["choice"]
|
|
current_user: "User" = self.context["request"].user
|
|
if current_user.is_supplier:
|
|
role = ChoiceRole.SUPPLIER
|
|
elif current_user.is_client:
|
|
role = ChoiceRole.CLIENT
|
|
else:
|
|
raise NotImplemented
|
|
|
|
current_choice, _ = BriefItemChoice.objects.get_or_create(
|
|
defaults={"item": choice["item"]},
|
|
brief=instance,
|
|
category=choice["category"],
|
|
role=role,
|
|
)
|
|
if current_choice.item != choice["item"]:
|
|
current_choice.item = choice["item"]
|
|
current_choice.save()
|
|
|
|
return instance
|