187 lines
6.1 KiB
Python
Executable File
187 lines
6.1 KiB
Python
Executable File
from rest_framework import serializers
|
|
from rest_framework.reverse import reverse_lazy
|
|
|
|
from outbo.apps.projects.models import Project, Member
|
|
from outbo.apps.projects.models.member import MembershipType
|
|
|
|
|
|
class _BaseProjectSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Project
|
|
fields = ["name"]
|
|
|
|
|
|
class BaseMemberSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Member
|
|
|
|
|
|
class MemberSerializer:
|
|
class Create(BaseMemberSerializer):
|
|
class Meta(BaseMemberSerializer.Meta):
|
|
fields = ["user"]
|
|
|
|
class AfterCreate(BaseMemberSerializer):
|
|
role = serializers.SerializerMethodField()
|
|
|
|
class Meta(BaseMemberSerializer.Meta):
|
|
fields = ["id", "user", "role"]
|
|
|
|
def get_role(self, instance):
|
|
t, val = str(instance.role).split(".", 1)
|
|
return MembershipType[val].value
|
|
|
|
class List(BaseMemberSerializer):
|
|
role = serializers.SerializerMethodField()
|
|
|
|
class Meta(BaseMemberSerializer.Meta):
|
|
fields = ["id", "user", "role"]
|
|
|
|
def get_role(self, instance):
|
|
t, val = str(instance.role).split(".", 1)
|
|
return MembershipType[val].value
|
|
|
|
|
|
class ProjectSerializer:
|
|
class Retrieve(_BaseProjectSerializer):
|
|
products = serializers.SerializerMethodField()
|
|
publishable = serializers.SerializerMethodField()
|
|
products_amount = serializers.SerializerMethodField()
|
|
max_product_stage = serializers.ReadOnlyField()
|
|
members = MemberSerializer.List(many=True)
|
|
|
|
class Meta(_BaseProjectSerializer.Meta):
|
|
fields = [
|
|
"slug",
|
|
*_BaseProjectSerializer.Meta.fields,
|
|
"description",
|
|
"category",
|
|
"members",
|
|
"brand",
|
|
"products_amount",
|
|
"products",
|
|
"printing_files_date",
|
|
"promo_date",
|
|
"max_product_stage",
|
|
"published",
|
|
"publishable",
|
|
"created_at",
|
|
"updated_at",
|
|
]
|
|
|
|
def get_publishable(self, project: "Project"):
|
|
current_user = self.context["request"].user
|
|
return project.publishable_for_user(user=current_user)
|
|
|
|
def get_products(self, project: "Project"):
|
|
url = reverse_lazy("products:product-list")
|
|
return f"{url}?project={project.pk}"
|
|
|
|
def get_products_amount(self, project: "Project"):
|
|
return project.products.count()
|
|
|
|
class AfterCreate(_BaseProjectSerializer):
|
|
products = serializers.SerializerMethodField()
|
|
publishable = serializers.SerializerMethodField()
|
|
products_amount = serializers.SerializerMethodField()
|
|
max_product_stage = serializers.ReadOnlyField()
|
|
members = MemberSerializer.List(many=True)
|
|
|
|
class Meta(_BaseProjectSerializer.Meta):
|
|
fields = [
|
|
"id",
|
|
"slug",
|
|
*_BaseProjectSerializer.Meta.fields,
|
|
"description",
|
|
"category",
|
|
"brand",
|
|
"products_amount",
|
|
"products",
|
|
"printing_files_date",
|
|
"promo_date",
|
|
"members",
|
|
# Computed
|
|
"max_product_stage",
|
|
"published",
|
|
"publishable",
|
|
"created_at",
|
|
"updated_at",
|
|
]
|
|
|
|
def get_publishable(self, project: "Project"):
|
|
current_user = self.context["request"].user
|
|
return project.publishable_for_user(user=current_user)
|
|
|
|
def get_products(self, project: "Project"):
|
|
# TODO: Hyperlink?
|
|
url = reverse_lazy("products:product-list")
|
|
return f"{url}?project={project.pk}"
|
|
|
|
def get_products_amount(self, project: "Project"):
|
|
return project.products.count()
|
|
|
|
class List(_BaseProjectSerializer):
|
|
products = serializers.SerializerMethodField()
|
|
max_product_stage = serializers.ReadOnlyField()
|
|
members = MemberSerializer.List(many=True)
|
|
|
|
class Meta(_BaseProjectSerializer.Meta):
|
|
fields = [
|
|
"id",
|
|
"slug",
|
|
*_BaseProjectSerializer.Meta.fields,
|
|
"members",
|
|
"products",
|
|
"printing_files_date",
|
|
"category",
|
|
"brand",
|
|
# Computed
|
|
"max_product_stage",
|
|
"published",
|
|
"created_at",
|
|
"updated_at",
|
|
]
|
|
|
|
def get_products(self, instance):
|
|
# TODO: refactor, maybe custom serializerfield
|
|
url = reverse_lazy("products:product-list")
|
|
return f"{url}?project={instance.pk}"
|
|
|
|
class Create(_BaseProjectSerializer):
|
|
products_amount = serializers.IntegerField(min_value=1, write_only=True)
|
|
|
|
class Meta(_BaseProjectSerializer.Meta):
|
|
fields = [
|
|
*_BaseProjectSerializer.Meta.fields,
|
|
"description",
|
|
"category",
|
|
"brand",
|
|
"products_amount",
|
|
"printing_files_date",
|
|
"promo_date",
|
|
"created_at",
|
|
"updated_at",
|
|
]
|
|
|
|
# NOTE: business logic?
|
|
def create(self, validated_data):
|
|
products_amount = validated_data.pop("products_amount")
|
|
project = super().create(validated_data)
|
|
project.add_products(products_amount=products_amount)
|
|
membership = Member.objects.create(
|
|
user=self.context["request"].user,
|
|
role=MembershipType.SUPPLIER,
|
|
project=project,
|
|
)
|
|
project.members.add(membership)
|
|
return project
|
|
|
|
class Update(serializers.Serializer):
|
|
publish = serializers.BooleanField(default=False)
|
|
|
|
def update(self, instance: Project, validated_data):
|
|
current_user = self.context["request"].user
|
|
if validated_data["publish"] is True:
|
|
instance.publish_as_user(user=current_user)
|
|
return instance
|