diff --git a/apiserver/plane/api/urls.py b/apiserver/plane/api/urls.py index 6a6fcf1ae..f175736f1 100644 --- a/apiserver/plane/api/urls.py +++ b/apiserver/plane/api/urls.py @@ -83,6 +83,7 @@ from plane.api.views import ( EstimateViewSet, EstimatePointViewSet, ProjectEstimatePointEndpoint, + BulkCreateEstimatePointEndpoint, ## End Estimates # Shortcuts ShortCutViewSet, @@ -534,6 +535,11 @@ urlpatterns = [ ProjectEstimatePointEndpoint.as_view(), name="project-estimate-points", ), + path( + "workspaces//projects//estimates//bulk-create-estimate-points/", + BulkCreateEstimatePointEndpoint.as_view(), + name="bulk-create-estimate-points", + ), # End States ## # Shortcuts path( @@ -753,7 +759,7 @@ urlpatterns = [ name="project-issue-labels", ), path( - "workspaces//projects//bulk-create-labels/", + "workspaces//projects//lk-create-labels/", BulkCreateIssueLabelsEndpoint.as_view(), name="project-bulk-labels", ), diff --git a/apiserver/plane/api/views/__init__.py b/apiserver/plane/api/views/__init__.py index be1cfb4cd..b6780a518 100644 --- a/apiserver/plane/api/views/__init__.py +++ b/apiserver/plane/api/views/__init__.py @@ -135,4 +135,5 @@ from .estimate import ( EstimateViewSet, EstimatePointViewSet, ProjectEstimatePointEndpoint, + BulkCreateEstimatePointEndpoint, ) diff --git a/apiserver/plane/api/views/estimate.py b/apiserver/plane/api/views/estimate.py index fcc2ddfb0..fced7ccfc 100644 --- a/apiserver/plane/api/views/estimate.py +++ b/apiserver/plane/api/views/estimate.py @@ -135,3 +135,50 @@ class ProjectEstimatePointEndpoint(BaseAPIView): {"error": "Something went wrong please try again later"}, status=status.HTTP_400_BAD_REQUEST, ) + + +class BulkCreateEstimatePointEndpoint(BaseAPIView): + def post(self, request, slug, project_id, estimate_id): + try: + estimate = Estimate.objects.get( + pk=estimate_id, workspace__slug=slug, project=project_id + ) + + estimate_points = request.data.get("estimate_points", []) + + if not len(estimate_points) or len(estimate_points) > 8: + return Response( + {"error": "Estimate points are required"}, + status=status.HTTP_400_BAD_REQUEST, + ) + + estimate_points = EstimatePoint.objects.bulk_create( + [ + EstimatePoint( + estimate=estimate, + key=estimate_point.get("key", 0), + value=estimate_point.get("value", ""), + description=estimate_point.get("description", ""), + project_id=project_id, + workspace_id=estimate.workspace_id, + ) + for estimate_point in estimate_points + ], + batch_size=10, + ignore_conflicts=True, + ) + + serializer = EstimatePointSerializer(estimate_points, many=True) + + return Response(serializer.data, status=status.HTTP_200_OK) + except Estimate.DoesNotExist: + return Response( + {"error": "Estimate does not exist"}, + status=status.HTTP_400_BAD_REQUEST, + ) + except Exception as e: + capture_exception(e) + return Response( + {"error": "Something went wrong please try again later"}, + status=status.HTTP_400_BAD_REQUEST, + ) diff --git a/apiserver/plane/db/models/estimate.py b/apiserver/plane/db/models/estimate.py index a04c48360..f163a1407 100644 --- a/apiserver/plane/db/models/estimate.py +++ b/apiserver/plane/db/models/estimate.py @@ -27,7 +27,6 @@ class EstimatePoint(ProjectBaseModel): "db.Estimate", on_delete=models.CASCADE, related_name="points", - limit_choices_to={"estimate__points__count__lt": 10}, ) key = models.IntegerField( default=0, validators=[MinValueValidator(0), MaxValueValidator(7)]