diff --git a/settings/common.py b/settings/common.py index 1adb306a..5b20b21a 100644 --- a/settings/common.py +++ b/settings/common.py @@ -183,10 +183,8 @@ INSTALLED_APPS = [ "taiga.projects.userstories", "taiga.projects.tasks", "taiga.projects.issues", - "taiga.front", - #"taiga.projects.questions", - #"taiga.projects.documents", "taiga.projects.wiki", + "taiga.front", "south", "reversion", diff --git a/taiga/projects/admin.py b/taiga/projects/admin.py index d7959c48..4d501bda 100644 --- a/taiga/projects/admin.py +++ b/taiga/projects/admin.py @@ -60,8 +60,7 @@ class ProjectAdmin(reversion.VersionAdmin): def formfield_for_foreignkey(self, db_field, request, **kwargs): if (db_field.name in ["default_points", "default_us_status", "default_task_status", "default_priority", "default_severity", - "default_issue_status", "default_issue_type", - "default_question_status"]): + "default_issue_status", "default_issue_type"]): if getattr(self, 'obj', None): kwargs["queryset"] = db_field.related.parent_model.objects.filter( project=self.obj) @@ -125,15 +124,6 @@ class IssueStatusAdmin(admin.ModelAdmin): 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.TaskStatus, TaskStatusAdmin) 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.Priority, PriorityAdmin) admin.site.register(models.IssueType, IssueTypeAdmin) - -admin.site.register(models.QuestionStatus, QuestionStatusAdmin) diff --git a/taiga/projects/api.py b/taiga/projects/api.py index d4b85f09..01dc9d78 100644 --- a/taiga/projects/api.py +++ b/taiga/projects/api.py @@ -291,16 +291,6 @@ class IssueStatusViewSet(ModelCrudViewSet, BulkUpdateOrderMixin): 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): model = models.ProjectTemplate serializer_class = serializers.ProjectTemplateSerializer diff --git a/taiga/projects/documents/__init__.py b/taiga/projects/documents/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/taiga/projects/documents/admin.py b/taiga/projects/documents/admin.py deleted file mode 100644 index 6d1a9400..00000000 --- a/taiga/projects/documents/admin.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2014 Andrey Antukh -# Copyright (C) 2014 Jesús Espino -# Copyright (C) 2014 David Barragán -# 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 . - -from django.contrib import admin - -from . import models - - -class DocumentAdmin(admin.ModelAdmin): - list_display = ["title", "project", "owner"] - -admin.site.register(models.Document, DocumentAdmin) diff --git a/taiga/projects/documents/api.py b/taiga/projects/documents/api.py deleted file mode 100644 index fd573c6c..00000000 --- a/taiga/projects/documents/api.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2014 Andrey Antukh -# Copyright (C) 2014 Jesús Espino -# Copyright (C) 2014 David Barragán -# 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 . - -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,) - diff --git a/taiga/projects/documents/models.py b/taiga/projects/documents/models.py deleted file mode 100644 index b7c3b985..00000000 --- a/taiga/projects/documents/models.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (C) 2014 Andrey Antukh -# Copyright (C) 2014 Jesús Espino -# Copyright (C) 2014 David Barragán -# 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 . - -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) - diff --git a/taiga/projects/documents/permissions.py b/taiga/projects/documents/permissions.py deleted file mode 100644 index 371fd0d7..00000000 --- a/taiga/projects/documents/permissions.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2014 Andrey Antukh -# Copyright (C) 2014 Jesús Espino -# Copyright (C) 2014 David Barragán -# 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 . - -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"] diff --git a/taiga/projects/documents/serializers.py b/taiga/projects/documents/serializers.py deleted file mode 100644 index 32b42428..00000000 --- a/taiga/projects/documents/serializers.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2014 Andrey Antukh -# Copyright (C) 2014 Jesús Espino -# Copyright (C) 2014 David Barragán -# 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 . - -from rest_framework import serializers - -from . import models - - -class DocumentSerializer(serializers.ModelSerializer): - class Meta: - model = models.Document - fields = () diff --git a/taiga/projects/management/commands/sample_data.py b/taiga/projects/management/commands/sample_data.py index 7db2ffa6..08e5113c 100644 --- a/taiga/projects/management/commands/sample_data.py +++ b/taiga/projects/management/commands/sample_data.py @@ -29,8 +29,6 @@ from taiga.projects.milestones.models import * from taiga.projects.userstories.models import * from taiga.projects.tasks.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 * import random @@ -153,10 +151,6 @@ class Command(BaseCommand): for y in range(self.sd.int(15,25)): 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 wiki_page = self.create_wiki(project, "home") @@ -184,20 +178,6 @@ class Command(BaseCommand): 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): bug = Issue.objects.create( project=project, diff --git a/taiga/projects/migrations/0020_auto__del_questionstatus__del_unique_questionstatus_project_name__del_.py b/taiga/projects/migrations/0020_auto__del_questionstatus__del_unique_questionstatus_project_name__del_.py new file mode 100644 index 00000000..20461213 --- /dev/null +++ b/taiga/projects/migrations/0020_auto__del_questionstatus__del_unique_questionstatus_project_name__del_.py @@ -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'] \ No newline at end of file diff --git a/taiga/projects/models.py b/taiga/projects/models.py index 609d0c07..c7992bdd 100644 --- a/taiga/projects/models.py +++ b/taiga/projects/models.py @@ -110,11 +110,6 @@ class ProjectDefaults(models.Model): on_delete=models.SET_NULL, related_name="+", null=True, blank=True, 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: abstract = True @@ -504,34 +499,6 @@ class IssueType(models.Model): 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): name = models.CharField(max_length=250, null=False, blank=False, verbose_name=_("name")) diff --git a/taiga/projects/permissions.py b/taiga/projects/permissions.py index b56c8a1e..dfbb5735 100644 --- a/taiga/projects/permissions.py +++ b/taiga/projects/permissions.py @@ -157,16 +157,7 @@ class RolesPermission(BasePermission): path_to_project = ["project"] -# Questions - -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"] +# Project Templates class ProjectTemplatePermission(BasePermission): def has_permission(self, request, view): diff --git a/taiga/projects/questions/__init__.py b/taiga/projects/questions/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/taiga/projects/questions/admin.py b/taiga/projects/questions/admin.py deleted file mode 100644 index eb8a1c93..00000000 --- a/taiga/projects/questions/admin.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (C) 2014 Andrey Antukh -# Copyright (C) 2014 Jesús Espino -# Copyright (C) 2014 David Barragán -# 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 . - -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) diff --git a/taiga/projects/questions/api.py b/taiga/projects/questions/api.py deleted file mode 100644 index 9ee4eae5..00000000 --- a/taiga/projects/questions/api.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (C) 2014 Andrey Antukh -# Copyright (C) 2014 Jesús Espino -# Copyright (C) 2014 David Barragán -# 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 . - -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) diff --git a/taiga/projects/questions/models.py b/taiga/projects/questions/models.py deleted file mode 100644 index a1cff463..00000000 --- a/taiga/projects/questions/models.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright (C) 2014 Andrey Antukh -# Copyright (C) 2014 Jesús Espino -# Copyright (C) 2014 David Barragán -# 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 . - -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__) - - diff --git a/taiga/projects/questions/permissions.py b/taiga/projects/questions/permissions.py deleted file mode 100644 index f26f0d69..00000000 --- a/taiga/projects/questions/permissions.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2014 Andrey Antukh -# Copyright (C) 2014 Jesús Espino -# Copyright (C) 2014 David Barragán -# 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 . - -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"] - diff --git a/taiga/projects/questions/serializers.py b/taiga/projects/questions/serializers.py deleted file mode 100644 index 6f66dc93..00000000 --- a/taiga/projects/questions/serializers.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (C) 2014 Andrey Antukh -# Copyright (C) 2014 Jesús Espino -# Copyright (C) 2014 David Barragán -# 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 . - -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 diff --git a/taiga/projects/serializers.py b/taiga/projects/serializers.py index fffe06ed..57e6d097 100644 --- a/taiga/projects/serializers.py +++ b/taiga/projects/serializers.py @@ -94,13 +94,6 @@ class IssueTypeSerializer(serializers.ModelSerializer): model = models.IssueType -# Questions common serializers - -class QuestionStatusSerializer(serializers.ModelSerializer): - class Meta: - model = models.QuestionStatus - - # Projects class MembershipSerializer(serializers.ModelSerializer): @@ -139,7 +132,6 @@ class ProjectDetailSerializer(ProjectSerializer): severities = SeveritySerializer(many=True, required=False) issue_statuses = IssueStatusSerializer(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): memberships = obj.memberships.filter(user__isnull=False).order_by('user__first_name', 'user__last_name', 'user__username') diff --git a/taiga/projects/services/__init__.py b/taiga/projects/services/__init__.py index e5f14002..5ee8e086 100644 --- a/taiga/projects/services/__init__.py +++ b/taiga/projects/services/__init__.py @@ -17,7 +17,6 @@ # This makes all code that import services works and # 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_priority_order from .bulk_update_order import bulk_update_issue_type_order diff --git a/taiga/projects/services/bulk_update_order.py b/taiga/projects/services/bulk_update_order.py index 6764aaa6..8a0beda1 100644 --- a/taiga/projects/services/bulk_update_order.py +++ b/taiga/projects/services/bulk_update_order.py @@ -134,20 +134,3 @@ def bulk_update_severity_order(project, user, data): cursor.execute("EXECUTE bulk_update_order (%s, %s, %s);", (order, id, project.id)) 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() diff --git a/taiga/routers.py b/taiga/routers.py index e1f80c6b..d031ccb4 100644 --- a/taiga/routers.py +++ b/taiga/routers.py @@ -23,14 +23,12 @@ from taiga.base.resolver.api import ResolverViewSet from taiga.projects.api import (ProjectViewSet, MembershipViewSet, InvitationViewSet, UserStoryStatusViewSet, PointsViewSet, TaskStatusViewSet, IssueStatusViewSet, IssueTypeViewSet, PriorityViewSet, - SeverityViewSet, ProjectAdminViewSet, RolesViewSet) #, QuestionStatusViewSet) + SeverityViewSet, ProjectAdminViewSet, RolesViewSet) from taiga.domains.api import DomainViewSet, DomainMembersViewSet from taiga.projects.milestones.api import MilestoneViewSet from taiga.projects.userstories.api import UserStoryViewSet, UserStoryAttachmentViewSet from taiga.projects.tasks.api import TaskViewSet, TaskAttachmentViewSet 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 diff --git a/taiga/users/api.py b/taiga/users/api.py index aaac653d..685bc9cc 100644 --- a/taiga/users/api.py +++ b/taiga/users/api.py @@ -68,7 +68,6 @@ class PermissionsViewSet(ModelListViewSet): "add_migrationhistory", "change_migrationhistory", "delete_migrationhistory", "add_version", "change_version", "delete_version", "add_revision", "change_revision", "delete_revision", - "add_questionstatus", "change_questionstatus", "delete_questionstatus", "view_questionstatus", "add_user", "delete_user", "add_project", "add_domainmember", "change_domainmember", "delete_domainmember",