from django.db.models import Q from django_filters import rest_framework as filters from outbo.apps.core.viewsets import ( AutoPermissionViewSetMixin, MultipleSerializerViewSet, CreateModelMixin, PartialUpdateModelMixin, RetrieveModelMixin, ListModelMixin, DestroyModelMixin, NestedViewSetMixin, ) from outbo.apps.projects.filters import ProjectFilterSet from outbo.apps.projects.models import Project, Member from outbo.apps.projects.models.member import MembershipType from outbo.apps.projects.queries import read_project_query from outbo.apps.projects.serializers import ProjectSerializer, MemberSerializer class ProjectViewSet( RetrieveModelMixin, ListModelMixin, CreateModelMixin, PartialUpdateModelMixin, AutoPermissionViewSetMixin, MultipleSerializerViewSet, ): queryset = Project.objects.all() serializer_class_set = ProjectSerializer filter_backends = (filters.DjangoFilterBackend,) filterset_class = ProjectFilterSet def get_queryset(self): qs = super().get_queryset() if self.action == "list": qs_filter = read_project_query(self.request.user) qs = qs.filter(qs_filter) # TODO: try to refactor this poor loops if self.request.user.is_observer or self.request.user.is_trader: projects_id = [] for project in Project.objects.filter(published=True): members = project.members.filter(role=self.request.user.user_role) for member in members: if member.user.organization == self.request.user.organization: projects_id.append(project.id) qs_id = qs.values_list("id", flat=True) qs = Project.objects.filter(Q(id__in=projects_id) | Q(id__in=qs_id)) if self.request.user.is_trader and self.request.user.category is not None: qs = qs.filter(category=self.request.user.category) return qs def partial_update(self, request, *args, **kwargs): return super().partial_update(request=request, *args, **kwargs) class ProjectMemberNestedViewSet( ListModelMixin, CreateModelMixin, DestroyModelMixin, NestedViewSetMixin, AutoPermissionViewSetMixin, MultipleSerializerViewSet, ): queryset = Member.objects.all() serializer_class_set = MemberSerializer def perform_create(self, *, serializer: MemberSerializer.Create): user = serializer.validated_data["user"] role = None if user.is_agency: role = MembershipType.AGENCY elif user.is_client: role = MembershipType.CLIENT elif user.is_supplier: role = MembershipType.SUPPLIER parents = self.get_parents_query_dict() project = Project.objects.get(pk=parents["project_id"]) membership = Member.objects.filter(project=project, user=user).first() if membership: serializer.instance = membership return serializer.save(project=project, role=role)