Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

organisation api completed #629

Merged
merged 12 commits into from
Mar 17, 2024
5 changes: 2 additions & 3 deletions backend/content/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- DiscussionTag
- Image
"""

from uuid import uuid4

from django.contrib.postgres.fields import ArrayField
Expand All @@ -39,9 +40,7 @@ class Resource(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255)
description = models.TextField(max_length=500)
topics = ArrayField(
models.CharField(max_length=255), default=list, blank=True
)
topics = ArrayField(models.CharField(max_length=255), default=list, blank=True)
category = models.CharField(max_length=255, blank=True)
url = models.URLField(max_length=255)
private = models.BooleanField(default=True)
Expand Down
4 changes: 2 additions & 2 deletions backend/entities/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
GroupTopic,
Organization,
OrganizationApplication,
OrganizationApplicationStatus,
OrganizationEvent,
OrganizationMember,
OrganizationResource,
OrganizationTask,
OrganizationTopic,
StatusType,
)

admin.site.register(Group)
Expand All @@ -23,9 +23,9 @@
admin.site.register(GroupTopic)
admin.site.register(Organization)
admin.site.register(OrganizationApplication)
admin.site.register(OrganizationApplicationStatus)
admin.site.register(OrganizationEvent)
admin.site.register(OrganizationMember)
admin.site.register(OrganizationResource)
admin.site.register(OrganizationTask)
admin.site.register(OrganizationTopic)
admin.site.register(StatusType)
26 changes: 23 additions & 3 deletions backend/entities/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- GroupResource
- GroupTopic
"""

from uuid import uuid4

from django.contrib.postgres.fields import ArrayField
Expand All @@ -27,7 +28,7 @@

class Organization(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
name = models.CharField(max_length=255)
name = models.CharField(max_length=255, unique=True)
tagline = models.CharField(max_length=255, blank=True)
org_icon = models.OneToOneField(
"content.Image", on_delete=models.CASCADE, null=True, blank=True
Expand All @@ -43,8 +44,8 @@ class Organization(models.Model):
models.CharField(max_length=255), default=list, blank=True
)
high_risk = models.BooleanField(default=False)
# status = models.IntegerField(default=1)
# status_updated = models.DateTimeField(auto_now=True)
status = models.ForeignKey("StatusType", on_delete=models.CASCADE, default=1)
status_updated = models.DateTimeField(auto_now=True, null=True)
acceptance_date = models.DateTimeField()
deletion_date = models.DateTimeField(null=True, blank=True)

Expand Down Expand Up @@ -74,6 +75,7 @@ class OrganizationApplication(models.Model):
)
creation_date = models.DateTimeField(auto_now_add=True)
status_updated = models.DateTimeField(auto_now=True)
status = models.ForeignKey("StatusType", on_delete=models.CASCADE, default=1)

def __str__(self) -> str:
return f"{self.creation_date}"
Expand Down Expand Up @@ -180,3 +182,21 @@ class GroupTopic(models.Model):

def __str__(self) -> str:
return f"{self.id}"


class Status(models.Model):
status_type = models.ForeignKey("StatusType", on_delete=models.CASCADE)
org_id = models.ForeignKey(
Organization, on_delete=models.CASCADE, related_name="org_status"
)
user_id = models.ForeignKey("authentication.User", on_delete=models.CASCADE)

def __str__(self) -> str:
return f"{self.org_id.name} - {self.status_type.name}"


class StatusType(models.Model):
name = models.CharField(max_length=255)

def __str__(self) -> str:
return self.name
29 changes: 21 additions & 8 deletions backend/entities/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,23 @@
OrganizationResource,
OrganizationTask,
OrganizationTopic,
Status,
StatusType,
)


class OrganizationSerializer(serializers.ModelSerializer[Organization]):
class Meta:
model = Organization
exclude = ["deletion_date"]
extra_kwargs = {
"created_by": {"read_only": True},
"social_accounts": {"required": False},
"status_updated": {"read_only": True},
"acceptance_date": {"read_only": True},
}
fields = "__all__"

def validate(self, data: Dict[str, Union[str, int]]) -> Dict[str, Union[str, int]]:
validate_empty(data["name"], "name")
validate_empty(data["description"], "description")
validate_flags_number(data)
# validate_object_existence(User, data["created_by"]) TODO: BUG check if validate_object_existence can be fixed since causing errors during post requests

return data


class OrganizationApplicationStatusSerializer(
serializers.ModelSerializer[OrganizationApplicationStatus]
Expand Down Expand Up @@ -205,3 +206,15 @@ def validate(self, data: Dict[str, Union[str, int]]) -> Dict[str, Union[str, int
validate_object_existence(Topic, data["topic_id"])

return data


class StatusSerializer(serializers.ModelSerializer[Status]):
class Meta:
model = Status
fields = "__all__"


class StatusTypeSerializer(serializers.ModelSerializer[StatusType]):
class Meta:
model = StatusType
fields = "__all__"
5 changes: 2 additions & 3 deletions backend/entities/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
router = DefaultRouter()

router.register(r"organizations", views.OrganizationViewSet, basename="organization")
router.register(
r"organization_application_statuses", views.OrganizationApplicationStatusViewSet
)
router.register(r"organization_applications", views.OrganizationApplicationViewSet)
router.register(r"organization_events", views.OrganizationEventViewSet)
router.register(r"organization_members", views.OrganizationMemberViewSet)
Expand All @@ -22,6 +19,8 @@
router.register(r"group_members", views.GroupMemberViewSet)
router.register(r"group_resources", views.GroupResourceViewSet)
router.register(r"group_topics", views.GroupTopicViewSet)
router.register(r"status", views.StatusViewSet)
router.register(r"status_types", views.StatusTypeViewSet)

urlpatterns = [
path("", include(router.urls)),
Expand Down
139 changes: 102 additions & 37 deletions backend/entities/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from django.shortcuts import get_object_or_404
# mypy: disable-error-code="override"
from django.utils import timezone
from rest_framework import status, viewsets
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.throttling import AnonRateThrottle, UserRateThrottle
Expand All @@ -14,12 +16,13 @@
GroupTopic,
Organization,
OrganizationApplication,
OrganizationApplicationStatus,
OrganizationEvent,
OrganizationMember,
OrganizationResource,
OrganizationTask,
OrganizationTopic,
Status,
StatusType,
)
from .serializers import (
GroupEventSerializer,
Expand All @@ -28,13 +31,14 @@
GroupSerializer,
GroupTopicSerializer,
OrganizationApplicationSerializer,
OrganizationApplicationStatusSerializer,
OrganizationEventSerializer,
OrganizationMemberSerializer,
OrganizationResourceSerializer,
OrganizationSerializer,
OrganizationTaskSerializer,
OrganizationTopicSerializer,
StatusSerializer,
StatusTypeSerializer,
)


Expand All @@ -43,42 +47,91 @@ class OrganizationViewSet(viewsets.ModelViewSet[Organization]):
serializer_class = OrganizationSerializer
pagination_class = CustomPagination
throttle_classes = [AnonRateThrottle, UserRateThrottle]
permission_classes = [
IsAuthenticated,
]

def create(self, request: Request, *args: str, **kwargs: int) -> Response:
def create(self, request: Request) -> Response:
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
instance = serializer.save()
data = {"message": f"New Organization created with id: {instance.id}"}
return Response(data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

def retrieve(self, request: Request, *args: str, **kwargs: int) -> Response:
instance = get_object_or_404(Organization, pk=kwargs["pk"])
serializer = self.get_serializer(instance)
return Response(serializer.data)

def partial_update(self, request: Request, *args: str, **kwargs: int) -> Response:
instance = get_object_or_404(Organization, pk=kwargs["pk"])
serializer = self.get_serializer(instance, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
data = {"message": f'Organization {kwargs["pk"]} has been updated'}
return Response(data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

def destroy(self, request: Request, *args: str, **kwargs: int) -> Response:
instance = get_object_or_404(Organization, pk=kwargs["pk"])
instance.delete()
data = {"message": f'Organization {kwargs["pk"]} has been deleted successfully'}
return Response(data, status=status.HTTP_204_NO_CONTENT)


class OrganizationApplicationStatusViewSet(
viewsets.ModelViewSet[OrganizationApplicationStatus]
):
queryset = OrganizationApplicationStatus.objects.all()
serializer_class = OrganizationApplicationStatusSerializer
pagination_class = CustomPagination
serializer.is_valid(raise_exception=True)
org = serializer.save(created_by=request.user)
OrganizationApplication.objects.create(org_id=org)
return Response(serializer.data, status=status.HTTP_201_CREATED)

def retrieve(self, request: Request, pk: str | None = None) -> Response:
org = self.queryset.filter(id=pk).first()
if org:
serializer = self.get_serializer(org)
return Response(serializer.data, status=status.HTTP_200_OK)

return Response({"error": "Organization not found"}, status.HTTP_404_NOT_FOUND)

def list(self, request: Request) -> Response:
serializer = self.get_serializer(self.get_queryset(), many=True)
return Response(serializer.data, status=status.HTTP_200_OK)

def update(self, request: Request, pk: str | None = None) -> Response:
org = self.queryset.filter(id=pk).first()
if org is None:
return Response(
{"error": "Organization not found"}, status.HTTP_404_NOT_FOUND
)

if request.user != org.created_by:
return Response(
{"error": "You are not authorized to update this organization"},
status.HTTP_401_UNAUTHORIZED,
)

serializer = self.get_serializer(org, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status.HTTP_200_OK)

def partial_update(self, request: Request, pk: str | None = None) -> Response:
org = self.queryset.filter(id=pk).first()
if org is None:
return Response(
{"error": "Organization not found"}, status.HTTP_404_NOT_FOUND
)

if request.user != org.created_by:
return Response(
{"error": "You are not authorized to update this organization"},
status.HTTP_401_UNAUTHORIZED,
)

serializer = self.get_serializer(org, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status.HTTP_200_OK)

def destroy(self, request: Request, pk: str | None = None) -> Response:
org = self.queryset.filter(id=pk).first()
print(pk, org)
if org is None:
return Response(
{"error": "Organization not found"}, status.HTTP_404_NOT_FOUND
)

if request.user != org.created_by:
return Response(
{"error": "You are not authorized to delete this organization"},
status.HTTP_401_UNAUTHORIZED,
)

org.status = StatusType.objects.get(id=3) # 3 is the id of the deleted status
org.deletion_date = timezone.now()
org.high_risk = False
org.status_updated = None
org.tagline = ""
org.description = ""
org.social_accounts = []
org.save()

return Response(
{"message": "Organization deleted successfully"}, status.HTTP_200_OK
)


class OrganizationApplicationViewSet(viewsets.ModelViewSet[OrganizationApplication]):
Expand Down Expand Up @@ -145,3 +198,15 @@ class GroupTopicViewSet(viewsets.ModelViewSet[GroupTopic]):
queryset = GroupTopic.objects.all()
serializer_class = GroupTopicSerializer
pagination_class = CustomPagination


class StatusViewSet(viewsets.ModelViewSet[Status]):
queryset = Status.objects.all()
serializer_class = StatusSerializer
pagination_class = CustomPagination


class StatusTypeViewSet(viewsets.ModelViewSet[StatusType]):
queryset = StatusType.objects.all()
serializer_class = StatusTypeSerializer
pagination_class = CustomPagination
Loading