Remove code of questions and documents

remotes/origin/enhancement/email-actions
David Barragán Merino 2014-05-09 09:42:14 +02:00
parent 64d9ba17ca
commit 1a9ef0fe04
24 changed files with 257 additions and 638 deletions

View File

@ -183,10 +183,8 @@ INSTALLED_APPS = [
"taiga.projects.userstories", "taiga.projects.userstories",
"taiga.projects.tasks", "taiga.projects.tasks",
"taiga.projects.issues", "taiga.projects.issues",
"taiga.front",
#"taiga.projects.questions",
#"taiga.projects.documents",
"taiga.projects.wiki", "taiga.projects.wiki",
"taiga.front",
"south", "south",
"reversion", "reversion",

View File

@ -60,8 +60,7 @@ class ProjectAdmin(reversion.VersionAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs): def formfield_for_foreignkey(self, db_field, request, **kwargs):
if (db_field.name in ["default_points", "default_us_status", "default_task_status", if (db_field.name in ["default_points", "default_us_status", "default_task_status",
"default_priority", "default_severity", "default_priority", "default_severity",
"default_issue_status", "default_issue_type", "default_issue_status", "default_issue_type"]):
"default_question_status"]):
if getattr(self, 'obj', None): if getattr(self, 'obj', None):
kwargs["queryset"] = db_field.related.parent_model.objects.filter( kwargs["queryset"] = db_field.related.parent_model.objects.filter(
project=self.obj) project=self.obj)
@ -125,15 +124,6 @@ class IssueStatusAdmin(admin.ModelAdmin):
list_filter = ["project"] list_filter = ["project"]
# Questions common admins
class QuestionStatusAdmin(admin.ModelAdmin):
list_display = ["project", "order", "name", "is_closed", "color"]
list_display_links = ["name"]
list_filter = ["project"]
admin.site.register(models.IssueStatus, IssueStatusAdmin) admin.site.register(models.IssueStatus, IssueStatusAdmin)
admin.site.register(models.TaskStatus, TaskStatusAdmin) admin.site.register(models.TaskStatus, TaskStatusAdmin)
admin.site.register(models.UserStoryStatus, UserStoryStatusAdmin) admin.site.register(models.UserStoryStatus, UserStoryStatusAdmin)
@ -144,5 +134,3 @@ admin.site.register(models.Membership, MembershipAdmin)
admin.site.register(models.Severity, SeverityAdmin) admin.site.register(models.Severity, SeverityAdmin)
admin.site.register(models.Priority, PriorityAdmin) admin.site.register(models.Priority, PriorityAdmin)
admin.site.register(models.IssueType, IssueTypeAdmin) admin.site.register(models.IssueType, IssueTypeAdmin)
admin.site.register(models.QuestionStatus, QuestionStatusAdmin)

View File

@ -291,16 +291,6 @@ class IssueStatusViewSet(ModelCrudViewSet, BulkUpdateOrderMixin):
bulk_update_order = services.bulk_update_issue_status_order bulk_update_order = services.bulk_update_issue_status_order
class QuestionStatusViewSet(ModelCrudViewSet, BulkUpdateOrderMixin):
model = models.QuestionStatus
serializer_class = serializers.QuestionStatusSerializer
permission_classes = (IsAuthenticated, permissions.QuestionStatusPermission)
filter_backends = (filters.IsProjectMemberFilterBackend,)
filter_fields = ("project",)
bulk_update_param = "bulk_question_statuses"
bulk_update_perm = "change_questionstatus"
bulk_update_order = services.bulk_update_question_status_order
class ProjectTemplateViewSet(ModelCrudViewSet): class ProjectTemplateViewSet(ModelCrudViewSet):
model = models.ProjectTemplate model = models.ProjectTemplate
serializer_class = serializers.ProjectTemplateSerializer serializer_class = serializers.ProjectTemplateSerializer

View File

@ -1,25 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.contrib import admin
from . import models
class DocumentAdmin(admin.ModelAdmin):
list_display = ["title", "project", "owner"]
admin.site.register(models.Document, DocumentAdmin)

View File

@ -1,32 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from rest_framework.permissions import IsAuthenticated
from taiga.base import filters
from taiga.base.api import ModelCrudViewSet
from . import serializers
from . import models
from . import permissions
class DocumentsViewSet(ModelCrudViewSet):
model = models.Document
serializer_class = serializers.DocumentSerializer
permission_classes = (permissions.DocumentPermission,)
filter_backends = (filters.IsProjectMemberFilterBackend,)

View File

@ -1,63 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.db import models
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from picklefield.fields import PickledObjectField
from taiga.base.utils.slug import slugify_uniquely as slugify
class Document(models.Model):
slug = models.SlugField(unique=True, max_length=200, null=False, blank=True,
verbose_name=_("slug"))
title = models.CharField(max_length=150, null=False, blank=False,
verbose_name=_("title"))
description = models.TextField(null=False, blank=True,
verbose_name=_("description"))
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
verbose_name=_("modified date"))
project = models.ForeignKey("projects.Project", null=False, blank=False,
related_name="documents",
verbose_name=_("project"))
owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=False, blank=False,
related_name="owned_documents",
verbose_name=_("owner"))
attached_file = models.FileField(max_length=1000, null=True, blank=True,
upload_to="documents",
verbose_name=_("attached_file"))
tags = PickledObjectField(null=False, blank=True,
verbose_name=_("tags"))
class Meta:
verbose_name = u"Document"
verbose_name_plural = u"Documents"
ordering = ["project", "title",]
permissions = (
("view_document", "Can view document"),
)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title, self.__class__)
super().save(*args, **kwargs)

View File

@ -1,27 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from taiga.base.permissions import BasePermission
class DocumentPermission(BasePermission):
get_permission = "view_document"
post_permission = "add_document"
put_permission = "change_document"
patch_permission = "change_document"
delete_permission = "delete_document"
safe_methods = ["HEAD", "OPTIONS"]
path_to_project = ["project"]

View File

@ -1,25 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from rest_framework import serializers
from . import models
class DocumentSerializer(serializers.ModelSerializer):
class Meta:
model = models.Document
fields = ()

View File

@ -29,8 +29,6 @@ from taiga.projects.milestones.models import *
from taiga.projects.userstories.models import * from taiga.projects.userstories.models import *
from taiga.projects.tasks.models import * from taiga.projects.tasks.models import *
from taiga.projects.issues.models import * from taiga.projects.issues.models import *
#from taiga.projects.questions.models import *
#from taiga.projects.documents.models import *
from taiga.projects.wiki.models import * from taiga.projects.wiki.models import *
import random import random
@ -153,10 +151,6 @@ class Command(BaseCommand):
for y in range(self.sd.int(15,25)): for y in range(self.sd.int(15,25)):
bug = self.create_bug(project) bug = self.create_bug(project)
# create questions.
#for y in range(self.sd.int(15,25)):
# question = self.create_question(project)
# create a wiki page # create a wiki page
wiki_page = self.create_wiki(project, "home") wiki_page = self.create_wiki(project, "home")
@ -184,20 +178,6 @@ class Command(BaseCommand):
return wiki_page return wiki_page
#def create_question(self, project):
# question = Question.objects.create(
# project=project,
# subject=self.sd.choice(SUBJECT_CHOICES),
# content=self.sd.paragraph(),
# owner=self.sd.db_object_from_queryset(project.memberships.all()).user,
# status=self.sd.db_object_from_queryset(project.question_status.all()),
# tags=self.sd.words(1,5).split(" "))
#
# for i in range(self.sd.int(0, 4)):
# attachment = self.create_attachment(question)
#
# return question
def create_bug(self, project): def create_bug(self, project):
bug = Issue.objects.create( bug = Issue.objects.create(
project=project, project=project,

View File

@ -0,0 +1,253 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Removing unique constraint on 'QuestionStatus', fields ['project', 'name']
db.delete_unique('projects_questionstatus', ['project_id', 'name'])
# Deleting model 'QuestionStatus'
db.delete_table('projects_questionstatus')
# Deleting field 'Project.default_question_status'
db.delete_column('projects_project', 'default_question_status_id')
def backwards(self, orm):
# Adding model 'QuestionStatus'
db.create_table('projects_questionstatus', (
('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='question_status', to=orm['projects.Project'])),
('order', self.gf('django.db.models.fields.IntegerField')(default=10)),
('is_closed', self.gf('django.db.models.fields.BooleanField')(default=False)),
('color', self.gf('django.db.models.fields.CharField')(max_length=20, default='#999999')),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
))
db.send_create_signal('projects', ['QuestionStatus'])
# Adding unique constraint on 'QuestionStatus', fields ['project', 'name']
db.create_unique('projects_questionstatus', ['project_id', 'name'])
# Adding field 'Project.default_question_status'
db.add_column('projects_project', 'default_question_status',
self.gf('django.db.models.fields.related.OneToOneField')(unique=True, related_name='+', null=True, on_delete=models.SET_NULL, blank=True, to=orm['projects.QuestionStatus']),
keep_default=False)
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'to': "orm['auth.Permission']"})
},
'auth.permission': {
'Meta': {'object_name': 'Permission', 'unique_together': "(('content_type', 'codename'),)", 'ordering': "('content_type__app_label', 'content_type__model', 'codename')"},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'contenttypes.contenttype': {
'Meta': {'object_name': 'ContentType', 'unique_together': "(('app_label', 'model'),)", 'ordering': "('name',)", 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'domains.domain': {
'Meta': {'object_name': 'Domain', 'ordering': "('domain',)"},
'alias_of': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'blank': 'True', 'to': "orm['domains.Domain']", 'null': 'True', 'default': 'None'}),
'default_language': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '20', 'default': "''"}),
'domain': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'public_register': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'scheme': ('django.db.models.fields.CharField', [], {'max_length': '60', 'null': 'True', 'default': 'None'})
},
'projects.attachment': {
'Meta': {'object_name': 'Attachment', 'ordering': "['project', 'created_date']"},
'attached_file': ('django.db.models.fields.files.FileField', [], {'blank': 'True', 'max_length': '500', 'null': 'True'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_deprecated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}),
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'change_attachments'", 'to': "orm['users.User']"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attachments'", 'to': "orm['projects.Project']"})
},
'projects.issuestatus': {
'Meta': {'object_name': 'IssueStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_statuses'", 'to': "orm['projects.Project']"})
},
'projects.issuetype': {
'Meta': {'object_name': 'IssueType', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_types'", 'to': "orm['projects.Project']"})
},
'projects.membership': {
'Meta': {'object_name': 'Membership', 'unique_together': "(('user', 'project', 'email'),)", 'ordering': "['project', 'role']"},
'created_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True', 'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '255', 'null': 'True', 'default': 'None'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['projects.Project']"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['users.Role']"}),
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '60', 'null': 'True', 'default': 'None'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'default': 'None'})
},
'projects.points': {
'Meta': {'object_name': 'Points', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'points'", 'to': "orm['projects.Project']"}),
'value': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'null': 'True', 'default': 'None'})
},
'projects.priority': {
'Meta': {'object_name': 'Priority', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'priorities'", 'to': "orm['projects.Project']"})
},
'projects.project': {
'Meta': {'object_name': 'Project', 'ordering': "['name']"},
'created_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'blank': 'True', 'to': "orm['projects.ProjectTemplate']", 'null': 'True', 'default': 'None'}),
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.IssueStatus']"}),
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.IssueType']"}),
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.Points']"}),
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.Priority']"}),
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.Severity']"}),
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.TaskStatus']"}),
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.UserStoryStatus']"}),
'description': ('django.db.models.fields.TextField', [], {}),
'domain': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'blank': 'True', 'to': "orm['domains.Domain']", 'null': 'True', 'default': 'None'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'last_issue_ref': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'default': '0'}),
'last_task_ref': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'default': '0'}),
'last_us_ref': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'default': '0'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'projects'", 'to': "orm['users.User']", 'through': "orm['projects.Membership']"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '250'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_projects'", 'to': "orm['users.User']"}),
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'blank': 'True', 'max_length': '250'}),
'tags': ('picklefield.fields.PickledObjectField', [], {'blank': 'True'}),
'total_milestones': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True', 'default': '0'}),
'total_story_points': ('django.db.models.fields.FloatField', [], {'null': 'True', 'default': 'None'}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'})
},
'projects.projecttemplate': {
'Meta': {'object_name': 'ProjectTemplate', 'unique_together': "(['slug', 'domain'],)", 'ordering': "['name']"},
'created_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
'default_options': ('django_pgjson.fields.JsonField', [], {}),
'default_owner_role': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'description': ('django.db.models.fields.TextField', [], {}),
'domain': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'templates'", 'blank': 'True', 'to': "orm['domains.Domain']", 'null': 'True', 'default': 'None'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'issue_statuses': ('django_pgjson.fields.JsonField', [], {}),
'issue_types': ('django_pgjson.fields.JsonField', [], {}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'points': ('django_pgjson.fields.JsonField', [], {}),
'priorities': ('django_pgjson.fields.JsonField', [], {}),
'roles': ('django_pgjson.fields.JsonField', [], {}),
'severities': ('django_pgjson.fields.JsonField', [], {}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'}),
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'})
},
'projects.severity': {
'Meta': {'object_name': 'Severity', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'severities'", 'to': "orm['projects.Project']"})
},
'projects.taskstatus': {
'Meta': {'object_name': 'TaskStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_statuses'", 'to': "orm['projects.Project']"})
},
'projects.userstorystatus': {
'Meta': {'object_name': 'UserStoryStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'us_statuses'", 'to': "orm['projects.Project']"}),
'wip_limit': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True', 'default': 'None'})
},
'users.role': {
'Meta': {'object_name': 'Role', 'unique_together': "(('slug', 'project'),)", 'ordering': "['order', 'slug']"},
'computable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'roles'", 'to': "orm['auth.Permission']"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'roles'", 'to': "orm['projects.Project']"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'})
},
'users.user': {
'Meta': {'object_name': 'User', 'ordering': "['username']"},
'color': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '9', 'default': "'#f38bf5'"}),
'colorize_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_language': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '20', 'default': "''"}),
'default_timezone': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '20', 'default': "''"}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75'}),
'first_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '30'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'user_set'", 'blank': 'True', 'to': "orm['auth.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '30'}),
'notify_changes_by_me': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'notify_level': ('django.db.models.fields.CharField', [], {'max_length': '32', 'default': "'all_owned_projects'"}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'photo': ('django.db.models.fields.files.FileField', [], {'blank': 'True', 'max_length': '500', 'null': 'True'}),
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '200', 'null': 'True', 'default': 'None'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'user_set'", 'blank': 'True', 'to': "orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
}
}
complete_apps = ['projects']

View File

@ -110,11 +110,6 @@ class ProjectDefaults(models.Model):
on_delete=models.SET_NULL, related_name="+", on_delete=models.SET_NULL, related_name="+",
null=True, blank=True, null=True, blank=True,
verbose_name=_("default issue type")) verbose_name=_("default issue type"))
default_question_status = models.OneToOneField("projects.QuestionStatus",
on_delete=models.SET_NULL,
related_name="+", null=True, blank=True,
verbose_name=_("default questions "
"status"))
class Meta: class Meta:
abstract = True abstract = True
@ -504,34 +499,6 @@ class IssueType(models.Model):
return self.name return self.name
# Questions common models
class QuestionStatus(models.Model):
name = models.CharField(max_length=255, null=False, blank=False,
verbose_name=_("name"))
order = models.IntegerField(default=10, null=False, blank=False,
verbose_name=_("order"))
is_closed = models.BooleanField(default=False, null=False, blank=True,
verbose_name=_("is closed"))
color = models.CharField(max_length=20, null=False, blank=False, default="#999999",
verbose_name=_("color"))
project = models.ForeignKey("Project", null=False, blank=False,
related_name="question_status",
verbose_name=_("project"))
class Meta:
verbose_name = "question status"
verbose_name_plural = "question statuses"
ordering = ["project", "order", "name"]
unique_together = ("project", "name")
permissions = (
("view_questionstatus", "Can view question status"),
)
def __str__(self):
return self.name
class ProjectTemplate(models.Model): class ProjectTemplate(models.Model):
name = models.CharField(max_length=250, null=False, blank=False, name = models.CharField(max_length=250, null=False, blank=False,
verbose_name=_("name")) verbose_name=_("name"))

View File

@ -157,16 +157,7 @@ class RolesPermission(BasePermission):
path_to_project = ["project"] path_to_project = ["project"]
# Questions # Project Templates
class QuestionStatusPermission(BasePermission):
get_permission = "view_questionstatus"
post_permission = "add_questionstatus"
put_permission = "change_questionstatus"
patch_permission = "change_questionstatus"
delete_permission = "delete_questionstatus"
safe_methods = ["HEAD", "OPTIONS"]
path_to_project = ["project"]
class ProjectTemplatePermission(BasePermission): class ProjectTemplatePermission(BasePermission):
def has_permission(self, request, view): def has_permission(self, request, view):

View File

@ -1,53 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.contrib import admin
from taiga.projects.admin import AttachmentInline
from . import models
import reversion
class QuestionAdmin(reversion.VersionAdmin):
list_display = ["project", "milestone", "ref", "subject",]
list_display_links = ["ref", "subject",]
inlines = [AttachmentInline]
def get_object(self, *args, **kwargs):
self.obj = super().get_object(*args, **kwargs)
return self.obj
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if (db_field.name in ["status", "milestone"]
and getattr(self, 'obj', None)):
kwargs["queryset"] = db_field.related.parent_model.objects.filter(
project=self.obj.project)
elif (db_field.name in ["owner", "assigned_to"]
and getattr(self, 'obj', None)):
kwargs["queryset"] = db_field.related.parent_model.objects.filter(
memberships__project=self.obj.project)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
def formfield_for_manytomany(self, db_field, request, **kwargs):
if (db_field.name in ["watchers"]
and getattr(self, 'obj', None)):
kwargs["queryset"] = db_field.related.parent_model.objects.filter(
memberships__project=self.obj.project)
return super().formfield_for_manytomany(db_field, request, **kwargs)
admin.site.register(models.Question, QuestionAdmin)

View File

@ -1,75 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.contrib.contenttypes.models import ContentType
from rest_framework.permissions import IsAuthenticated
from taiga.base import filters
from taiga.base.api import ModelCrudViewSet
from taiga.base.notifications.api import NotificationSenderMixin
from taiga.projects.permissions import AttachmentPermission
from taiga.projects.serializers import AttachmentSerializer
from taiga.projects.models import Attachment
from . import serializers
from . import models
from . import permissions
import reversion
class QuestionAttachmentViewSet(ModelCrudViewSet):
model = Attachment
serializer_class = AttachmentSerializer
permission_classes = (IsAuthenticated, AttachmentPermission)
filter_backends = (filters.IsProjectMemberFilterBackend,)
filter_fields = ["project", "object_id"]
def get_queryset(self):
ct = ContentType.objects.get_for_model(models.Question)
qs = super().get_queryset()
qs = qs.filter(content_type=ct)
return qs.distinct()
def pre_save(self, obj):
super().pre_save(obj)
if not obj.id:
obj.content_type = ContentType.objects.get_for_model(models.Question)
obj.owner = self.request.user
class QuestionViewSet(NotificationSenderMixin, ModelCrudViewSet):
model = models.Question
serializer_class = serializers.QuestionSerializer
permission_classes = (IsAuthenticated, permissions.QuestionPermission)
filter_backends = (filters.IsProjectMemberFilterBackend,)
filter_fields = ("project",)
create_notification_template = "create_question_notification"
update_notification_template = "update_question_notification"
destroy_notification_template = "destroy_question_notification"
def pre_save(self, obj):
super().pre_save(obj)
if not obj.id:
obj.owner = self.request.user
def post_save(self, obj, created=False):
with reversion.create_revision():
if "comment" in self.request.DATA:
# Update the comment in the last version
reversion.set_comment(self.request.DATA["comment"])
super().post_save(obj, created)

View File

@ -1,115 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.db import models
from django.contrib.contenttypes import generic
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.utils import timezone
from django.dispatch import receiver
from taiga.base.utils.slug import ref_uniquely
from taiga.base.notifications.models import WatchedMixin
from picklefield.fields import PickledObjectField
import reversion
class Question(WatchedMixin):
ref = models.BigIntegerField(db_index=True, null=True, blank=True, default=None,
verbose_name=_("ref"))
owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, default=None,
related_name="owned_questions", verbose_name=_("owner"))
status = models.ForeignKey("projects.QuestionStatus", null=False, blank=False,
related_name="questions", verbose_name=_("status"))
subject = models.CharField(max_length=250, null=False, blank=False,
verbose_name=_("subject"))
content = models.TextField(null=False, blank=True, verbose_name=_("content"))
project = models.ForeignKey("projects.Project", null=False, blank=False,
related_name="questions", verbose_name=_("project"))
milestone = models.ForeignKey("milestones.Milestone", null=True, blank=True,
default=None, related_name="questions",
verbose_name=_("milestone"))
finished_date = models.DateTimeField(null=True, blank=True,
verbose_name=_("finished date"))
assigned_to = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,
default=None, related_name="questions_assigned_to_me",
verbose_name=_("assigned_to"))
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
verbose_name=_("modified date"))
watchers = models.ManyToManyField(settings.AUTH_USER_MODEL, null=True, blank=True,
related_name="watched_questions",
verbose_name=_("watchers"))
tags = PickledObjectField(null=False, blank=True, verbose_name=_("tags"))
attachments = generic.GenericRelation("projects.Attachment")
notifiable_fields = [
"owner",
"status",
"milestone",
"finished_date",
"subject",
"content",
"assigned_to",
"tags"
]
class Meta:
verbose_name = "question"
verbose_name_plural = "questions"
ordering = ["project", "created_date"]
unique_together = ("ref", "project")
permissions = (
("view_question", "Can view question"),
)
def __str__(self):
return self.subject
@property
def is_closed(self):
return self.status.is_closed
def _get_watchers_by_role(self):
return {
"owner": self.owner,
"assigned_to": self.assigned_to,
"suscribed_watchers": self.watchers.all(),
"project": self.project,
}
# Reversion registration (usufull for base.notification and for meke a historical)
reversion.register(Question)
# Model related signals handlers
@receiver(models.signals.pre_save, sender=Issue, dispatch_uid="question_finished_date_handler")
def question_finished_date_handler(sender, instance, **kwargs):
if instance.status.is_closed and not instance.finished_date:
instance.finished_date = timezone.now()
elif not instance.status.is_closed and instance.finished_date:
instance.finished_date = None
@receiver(models.signals.pre_save, sender=Question, dispatch_uid="question_ref_handler")
def question_ref_handler(sender, instance, **kwargs):
if not instance.id and instance.project:
instance.ref = ref_uniquely(instance.project,"last_question_ref",
instance.__class__)

View File

@ -1,28 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from taiga.base.permissions import BasePermission
class QuestionPermission(BasePermission):
get_permission = "view_question"
post_permission = "add_question"
put_permission = "change_question"
patch_permission = "change_question"
delete_permission = "delete_question"
safe_methods = ["HEAD", "OPTIONS"]
path_to_project = ["project"]

View File

@ -1,76 +0,0 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from rest_framework import serializers
import reversion
from taiga.base.serializers import PickleField
from . import models
class QuestionSerializer(serializers.ModelSerializer):
tags = PickleField()
comment = serializers.SerializerMethodField("get_comment")
history = serializers.SerializerMethodField("get_history")
is_closed = serializers.Field(source="is_closed")
class Meta:
model = models.Question
fields = ()
def get_comment(self, obj):
# NOTE: This method and field is necessary to historical comments work
return ""
def get_questions_diff(self, old_question_version, new_question_version):
old_obj = old_question_version.field_dict
new_obj = new_question_version.field_dict
diff_dict = {
"modified_date": new_obj["modified_date"],
"by": old_question_version.revision.user,
"comment": old_question_version.revision.comment,
}
for key in old_obj.keys():
if key == "modified_date":
continue
if old_obj[key] == new_obj[key]:
continue
diff_dict[key] = {
"old": old_obj[key],
"new": new_obj[key],
}
return diff_dict
def get_history(self, obj):
diff_list = []
current = None
if obj:
for version in reversed(list(reversion.get_for_object(obj))):
if current:
questions_diff = self.get_questions_diff(current, version)
diff_list.append(questions_diff)
current = version
return diff_list

View File

@ -94,13 +94,6 @@ class IssueTypeSerializer(serializers.ModelSerializer):
model = models.IssueType model = models.IssueType
# Questions common serializers
class QuestionStatusSerializer(serializers.ModelSerializer):
class Meta:
model = models.QuestionStatus
# Projects # Projects
class MembershipSerializer(serializers.ModelSerializer): class MembershipSerializer(serializers.ModelSerializer):
@ -139,7 +132,6 @@ class ProjectDetailSerializer(ProjectSerializer):
severities = SeveritySerializer(many=True, required=False) severities = SeveritySerializer(many=True, required=False)
issue_statuses = IssueStatusSerializer(many=True, required=False) issue_statuses = IssueStatusSerializer(many=True, required=False)
issue_types = IssueTypeSerializer(many=True, required=False) issue_types = IssueTypeSerializer(many=True, required=False)
#question_statuses = QuestionStatusSerializer(many=True, required=False) # Questions
def get_active_membership(self, obj): def get_active_membership(self, obj):
memberships = obj.memberships.filter(user__isnull=False).order_by('user__first_name', 'user__last_name', 'user__username') memberships = obj.memberships.filter(user__isnull=False).order_by('user__first_name', 'user__last_name', 'user__username')

View File

@ -17,7 +17,6 @@
# This makes all code that import services works and # This makes all code that import services works and
# is not the baddest practice ;) # is not the baddest practice ;)
from .bulk_update_order import bulk_update_question_status_order
from .bulk_update_order import bulk_update_severity_order from .bulk_update_order import bulk_update_severity_order
from .bulk_update_order import bulk_update_priority_order from .bulk_update_order import bulk_update_priority_order
from .bulk_update_order import bulk_update_issue_type_order from .bulk_update_order import bulk_update_issue_type_order

View File

@ -134,20 +134,3 @@ def bulk_update_severity_order(project, user, data):
cursor.execute("EXECUTE bulk_update_order (%s, %s, %s);", cursor.execute("EXECUTE bulk_update_order (%s, %s, %s);",
(order, id, project.id)) (order, id, project.id))
cursor.close() cursor.close()
@transaction.atomic
def bulk_update_question_status_order(project, user, data):
cursor = connection.cursor()
sql = """
prepare bulk_update_order as update projects_questionstatus set "order" = $1
where projects_questionstatus.id = $2 and
projects_questionstatus.project_id = $3;
"""
cursor.execute(sql)
for id, order in data:
cursor.execute("EXECUTE bulk_update_order (%s, %s, %s);",
(order, id, project.id))
cursor.close()

View File

@ -23,14 +23,12 @@ from taiga.base.resolver.api import ResolverViewSet
from taiga.projects.api import (ProjectViewSet, MembershipViewSet, InvitationViewSet, from taiga.projects.api import (ProjectViewSet, MembershipViewSet, InvitationViewSet,
UserStoryStatusViewSet, PointsViewSet, TaskStatusViewSet, UserStoryStatusViewSet, PointsViewSet, TaskStatusViewSet,
IssueStatusViewSet, IssueTypeViewSet, PriorityViewSet, IssueStatusViewSet, IssueTypeViewSet, PriorityViewSet,
SeverityViewSet, ProjectAdminViewSet, RolesViewSet) #, QuestionStatusViewSet) SeverityViewSet, ProjectAdminViewSet, RolesViewSet)
from taiga.domains.api import DomainViewSet, DomainMembersViewSet from taiga.domains.api import DomainViewSet, DomainMembersViewSet
from taiga.projects.milestones.api import MilestoneViewSet from taiga.projects.milestones.api import MilestoneViewSet
from taiga.projects.userstories.api import UserStoryViewSet, UserStoryAttachmentViewSet from taiga.projects.userstories.api import UserStoryViewSet, UserStoryAttachmentViewSet
from taiga.projects.tasks.api import TaskViewSet, TaskAttachmentViewSet from taiga.projects.tasks.api import TaskViewSet, TaskAttachmentViewSet
from taiga.projects.issues.api import IssueViewSet, IssueAttachmentViewSet from taiga.projects.issues.api import IssueViewSet, IssueAttachmentViewSet
#from taiga.projects.questions.api import QuestionViewSet, QuestionAttachmentViewSet
#from taiga.projects.documents.api import DocumentViewSet, DocumentAttachmentViewSet
from taiga.projects.wiki.api import WikiViewSet, WikiAttachmentViewSet from taiga.projects.wiki.api import WikiViewSet, WikiAttachmentViewSet

View File

@ -68,7 +68,6 @@ class PermissionsViewSet(ModelListViewSet):
"add_migrationhistory", "change_migrationhistory", "delete_migrationhistory", "add_migrationhistory", "change_migrationhistory", "delete_migrationhistory",
"add_version", "change_version", "delete_version", "add_version", "change_version", "delete_version",
"add_revision", "change_revision", "delete_revision", "add_revision", "change_revision", "delete_revision",
"add_questionstatus", "change_questionstatus", "delete_questionstatus", "view_questionstatus",
"add_user", "delete_user", "add_user", "delete_user",
"add_project", "add_project",
"add_domainmember", "change_domainmember", "delete_domainmember", "add_domainmember", "change_domainmember", "delete_domainmember",