chore: estimate points float field (#5038)

This commit is contained in:
Bavisetti Narayan 2024-07-04 19:50:08 +05:30 committed by GitHub
parent 72f00e378d
commit 9a927ded84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 81 additions and 68 deletions

View file

@ -12,7 +12,7 @@ from django.db.models import (
OuterRef, OuterRef,
Q, Q,
Sum, Sum,
IntegerField, FloatField,
) )
from django.db.models.functions import Cast from django.db.models.functions import Cast
@ -867,12 +867,12 @@ class TransferCycleIssueAPIEndpoint(BaseAPIView):
.values("display_name", "assignee_id", "avatar") .values("display_name", "assignee_id", "avatar")
.annotate( .annotate(
total_estimates=Sum( total_estimates=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.annotate( .annotate(
completed_estimates=Sum( completed_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=False, completed_at__isnull=False,
archived_at__isnull=True, archived_at__isnull=True,
@ -882,7 +882,7 @@ class TransferCycleIssueAPIEndpoint(BaseAPIView):
) )
.annotate( .annotate(
pending_estimates=Sum( pending_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=True, completed_at__isnull=True,
archived_at__isnull=True, archived_at__isnull=True,
@ -921,12 +921,12 @@ class TransferCycleIssueAPIEndpoint(BaseAPIView):
.values("label_name", "color", "label_id") .values("label_name", "color", "label_id")
.annotate( .annotate(
total_estimates=Sum( total_estimates=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.annotate( .annotate(
completed_estimates=Sum( completed_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=False, completed_at__isnull=False,
archived_at__isnull=True, archived_at__isnull=True,
@ -936,7 +936,7 @@ class TransferCycleIssueAPIEndpoint(BaseAPIView):
) )
.annotate( .annotate(
pending_estimates=Sum( pending_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=True, completed_at__isnull=True,
archived_at__isnull=True, archived_at__isnull=True,

View file

@ -177,8 +177,8 @@ class ModuleSerializer(DynamicBaseSerializer):
started_issues = serializers.IntegerField(read_only=True) started_issues = serializers.IntegerField(read_only=True)
unstarted_issues = serializers.IntegerField(read_only=True) unstarted_issues = serializers.IntegerField(read_only=True)
backlog_issues = serializers.IntegerField(read_only=True) backlog_issues = serializers.IntegerField(read_only=True)
total_estimate_points = serializers.IntegerField(read_only=True) total_estimate_points = serializers.FloatField(read_only=True)
completed_estimate_points = serializers.IntegerField(read_only=True) completed_estimate_points = serializers.FloatField(read_only=True)
class Meta: class Meta:
model = Module model = Module
@ -222,10 +222,10 @@ class ModuleSerializer(DynamicBaseSerializer):
class ModuleDetailSerializer(ModuleSerializer): class ModuleDetailSerializer(ModuleSerializer):
link_module = ModuleLinkSerializer(read_only=True, many=True) link_module = ModuleLinkSerializer(read_only=True, many=True)
sub_issues = serializers.IntegerField(read_only=True) sub_issues = serializers.IntegerField(read_only=True)
backlog_estimate_points = serializers.IntegerField(read_only=True) backlog_estimate_points = serializers.FloatField(read_only=True)
unstarted_estimate_points = serializers.IntegerField(read_only=True) unstarted_estimate_points = serializers.FloatField(read_only=True)
started_estimate_points = serializers.IntegerField(read_only=True) started_estimate_points = serializers.FloatField(read_only=True)
cancelled_estimate_points = serializers.IntegerField(read_only=True) cancelled_estimate_points = serializers.FloatField(read_only=True)
class Meta(ModuleSerializer.Meta): class Meta(ModuleSerializer.Meta):
fields = ModuleSerializer.Meta.fields + ["link_module", "sub_issues", "backlog_estimate_points", "unstarted_estimate_points", "started_estimate_points", "cancelled_estimate_points"] fields = ModuleSerializer.Meta.fields + ["link_module", "sub_issues", "backlog_estimate_points", "unstarted_estimate_points", "started_estimate_points", "cancelled_estimate_points"]

View file

@ -19,7 +19,7 @@ from django.db.models import (
When, When,
Subquery, Subquery,
Sum, Sum,
IntegerField, FloatField,
) )
from django.db.models.functions import Coalesce, Cast from django.db.models.functions import Coalesce, Cast
from django.utils import timezone from django.utils import timezone
@ -86,7 +86,7 @@ class CycleViewSet(BaseViewSet):
.values("issue_cycle__cycle_id") .values("issue_cycle__cycle_id")
.annotate( .annotate(
backlog_estimate_point=Sum( backlog_estimate_point=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("backlog_estimate_point")[:1] .values("backlog_estimate_point")[:1]
@ -100,7 +100,7 @@ class CycleViewSet(BaseViewSet):
.values("issue_cycle__cycle_id") .values("issue_cycle__cycle_id")
.annotate( .annotate(
unstarted_estimate_point=Sum( unstarted_estimate_point=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("unstarted_estimate_point")[:1] .values("unstarted_estimate_point")[:1]
@ -114,7 +114,7 @@ class CycleViewSet(BaseViewSet):
.values("issue_cycle__cycle_id") .values("issue_cycle__cycle_id")
.annotate( .annotate(
started_estimate_point=Sum( started_estimate_point=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("started_estimate_point")[:1] .values("started_estimate_point")[:1]
@ -128,7 +128,7 @@ class CycleViewSet(BaseViewSet):
.values("issue_cycle__cycle_id") .values("issue_cycle__cycle_id")
.annotate( .annotate(
cancelled_estimate_point=Sum( cancelled_estimate_point=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("cancelled_estimate_point")[:1] .values("cancelled_estimate_point")[:1]
@ -142,7 +142,7 @@ class CycleViewSet(BaseViewSet):
.values("issue_cycle__cycle_id") .values("issue_cycle__cycle_id")
.annotate( .annotate(
completed_estimate_points=Sum( completed_estimate_points=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("completed_estimate_points")[:1] .values("completed_estimate_points")[:1]
@ -155,7 +155,7 @@ class CycleViewSet(BaseViewSet):
.values("issue_cycle__cycle_id") .values("issue_cycle__cycle_id")
.annotate( .annotate(
total_estimate_points=Sum( total_estimate_points=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("total_estimate_points")[:1] .values("total_estimate_points")[:1]
@ -287,37 +287,37 @@ class CycleViewSet(BaseViewSet):
.annotate( .annotate(
backlog_estimate_points=Coalesce( backlog_estimate_points=Coalesce(
Subquery(backlog_estimate_point), Subquery(backlog_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
unstarted_estimate_points=Coalesce( unstarted_estimate_points=Coalesce(
Subquery(unstarted_estimate_point), Subquery(unstarted_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
started_estimate_points=Coalesce( started_estimate_points=Coalesce(
Subquery(started_estimate_point), Subquery(started_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
cancelled_estimate_points=Coalesce( cancelled_estimate_points=Coalesce(
Subquery(cancelled_estimate_point), Subquery(cancelled_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
completed_estimate_points=Coalesce( completed_estimate_points=Coalesce(
Subquery(completed_estimate_point), Subquery(completed_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
total_estimate_points=Coalesce( total_estimate_points=Coalesce(
Subquery(total_estimate_point), Subquery(total_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.order_by("-is_favorite", "name") .order_by("-is_favorite", "name")
@ -395,12 +395,12 @@ class CycleViewSet(BaseViewSet):
.values("display_name", "assignee_id", "avatar") .values("display_name", "assignee_id", "avatar")
.annotate( .annotate(
total_estimates=Sum( total_estimates=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.annotate( .annotate(
completed_estimates=Sum( completed_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=False, completed_at__isnull=False,
archived_at__isnull=True, archived_at__isnull=True,
@ -410,7 +410,7 @@ class CycleViewSet(BaseViewSet):
) )
.annotate( .annotate(
pending_estimates=Sum( pending_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=True, completed_at__isnull=True,
archived_at__isnull=True, archived_at__isnull=True,
@ -433,12 +433,12 @@ class CycleViewSet(BaseViewSet):
.values("label_name", "color", "label_id") .values("label_name", "color", "label_id")
.annotate( .annotate(
total_estimates=Sum( total_estimates=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.annotate( .annotate(
completed_estimates=Sum( completed_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=False, completed_at__isnull=False,
archived_at__isnull=True, archived_at__isnull=True,
@ -448,7 +448,7 @@ class CycleViewSet(BaseViewSet):
) )
.annotate( .annotate(
pending_estimates=Sum( pending_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=True, completed_at__isnull=True,
archived_at__isnull=True, archived_at__isnull=True,
@ -836,12 +836,12 @@ class CycleViewSet(BaseViewSet):
.values("display_name", "assignee_id", "avatar") .values("display_name", "assignee_id", "avatar")
.annotate( .annotate(
total_estimates=Sum( total_estimates=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.annotate( .annotate(
completed_estimates=Sum( completed_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=False, completed_at__isnull=False,
archived_at__isnull=True, archived_at__isnull=True,
@ -851,7 +851,7 @@ class CycleViewSet(BaseViewSet):
) )
.annotate( .annotate(
pending_estimates=Sum( pending_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=True, completed_at__isnull=True,
archived_at__isnull=True, archived_at__isnull=True,
@ -874,12 +874,12 @@ class CycleViewSet(BaseViewSet):
.values("label_name", "color", "label_id") .values("label_name", "color", "label_id")
.annotate( .annotate(
total_estimates=Sum( total_estimates=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.annotate( .annotate(
completed_estimates=Sum( completed_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=False, completed_at__isnull=False,
archived_at__isnull=True, archived_at__isnull=True,
@ -889,7 +889,7 @@ class CycleViewSet(BaseViewSet):
) )
.annotate( .annotate(
pending_estimates=Sum( pending_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=True, completed_at__isnull=True,
archived_at__isnull=True, archived_at__isnull=True,
@ -1234,12 +1234,12 @@ class TransferCycleIssueEndpoint(BaseAPIView):
.values("display_name", "assignee_id", "avatar") .values("display_name", "assignee_id", "avatar")
.annotate( .annotate(
total_estimates=Sum( total_estimates=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.annotate( .annotate(
completed_estimates=Sum( completed_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=False, completed_at__isnull=False,
archived_at__isnull=True, archived_at__isnull=True,
@ -1249,7 +1249,7 @@ class TransferCycleIssueEndpoint(BaseAPIView):
) )
.annotate( .annotate(
pending_estimates=Sum( pending_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=True, completed_at__isnull=True,
archived_at__isnull=True, archived_at__isnull=True,
@ -1288,12 +1288,12 @@ class TransferCycleIssueEndpoint(BaseAPIView):
.values("label_name", "color", "label_id") .values("label_name", "color", "label_id")
.annotate( .annotate(
total_estimates=Sum( total_estimates=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.annotate( .annotate(
completed_estimates=Sum( completed_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=False, completed_at__isnull=False,
archived_at__isnull=True, archived_at__isnull=True,
@ -1303,7 +1303,7 @@ class TransferCycleIssueEndpoint(BaseAPIView):
) )
.annotate( .annotate(
pending_estimates=Sum( pending_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=True, completed_at__isnull=True,
archived_at__isnull=True, archived_at__isnull=True,

View file

@ -17,6 +17,7 @@ from django.db.models import (
UUIDField, UUIDField,
Value, Value,
Sum, Sum,
FloatField,
) )
from django.db.models.functions import Coalesce, Cast from django.db.models.functions import Coalesce, Cast
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers.json import DjangoJSONEncoder
@ -138,7 +139,7 @@ class ModuleViewSet(BaseViewSet):
.values("issue_module__module_id") .values("issue_module__module_id")
.annotate( .annotate(
completed_estimate_points=Sum( completed_estimate_points=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("completed_estimate_points")[:1] .values("completed_estimate_points")[:1]
@ -152,7 +153,7 @@ class ModuleViewSet(BaseViewSet):
.values("issue_module__module_id") .values("issue_module__module_id")
.annotate( .annotate(
total_estimate_points=Sum( total_estimate_points=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("total_estimate_points")[:1] .values("total_estimate_points")[:1]
@ -166,7 +167,7 @@ class ModuleViewSet(BaseViewSet):
.values("issue_module__module_id") .values("issue_module__module_id")
.annotate( .annotate(
backlog_estimate_point=Sum( backlog_estimate_point=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("backlog_estimate_point")[:1] .values("backlog_estimate_point")[:1]
@ -180,7 +181,7 @@ class ModuleViewSet(BaseViewSet):
.values("issue_module__module_id") .values("issue_module__module_id")
.annotate( .annotate(
unstarted_estimate_point=Sum( unstarted_estimate_point=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("unstarted_estimate_point")[:1] .values("unstarted_estimate_point")[:1]
@ -194,7 +195,7 @@ class ModuleViewSet(BaseViewSet):
.values("issue_module__module_id") .values("issue_module__module_id")
.annotate( .annotate(
started_estimate_point=Sum( started_estimate_point=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("started_estimate_point")[:1] .values("started_estimate_point")[:1]
@ -208,7 +209,7 @@ class ModuleViewSet(BaseViewSet):
.values("issue_module__module_id") .values("issue_module__module_id")
.annotate( .annotate(
cancelled_estimate_point=Sum( cancelled_estimate_point=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
) )
) )
.values("cancelled_estimate_point")[:1] .values("cancelled_estimate_point")[:1]
@ -270,37 +271,37 @@ class ModuleViewSet(BaseViewSet):
.annotate( .annotate(
backlog_estimate_points=Coalesce( backlog_estimate_points=Coalesce(
Subquery(backlog_estimate_point), Subquery(backlog_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
unstarted_estimate_points=Coalesce( unstarted_estimate_points=Coalesce(
Subquery(unstarted_estimate_point), Subquery(unstarted_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
started_estimate_points=Coalesce( started_estimate_points=Coalesce(
Subquery(started_estimate_point), Subquery(started_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
cancelled_estimate_points=Coalesce( cancelled_estimate_points=Coalesce(
Subquery(cancelled_estimate_point), Subquery(cancelled_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
completed_estimate_points=Coalesce( completed_estimate_points=Coalesce(
Subquery(completed_estimate_point), Subquery(completed_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
total_estimate_points=Coalesce( total_estimate_points=Coalesce(
Subquery(total_estimate_point), Subquery(total_estimate_point),
Value(0, output_field=IntegerField()), Value(0, output_field=FloatField()),
), ),
) )
.annotate( .annotate(
@ -475,12 +476,12 @@ class ModuleViewSet(BaseViewSet):
) )
.annotate( .annotate(
total_estimates=Sum( total_estimates=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
), ),
) )
.annotate( .annotate(
completed_estimates=Sum( completed_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=False, completed_at__isnull=False,
archived_at__isnull=True, archived_at__isnull=True,
@ -490,7 +491,7 @@ class ModuleViewSet(BaseViewSet):
) )
.annotate( .annotate(
pending_estimates=Sum( pending_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=True, completed_at__isnull=True,
archived_at__isnull=True, archived_at__isnull=True,
@ -513,12 +514,12 @@ class ModuleViewSet(BaseViewSet):
.values("label_name", "color", "label_id") .values("label_name", "color", "label_id")
.annotate( .annotate(
total_estimates=Sum( total_estimates=Sum(
Cast("estimate_point__value", IntegerField()) Cast("estimate_point__value", FloatField())
), ),
) )
.annotate( .annotate(
completed_estimates=Sum( completed_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=False, completed_at__isnull=False,
archived_at__isnull=True, archived_at__isnull=True,
@ -528,7 +529,7 @@ class ModuleViewSet(BaseViewSet):
) )
.annotate( .annotate(
pending_estimates=Sum( pending_estimates=Sum(
Cast("estimate_point__value", IntegerField()), Cast("estimate_point__value", FloatField()),
filter=Q( filter=Q(
completed_at__isnull=True, completed_at__isnull=True,
archived_at__isnull=True, archived_at__isnull=True,

View file

@ -137,7 +137,7 @@ def burndown_plot(
estimate__isnull=False, estimate__isnull=False,
estimate__type="points", estimate__type="points",
).exists() ).exists()
if estimate_type and plot_type == "points": if estimate_type and plot_type == "points" and cycle_id:
issue_estimates = Issue.objects.filter( issue_estimates = Issue.objects.filter(
workspace__slug=slug, workspace__slug=slug,
project_id=project_id, project_id=project_id,
@ -145,7 +145,18 @@ def burndown_plot(
estimate_point__isnull=False, estimate_point__isnull=False,
).values_list("estimate_point__value", flat=True) ).values_list("estimate_point__value", flat=True)
issue_estimates = [int(value) for value in issue_estimates] issue_estimates = [float(value) for value in issue_estimates]
total_estimate_points = sum(issue_estimates)
if estimate_type and plot_type == "points" and module_id:
issue_estimates = Issue.objects.filter(
workspace__slug=slug,
project_id=project_id,
issue_module__module_id=module_id,
estimate_point__isnull=False,
).values_list("estimate_point__value", flat=True)
issue_estimates = [float(value) for value in issue_estimates]
total_estimate_points = sum(issue_estimates) total_estimate_points = sum(issue_estimates)
if cycle_id: if cycle_id:
@ -227,12 +238,12 @@ def burndown_plot(
.order_by("date") .order_by("date")
) )
for date in date_range:
if plot_type == "points": if plot_type == "points":
for date in date_range:
cumulative_pending_issues = total_estimate_points cumulative_pending_issues = total_estimate_points
total_completed = 0 total_completed = 0
total_completed = sum( total_completed = sum(
int(item["estimate_point__value"]) float(item["estimate_point__value"])
for item in completed_issues_estimate_point_distribution for item in completed_issues_estimate_point_distribution
if item["date"] is not None and item["date"] <= date if item["date"] is not None and item["date"] <= date
) )
@ -242,6 +253,7 @@ def burndown_plot(
else: else:
chart_data[str(date)] = cumulative_pending_issues chart_data[str(date)] = cumulative_pending_issues
else: else:
for date in date_range:
cumulative_pending_issues = total_issues cumulative_pending_issues = total_issues
total_completed = 0 total_completed = 0
total_completed = sum( total_completed = sum(