refactor: create new endpoints for date checking getting current upcoming and past cycles (#343)

* refactor: create new endpoints for date checking getting current upcoming and past cycles

* refactor: rename endpoint to match consistency
This commit is contained in:
pablohashescobar 2023-02-28 02:08:55 +05:30 committed by GitHub
parent 1ff0970ed6
commit 1255552ebe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 117 additions and 14 deletions

View File

@ -78,6 +78,9 @@ from plane.api.views import (
# Cycles # Cycles
CycleViewSet, CycleViewSet,
CycleIssueViewSet, CycleIssueViewSet,
CycleDateCheckEndpoint,
CurrentUpcomingCyclesEndpoint,
CompletedCyclesEndpoint,
## End Cycles ## End Cycles
# Modules # Modules
ModuleViewSet, ModuleViewSet,
@ -490,6 +493,21 @@ urlpatterns = [
), ),
name="project-cycle", name="project-cycle",
), ),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/cycles/date-check/",
CycleDateCheckEndpoint.as_view(),
name="project-cycle",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/cycles/current-upcoming-cycles/",
CurrentUpcomingCyclesEndpoint.as_view(),
name="project-cycle",
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/cycles/completed-cycles/",
CompletedCyclesEndpoint.as_view(),
name="project-cycle",
),
## End Cycles ## End Cycles
# Issue # Issue
path( path(

View File

@ -39,7 +39,13 @@ from .workspace import (
from .state import StateViewSet from .state import StateViewSet
from .shortcut import ShortCutViewSet from .shortcut import ShortCutViewSet
from .view import ViewViewSet from .view import ViewViewSet
from .cycle import CycleViewSet, CycleIssueViewSet from .cycle import (
CycleViewSet,
CycleIssueViewSet,
CycleDateCheckEndpoint,
CurrentUpcomingCyclesEndpoint,
CompletedCyclesEndpoint,
)
from .asset import FileAssetEndpoint from .asset import FileAssetEndpoint
from .issue import ( from .issue import (
IssueViewSet, IssueViewSet,

View File

@ -2,8 +2,9 @@
import json import json
# Django imports # Django imports
from django.db.models import OuterRef, Func, F from django.db.models import OuterRef, Func, F, Q
from django.core import serializers from django.core import serializers
from django.utils import timezone
# Third party imports # Third party imports
from rest_framework.response import Response from rest_framework.response import Response
@ -11,7 +12,7 @@ from rest_framework import status
from sentry_sdk import capture_exception from sentry_sdk import capture_exception
# Module imports # Module imports
from . import BaseViewSet from . import BaseViewSet, BaseAPIView
from plane.api.serializers import CycleSerializer, CycleIssueSerializer from plane.api.serializers import CycleSerializer, CycleIssueSerializer
from plane.api.permissions import ProjectEntityPermission from plane.api.permissions import ProjectEntityPermission
from plane.db.models import Cycle, CycleIssue, Issue from plane.db.models import Cycle, CycleIssue, Issue
@ -206,3 +207,90 @@ class CycleIssueViewSet(BaseViewSet):
{"error": "Something went wrong please try again later"}, {"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST, status=status.HTTP_400_BAD_REQUEST,
) )
class CycleDateCheckEndpoint(BaseAPIView):
def post(self, request, slug, project_id):
try:
start_date = request.data.get("start_date")
end_date = request.data.get("end_date")
cycles = Cycle.objects.filter(
Q(start_date__lte=start_date, end_date__gte=start_date)
| Q(start_date__gte=end_date, end_date__lte=end_date),
workspace__slug=slug,
project_id=project_id,
)
if cycles.exists():
return Response(
{
"error": "You have a cycle already on the given dates, if you want to create your draft cycle you can do that by removing dates",
"cycles": CycleSerializer(cycles, many=True).data,
"status": False,
}
)
else:
return Response({"status": True}, status=status.HTTP_200_OK)
except Exception as e:
capture_exception(e)
return Response(
{"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST,
)
class CurrentUpcomingCyclesEndpoint(BaseAPIView):
def get(self, request, slug, project_id):
try:
current_cycle = Cycle.objects.filter(
workspace__slug=slug,
project_id=project_id,
start_date__lte=timezone.now(),
end_date__gte=timezone.now(),
)
upcoming_cycle = Cycle.objects.filter(
workspace__slug=slug,
project_id=project_id,
start_date__gte=timezone.now(),
)
return Response(
{
"current_cycle": CycleSerializer(current_cycle, many=True).data,
"upcoming_cycle": CycleSerializer(upcoming_cycle, many=True).data,
},
status=status.HTTP_200_OK,
)
except Exception as e:
capture_exception(e)
return Response(
{"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST,
)
class CompletedCyclesEndpoint(BaseAPIView):
def get(self, request, slug, project_id):
try:
past_cycles = Cycle.objects.filter(
workspace__slug=slug,
project_id=project_id,
end_date__lte=timezone.now(),
)
return Response(
{
"past_cycles": CycleSerializer(past_cycles, many=True).data,
},
status=status.HTTP_200_OK,
)
except Exception as e:
capture_exception(e)
return Response(
{"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST,
)

View File

@ -7,11 +7,7 @@ from . import ProjectBaseModel
class Cycle(ProjectBaseModel): class Cycle(ProjectBaseModel):
STATUS_CHOICES = (
("draft", "Draft"),
("started", "Started"),
("completed", "Completed"),
)
name = models.CharField(max_length=255, verbose_name="Cycle Name") name = models.CharField(max_length=255, verbose_name="Cycle Name")
description = models.TextField(verbose_name="Cycle Description", blank=True) description = models.TextField(verbose_name="Cycle Description", blank=True)
start_date = models.DateField(verbose_name="Start Date", blank=True, null=True) start_date = models.DateField(verbose_name="Start Date", blank=True, null=True)
@ -21,12 +17,7 @@ class Cycle(ProjectBaseModel):
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name="owned_by_cycle", related_name="owned_by_cycle",
) )
status = models.CharField(
max_length=255,
verbose_name="Cycle Status",
choices=STATUS_CHOICES,
default="draft",
)
class Meta: class Meta:
verbose_name = "Cycle" verbose_name = "Cycle"