Add task & issues due dates configuration

remotes/origin/endpoint-for-estimation-system-new
Álex Hermida 2018-06-06 12:39:15 +02:00 committed by Alex Hermida
parent 758109ac22
commit 6a5e870564
7 changed files with 205 additions and 2 deletions

View File

@ -596,7 +596,7 @@ class UserStoryDueDateViewSet(BlockedByProjectMixin, ModelCrudViewSet):
def create(self, request, *args, **kwargs):
project_id = request.DATA.get("project", 0)
with advisory_lock("user-story-duedate-creation-{}".format(project_id)):
with advisory_lock("user-story-due-date-creation-{}".format(project_id)):
return super().create(request, *args, **kwargs)
@ -622,6 +622,21 @@ class TaskStatusViewSet(MoveOnDestroyMixin, BlockedByProjectMixin,
return super().create(request, *args, **kwargs)
class TaskDueDateViewSet(BlockedByProjectMixin, ModelCrudViewSet):
model = models.TaskDueDate
serializer_class = serializers.TaskDueDateSerializer
validator_class = validators.TaskDueDateValidator
permission_classes = (permissions.TaskDueDatePermission,)
filter_backends = (filters.CanViewProjectFilterBackend,)
filter_fields = ('project',)
def create(self, request, *args, **kwargs):
project_id = request.DATA.get("project", 0)
with advisory_lock("task-due-date-creation-{}".format(project_id)):
return super().create(request, *args, **kwargs)
class SeverityViewSet(MoveOnDestroyMixin, BlockedByProjectMixin,
ModelCrudViewSet, BulkUpdateOrderMixin):
@ -707,6 +722,21 @@ class IssueStatusViewSet(MoveOnDestroyMixin, BlockedByProjectMixin,
return super().create(request, *args, **kwargs)
class IssueDueDateViewSet(BlockedByProjectMixin, ModelCrudViewSet):
model = models.IssueDueDate
serializer_class = serializers.IssueDueDateSerializer
validator_class = validators.IssueDueDateValidator
permission_classes = (permissions.IssueDueDatePermission,)
filter_backends = (filters.CanViewProjectFilterBackend,)
filter_fields = ('project',)
def create(self, request, *args, **kwargs):
project_id = request.DATA.get("project", 0)
with advisory_lock("issue-due-date-creation-{}".format(project_id)):
return super().create(request, *args, **kwargs)
######################################################
## Project Template
######################################################

View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2018-06-06 10:34
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('projects', '0060_auto_20180605_1042'),
]
operations = [
migrations.CreateModel(
name='IssueDueDate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='name')),
('slug', models.SlugField(blank=True, max_length=255, verbose_name='slug')),
('order', models.IntegerField(default=10, verbose_name='order')),
('by_default', models.BooleanField(default=False, verbose_name='by default')),
('color', models.CharField(default='#999999', max_length=20, verbose_name='color')),
('days_to_due', models.IntegerField(blank=True, default=None, null=True, verbose_name='days to due')),
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='issue_duedates', to='projects.Project', verbose_name='project')),
],
options={
'verbose_name': 'issue due date',
'verbose_name_plural': 'issue due dates',
'ordering': ['project', 'order', 'name'],
},
),
migrations.CreateModel(
name='TaskDueDate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, verbose_name='name')),
('slug', models.SlugField(blank=True, max_length=255, verbose_name='slug')),
('order', models.IntegerField(default=10, verbose_name='order')),
('by_default', models.BooleanField(default=False, verbose_name='by default')),
('color', models.CharField(default='#999999', max_length=20, verbose_name='color')),
('days_to_due', models.IntegerField(blank=True, default=None, null=True, verbose_name='days to due')),
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='task_duedates', to='projects.Project', verbose_name='project')),
],
options={
'verbose_name': 'task due date',
'verbose_name_plural': 'task due dates',
'ordering': ['project', 'order', 'name'],
},
),
migrations.AlterUniqueTogether(
name='taskduedate',
unique_together=set([('project', 'name'), ('project', 'slug')]),
),
migrations.AlterUniqueTogether(
name='issueduedate',
unique_together=set([('project', 'name'), ('project', 'slug')]),
),
]

View File

@ -677,6 +677,40 @@ class TaskStatus(models.Model):
return super().save(*args, **kwargs)
class TaskDueDate(models.Model):
name = models.CharField(max_length=255, null=False, blank=False,
verbose_name=_("name"))
slug = models.SlugField(max_length=255, null=False, blank=True,
verbose_name=_("slug"))
order = models.IntegerField(default=10, null=False, blank=False,
verbose_name=_("order"))
by_default = models.BooleanField(default=False, null=False, blank=True,
verbose_name=_("by default"))
color = models.CharField(max_length=20, null=False, blank=False, default="#999999",
verbose_name=_("color"))
days_to_due = models.IntegerField(null=True, blank=True, default=None,
verbose_name=_("days to due"))
project = models.ForeignKey("Project", null=False, blank=False,
related_name="task_duedates", verbose_name=_("project"))
class Meta:
verbose_name = "task due date"
verbose_name_plural = "task due dates"
ordering = ["project", "order", "name"]
unique_together = (("project", "name"), ("project", "slug"))
def __str__(self):
return self.name
def save(self, *args, **kwargs):
qs = self.project.task_duedates
if self.id:
qs = qs.exclude(id=self.id)
self.slug = slugify_uniquely_for_queryset(self.name, qs)
return super().save(*args, **kwargs)
# Issue common Models
class Priority(models.Model):
@ -771,6 +805,40 @@ class IssueType(models.Model):
return self.name
class IssueDueDate(models.Model):
name = models.CharField(max_length=255, null=False, blank=False,
verbose_name=_("name"))
slug = models.SlugField(max_length=255, null=False, blank=True,
verbose_name=_("slug"))
order = models.IntegerField(default=10, null=False, blank=False,
verbose_name=_("order"))
by_default = models.BooleanField(default=False, null=False, blank=True,
verbose_name=_("by default"))
color = models.CharField(max_length=20, null=False, blank=False, default="#999999",
verbose_name=_("color"))
days_to_due = models.IntegerField(null=True, blank=True, default=None,
verbose_name=_("days to due"))
project = models.ForeignKey("Project", null=False, blank=False,
related_name="issue_duedates", verbose_name=_("project"))
class Meta:
verbose_name = "issue due date"
verbose_name_plural = "issue due dates"
ordering = ["project", "order", "name"]
unique_together = (("project", "name"), ("project", "slug"))
def __str__(self):
return self.name
def save(self, *args, **kwargs):
qs = self.project.issue_duedates
if self.id:
qs = qs.exclude(id=self.id)
self.slug = slugify_uniquely_for_queryset(self.name, qs)
return super().save(*args, **kwargs)
class ProjectTemplate(TaggedMixin, TagsColorsMixin, models.Model):
name = models.CharField(max_length=250, null=False, blank=False,
verbose_name=_("name"))

View File

@ -167,6 +167,15 @@ class TaskStatusPermission(TaigaResourcePermission):
bulk_update_order_perms = IsProjectAdmin()
class TaskDueDatePermission(TaigaResourcePermission):
retrieve_perms = HasProjectPerm('view_project')
create_perms = IsProjectAdmin()
update_perms = IsProjectAdmin()
partial_update_perms = IsProjectAdmin()
destroy_perms = IsProjectAdmin()
list_perms = AllowAny()
bulk_update_order_perms = IsProjectAdmin()
# Issues
class SeverityPermission(TaigaResourcePermission):
@ -209,6 +218,16 @@ class IssueTypePermission(TaigaResourcePermission):
bulk_update_order_perms = IsProjectAdmin()
class IssueDueDatePermission(TaigaResourcePermission):
retrieve_perms = HasProjectPerm('view_project')
create_perms = IsProjectAdmin()
update_perms = IsProjectAdmin()
partial_update_perms = IsProjectAdmin()
destroy_perms = IsProjectAdmin()
list_perms = AllowAny()
bulk_update_order_perms = IsProjectAdmin()
# Project Templates
class ProjectTemplatePermission(TaigaResourcePermission):

View File

@ -67,7 +67,7 @@ class PointsSerializer(serializers.LightSerializer):
project = Field(attr="project_id")
class UserStoryDueDateSerializer(serializers.LightSerializer):
class BaseDueDateSerializer(serializers.LightSerializer):
id = Field()
name = I18NField()
slug = Field()
@ -78,6 +78,10 @@ class UserStoryDueDateSerializer(serializers.LightSerializer):
project = Field(attr="project_id")
class UserStoryDueDateSerializer(BaseDueDateSerializer):
pass
class TaskStatusSerializer(serializers.LightSerializer):
id = Field()
name = I18NField()
@ -88,6 +92,10 @@ class TaskStatusSerializer(serializers.LightSerializer):
project = Field(attr="project_id")
class TaskDueDateSerializer(BaseDueDateSerializer):
pass
class SeveritySerializer(serializers.LightSerializer):
id = Field()
name = I18NField()
@ -122,6 +130,10 @@ class IssueTypeSerializer(serializers.LightSerializer):
project = Field(attr="project_id")
class IssueDueDateSerializer(BaseDueDateSerializer):
pass
######################################################
# Members
######################################################

View File

@ -94,6 +94,11 @@ class TaskStatusValidator(DuplicatedNameInProjectValidator, validators.ModelVali
model = models.TaskStatus
class TaskDueDateValidator(DuplicatedNameInProjectValidator, validators.ModelValidator):
class Meta:
model = models.TaskDueDate
class SeverityValidator(DuplicatedNameInProjectValidator, validators.ModelValidator):
class Meta:
model = models.Severity
@ -114,6 +119,11 @@ class IssueTypeValidator(DuplicatedNameInProjectValidator, validators.ModelValid
model = models.IssueType
class IssueDueDateValidator(DuplicatedNameInProjectValidator, validators.ModelValidator):
class Meta:
model = models.IssueDueDate
######################################################
# Members
######################################################

View File

@ -60,8 +60,10 @@ from taiga.projects.api import UserStoryStatusViewSet
from taiga.projects.api import PointsViewSet
from taiga.projects.api import UserStoryDueDateViewSet
from taiga.projects.api import TaskStatusViewSet
from taiga.projects.api import TaskDueDateViewSet
from taiga.projects.api import IssueStatusViewSet
from taiga.projects.api import IssueTypeViewSet
from taiga.projects.api import IssueDueDateViewSet
from taiga.projects.api import PriorityViewSet
from taiga.projects.api import SeverityViewSet
from taiga.projects.api import ProjectTemplateViewSet
@ -77,8 +79,10 @@ router.register(r"userstory-statuses", UserStoryStatusViewSet, base_name="userst
router.register(r"points", PointsViewSet, base_name="points")
router.register(r"userstory-due-dates", UserStoryDueDateViewSet, base_name="userstory-due-dates")
router.register(r"task-statuses", TaskStatusViewSet, base_name="task-statuses")
router.register(r"task-due-dates", TaskDueDateViewSet, base_name="task-due-dates")
router.register(r"issue-statuses", IssueStatusViewSet, base_name="issue-statuses")
router.register(r"issue-types", IssueTypeViewSet, base_name="issue-types")
router.register(r"issue-due-dates", IssueDueDateViewSet, base_name="issue-due-dates")
router.register(r"priorities", PriorityViewSet, base_name="priorities")
router.register(r"severities",SeverityViewSet , base_name="severities")