mirror of
https://github.com/makeplane/plane.git
synced 2026-07-11 21:10:13 +02:00
Merge branch 'chore-cycles-upgrade' of https://github.com/makeplane/plane into chore-cycles-upgrade
This commit is contained in:
@@ -311,7 +311,7 @@ class CycleAPIEndpoint(BaseAPIView):
|
||||
|
||||
if (
|
||||
cycle.end_date is not None
|
||||
and cycle.end_date < timezone.now().date()
|
||||
and cycle.end_date < timezone.now()
|
||||
):
|
||||
if "sort_order" in request_data:
|
||||
# Can only change sort order
|
||||
@@ -537,7 +537,7 @@ class CycleArchiveUnarchiveAPIEndpoint(BaseAPIView):
|
||||
cycle = Cycle.objects.get(
|
||||
pk=cycle_id, project_id=project_id, workspace__slug=slug
|
||||
)
|
||||
if cycle.end_date >= timezone.now().date():
|
||||
if cycle.end_date >= timezone.now():
|
||||
return Response(
|
||||
{"error": "Only completed cycles can be archived"},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
@@ -1146,7 +1146,7 @@ class TransferCycleIssueAPIEndpoint(BaseAPIView):
|
||||
|
||||
if (
|
||||
new_cycle.end_date is not None
|
||||
and new_cycle.end_date < timezone.now().date()
|
||||
and new_cycle.end_date < timezone.now()
|
||||
):
|
||||
return Response(
|
||||
{
|
||||
|
||||
@@ -604,7 +604,7 @@ class CycleArchiveUnarchiveEndpoint(BaseAPIView):
|
||||
pk=cycle_id, project_id=project_id, workspace__slug=slug
|
||||
)
|
||||
|
||||
if cycle.end_date >= timezone.now().date():
|
||||
if cycle.end_date >= timezone.now():
|
||||
return Response(
|
||||
{"error": "Only completed cycles can be archived"},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
|
||||
@@ -311,7 +311,7 @@ class CycleViewSet(BaseViewSet):
|
||||
|
||||
if (
|
||||
cycle.end_date is not None
|
||||
and cycle.end_date < timezone.now().date()
|
||||
and cycle.end_date < timezone.now()
|
||||
):
|
||||
if "sort_order" in request_data:
|
||||
# Can only change sort order for a completed cycle``
|
||||
@@ -928,7 +928,7 @@ class TransferCycleIssueEndpoint(BaseAPIView):
|
||||
|
||||
if (
|
||||
new_cycle.end_date is not None
|
||||
and new_cycle.end_date < timezone.now().date()
|
||||
and new_cycle.end_date < timezone.now()
|
||||
):
|
||||
return Response(
|
||||
{
|
||||
|
||||
@@ -248,10 +248,7 @@ class CycleIssueViewSet(BaseViewSet):
|
||||
workspace__slug=slug, project_id=project_id, pk=cycle_id
|
||||
)
|
||||
|
||||
if (
|
||||
cycle.end_date is not None
|
||||
and cycle.end_date < timezone.now().date()
|
||||
):
|
||||
if cycle.end_date is not None and cycle.end_date < timezone.now():
|
||||
return Response(
|
||||
{
|
||||
"error": "The Cycle has already been completed so no new issues can be added"
|
||||
@@ -271,8 +268,10 @@ class CycleIssueViewSet(BaseViewSet):
|
||||
new_issues = list(set(issues) - set(existing_issues))
|
||||
|
||||
# Fetch issue details
|
||||
issue_objects = Issue.objects.filter(id__in=new_issues)
|
||||
issue_dict = {issue.id: issue for issue in issue_objects}
|
||||
issue_objects = Issue.objects.filter(id__in=issues).annotate(
|
||||
cycle_id=F("issue_cycle__cycle_id")
|
||||
)
|
||||
issue_dict = {str(issue.id): issue for issue in issue_objects}
|
||||
|
||||
# New issues to create
|
||||
created_records = CycleIssue.objects.bulk_create(
|
||||
@@ -290,41 +289,59 @@ class CycleIssueViewSet(BaseViewSet):
|
||||
batch_size=10,
|
||||
)
|
||||
|
||||
# estimate_type = Project.objects.filter(
|
||||
# workspace__slug=slug,
|
||||
# pk=project_id,
|
||||
# estimate__isnull=False,
|
||||
# estimate__type="points",
|
||||
# ).exists()
|
||||
estimate_type = Project.objects.filter(
|
||||
workspace__slug=slug,
|
||||
pk=project_id,
|
||||
estimate__isnull=False,
|
||||
estimate__type="points",
|
||||
).exists()
|
||||
|
||||
# for issue_id in new_issues:
|
||||
# print(issue_id, "issue id")
|
||||
# print(issue_dict[issue_id].state_id, "state_id")
|
||||
CycleIssueStateProgress.objects.bulk_create(
|
||||
[
|
||||
CycleIssueStateProgress(
|
||||
cycle_id=cycle_id,
|
||||
state_id=str(issue_dict[issue_id].state_id),
|
||||
issue_id=issue_id,
|
||||
state_group=issue_dict[issue_id].state.group,
|
||||
type="ADDED",
|
||||
estimate_id=issue_dict[issue_id].estimate_point_id,
|
||||
estimate_value=(
|
||||
issue_dict[issue_id].estimate_point.value
|
||||
if estimate_type
|
||||
else None
|
||||
),
|
||||
project_id=project_id,
|
||||
workspace_id=cycle.workspace_id,
|
||||
created_by_id=request.user.id,
|
||||
updated_by_id=request.user.id,
|
||||
)
|
||||
for issue_id in issues
|
||||
],
|
||||
batch_size=10,
|
||||
)
|
||||
|
||||
# CycleIssueStateProgress.objects.bulk_create(
|
||||
# [
|
||||
# CycleIssueStateProgress(
|
||||
# cycle_id=cycle_id,
|
||||
# state_id=str(issue_dict[issue_id].state_id),
|
||||
# issue_id=issue_id,
|
||||
# state_group=issue_dict[issue_id].state.group,
|
||||
# type="ADDED",
|
||||
# estimate_id=issue_dict[issue_id].estimate_id,
|
||||
# estimate_value=(
|
||||
# issue_dict[issue_id].estimate_point.value
|
||||
# if estimate_type
|
||||
# else None
|
||||
# ),
|
||||
# project_id=project_id,
|
||||
# workspace_id=cycle.workspace_id,
|
||||
# created_by_id=request.user.id,
|
||||
# updated_by_id=request.user.id,
|
||||
# )
|
||||
# print(issue_id, "issue id")
|
||||
# for issue_id in new_issues
|
||||
# ],
|
||||
# batch_size=10,
|
||||
# )
|
||||
CycleIssueStateProgress.objects.bulk_create(
|
||||
[
|
||||
CycleIssueStateProgress(
|
||||
cycle_id=issue_dict[issue_id].cycle_id,
|
||||
state_id=str(issue_dict[issue_id].state_id),
|
||||
issue_id=issue_id,
|
||||
state_group=issue_dict[issue_id].state.group,
|
||||
type="REMOVED",
|
||||
estimate_id=issue_dict[issue_id].estimate_point_id,
|
||||
estimate_value=(
|
||||
issue_dict[issue_id].estimate_point.value
|
||||
if estimate_type
|
||||
else None
|
||||
),
|
||||
project_id=project_id,
|
||||
workspace_id=cycle.workspace_id,
|
||||
created_by_id=request.user.id,
|
||||
updated_by_id=request.user.id,
|
||||
)
|
||||
for issue_id in existing_issues
|
||||
]
|
||||
)
|
||||
|
||||
# Updated Issues
|
||||
updated_records = []
|
||||
@@ -392,7 +409,7 @@ class CycleIssueViewSet(BaseViewSet):
|
||||
issue_id=issue_id,
|
||||
state_group=issue.state.group,
|
||||
type="REMOVED",
|
||||
estimate_id=issue.estimate_id,
|
||||
estimate_id=issue.estimate_point_id,
|
||||
estimate_value=(
|
||||
issue.estimate_point.value if estimate_type else None
|
||||
),
|
||||
|
||||
@@ -40,8 +40,6 @@ from plane.db.models import (
|
||||
IssueLink,
|
||||
IssueRelation,
|
||||
Project,
|
||||
ProjectMember,
|
||||
User,
|
||||
Widget,
|
||||
WorkspaceMember,
|
||||
)
|
||||
|
||||
@@ -167,10 +167,10 @@ class InboxIssueViewSet(BaseViewSet):
|
||||
|
||||
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
|
||||
def list(self, request, slug, project_id):
|
||||
inbox_id = Inbox.objects.get(
|
||||
inbox_id = Inbox.objects.filter(
|
||||
workspace__slug=slug, project_id=project_id
|
||||
)
|
||||
project = Project.objects.get(pk=project_id)
|
||||
).first()
|
||||
project = Project.objects.get(pk=project_id)
|
||||
filters = issue_filters(request.GET, "GET", "issue__")
|
||||
inbox_issue = (
|
||||
InboxIssue.objects.filter(
|
||||
@@ -527,9 +527,9 @@ class InboxIssueViewSet(BaseViewSet):
|
||||
model=Issue,
|
||||
)
|
||||
def retrieve(self, request, slug, project_id, pk):
|
||||
inbox_id = Inbox.objects.get(
|
||||
inbox_id = Inbox.objects.filter(
|
||||
workspace__slug=slug, project_id=project_id
|
||||
)
|
||||
).first()
|
||||
project = Project.objects.get(pk=project_id)
|
||||
inbox_issue = (
|
||||
InboxIssue.objects.select_related("issue")
|
||||
|
||||
@@ -545,8 +545,6 @@ class IssueViewSet(BaseViewSet):
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
|
||||
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
entity_name="issue",
|
||||
@@ -611,23 +609,6 @@ class IssueViewSet(BaseViewSet):
|
||||
estimate__type="points",
|
||||
).exists()
|
||||
|
||||
if issue.cycle_id:
|
||||
CycleIssueStateProgress.objects.create(
|
||||
cycle_id=issue.cycle_id,
|
||||
state_id=issue.state_id,
|
||||
issue_id=issue.id,
|
||||
state_group=issue.state.group,
|
||||
type="UPDATED",
|
||||
estimate_id=issue.estimate_point_id,
|
||||
estimate_value=(
|
||||
issue.estimate_point.value if estimate_type else None
|
||||
),
|
||||
project_id=project_id,
|
||||
workspace_id=issue.workspace_id,
|
||||
created_by_id=request.user.id,
|
||||
updated_by_id=request.user.id,
|
||||
)
|
||||
|
||||
requested_data = json.dumps(self.request.data, cls=DjangoJSONEncoder)
|
||||
serializer = IssueCreateSerializer(
|
||||
issue, data=request.data, partial=True
|
||||
@@ -645,6 +626,23 @@ class IssueViewSet(BaseViewSet):
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
)
|
||||
if issue.cycle_id and request.data.get("state_id"):
|
||||
CycleIssueStateProgress.objects.create(
|
||||
cycle_id=issue.cycle_id,
|
||||
state_id=issue.state_id,
|
||||
issue_id=issue.id,
|
||||
state_group=issue.state.group,
|
||||
type="UPDATED",
|
||||
estimate_id=issue.estimate_point_id,
|
||||
estimate_value=(
|
||||
issue.estimate_point.value if estimate_type else None
|
||||
),
|
||||
project_id=project_id,
|
||||
workspace_id=issue.workspace_id,
|
||||
created_by_id=request.user.id,
|
||||
updated_by_id=request.user.id,
|
||||
)
|
||||
|
||||
model_activity.delay(
|
||||
model_name="issue",
|
||||
model_id=str(serializer.data.get("id", None)),
|
||||
|
||||
@@ -512,8 +512,8 @@ class WorkspaceUserProfileStatsEndpoint(BaseAPIView):
|
||||
|
||||
present_cycle = CycleIssue.objects.filter(
|
||||
workspace__slug=slug,
|
||||
cycle__start_date__lt=timezone.now().date(),
|
||||
cycle__end_date__gt=timezone.now().date(),
|
||||
cycle__start_date__lt=timezone.now(),
|
||||
cycle__end_date__gt=timezone.now(),
|
||||
issue__assignees__in=[
|
||||
user_id,
|
||||
],
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
# Django imports
|
||||
from django.db.models import Sum
|
||||
from django.utils import timezone
|
||||
from django.db.models import F
|
||||
from django.db.models.functions import RowNumber
|
||||
from django.db.models import Max, Subquery, OuterRef
|
||||
from django.db.models import Subquery, OuterRef
|
||||
|
||||
# Third party imports
|
||||
from celery import shared_task
|
||||
@@ -21,39 +19,17 @@ def track_cycle_issue_state_progress():
|
||||
current_date = timezone.now().date()
|
||||
|
||||
for cycle_id, project_id, workspace_id in active_cycles:
|
||||
# Subquery to get the latest id for each issue_id
|
||||
# Subquery to get the latest created_at for each issue_id
|
||||
# latest_created_at = CycleIssueStateProgress.objects.filter(
|
||||
# cycle_id=cycle_id,
|
||||
# type__in=["ADDED", "UPDATED"],
|
||||
# issue_id=OuterRef("issue_id"),
|
||||
# created_at__lte=timezone.now(),
|
||||
# ).values('issue_id').annotate(
|
||||
# latest_created=Max('created_at')
|
||||
# ).values('latest_created')
|
||||
|
||||
# # Main query to get the latest unique issues
|
||||
# cycle_issues = CycleIssueStateProgress.objects.filter(
|
||||
# cycle_id=cycle_id,
|
||||
# type__in=["ADDED", "UPDATED"],
|
||||
# created_at=Subquery(latest_created_at),
|
||||
# issue_id=OuterRef("issue_id")
|
||||
# ).order_by("issue_id")
|
||||
|
||||
cycle_issues = CycleIssueStateProgress.objects.filter(
|
||||
id=Subquery(
|
||||
CycleIssueStateProgress.objects.filter(
|
||||
cycle_id=cycle_id,
|
||||
type__in=["ADDED", "UPDATED"],
|
||||
cycle_id="bbc67c04-9796-4773-a598-28c170567ddb",
|
||||
issue=OuterRef("issue"),
|
||||
)
|
||||
.order_by("-created_at")
|
||||
.values("id")[:1]
|
||||
)
|
||||
),
|
||||
type__in=["ADDED", "UPDATED"],
|
||||
)
|
||||
# print()
|
||||
for issue in cycle_issues.values():
|
||||
print(issue, "issues")
|
||||
|
||||
total_issues = cycle_issues.count()
|
||||
total_estimate_points = (
|
||||
|
||||
@@ -42,7 +42,7 @@ app.conf.beat_schedule = {
|
||||
},
|
||||
"track-cycle-issue-state-progress": {
|
||||
"task": "plane.bgtasks.cycle_issue_state_progress_task.track_cycle_issue_state_progress",
|
||||
"schedule": crontab(hour=9, minute=6),
|
||||
"schedule": crontab(hour=0, minute=0),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -153,7 +153,7 @@ class Issue(ProjectBaseModel):
|
||||
through_fields=("issue", "assignee"),
|
||||
)
|
||||
sequence_id = models.IntegerField(
|
||||
default=1, verbose_name="Issue Sequence ID"
|
||||
default=1, verbose_name="Issue Sequence ID", null=True, blank=True
|
||||
)
|
||||
labels = models.ManyToManyField(
|
||||
"db.Label", blank=True, related_name="labels", through="IssueLabel"
|
||||
|
||||
@@ -163,7 +163,7 @@ def burndown_plot(
|
||||
if queryset.end_date and queryset.start_date:
|
||||
# Get all dates between the two dates
|
||||
date_range = [
|
||||
queryset.start_date + timedelta(days=x)
|
||||
(queryset.start_date + timedelta(days=x)).date()
|
||||
for x in range(
|
||||
(queryset.end_date - queryset.start_date).days + 1
|
||||
)
|
||||
@@ -201,9 +201,11 @@ def burndown_plot(
|
||||
)
|
||||
|
||||
if module_id:
|
||||
# start_date = queryset.start_date.date()
|
||||
# target_date = queryset.target_date.date()
|
||||
# Get all dates between the two dates
|
||||
date_range = [
|
||||
queryset.start_date + timedelta(days=x)
|
||||
(queryset.start_date + timedelta(days=x)).date()
|
||||
for x in range(
|
||||
(queryset.target_date - queryset.start_date).days + 1
|
||||
)
|
||||
@@ -254,6 +256,7 @@ def burndown_plot(
|
||||
chart_data[str(date)] = cumulative_pending_issues
|
||||
else:
|
||||
for date in date_range:
|
||||
print(date, "date")
|
||||
cumulative_pending_issues = total_issues
|
||||
total_completed = 0
|
||||
total_completed = sum(
|
||||
|
||||
Reference in New Issue
Block a user