from rest_framework import serializers from core.serializers.base import BaseModelSerializer from apps.projects.models import ( Project, ProjectMembership, ProjectRate, ProjectUserRate, ) from core.serializers.mini import UserMiniSerializer class ProjectMemberInputSerializer(serializers.Serializer): user_id = serializers.UUIDField() role = serializers.ChoiceField(choices=ProjectMembership.Role.choices, default=ProjectMembership.Role.MEMBER) class ProjectSerializer(BaseModelSerializer): my_role = serializers.SerializerMethodField() members = serializers.SerializerMethodField() class Meta: model = Project fields = BaseModelSerializer.Meta.fields + ( "workspace", "name", "client", "description", "is_archived", "color", "my_role", "members", ) read_only_fields = fields def get_my_role(self, obj): request = self.context.get("request") if not request or not request.user.is_authenticated: return None membership = obj.memberships.filter(user=request.user, is_active=True, is_deleted=False).first() return getattr(membership, "role", None) def get_members(self, obj): """ Returns active project members in the response """ active_memberships = obj.memberships.filter(is_active=True, is_deleted=False) return ProjectMembershipSerializer(active_memberships, many=True).data def to_representation(self, instance): representation = super().to_representation(instance) if instance.client: representation['client'] = { 'id': instance.client.id, 'name': instance.client.name } return representation class ProjectCreateSerializer(serializers.Serializer): workspace = serializers.UUIDField() name = serializers.CharField(max_length=255) client = serializers.UUIDField(required=False, allow_null=True) description = serializers.CharField(required=False, allow_blank=True, default="") color = serializers.CharField(max_length=7, required=False, allow_blank=True, default="") members = ProjectMemberInputSerializer(many=True, required=False) class ProjectUpdateSerializer(serializers.Serializer): name = serializers.CharField(max_length=255, required=False) client = serializers.UUIDField(required=False, allow_null=True) description = serializers.CharField(required=False, allow_blank=True) color = serializers.CharField(max_length=7, required=False, allow_blank=True) is_archived = serializers.BooleanField(required=False) members = ProjectMemberInputSerializer(many=True, required=False) class ProjectMembershipSerializer(BaseModelSerializer): user_details = UserMiniSerializer(read_only=True) class Meta: model = ProjectMembership fields = BaseModelSerializer.Meta.fields + ( "project", "user", "user_details", "role", "is_active", ) read_only_fields = fields class ProjectMembershipCreateSerializer(serializers.Serializer): project_id = serializers.UUIDField() user_id = serializers.UUIDField() role = serializers.ChoiceField(choices=ProjectMembership.Role.choices) class ProjectMembershipUpdateSerializer(serializers.Serializer): role = serializers.ChoiceField(choices=ProjectMembership.Role.choices, required=False) is_active = serializers.BooleanField(required=False) class ProjectRateSerializer(BaseModelSerializer): class Meta: model = ProjectRate fields = BaseModelSerializer.Meta.fields + ( "project", "hourly_rate", "currency", ) read_only_fields = fields class ProjectRateCreateSerializer(serializers.Serializer): project_id = serializers.UUIDField() hourly_rate = serializers.DecimalField(max_digits=10, decimal_places=2) currency = serializers.CharField(max_length=3, default="USD") class ProjectRateUpdateSerializer(serializers.Serializer): hourly_rate = serializers.DecimalField(max_digits=10, decimal_places=2, required=False) currency = serializers.CharField(max_length=3, required=False) class ProjectUserRateSerializer(BaseModelSerializer): class Meta: model = ProjectUserRate fields = BaseModelSerializer.Meta.fields + ( "project", "user", "hourly_rate", "currency", ) read_only_fields = fields class ProjectUserRateCreateSerializer(serializers.Serializer): project_id = serializers.UUIDField() user_id = serializers.UUIDField() hourly_rate = serializers.DecimalField(max_digits=10, decimal_places=2) currency = serializers.CharField(max_length=3, default="USD") class ProjectUserRateUpdateSerializer(serializers.Serializer): hourly_rate = serializers.DecimalField(max_digits=10, decimal_places=2, required=False) currency = serializers.CharField(max_length=3, required=False)