|
|
@@ -134,7 +134,6 @@ class Sprint(BaseModel):
|
|
|
date_end = models.DateField()
|
|
|
closed = models.BooleanField(default=False, verbose_name="Terminé")
|
|
|
retro = MartorField(blank=True, default="", verbose_name="Bilan / Rétrospective")
|
|
|
- unplanned_weight = models.IntegerField(default=0)
|
|
|
|
|
|
def __str__(self):
|
|
|
return "Sprint #{} ({:%d/%m/%Y} > {:%d/%m/%Y})".format(self.number, self.date_start, self.date_end)
|
|
|
@@ -165,6 +164,10 @@ class Sprint(BaseModel):
|
|
|
row = cursor.fetchone()
|
|
|
return row[0] if row[0] else 0
|
|
|
|
|
|
+ def unplanned(self):
|
|
|
+ total = self.stories.filter(story_type=2).aggregate(Sum('weight'))['weight__sum']
|
|
|
+ return total if total is not None else 0
|
|
|
+
|
|
|
@classmethod
|
|
|
def current(cls):
|
|
|
""" the current sprint is the first non-closed sprint """
|
|
|
@@ -196,7 +199,8 @@ class Story(BaseModel):
|
|
|
ordering = ('closed', '-updated')
|
|
|
|
|
|
WEIGHTS = ((None, '------'), (1, 1),(2, 2),(3, 3),(5, 5),(8, 8),(13, 13),(21, 21))
|
|
|
-
|
|
|
+ STORY_TYPE = ((0, 'Standard'), (1, 'NEW'), (2, 'Non Planifiée'))
|
|
|
+
|
|
|
epic = models.ForeignKey(Epic,
|
|
|
on_delete=models.PROTECT,
|
|
|
null=True, blank=True,
|
|
|
@@ -204,6 +208,7 @@ class Story(BaseModel):
|
|
|
verbose_name="Epic")
|
|
|
name = models.CharField(max_length=200, default="", verbose_name="Nom")
|
|
|
weight = models.IntegerField(null=True, choices=WEIGHTS, verbose_name="Poids")
|
|
|
+ story_type = models.IntegerField(default=0, choices=STORY_TYPE, verbose_name="Type")
|
|
|
description = MartorField(blank=True, default="", verbose_name="Description")
|
|
|
closed = models.BooleanField(default=False, verbose_name="Clôturée")
|
|
|
author = models.ForeignKey(User,
|
|
|
@@ -247,5 +252,3 @@ class Story(BaseModel):
|
|
|
def reopen(self):
|
|
|
self.closed = False
|
|
|
self.save()
|
|
|
-
|
|
|
-
|