# Third party imports from rest_framework import serializers # Module imports from .base import BaseSerializer from .user import UserLiteSerializer from .issue import IssueStateSerializer from .workspace import WorkspaceLiteSerializer from .project import ProjectLiteSerializer from plane.db.models import Cycle, CycleIssue, CycleFavorite, CycleUserProperties class CycleWriteSerializer(BaseSerializer): def validate(self, data): if ( data.get("start_date", None) is not None and data.get("end_date", None) is not None and data.get("start_date", None) > data.get("end_date", None) ): raise serializers.ValidationError("Start date cannot exceed end date") return data class Meta: model = Cycle fields = "__all__" class CycleSerializer(BaseSerializer): owned_by = UserLiteSerializer(read_only=True) is_favorite = serializers.BooleanField(read_only=True) total_issues = serializers.IntegerField(read_only=True) cancelled_issues = serializers.IntegerField(read_only=True) completed_issues = serializers.IntegerField(read_only=True) started_issues = serializers.IntegerField(read_only=True) unstarted_issues = serializers.IntegerField(read_only=True) backlog_issues = serializers.IntegerField(read_only=True) assignees = serializers.SerializerMethodField(read_only=True) total_estimates = serializers.IntegerField(read_only=True) completed_estimates = serializers.IntegerField(read_only=True) started_estimates = serializers.IntegerField(read_only=True) workspace_detail = WorkspaceLiteSerializer(read_only=True, source="workspace") project_detail = ProjectLiteSerializer(read_only=True, source="project") status = serializers.CharField(read_only=True) def validate(self, data): if ( data.get("start_date", None) is not None and data.get("end_date", None) is not None and data.get("start_date", None) > data.get("end_date", None) ): raise serializers.ValidationError("Start date cannot exceed end date") return data def get_assignees(self, obj): members = [ { "avatar": assignee.avatar, "display_name": assignee.display_name, "id": assignee.id, } for issue_cycle in obj.issue_cycle.prefetch_related( "issue__assignees" ).all() for assignee in issue_cycle.issue.assignees.all() ] # Use a set comprehension to return only the unique objects unique_objects = {frozenset(item.items()) for item in members} # Convert the set back to a list of dictionaries unique_list = [dict(item) for item in unique_objects] return unique_list class Meta: model = Cycle fields = "__all__" read_only_fields = [ "workspace", "project", "owned_by", ] class CycleIssueSerializer(BaseSerializer): issue_detail = IssueStateSerializer(read_only=True, source="issue") sub_issues_count = serializers.IntegerField(read_only=True) class Meta: model = CycleIssue fields = "__all__" read_only_fields = [ "workspace", "project", "cycle", ] class CycleFavoriteSerializer(BaseSerializer): cycle_detail = CycleSerializer(source="cycle", read_only=True) class Meta: model = CycleFavorite fields = "__all__" read_only_fields = [ "workspace", "project", "user", ] class CycleUserPropertiesSerializer(BaseSerializer): class Meta: model = CycleUserProperties fields = "__all__" read_only_fields = [ "workspace", "project", "cycle" "user", ]