Making total_points and total_sprints nullable values

remotes/origin/logger
Alejandro Alonso 2015-09-17 10:33:41 +02:00 committed by David Barragán Merino
parent d5fbe6bafe
commit b750236a56
4 changed files with 50 additions and 19 deletions

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('projects', '0026_auto_20150911_1237'),
]
operations = [
migrations.AlterField(
model_name='project',
name='total_milestones',
field=models.IntegerField(verbose_name='total of milestones', null=True, blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='project',
name='total_story_points',
field=models.FloatField(verbose_name='total story points', null=True, blank=True),
preserve_default=True,
),
]

View File

@ -146,9 +146,9 @@ class Project(ProjectDefaults, TaggedMixin, models.Model):
members = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="projects",
through="Membership", verbose_name=_("members"),
through_fields=("project", "user"))
total_milestones = models.IntegerField(default=0, null=False, blank=False,
total_milestones = models.IntegerField(null=True, blank=True,
verbose_name=_("total of milestones"))
total_story_points = models.FloatField(default=0, verbose_name=_("total story points"))
total_story_points = models.FloatField(null=True, blank=True, verbose_name=_("total story points"))
is_backlog_activated = models.BooleanField(default=True, null=False, blank=True,
verbose_name=_("active backlog panel"))

View File

@ -342,16 +342,6 @@ class ProjectSerializer(WatchersValidator, LikedResourceSerializerMixin, Watched
def get_notify_level(self, obj):
return getattr(obj, "notify_level", None)
def validate_total_milestones(self, attrs, source):
"""
Check that total_milestones is not null, it's an optional parameter but
not nullable in the model.
"""
value = attrs[source]
if value is None:
raise serializers.ValidationError(_("Total milestones must be major or equal to zero"))
return attrs
class ProjectDetailSerializer(ProjectSerializer):
us_statuses = UserStoryStatusSerializer(many=True, required=False) # User Stories

View File

@ -23,6 +23,14 @@ import copy
from taiga.projects.history.models import HistoryEntry
def _get_total_story_points(project):
return (project.total_story_points if project.total_story_points is not None else
sum(project.calculated_points["defined"].values()))
def _get_total_milestones(project):
return (project.total_milestones if project.total_milestones is not None else
project.milestones.count())
def _get_milestones_stats_for_backlog(project):
"""
Get collection of stats for each millestone of project.
@ -33,8 +41,12 @@ def _get_milestones_stats_for_backlog(project):
current_client_increment = 0
optimal_points_per_sprint = 0
if project.total_story_points and project.total_milestones:
optimal_points_per_sprint = project.total_story_points / project.total_milestones
total_story_points = _get_total_story_points(project)
total_milestones = _get_total_milestones(project)
if total_story_points and total_milestones:
optimal_points_per_sprint = total_story_points / total_milestones
future_team_increment = sum(project.future_team_increment.values())
future_client_increment = sum(project.future_client_increment.values())
@ -50,11 +62,11 @@ def _get_milestones_stats_for_backlog(project):
team_increment = 0
client_increment = 0
for current_milestone in range(0, max(milestones_count, project.total_milestones)):
optimal_points = (project.total_story_points -
for current_milestone in range(0, max(milestones_count, total_milestones)):
optimal_points = (total_story_points -
(optimal_points_per_sprint * current_milestone))
evolution = (project.total_story_points - current_evolution
evolution = (total_story_points - current_evolution
if current_evolution is not None else None)
if current_milestone < milestones_count:
@ -83,8 +95,8 @@ def _get_milestones_stats_for_backlog(project):
}
optimal_points -= optimal_points_per_sprint
evolution = (project.total_story_points - current_evolution
if current_evolution is not None and project.total_story_points else None)
evolution = (total_story_points - current_evolution
if current_evolution is not None and total_story_points else None)
yield {
'name': _('Project End'),
'optimal': optimal_points,
@ -104,6 +116,7 @@ def _count_status_object(status_obj, counting_storage):
counting_storage[status_obj.id]['id'] = status_obj.id
counting_storage[status_obj.id]['color'] = status_obj.color
def _count_owned_object(user_obj, counting_storage):
if user_obj:
if user_obj.id in counting_storage:
@ -126,6 +139,7 @@ def _count_owned_object(user_obj, counting_storage):
counting_storage[0]['id'] = 0
counting_storage[0]['color'] = 'black'
def get_stats_for_project_issues(project):
project_issues_stats = {
'total_issues': 0,
@ -283,6 +297,7 @@ def _get_closed_tasks_per_member_stats(project):
closed_tasks = {p["assigned_to"]: p["count"] for p in closed_tasks}
return closed_tasks
def get_member_stats_for_project(project):
base_counters = {id: 0 for id in project.members.values_list("id", flat=True)}
closed_bugs = base_counters.copy()