From be57757b2c890aa4c69893e3e2ee3fd5601cf0ab Mon Sep 17 00:00:00 2001 From: gurusinath Date: Mon, 6 Jan 2025 18:43:13 +0530 Subject: [PATCH 1/3] chore: handled start and end date issue when user send the start and end date equal --- apiserver/plane/api/serializers/cycle.py | 12 ++++++++-- apiserver/plane/app/serializers/cycle.py | 11 +++++++-- apiserver/plane/app/views/cycle/base.py | 26 ++++++++++++++------- apiserver/plane/utils/timezone_converter.py | 9 +++++-- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/apiserver/plane/api/serializers/cycle.py b/apiserver/plane/api/serializers/cycle.py index d394dc9bd6d..696de4cbe6c 100644 --- a/apiserver/plane/api/serializers/cycle.py +++ b/apiserver/plane/api/serializers/cycle.py @@ -6,6 +6,7 @@ from plane.db.models import Cycle, CycleIssue from plane.utils.timezone_converter import convert_to_utc + class CycleSerializer(BaseSerializer): total_issues = serializers.IntegerField(read_only=True) cancelled_issues = serializers.IntegerField(read_only=True) @@ -30,11 +31,18 @@ def validate(self, data): and data.get("end_date", None) is not None ): project_id = self.initial_data.get("project_id") or self.instance.project_id + is_start_date_end_date_equal = ( + True if data.get("start_date") == data.get("end_date") else False + ) data["start_date"] = convert_to_utc( - str(data.get("start_date").date()), project_id, is_start_date=True + date=str(data.get("start_date").date()), + project_id=project_id, + is_start_date=True, ) data["end_date"] = convert_to_utc( - str(data.get("end_date", None).date()), project_id + date=str(data.get("end_date", None).date()), + project_id=project_id, + is_end_date=is_start_date_end_date_equal, ) return data diff --git a/apiserver/plane/app/serializers/cycle.py b/apiserver/plane/app/serializers/cycle.py index 28ec62134cf..019dc0c2051 100644 --- a/apiserver/plane/app/serializers/cycle.py +++ b/apiserver/plane/app/serializers/cycle.py @@ -21,11 +21,18 @@ def validate(self, data): and data.get("end_date", None) is not None ): project_id = self.initial_data.get("project_id") or self.instance.project_id + is_start_date_end_date_equal = ( + True if data.get("start_date") == data.get("end_date") else False + ) data["start_date"] = convert_to_utc( - str(data.get("start_date").date()), project_id, is_start_date=True + date=str(data.get("start_date").date()), + project_id=project_id, + is_start_date=True, ) data["end_date"] = convert_to_utc( - str(data.get("end_date", None).date()), project_id + date=str(data.get("end_date", None).date()), + project_id=project_id, + is_end_date=is_start_date_end_date_equal, ) return data diff --git a/apiserver/plane/app/views/cycle/base.py b/apiserver/plane/app/views/cycle/base.py index 9bf498886b3..42d785e6a15 100644 --- a/apiserver/plane/app/views/cycle/base.py +++ b/apiserver/plane/app/views/cycle/base.py @@ -143,10 +143,7 @@ def get_queryset(self): & Q(end_date__gte=current_time_in_utc), then=Value("CURRENT"), ), - When( - start_date__gt=current_time_in_utc, - then=Value("UPCOMING"), - ), + When(start_date__gt=current_time_in_utc, then=Value("UPCOMING")), When(end_date__lt=current_time_in_utc, then=Value("COMPLETED")), When( Q(start_date__isnull=True) & Q(end_date__isnull=True), @@ -259,7 +256,9 @@ def list(self, request, slug, project_id): "created_by", ) datetime_fields = ["start_date", "end_date"] - data = user_timezone_converter(data, datetime_fields, request.user.user_timezone) + data = user_timezone_converter( + data, datetime_fields, request.user.user_timezone + ) return Response(data, status=status.HTTP_200_OK) @allow_permission([ROLE.ADMIN, ROLE.MEMBER]) @@ -457,7 +456,9 @@ def retrieve(self, request, slug, project_id, pk): queryset = queryset.first() datetime_fields = ["start_date", "end_date"] - data = user_timezone_converter(data, datetime_fields, request.user.user_timezone) + data = user_timezone_converter( + data, datetime_fields, request.user.user_timezone + ) recent_visited_task.delay( slug=slug, @@ -533,8 +534,17 @@ def post(self, request, slug, project_id): status=status.HTTP_400_BAD_REQUEST, ) - start_date = convert_to_utc(str(start_date), project_id, is_start_date=True) - end_date = convert_to_utc(str(end_date), project_id) + is_start_date_end_date_equal = ( + True if str("start_date") == str("end_date") else False + ) + start_date = convert_to_utc( + date=str(start_date), project_id=project_id, is_start_date=True + ) + end_date = convert_to_utc( + date=str(end_date), + project_id=project_id, + is_end_date=is_start_date_end_date_equal, + ) # Check if any cycle intersects in the given interval cycles = Cycle.objects.filter( diff --git a/apiserver/plane/utils/timezone_converter.py b/apiserver/plane/utils/timezone_converter.py index 46a864b62dd..163a1f844e1 100644 --- a/apiserver/plane/utils/timezone_converter.py +++ b/apiserver/plane/utils/timezone_converter.py @@ -3,6 +3,7 @@ from datetime import datetime, time from datetime import timedelta + def user_timezone_converter(queryset, datetime_fields, user_timezone): # Create a timezone object for the user's timezone user_tz = pytz.timezone(user_timezone) @@ -28,7 +29,7 @@ def user_timezone_converter(queryset, datetime_fields, user_timezone): return queryset_values -def convert_to_utc(date, project_id, is_start_date=False): +def convert_to_utc(date, project_id, is_start_date=False, is_end_date=False): """ Converts a start date string to the project's local timezone at 12:00 AM and then converts it to UTC for storage. @@ -60,7 +61,11 @@ def convert_to_utc(date, project_id, is_start_date=False): # If it's an start date, add one minute if is_start_date: - localized_datetime += timedelta(minutes=1) + localized_datetime += timedelta(minutes=0, seconds=1) + + # If it's an end date, add 23 hours, 59 minutes, and 59 seconds + if is_end_date: + localized_datetime += timedelta(hours=23, minutes=59, seconds=59) # Convert the localized datetime to UTC utc_datetime = localized_datetime.astimezone(pytz.utc) From e867bca7121fc6e9e79657b406b0f59e0c6265a2 Mon Sep 17 00:00:00 2001 From: gurusinath Date: Mon, 6 Jan 2025 19:23:04 +0530 Subject: [PATCH 2/3] chore: updated variable name and comment --- apiserver/plane/api/serializers/cycle.py | 2 +- apiserver/plane/app/serializers/cycle.py | 2 +- apiserver/plane/app/views/cycle/base.py | 2 +- apiserver/plane/utils/timezone_converter.py | 9 ++++++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apiserver/plane/api/serializers/cycle.py b/apiserver/plane/api/serializers/cycle.py index 696de4cbe6c..357cb35ea12 100644 --- a/apiserver/plane/api/serializers/cycle.py +++ b/apiserver/plane/api/serializers/cycle.py @@ -42,7 +42,7 @@ def validate(self, data): data["end_date"] = convert_to_utc( date=str(data.get("end_date", None).date()), project_id=project_id, - is_end_date=is_start_date_end_date_equal, + is_end_date=is_start_date_end_date_equal=is_start_date_end_date_equal, ) return data diff --git a/apiserver/plane/app/serializers/cycle.py b/apiserver/plane/app/serializers/cycle.py index 019dc0c2051..f6572e94e01 100644 --- a/apiserver/plane/app/serializers/cycle.py +++ b/apiserver/plane/app/serializers/cycle.py @@ -32,7 +32,7 @@ def validate(self, data): data["end_date"] = convert_to_utc( date=str(data.get("end_date", None).date()), project_id=project_id, - is_end_date=is_start_date_end_date_equal, + is_end_date=is_start_date_end_date_equal=is_start_date_end_date_equal, ) return data diff --git a/apiserver/plane/app/views/cycle/base.py b/apiserver/plane/app/views/cycle/base.py index 42d785e6a15..530b91fc57a 100644 --- a/apiserver/plane/app/views/cycle/base.py +++ b/apiserver/plane/app/views/cycle/base.py @@ -543,7 +543,7 @@ def post(self, request, slug, project_id): end_date = convert_to_utc( date=str(end_date), project_id=project_id, - is_end_date=is_start_date_end_date_equal, + is_end_date=is_start_date_end_date_equal=is_start_date_end_date_equal, ) # Check if any cycle intersects in the given interval diff --git a/apiserver/plane/utils/timezone_converter.py b/apiserver/plane/utils/timezone_converter.py index 163a1f844e1..3e14d0bf60b 100644 --- a/apiserver/plane/utils/timezone_converter.py +++ b/apiserver/plane/utils/timezone_converter.py @@ -29,7 +29,9 @@ def user_timezone_converter(queryset, datetime_fields, user_timezone): return queryset_values -def convert_to_utc(date, project_id, is_start_date=False, is_end_date=False): +def convert_to_utc( + date, project_id, is_start_date=False, is_start_date_end_date_equal=False +): """ Converts a start date string to the project's local timezone at 12:00 AM and then converts it to UTC for storage. @@ -63,8 +65,9 @@ def convert_to_utc(date, project_id, is_start_date=False, is_end_date=False): if is_start_date: localized_datetime += timedelta(minutes=0, seconds=1) - # If it's an end date, add 23 hours, 59 minutes, and 59 seconds - if is_end_date: + # If it's start an end date are equal, add 23 hours, 59 minutes, and 59 seconds + # to make it the end of the day + if is_start_date_end_date_equal: localized_datetime += timedelta(hours=23, minutes=59, seconds=59) # Convert the localized datetime to UTC From debe5b1697792dea5f348ae801ee7da0a33a21d2 Mon Sep 17 00:00:00 2001 From: gurusinath Date: Mon, 6 Jan 2025 19:24:01 +0530 Subject: [PATCH 3/3] chore: typo --- apiserver/plane/api/serializers/cycle.py | 2 +- apiserver/plane/app/serializers/cycle.py | 2 +- apiserver/plane/app/views/cycle/base.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apiserver/plane/api/serializers/cycle.py b/apiserver/plane/api/serializers/cycle.py index 357cb35ea12..f7aef438494 100644 --- a/apiserver/plane/api/serializers/cycle.py +++ b/apiserver/plane/api/serializers/cycle.py @@ -42,7 +42,7 @@ def validate(self, data): data["end_date"] = convert_to_utc( date=str(data.get("end_date", None).date()), project_id=project_id, - is_end_date=is_start_date_end_date_equal=is_start_date_end_date_equal, + is_start_date_end_date_equal=is_start_date_end_date_equal, ) return data diff --git a/apiserver/plane/app/serializers/cycle.py b/apiserver/plane/app/serializers/cycle.py index f6572e94e01..6e0d31553e7 100644 --- a/apiserver/plane/app/serializers/cycle.py +++ b/apiserver/plane/app/serializers/cycle.py @@ -32,7 +32,7 @@ def validate(self, data): data["end_date"] = convert_to_utc( date=str(data.get("end_date", None).date()), project_id=project_id, - is_end_date=is_start_date_end_date_equal=is_start_date_end_date_equal, + is_start_date_end_date_equal=is_start_date_end_date_equal, ) return data diff --git a/apiserver/plane/app/views/cycle/base.py b/apiserver/plane/app/views/cycle/base.py index 530b91fc57a..b063a8a2659 100644 --- a/apiserver/plane/app/views/cycle/base.py +++ b/apiserver/plane/app/views/cycle/base.py @@ -543,7 +543,7 @@ def post(self, request, slug, project_id): end_date = convert_to_utc( date=str(end_date), project_id=project_id, - is_end_date=is_start_date_end_date_equal=is_start_date_end_date_equal, + is_start_date_end_date_equal=is_start_date_end_date_equal, ) # Check if any cycle intersects in the given interval