Reference refactor.
(Merged from stable/reference-refactor)remotes/origin/enhancement/email-actions
parent
5c96919c24
commit
bb595b8fdd
|
@ -184,6 +184,7 @@ INSTALLED_APPS = [
|
||||||
"taiga.projects.userstories",
|
"taiga.projects.userstories",
|
||||||
"taiga.projects.tasks",
|
"taiga.projects.tasks",
|
||||||
"taiga.projects.issues",
|
"taiga.projects.issues",
|
||||||
|
"taiga.projects.references",
|
||||||
"taiga.projects.wiki",
|
"taiga.projects.wiki",
|
||||||
"taiga.projects.history",
|
"taiga.projects.history",
|
||||||
"taiga.projects.notifications",
|
"taiga.projects.notifications",
|
||||||
|
|
|
@ -1,80 +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.models.loading import get_model
|
|
||||||
|
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework import viewsets
|
|
||||||
from rest_framework.permissions import IsAuthenticated
|
|
||||||
|
|
||||||
from taiga.base import exceptions as excp
|
|
||||||
|
|
||||||
|
|
||||||
class ResolverViewSet(viewsets.ViewSet):
|
|
||||||
permission_classes = (IsAuthenticated,)
|
|
||||||
|
|
||||||
def list(self, request, **kwargs):
|
|
||||||
project_model = get_model("projects", "Project")
|
|
||||||
userstory_model = get_model("userstories", "UserStory")
|
|
||||||
task_model = get_model("tasks", "Task")
|
|
||||||
issue_model = get_model("issues", "Issue")
|
|
||||||
milestone_model = get_model("milestones", "Milestone")
|
|
||||||
|
|
||||||
project_slug = request.QUERY_PARAMS.get('project', None)
|
|
||||||
us_ref = request.QUERY_PARAMS.get('us', None)
|
|
||||||
task_ref = request.QUERY_PARAMS.get('task', None)
|
|
||||||
issue_ref = request.QUERY_PARAMS.get('issue', None)
|
|
||||||
milestone_slug = request.QUERY_PARAMS.get('milestone', None)
|
|
||||||
|
|
||||||
if project_slug is None:
|
|
||||||
return Response({})
|
|
||||||
|
|
||||||
try:
|
|
||||||
project = project_model.objects.get(slug=project_slug)
|
|
||||||
except project_model.DoesNotExist:
|
|
||||||
return Response({})
|
|
||||||
|
|
||||||
result = {"project": project.id}
|
|
||||||
|
|
||||||
if us_ref is not None:
|
|
||||||
try:
|
|
||||||
us = project.user_stories.get(ref=us_ref)
|
|
||||||
result["us"] = us.id
|
|
||||||
except userstory_model.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if task_ref is not None:
|
|
||||||
try:
|
|
||||||
task = project.tasks.get(ref=task_ref)
|
|
||||||
result["task"] = task.id
|
|
||||||
except task_model.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if issue_ref is not None:
|
|
||||||
try:
|
|
||||||
issue = project.issues.get(ref=issue_ref)
|
|
||||||
result["issue"] = issue.id
|
|
||||||
except issue_model.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if milestone_slug is not None:
|
|
||||||
try:
|
|
||||||
milestone = project.milestones.get(slug=milestone_slug)
|
|
||||||
result["milestone"] = milestone.id
|
|
||||||
except milestone_model.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return Response(result)
|
|
|
@ -0,0 +1,237 @@
|
||||||
|
# -*- 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 'Issue', fields ['ref', 'project']
|
||||||
|
db.delete_unique('issues_issue', ['ref', 'project_id'])
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Adding unique constraint on 'Issue', fields ['ref', 'project']
|
||||||
|
db.create_unique('issues_issue', ['ref', 'project_id'])
|
||||||
|
|
||||||
|
|
||||||
|
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', [], {'blank': 'True', 'to': "orm['auth.Permission']", 'symmetrical': 'False'})
|
||||||
|
},
|
||||||
|
'auth.permission': {
|
||||||
|
'Meta': {'unique_together': "(('content_type', 'codename'),)", 'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'object_name': 'Permission'},
|
||||||
|
'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': {'unique_together': "(('app_label', 'model'),)", 'ordering': "('name',)", 'object_name': 'ContentType', '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': {'ordering': "('domain',)", 'object_name': 'Domain'},
|
||||||
|
'alias_of': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['domains.Domain']", 'null': 'True', 'default': 'None', 'related_name': "'+'"}),
|
||||||
|
'default_language': ('django.db.models.fields.CharField', [], {'blank': 'True', 'default': "''", 'max_length': '20'}),
|
||||||
|
'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', [], {'null': 'True', 'default': 'None', 'max_length': '60'})
|
||||||
|
},
|
||||||
|
'issues.issue': {
|
||||||
|
'Meta': {'ordering': "['project', 'created_date']", 'object_name': 'Issue'},
|
||||||
|
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'default': 'None', 'related_name': "'issues_assigned_to_me'"}),
|
||||||
|
'blocked_note': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||||
|
'finished_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['milestones.Milestone']", 'null': 'True', 'default': 'None', 'related_name': "'issues'"}),
|
||||||
|
'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||||
|
'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'default': 'None', 'related_name': "'owned_issues'"}),
|
||||||
|
'priority': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Priority']", 'related_name': "'issues'"}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issues'"}),
|
||||||
|
'ref': ('django.db.models.fields.BigIntegerField', [], {'blank': 'True', 'db_index': 'True', 'null': 'True', 'default': 'None'}),
|
||||||
|
'severity': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Severity']", 'related_name': "'issues'"}),
|
||||||
|
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.IssueStatus']", 'related_name': "'issues'"}),
|
||||||
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
|
||||||
|
'tags': ('picklefield.fields.PickledObjectField', [], {'blank': 'True'}),
|
||||||
|
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.IssueType']", 'related_name': "'issues'"}),
|
||||||
|
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'to': "orm['users.User']", 'symmetrical': 'False', 'null': 'True', 'related_name': "'watched_issues'"})
|
||||||
|
},
|
||||||
|
'milestones.milestone': {
|
||||||
|
'Meta': {'unique_together': "(('name', 'project'),)", 'ordering': "['project', 'created_date']", 'object_name': 'Milestone'},
|
||||||
|
'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
|
||||||
|
'disponibility': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'null': 'True', 'default': '0.0'}),
|
||||||
|
'estimated_finish': ('django.db.models.fields.DateField', [], {'blank': 'True', 'null': 'True', 'default': 'None'}),
|
||||||
|
'estimated_start': ('django.db.models.fields.DateField', [], {'blank': 'True', 'null': 'True', 'default': 'None'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '200'}),
|
||||||
|
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
|
||||||
|
'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'related_name': "'owned_milestones'"}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'milestones'"}),
|
||||||
|
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'unique': 'True', 'max_length': '250'})
|
||||||
|
},
|
||||||
|
'projects.issuestatus': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'IssueStatus'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'issue_statuses'"})
|
||||||
|
},
|
||||||
|
'projects.issuetype': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'IssueType'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'issue_types'"})
|
||||||
|
},
|
||||||
|
'projects.membership': {
|
||||||
|
'Meta': {'ordering': "['project', 'role']", 'object_name': 'Membership'},
|
||||||
|
'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', 'null': 'True', 'default': 'None', 'max_length': '255'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'memberships'"}),
|
||||||
|
'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.Role']", 'related_name': "'memberships'"}),
|
||||||
|
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'max_length': '60'}),
|
||||||
|
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'default': 'None', 'related_name': "'memberships'"})
|
||||||
|
},
|
||||||
|
'projects.points': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Points'},
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'points'"}),
|
||||||
|
'value': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'null': 'True', 'default': 'None'})
|
||||||
|
},
|
||||||
|
'projects.priority': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Priority'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'priorities'"})
|
||||||
|
},
|
||||||
|
'projects.project': {
|
||||||
|
'Meta': {'ordering': "['name']", 'object_name': 'Project'},
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
|
||||||
|
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'to': "orm['projects.IssueStatus']", 'unique': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'to': "orm['projects.IssueType']", 'unique': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'to': "orm['projects.Points']", 'unique': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'to': "orm['projects.Priority']", 'unique': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_question_status': ('django.db.models.fields.related.OneToOneField', [], {'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'to': "orm['projects.QuestionStatus']", 'unique': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'to': "orm['projects.Severity']", 'unique': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'to': "orm['projects.TaskStatus']", 'unique': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'to': "orm['projects.UserStoryStatus']", 'unique': 'True', 'related_name': "'+'"}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {}),
|
||||||
|
'domain': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['domains.Domain']", 'null': 'True', 'default': 'None', 'related_name': "'projects'"}),
|
||||||
|
'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', [], {'to': "orm['users.User']", 'symmetrical': 'False', 'through': "orm['projects.Membership']", 'related_name': "'projects'"}),
|
||||||
|
'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '250'}),
|
||||||
|
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.User']", 'related_name': "'owned_projects'"}),
|
||||||
|
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'unique': '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', 'null': 'True', 'max_length': '250'}),
|
||||||
|
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'max_length': '250'})
|
||||||
|
},
|
||||||
|
'projects.questionstatus': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'QuestionStatus'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'question_status'"})
|
||||||
|
},
|
||||||
|
'projects.severity': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Severity'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'severities'"})
|
||||||
|
},
|
||||||
|
'projects.taskstatus': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'TaskStatus'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'task_statuses'"})
|
||||||
|
},
|
||||||
|
'projects.userstorystatus': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'UserStoryStatus'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'us_statuses'"}),
|
||||||
|
'wip_limit': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True', 'default': 'None'})
|
||||||
|
},
|
||||||
|
'users.role': {
|
||||||
|
'Meta': {'unique_together': "(('slug', 'project'),)", 'ordering': "['order', 'slug']", 'object_name': 'Role'},
|
||||||
|
'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', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'related_name': "'roles'"}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'roles'"}),
|
||||||
|
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'})
|
||||||
|
},
|
||||||
|
'users.user': {
|
||||||
|
'Meta': {'ordering': "['username']", 'object_name': 'User'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'blank': 'True', 'default': "'#19ba05'", 'max_length': '9'}),
|
||||||
|
'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', 'default': "''", 'max_length': '20'}),
|
||||||
|
'default_timezone': ('django.db.models.fields.CharField', [], {'blank': 'True', 'default': "''", 'max_length': '20'}),
|
||||||
|
'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', [], {'blank': 'True', 'to': "orm['auth.Group']", 'symmetrical': 'False', 'related_name': "'user_set'"}),
|
||||||
|
'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', [], {'default': "'all_owned_projects'", 'max_length': '32'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'photo': ('django.db.models.fields.files.FileField', [], {'blank': 'True', 'null': 'True', 'max_length': '500'}),
|
||||||
|
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'max_length': '200'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'to': "orm['auth.Permission']", 'symmetrical': 'False', 'related_name': "'user_set'"}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['issues']
|
|
@ -69,7 +69,7 @@ class Issue(NeighborsMixin, WatchedMixin, BlockedMixin, models.Model):
|
||||||
verbose_name = "issue"
|
verbose_name = "issue"
|
||||||
verbose_name_plural = "issues"
|
verbose_name_plural = "issues"
|
||||||
ordering = ["project", "created_date"]
|
ordering = ["project", "created_date"]
|
||||||
unique_together = ("ref", "project")
|
#unique_together = ("ref", "project")
|
||||||
permissions = (
|
permissions = (
|
||||||
("view_issue", "Can view issue"),
|
("view_issue", "Can view issue"),
|
||||||
)
|
)
|
||||||
|
@ -267,12 +267,6 @@ def issue_finished_date_handler(sender, instance, **kwargs):
|
||||||
instance.finished_date = None
|
instance.finished_date = None
|
||||||
|
|
||||||
|
|
||||||
@receiver(models.signals.pre_save, sender=Issue, dispatch_uid="issue_ref_handler")
|
|
||||||
def issue_ref_handler(sender, instance, **kwargs):
|
|
||||||
if not instance.id and instance.project:
|
|
||||||
instance.ref = ref_uniquely(instance.project, "last_issue_ref", instance.__class__)
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(models.signals.pre_save, sender=Issue, dispatch_uid="issue-tags-normalization")
|
@receiver(models.signals.pre_save, sender=Issue, dispatch_uid="issue-tags-normalization")
|
||||||
def issue_tags_normalization(sender, instance, **kwargs):
|
def issue_tags_normalization(sender, instance, **kwargs):
|
||||||
if isinstance(instance.tags, (list, tuple)):
|
if isinstance(instance.tags, (list, tuple)):
|
||||||
|
|
|
@ -0,0 +1,235 @@
|
||||||
|
# -*- 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):
|
||||||
|
depends_on = (
|
||||||
|
('references', '0001_initial'),
|
||||||
|
)
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
# Deleting field 'Project.last_us_ref'
|
||||||
|
db.delete_column('projects_project', 'last_us_ref')
|
||||||
|
|
||||||
|
# Deleting field 'Project.last_issue_ref'
|
||||||
|
db.delete_column('projects_project', 'last_issue_ref')
|
||||||
|
|
||||||
|
# Deleting field 'Project.last_task_ref'
|
||||||
|
db.delete_column('projects_project', 'last_task_ref')
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Adding field 'Project.last_us_ref'
|
||||||
|
db.add_column('projects_project', 'last_us_ref',
|
||||||
|
self.gf('django.db.models.fields.BigIntegerField')(default=0, null=True),
|
||||||
|
keep_default=False)
|
||||||
|
|
||||||
|
# Adding field 'Project.last_issue_ref'
|
||||||
|
db.add_column('projects_project', 'last_issue_ref',
|
||||||
|
self.gf('django.db.models.fields.BigIntegerField')(default=0, null=True),
|
||||||
|
keep_default=False)
|
||||||
|
|
||||||
|
# Adding field 'Project.last_task_ref'
|
||||||
|
db.add_column('projects_project', 'last_task_ref',
|
||||||
|
self.gf('django.db.models.fields.BigIntegerField')(default=0, null=True),
|
||||||
|
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', [], {'max_length': '80', 'unique': 'True'}),
|
||||||
|
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'to': "orm['auth.Permission']"})
|
||||||
|
},
|
||||||
|
'auth.permission': {
|
||||||
|
'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission', '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': {'unique_together': "(('app_label', 'model'),)", 'ordering': "('name',)", 'object_name': 'ContentType', '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', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['domains.Domain']"}),
|
||||||
|
'default_language': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20', 'blank': 'True'}),
|
||||||
|
'domain': ('django.db.models.fields.CharField', [], {'max_length': '255', 'unique': 'True'}),
|
||||||
|
'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', [], {'default': 'None', 'max_length': '60', 'null': 'True'})
|
||||||
|
},
|
||||||
|
'projects.issuestatus': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'IssueStatus', 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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': {'unique_together': "(('project', 'name'),)", 'object_name': 'IssueType', 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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': {'unique_together': "(('user', 'project', 'email'),)", 'object_name': 'Membership', 'ordering': "['project', 'role']"},
|
||||||
|
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'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', [], {'default': 'None', 'max_length': '60', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'memberships'", 'null': 'True', 'blank': 'True', 'to': "orm['users.User']"})
|
||||||
|
},
|
||||||
|
'projects.points': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'Points', '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', [], {'default': 'None', 'null': 'True', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'projects.priority': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'Priority', 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'projects'", 'null': 'True', 'blank': 'True', 'to': "orm['projects.ProjectTemplate']"}),
|
||||||
|
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'null': 'True', 'blank': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.IssueStatus']", 'unique': 'True'}),
|
||||||
|
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'null': 'True', 'blank': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.IssueType']", 'unique': 'True'}),
|
||||||
|
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'null': 'True', 'blank': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.Points']", 'unique': 'True'}),
|
||||||
|
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'null': 'True', 'blank': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.Priority']", 'unique': 'True'}),
|
||||||
|
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'null': 'True', 'blank': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.Severity']", 'unique': 'True'}),
|
||||||
|
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'null': 'True', 'blank': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.TaskStatus']", 'unique': 'True'}),
|
||||||
|
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'null': 'True', 'blank': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.UserStoryStatus']", 'unique': 'True'}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {}),
|
||||||
|
'domain': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'projects'", 'null': 'True', 'blank': 'True', 'to': "orm['domains.Domain']"}),
|
||||||
|
'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'}),
|
||||||
|
'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', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '250', 'unique': 'True'}),
|
||||||
|
'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', [], {'max_length': '250', 'blank': 'True', 'unique': 'True'}),
|
||||||
|
'tags': ('picklefield.fields.PickledObjectField', [], {'blank': 'True'}),
|
||||||
|
'total_milestones': ('django.db.models.fields.IntegerField', [], {'default': '0', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': 'None', 'null': 'True'}),
|
||||||
|
'videoconferences': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'projects.projecttemplate': {
|
||||||
|
'Meta': {'unique_together': "(['slug', 'domain'],)", 'object_name': 'ProjectTemplate', 'ordering': "['name']"},
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': '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', [], {'default': 'None', 'related_name': "'templates'", 'null': 'True', 'blank': 'True', 'to': "orm['domains.Domain']"}),
|
||||||
|
'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', [], {'auto_now': 'True', 'blank': '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', [], {'max_length': '250', 'blank': 'True'}),
|
||||||
|
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
|
||||||
|
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
|
||||||
|
'videoconferences': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'projects.severity': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'Severity', 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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': {'unique_together': "(('project', 'name'),)", 'object_name': 'TaskStatus', 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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': {'unique_together': "(('project', 'name'),)", 'object_name': 'UserStoryStatus', 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'default': 'None', 'null': 'True', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'users.role': {
|
||||||
|
'Meta': {'unique_together': "(('slug', 'project'),)", 'object_name': 'Role', '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', [], {'max_length': '250', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'users.user': {
|
||||||
|
'Meta': {'object_name': 'User', 'ordering': "['username']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#a1402e'", 'max_length': '9', 'blank': 'True'}),
|
||||||
|
'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', [], {'default': "''", 'max_length': '20', 'blank': 'True'}),
|
||||||
|
'default_timezone': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20', 'blank': 'True'}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||||
|
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'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', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'notify_changes_by_me': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'notify_level': ('django.db.models.fields.CharField', [], {'default': "'all_owned_projects'", 'max_length': '32'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'photo': ('django.db.models.fields.files.FileField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'token': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'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', [], {'max_length': '30', 'unique': 'True'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['projects']
|
|
@ -128,12 +128,6 @@ class Project(ProjectDefaults, models.Model):
|
||||||
through="Membership", verbose_name=_("members"))
|
through="Membership", verbose_name=_("members"))
|
||||||
public = models.BooleanField(default=True, null=False, blank=True,
|
public = models.BooleanField(default=True, null=False, blank=True,
|
||||||
verbose_name=_("public"))
|
verbose_name=_("public"))
|
||||||
last_us_ref = models.BigIntegerField(null=True, blank=False, default=0,
|
|
||||||
verbose_name=_("last us ref"))
|
|
||||||
last_task_ref = models.BigIntegerField(null=True, blank=False, default=0,
|
|
||||||
verbose_name=_("last task ref"))
|
|
||||||
last_issue_ref = models.BigIntegerField(null=True, blank=False, default=0,
|
|
||||||
verbose_name=_("last issue ref"))
|
|
||||||
total_milestones = models.IntegerField(default=0, null=True, blank=True,
|
total_milestones = models.IntegerField(default=0, null=True, blank=True,
|
||||||
verbose_name=_("total of milestones"))
|
verbose_name=_("total of milestones"))
|
||||||
total_story_points = models.FloatField(default=None, null=True, blank=False,
|
total_story_points = models.FloatField(default=None, null=True, blank=False,
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from django.db.models.loading import get_model
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework import viewsets
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
|
||||||
|
from taiga.base import exceptions as exc
|
||||||
|
from .serializers import ResolverSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class ResolverViewSet(viewsets.ViewSet):
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
|
|
||||||
|
def list(self, request, **kwargs):
|
||||||
|
serializer = ResolverSerializer(data=request.QUERY_PARAMS)
|
||||||
|
if not serializer.is_valid():
|
||||||
|
raise exc.BadRequest(serializer.errors)
|
||||||
|
|
||||||
|
data = serializer.data
|
||||||
|
|
||||||
|
project_model = get_model("projects", "Project")
|
||||||
|
project = get_object_or_404(project_model, slug=data["project"])
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"project": project.pk
|
||||||
|
}
|
||||||
|
|
||||||
|
if data["us"]:
|
||||||
|
result["us"] = get_object_or_404(project.user_stories.all(), ref=data["us"]).pk
|
||||||
|
if data["task"]:
|
||||||
|
result["us"] = get_object_or_404(project.tasks.all(), ref=data["task"]).pk
|
||||||
|
if data["issue"]:
|
||||||
|
result["issue"] = get_object_or_404(project.issues.all(), ref=data["issue"]).pk
|
||||||
|
if data["milestone"]:
|
||||||
|
result["milestone"] = get_object_or_404(project.milestones.all(), slug=data["milestones"]).pk
|
||||||
|
|
||||||
|
return Response(result)
|
|
@ -0,0 +1,171 @@
|
||||||
|
import re
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
from django.core.paginator import Paginator
|
||||||
|
from django.db.models.loading import get_model
|
||||||
|
from django.db.models import signals
|
||||||
|
from django.db import models
|
||||||
|
from django.db import transaction as tx
|
||||||
|
|
||||||
|
from reversion import get_unique_for_object
|
||||||
|
|
||||||
|
from taiga.projects.references.models import make_reference
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "Migrate old references to new references system."
|
||||||
|
|
||||||
|
def iter_queryset(self, queryset):
|
||||||
|
paginator = Paginator(queryset, 20)
|
||||||
|
for page_num in paginator.page_range:
|
||||||
|
page = paginator.page(page_num)
|
||||||
|
for element in page.object_list:
|
||||||
|
yield element
|
||||||
|
|
||||||
|
def iter_object_versions(self, instance):
|
||||||
|
revs = get_unique_for_object(instance)
|
||||||
|
for rev in revs:
|
||||||
|
yield rev
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.refmap = defaultdict(lambda: {"us": {}, "task": {}, "issue": {},})
|
||||||
|
|
||||||
|
@tx.atomic
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
self.disable_signals()
|
||||||
|
self.process_userstories_refs()
|
||||||
|
self.process_issues_refs()
|
||||||
|
self.process_tasks_refs()
|
||||||
|
|
||||||
|
self.process_userstories_comments()
|
||||||
|
self.process_issues_comments()
|
||||||
|
self.process_tasks_comments()
|
||||||
|
self.process_wikipages()
|
||||||
|
|
||||||
|
def replace_references_on_text(self, ppk, text):
|
||||||
|
matches = re.findall(r"(\:((?:us|issue|task))\:(\d+))", text)
|
||||||
|
for val, t, ref in matches:
|
||||||
|
ref = int(ref)
|
||||||
|
if ref not in self.refmap[ppk][t]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
newref = self.refmap[ppk][t][ref]
|
||||||
|
text = text.replace(val, ":{}:{}".format(t, newref))
|
||||||
|
|
||||||
|
matches = re.findall(r"(((?:US|Issue|Task)) \#(\d+))", text)
|
||||||
|
for val, t, ref in matches:
|
||||||
|
ref = int(ref)
|
||||||
|
if ref not in self.refmap[ppk][t.lower()]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
newref = self.refmap[ppk][t.lower()][ref]
|
||||||
|
text = text.replace(val, "{} #{}".format(t, newref))
|
||||||
|
|
||||||
|
return text
|
||||||
|
|
||||||
|
def disable_signals(self):
|
||||||
|
print(".. Disabling signals.")
|
||||||
|
issue_model = get_model("issues", "Issue")
|
||||||
|
us_model = get_model("userstories", "UserStory")
|
||||||
|
task_model = get_model("tasks", "Task")
|
||||||
|
project_model = get_model("projects", "Project")
|
||||||
|
|
||||||
|
models.signals.post_save.disconnect(dispatch_uid="refus", sender=us_model)
|
||||||
|
models.signals.post_save.disconnect(dispatch_uid="refissue", sender=issue_model)
|
||||||
|
models.signals.post_save.disconnect(dispatch_uid="reftask", sender=task_model)
|
||||||
|
models.signals.post_save.disconnect(dispatch_uid="refproj", sender=project_model)
|
||||||
|
|
||||||
|
def process_userstories_comments(self):
|
||||||
|
print(".. Processing userstory comments.")
|
||||||
|
model_cls = get_model("userstories", "UserStory")
|
||||||
|
|
||||||
|
for item in self.iter_queryset(model_cls.objects.all()):
|
||||||
|
item.description = self.replace_references_on_text(item.project_id, item.description)
|
||||||
|
item.blocked_note = self.replace_references_on_text(item.project_id, item.blocked_note)
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
for rev in self.iter_object_versions(item):
|
||||||
|
rev.revision.comment = self.replace_references_on_text(item.project_id, rev.revision.comment)
|
||||||
|
rev.revision.save()
|
||||||
|
rev.save()
|
||||||
|
|
||||||
|
def process_issues_comments(self):
|
||||||
|
print(".. Processing issues comments.")
|
||||||
|
model_cls = get_model("issues", "Issue")
|
||||||
|
|
||||||
|
for item in self.iter_queryset(model_cls.objects.all()):
|
||||||
|
item.description = self.replace_references_on_text(item.project_id, item.description)
|
||||||
|
item.blocked_note = self.replace_references_on_text(item.project_id, item.blocked_note)
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
for rev in self.iter_object_versions(item):
|
||||||
|
rev.revision.comment = self.replace_references_on_text(item.project_id, rev.revision.comment)
|
||||||
|
rev.revision.save()
|
||||||
|
rev.save()
|
||||||
|
|
||||||
|
def process_tasks_comments(self):
|
||||||
|
print(".. Processing task comments.")
|
||||||
|
model_cls = get_model("tasks", "Task")
|
||||||
|
|
||||||
|
for item in self.iter_queryset(model_cls.objects.all()):
|
||||||
|
item.description = self.replace_references_on_text(item.project_id, item.description)
|
||||||
|
item.blocked_note = self.replace_references_on_text(item.project_id, item.blocked_note)
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
for rev in self.iter_object_versions(item):
|
||||||
|
rev.revision.comment = self.replace_references_on_text(item.project_id, rev.revision.comment)
|
||||||
|
rev.revision.save()
|
||||||
|
rev.save()
|
||||||
|
|
||||||
|
def process_wikipages(self):
|
||||||
|
print(".. Processing wikipages.")
|
||||||
|
model_cls = get_model("wiki", "WikiPage")
|
||||||
|
|
||||||
|
for item in self.iter_queryset(model_cls.objects.all()):
|
||||||
|
item.content = self.replace_references_on_text(item.project_id, item.content)
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
for rev in self.iter_object_versions(item):
|
||||||
|
rev.revision.comment = self.replace_references_on_text(item.project_id, rev.revision.comment)
|
||||||
|
rev.revision.save()
|
||||||
|
rev.save()
|
||||||
|
|
||||||
|
def process_userstories_refs(self):
|
||||||
|
print(".. Processing userstories.")
|
||||||
|
model_cls = get_model("userstories", "UserStory")
|
||||||
|
queryset = model_cls.objects.only("ref")
|
||||||
|
|
||||||
|
for item in self.iter_queryset(queryset):
|
||||||
|
refval, _ = make_reference(item, item.project, create=True)
|
||||||
|
print("process us {0}: {1} -> {2}".format(item.pk, item.ref, refval))
|
||||||
|
self.refmap[item.project_id]["us"][item.ref] = refval
|
||||||
|
item.ref = refval
|
||||||
|
item.save(update_fields=["ref"])
|
||||||
|
|
||||||
|
def process_tasks_refs(self):
|
||||||
|
print(".. Processing tasks.")
|
||||||
|
model_cls = get_model("tasks", "Task")
|
||||||
|
queryset = model_cls.objects.only("ref")
|
||||||
|
|
||||||
|
for item in self.iter_queryset(queryset):
|
||||||
|
refval, _ = make_reference(item, item.project, create=True)
|
||||||
|
print("process task {0}: {1} -> {2}".format(item.pk, item.ref, refval))
|
||||||
|
self.refmap[item.project_id]["task"][item.ref] = refval
|
||||||
|
item.ref = refval
|
||||||
|
item.save(update_fields=["ref"])
|
||||||
|
|
||||||
|
def process_issues_refs(self):
|
||||||
|
print(".. Processing issues.")
|
||||||
|
model_cls = get_model("issues", "Issue")
|
||||||
|
queryset = model_cls.objects.all()
|
||||||
|
|
||||||
|
for item in self.iter_queryset(queryset):
|
||||||
|
refval, _ = make_reference(item, item.project, create=True)
|
||||||
|
print("process issue {0}: {1} -> {2}".format(item.pk, item.ref, refval))
|
||||||
|
self.refmap[item.project_id]["issue"][item.ref] = refval
|
||||||
|
item.ref = refval
|
||||||
|
item.save()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# -*- 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):
|
||||||
|
# Adding model 'Reference'
|
||||||
|
db.create_table('references_reference', (
|
||||||
|
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||||
|
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(related_name='+', to=orm['contenttypes.ContentType'])),
|
||||||
|
('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
|
||||||
|
('ref', self.gf('django.db.models.fields.BigIntegerField')()),
|
||||||
|
('created_at', self.gf('django.db.models.fields.DateTimeField')(blank=True, auto_now_add=True)),
|
||||||
|
))
|
||||||
|
db.send_create_signal('references', ['Reference'])
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Deleting model 'Reference'
|
||||||
|
db.delete_table('references_reference')
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'contenttypes.contenttype': {
|
||||||
|
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', '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'})
|
||||||
|
},
|
||||||
|
'references.reference': {
|
||||||
|
'Meta': {'ordering': "['created_at']", 'object_name': 'Reference'},
|
||||||
|
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['contenttypes.ContentType']"}),
|
||||||
|
'created_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
|
||||||
|
'ref': ('django.db.models.fields.BigIntegerField', [], {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['references']
|
|
@ -0,0 +1,72 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.contrib.contenttypes.generic import GenericForeignKey
|
||||||
|
|
||||||
|
from taiga.projects.userstories.models import UserStory
|
||||||
|
from taiga.projects.tasks.models import Task
|
||||||
|
from taiga.projects.issues.models import Issue
|
||||||
|
from taiga.projects.models import Project
|
||||||
|
|
||||||
|
from . import sequences as seq
|
||||||
|
|
||||||
|
|
||||||
|
class Reference(models.Model):
|
||||||
|
content_type = models.ForeignKey(ContentType, related_name="+")
|
||||||
|
object_id = models.PositiveIntegerField()
|
||||||
|
ref = models.BigIntegerField()
|
||||||
|
content_object = GenericForeignKey("content_type", "object_id")
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ["created_at"]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "Reference {}".format(self.object_id)
|
||||||
|
|
||||||
|
|
||||||
|
def make_sequence_name(project) -> str:
|
||||||
|
return "references_project{0}".format(project.pk)
|
||||||
|
|
||||||
|
|
||||||
|
def make_unique_reference_id(project, *, create=False):
|
||||||
|
seqname = make_sequence_name(project)
|
||||||
|
if create and not seq.exists(seqname):
|
||||||
|
seq.create(seqname)
|
||||||
|
return seq.next_value(seqname)
|
||||||
|
|
||||||
|
|
||||||
|
def make_reference(instance, project, create=False):
|
||||||
|
refval = make_unique_reference_id(project, create=create)
|
||||||
|
ct = ContentType.objects.get_for_model(instance.__class__)
|
||||||
|
refinstance = Reference.objects.create(content_type=ct,
|
||||||
|
object_id=instance.pk,
|
||||||
|
ref=refval)
|
||||||
|
return refval, refinstance
|
||||||
|
|
||||||
|
|
||||||
|
def create_sequence(sender, instance, created, **kwargs):
|
||||||
|
if not created:
|
||||||
|
return
|
||||||
|
|
||||||
|
seqname = make_sequence_name(instance)
|
||||||
|
if not seq.exists(seqname):
|
||||||
|
seq.create(seqname)
|
||||||
|
|
||||||
|
def attach_sequence(sender, instance, **kwargs):
|
||||||
|
# Create a reference object. This operation should be
|
||||||
|
# used in transaction context, otherwise it can
|
||||||
|
# create a lot of phantom reference objects.
|
||||||
|
refval, _ = make_reference(instance, instance.project)
|
||||||
|
|
||||||
|
# Additionally, attach sequence number to instance as ref
|
||||||
|
sender.objects.filter(pk=instance.pk).update(ref=refval)
|
||||||
|
|
||||||
|
|
||||||
|
models.signals.post_save.connect(create_sequence, sender=Project, dispatch_uid="refproj")
|
||||||
|
models.signals.post_save.connect(attach_sequence, sender=UserStory, dispatch_uid="refus")
|
||||||
|
models.signals.post_save.connect(attach_sequence, sender=Issue, dispatch_uid="refissue")
|
||||||
|
models.signals.post_save.connect(attach_sequence, sender=Task, dispatch_uid="reftask")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
from contextlib import closing
|
||||||
|
from django.db import connection
|
||||||
|
from django.db import ProgrammingError
|
||||||
|
|
||||||
|
|
||||||
|
def create(seqname:str, start=1) -> None:
|
||||||
|
sql = "CREATE SEQUENCE {0} START %s".format(seqname)
|
||||||
|
|
||||||
|
with closing(connection.cursor()) as cursor:
|
||||||
|
cursor.execute(sql, [start])
|
||||||
|
|
||||||
|
|
||||||
|
def exists(seqname:str) -> bool:
|
||||||
|
sql = """
|
||||||
|
SELECT EXISTS(
|
||||||
|
SELECT relname FROM pg_class
|
||||||
|
WHERE relkind = 'S' AND relname = %s);
|
||||||
|
"""
|
||||||
|
|
||||||
|
with closing(connection.cursor()) as cursor:
|
||||||
|
cursor.execute(sql, [seqname])
|
||||||
|
result = cursor.fetchone()
|
||||||
|
return result[0]
|
||||||
|
|
||||||
|
|
||||||
|
def alter(seqname:str, value:int) -> None:
|
||||||
|
sql = "SELECT setval(%s, %s);"
|
||||||
|
with closing(connection.cursor()) as cursor:
|
||||||
|
cursor.execute(sql, [seqname, value])
|
||||||
|
|
||||||
|
|
||||||
|
def delete(seqname:str) -> None:
|
||||||
|
sql = "DROP SEQUENCE {0};".format(seqname)
|
||||||
|
with closing(connection.cursor()) as cursor:
|
||||||
|
cursor.execute(sql)
|
||||||
|
|
||||||
|
def next_value(seqname):
|
||||||
|
sql = "SELECT nextval(%s);"
|
||||||
|
with closing(connection.cursor()) as cursor:
|
||||||
|
cursor.execute(sql, [seqname])
|
||||||
|
result = cursor.fetchone()
|
||||||
|
return result[0]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
|
||||||
|
class ResolverSerializer(serializers.Serializer):
|
||||||
|
project = serializers.CharField(max_length=512, required=True)
|
||||||
|
milestone = serializers.CharField(max_length=512, required=False)
|
||||||
|
us = serializers.IntegerField(required=False)
|
||||||
|
task = serializers.IntegerField(required=False)
|
||||||
|
issue = serializers.IntegerField(required=False)
|
|
@ -0,0 +1,290 @@
|
||||||
|
# -*- 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 'Task', fields ['ref', 'project']
|
||||||
|
db.delete_unique('tasks_task', ['ref', 'project_id'])
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Adding unique constraint on 'Task', fields ['ref', 'project']
|
||||||
|
db.create_unique('tasks_task', ['ref', 'project_id'])
|
||||||
|
|
||||||
|
|
||||||
|
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': {'unique_together': "(('content_type', 'codename'),)", 'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'object_name': 'Permission'},
|
||||||
|
'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': {'db_table': "'django_content_type'", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'ordering': "('name',)"},
|
||||||
|
'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': {'ordering': "('domain',)", 'object_name': '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', [], {'null': 'True', 'default': 'None', 'max_length': '60'})
|
||||||
|
},
|
||||||
|
'issues.issue': {
|
||||||
|
'Meta': {'ordering': "['project', 'created_date']", 'object_name': 'Issue'},
|
||||||
|
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues_assigned_to_me'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'default': 'None'}),
|
||||||
|
'blocked_note': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||||
|
'finished_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'blank': 'True', 'to': "orm['milestones.Milestone']", 'null': 'True', 'default': 'None'}),
|
||||||
|
'modified_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}),
|
||||||
|
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_issues'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'default': 'None'}),
|
||||||
|
'priority': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.Priority']"}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.Project']"}),
|
||||||
|
'ref': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True', 'blank': 'True', 'null': 'True', 'default': 'None'}),
|
||||||
|
'severity': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.Severity']"}),
|
||||||
|
'status': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.IssueStatus']"}),
|
||||||
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
|
||||||
|
'tags': ('picklefield.fields.PickledObjectField', [], {'blank': 'True'}),
|
||||||
|
'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.IssueType']"}),
|
||||||
|
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'watched_issues'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True'})
|
||||||
|
},
|
||||||
|
'milestones.milestone': {
|
||||||
|
'Meta': {'unique_together': "(('name', 'project'),)", 'ordering': "['project', 'created_date']", 'object_name': 'Milestone'},
|
||||||
|
'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'disponibility': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'null': 'True', 'default': '0.0'}),
|
||||||
|
'estimated_finish': ('django.db.models.fields.DateField', [], {'blank': 'True', 'null': 'True', 'default': 'None'}),
|
||||||
|
'estimated_start': ('django.db.models.fields.DateField', [], {'blank': 'True', 'null': 'True', 'default': 'None'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'modified_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '200'}),
|
||||||
|
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
|
||||||
|
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_milestones'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True'}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'milestones'", 'to': "orm['projects.Project']"}),
|
||||||
|
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'blank': 'True', 'max_length': '250'})
|
||||||
|
},
|
||||||
|
'projects.issuestatus': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'IssueStatus'},
|
||||||
|
'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': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'IssueType'},
|
||||||
|
'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': {'ordering': "['project', 'role']", 'object_name': 'Membership'},
|
||||||
|
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True', 'default': 'datetime.datetime.now'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'max_length': '255'}),
|
||||||
|
'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', 'null': 'True', 'default': 'None', 'max_length': '60'}),
|
||||||
|
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'default': 'None'})
|
||||||
|
},
|
||||||
|
'projects.points': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Points'},
|
||||||
|
'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': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Priority'},
|
||||||
|
'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': {'ordering': "['name']", 'object_name': 'Project'},
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'to': "orm['projects.IssueStatus']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'blank': 'True'}),
|
||||||
|
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'to': "orm['projects.IssueType']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'blank': 'True'}),
|
||||||
|
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'to': "orm['projects.Points']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'blank': 'True'}),
|
||||||
|
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'to': "orm['projects.Priority']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'blank': 'True'}),
|
||||||
|
'default_question_status': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'to': "orm['projects.QuestionStatus']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'blank': 'True'}),
|
||||||
|
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'to': "orm['projects.Severity']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'blank': 'True'}),
|
||||||
|
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'to': "orm['projects.TaskStatus']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'blank': 'True'}),
|
||||||
|
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'to': "orm['projects.UserStoryStatus']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'blank': 'True'}),
|
||||||
|
'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', 'null': 'True', 'max_length': '250'}),
|
||||||
|
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'max_length': '250'})
|
||||||
|
},
|
||||||
|
'projects.questionstatus': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'QuestionStatus'},
|
||||||
|
'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': "'question_status'", 'to': "orm['projects.Project']"})
|
||||||
|
},
|
||||||
|
'projects.severity': {
|
||||||
|
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Severity'},
|
||||||
|
'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': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'TaskStatus'},
|
||||||
|
'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': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'UserStoryStatus'},
|
||||||
|
'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'})
|
||||||
|
},
|
||||||
|
'tasks.task': {
|
||||||
|
'Meta': {'ordering': "['project', 'created_date']", 'object_name': 'Task'},
|
||||||
|
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks_assigned_to_me'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'default': 'None'}),
|
||||||
|
'blocked_note': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||||
|
'finished_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_iocaine': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'blank': 'True', 'to': "orm['milestones.Milestone']", 'null': 'True', 'default': 'None'}),
|
||||||
|
'modified_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}),
|
||||||
|
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_tasks'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'default': 'None'}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'to': "orm['projects.Project']"}),
|
||||||
|
'ref': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True', 'blank': 'True', 'null': 'True', 'default': 'None'}),
|
||||||
|
'status': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'to': "orm['projects.TaskStatus']"}),
|
||||||
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
|
||||||
|
'tags': ('picklefield.fields.PickledObjectField', [], {'blank': 'True'}),
|
||||||
|
'user_story': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'blank': 'True', 'to': "orm['userstories.UserStory']", 'null': 'True'}),
|
||||||
|
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'watched_tasks'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True'})
|
||||||
|
},
|
||||||
|
'users.role': {
|
||||||
|
'Meta': {'unique_together': "(('slug', 'project'),)", 'ordering': "['order', 'slug']", 'object_name': 'Role'},
|
||||||
|
'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': {'ordering': "['username']", 'object_name': 'User'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '9', 'default': "'#888337'"}),
|
||||||
|
'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', 'null': 'True', 'max_length': '500'}),
|
||||||
|
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'max_length': '200'}),
|
||||||
|
'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'})
|
||||||
|
},
|
||||||
|
'userstories.rolepoints': {
|
||||||
|
'Meta': {'unique_together': "(('user_story', 'role'),)", 'ordering': "['user_story', 'role']", 'object_name': 'RolePoints'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'points': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'role_points'", 'to': "orm['projects.Points']"}),
|
||||||
|
'role': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'role_points'", 'to': "orm['users.Role']"}),
|
||||||
|
'user_story': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'role_points'", 'to': "orm['userstories.UserStory']"})
|
||||||
|
},
|
||||||
|
'userstories.userstory': {
|
||||||
|
'Meta': {'ordering': "['project', 'order', 'ref']", 'object_name': 'UserStory'},
|
||||||
|
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'userstories_assigned_to_me'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'default': 'None'}),
|
||||||
|
'blocked_note': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
|
||||||
|
'client_requirement': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||||
|
'finish_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}),
|
||||||
|
'generated_from_issue': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'generated_user_stories'", 'blank': 'True', 'to': "orm['issues.Issue']", 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_stories'", 'on_delete': 'models.SET_NULL', 'null': 'True', 'default': 'None', 'to': "orm['milestones.Milestone']", 'blank': 'True'}),
|
||||||
|
'modified_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}),
|
||||||
|
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '100'}),
|
||||||
|
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.User']", 'related_name': "'owned_user_stories'", 'blank': 'True', 'on_delete': 'models.SET_NULL', 'null': 'True'}),
|
||||||
|
'points': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'userstories'", 'to': "orm['projects.Points']", 'through': "orm['userstories.RolePoints']"}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_stories'", 'to': "orm['projects.Project']"}),
|
||||||
|
'ref': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True', 'blank': 'True', 'null': 'True', 'default': 'None'}),
|
||||||
|
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.UserStoryStatus']", 'related_name': "'user_stories'", 'blank': 'True', 'on_delete': 'models.SET_NULL', 'null': 'True'}),
|
||||||
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
|
||||||
|
'tags': ('picklefield.fields.PickledObjectField', [], {'blank': 'True'}),
|
||||||
|
'team_requirement': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'watched_user_stories'", 'blank': 'True', 'to': "orm['users.User']", 'null': 'True'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['tasks']
|
|
@ -67,7 +67,7 @@ class Task(WatchedMixin, BlockedMixin):
|
||||||
verbose_name = "task"
|
verbose_name = "task"
|
||||||
verbose_name_plural = "tasks"
|
verbose_name_plural = "tasks"
|
||||||
ordering = ["project", "created_date"]
|
ordering = ["project", "created_date"]
|
||||||
unique_together = ("ref", "project")
|
# unique_together = ("ref", "project")
|
||||||
permissions = (
|
permissions = (
|
||||||
("view_task", "Can view task"),
|
("view_task", "Can view task"),
|
||||||
)
|
)
|
||||||
|
@ -94,15 +94,6 @@ class Task(WatchedMixin, BlockedMixin):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Model related signals handlers
|
|
||||||
@receiver(models.signals.pre_save, sender=Task, dispatch_uid="task_ref_handler")
|
|
||||||
def task_ref_handler(sender, instance, **kwargs):
|
|
||||||
"""
|
|
||||||
Automatically assignes a seguent reference code to a
|
|
||||||
user story if that is not created.
|
|
||||||
"""
|
|
||||||
if not instance.id and instance.project:
|
|
||||||
instance.ref = ref_uniquely(instance.project, "last_task_ref", instance.__class__)
|
|
||||||
|
|
||||||
def us_has_open_tasks(us, exclude_task):
|
def us_has_open_tasks(us, exclude_task):
|
||||||
qs = us.tasks.all()
|
qs = us.tasks.all()
|
||||||
|
|
|
@ -0,0 +1,269 @@
|
||||||
|
# -*- 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 'UserStory', fields ['ref', 'project']
|
||||||
|
db.delete_unique('userstories_userstory', ['ref', 'project_id'])
|
||||||
|
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Adding unique constraint on 'UserStory', fields ['ref', 'project']
|
||||||
|
db.create_unique('userstories_userstory', ['ref', 'project_id'])
|
||||||
|
|
||||||
|
|
||||||
|
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', [], {'blank': 'True', 'symmetrical': 'False', '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', 'db_table': "'django_content_type'", 'unique_together': "(('app_label', 'model'),)", 'ordering': "('name',)"},
|
||||||
|
'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', [], {'default': 'None', 'blank': 'True', 'to': "orm['domains.Domain']", 'related_name': "'+'", 'null': 'True'}),
|
||||||
|
'default_language': ('django.db.models.fields.CharField', [], {'default': "''", 'blank': 'True', 'max_length': '20'}),
|
||||||
|
'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', [], {'default': 'None', 'null': 'True', 'max_length': '60'})
|
||||||
|
},
|
||||||
|
'issues.issue': {
|
||||||
|
'Meta': {'object_name': 'Issue', 'ordering': "['project', 'created_date']"},
|
||||||
|
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'blank': 'True', 'to': "orm['users.User']", 'related_name': "'issues_assigned_to_me'", 'null': 'True'}),
|
||||||
|
'blocked_note': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||||
|
'finished_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'blank': 'True', 'to': "orm['milestones.Milestone']", 'related_name': "'issues'", 'null': 'True'}),
|
||||||
|
'modified_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}),
|
||||||
|
'owner': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'blank': 'True', 'to': "orm['users.User']", 'related_name': "'owned_issues'", 'null': 'True'}),
|
||||||
|
'priority': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Priority']", 'related_name': "'issues'"}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issues'"}),
|
||||||
|
'ref': ('django.db.models.fields.BigIntegerField', [], {'default': 'None', 'db_index': 'True', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'severity': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Severity']", 'related_name': "'issues'"}),
|
||||||
|
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.IssueStatus']", 'related_name': "'issues'"}),
|
||||||
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
|
||||||
|
'tags': ('picklefield.fields.PickledObjectField', [], {'blank': 'True'}),
|
||||||
|
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.IssueType']", 'related_name': "'issues'"}),
|
||||||
|
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'null': 'True', 'blank': 'True', 'symmetrical': 'False', 'to': "orm['users.User']", 'related_name': "'watched_issues'"})
|
||||||
|
},
|
||||||
|
'milestones.milestone': {
|
||||||
|
'Meta': {'object_name': 'Milestone', 'unique_together': "(('name', 'project'),)", 'ordering': "['project', 'created_date']"},
|
||||||
|
'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
|
||||||
|
'disponibility': ('django.db.models.fields.FloatField', [], {'default': '0.0', 'blank': 'True', 'null': 'True'}),
|
||||||
|
'estimated_finish': ('django.db.models.fields.DateField', [], {'default': 'None', 'blank': 'True', 'null': 'True'}),
|
||||||
|
'estimated_start': ('django.db.models.fields.DateField', [], {'default': 'None', 'blank': 'True', 'null': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'modified_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '200'}),
|
||||||
|
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
|
||||||
|
'owner': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'blank': 'True', 'to': "orm['users.User']", 'related_name': "'owned_milestones'"}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'milestones'"}),
|
||||||
|
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '250', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'projects.issuestatus': {
|
||||||
|
'Meta': {'object_name': 'IssueStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'issue_statuses'"})
|
||||||
|
},
|
||||||
|
'projects.issuetype': {
|
||||||
|
'Meta': {'object_name': 'IssueType', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'issue_types'"})
|
||||||
|
},
|
||||||
|
'projects.membership': {
|
||||||
|
'Meta': {'object_name': 'Membership', 'ordering': "['project', 'role']"},
|
||||||
|
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'blank': 'True', 'auto_now_add': 'True'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'default': 'None', 'blank': 'True', 'null': 'True', 'max_length': '255'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'memberships'"}),
|
||||||
|
'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.Role']", 'related_name': "'memberships'"}),
|
||||||
|
'token': ('django.db.models.fields.CharField', [], {'default': 'None', 'blank': 'True', 'null': 'True', 'max_length': '60'}),
|
||||||
|
'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'blank': 'True', 'to': "orm['users.User']", 'related_name': "'memberships'", 'null': 'True'})
|
||||||
|
},
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'points'"}),
|
||||||
|
'value': ('django.db.models.fields.FloatField', [], {'default': 'None', 'blank': 'True', 'null': 'True'})
|
||||||
|
},
|
||||||
|
'projects.priority': {
|
||||||
|
'Meta': {'object_name': 'Priority', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'priorities'"})
|
||||||
|
},
|
||||||
|
'projects.project': {
|
||||||
|
'Meta': {'object_name': 'Project', 'ordering': "['name']"},
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
|
||||||
|
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'to': "orm['projects.IssueStatus']", 'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'to': "orm['projects.IssueType']", 'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'to': "orm['projects.Points']", 'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'to': "orm['projects.Priority']", 'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_question_status': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'to': "orm['projects.QuestionStatus']", 'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'to': "orm['projects.Severity']", 'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'to': "orm['projects.TaskStatus']", 'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'related_name': "'+'"}),
|
||||||
|
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'unique': 'True', 'to': "orm['projects.UserStoryStatus']", 'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'related_name': "'+'"}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {}),
|
||||||
|
'domain': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'blank': 'True', 'to': "orm['domains.Domain']", 'related_name': "'projects'", 'null': 'True'}),
|
||||||
|
'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', [], {'default': '0', 'null': 'True'}),
|
||||||
|
'last_task_ref': ('django.db.models.fields.BigIntegerField', [], {'default': '0', 'null': 'True'}),
|
||||||
|
'last_us_ref': ('django.db.models.fields.BigIntegerField', [], {'default': '0', 'null': 'True'}),
|
||||||
|
'members': ('django.db.models.fields.related.ManyToManyField', [], {'through': "orm['projects.Membership']", 'symmetrical': 'False', 'to': "orm['users.User']", 'related_name': "'projects'"}),
|
||||||
|
'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', [], {'to': "orm['users.User']", 'related_name': "'owned_projects'"}),
|
||||||
|
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '250', 'blank': 'True'}),
|
||||||
|
'tags': ('picklefield.fields.PickledObjectField', [], {'blank': 'True'}),
|
||||||
|
'total_milestones': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True', 'null': 'True'}),
|
||||||
|
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': 'None', 'null': 'True'}),
|
||||||
|
'videoconferences': ('django.db.models.fields.CharField', [], {'null': 'True', 'blank': 'True', 'max_length': '250'}),
|
||||||
|
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'null': 'True', 'blank': 'True', 'max_length': '250'})
|
||||||
|
},
|
||||||
|
'projects.questionstatus': {
|
||||||
|
'Meta': {'object_name': 'QuestionStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'question_status'"})
|
||||||
|
},
|
||||||
|
'projects.severity': {
|
||||||
|
'Meta': {'object_name': 'Severity', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'severities'"})
|
||||||
|
},
|
||||||
|
'projects.taskstatus': {
|
||||||
|
'Meta': {'object_name': 'TaskStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'task_statuses'"})
|
||||||
|
},
|
||||||
|
'projects.userstorystatus': {
|
||||||
|
'Meta': {'object_name': 'UserStoryStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
|
||||||
|
'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', [], {'to': "orm['projects.Project']", 'related_name': "'us_statuses'"}),
|
||||||
|
'wip_limit': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'blank': 'True', 'null': 'True'})
|
||||||
|
},
|
||||||
|
'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', 'to': "orm['auth.Permission']", 'related_name': "'roles'"}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'roles'"}),
|
||||||
|
'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', [], {'default': "'#1ecac2'", 'blank': 'True', 'max_length': '9'}),
|
||||||
|
'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', [], {'default': "''", 'blank': 'True', 'max_length': '20'}),
|
||||||
|
'default_timezone': ('django.db.models.fields.CharField', [], {'default': "''", 'blank': 'True', 'max_length': '20'}),
|
||||||
|
'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', [], {'blank': 'True', 'symmetrical': 'False', 'to': "orm['auth.Group']", 'related_name': "'user_set'"}),
|
||||||
|
'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', [], {'default': "'all_owned_projects'", 'max_length': '32'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'photo': ('django.db.models.fields.files.FileField', [], {'null': 'True', 'blank': 'True', 'max_length': '500'}),
|
||||||
|
'token': ('django.db.models.fields.CharField', [], {'default': 'None', 'blank': 'True', 'null': 'True', 'max_length': '200'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'symmetrical': 'False', 'to': "orm['auth.Permission']", 'related_name': "'user_set'"}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
},
|
||||||
|
'userstories.rolepoints': {
|
||||||
|
'Meta': {'object_name': 'RolePoints', 'unique_together': "(('user_story', 'role'),)", 'ordering': "['user_story', 'role']"},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'points': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Points']", 'related_name': "'role_points'"}),
|
||||||
|
'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.Role']", 'related_name': "'role_points'"}),
|
||||||
|
'user_story': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['userstories.UserStory']", 'related_name': "'role_points'"})
|
||||||
|
},
|
||||||
|
'userstories.userstory': {
|
||||||
|
'Meta': {'object_name': 'UserStory', 'ordering': "['project', 'order', 'ref']"},
|
||||||
|
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'blank': 'True', 'to': "orm['users.User']", 'related_name': "'userstories_assigned_to_me'", 'null': 'True'}),
|
||||||
|
'blocked_note': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||||
|
'client_requirement': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'created_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}),
|
||||||
|
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||||
|
'finish_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||||
|
'generated_from_issue': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'blank': 'True', 'to': "orm['issues.Issue']", 'related_name': "'generated_user_stories'"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['milestones.Milestone']", 'on_delete': 'models.SET_NULL', 'null': 'True', 'blank': 'True', 'related_name': "'user_stories'"}),
|
||||||
|
'modified_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}),
|
||||||
|
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '100'}),
|
||||||
|
'owner': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'blank': 'True', 'to': "orm['users.User']", 'related_name': "'owned_user_stories'", 'on_delete': 'models.SET_NULL'}),
|
||||||
|
'points': ('django.db.models.fields.related.ManyToManyField', [], {'through': "orm['userstories.RolePoints']", 'symmetrical': 'False', 'to': "orm['projects.Points']", 'related_name': "'userstories'"}),
|
||||||
|
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'user_stories'"}),
|
||||||
|
'ref': ('django.db.models.fields.BigIntegerField', [], {'default': 'None', 'db_index': 'True', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'status': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'blank': 'True', 'to': "orm['projects.UserStoryStatus']", 'related_name': "'user_stories'", 'on_delete': 'models.SET_NULL'}),
|
||||||
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
|
||||||
|
'tags': ('picklefield.fields.PickledObjectField', [], {'blank': 'True'}),
|
||||||
|
'team_requirement': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'null': 'True', 'blank': 'True', 'symmetrical': 'False', 'to': "orm['users.User']", 'related_name': "'watched_user_stories'"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['userstories']
|
|
@ -101,7 +101,7 @@ class UserStory(NeighborsMixin, WatchedMixin, BlockedMixin, models.Model):
|
||||||
verbose_name = "user story"
|
verbose_name = "user story"
|
||||||
verbose_name_plural = "user stories"
|
verbose_name_plural = "user stories"
|
||||||
ordering = ["project", "order", "ref"]
|
ordering = ["project", "order", "ref"]
|
||||||
unique_together = ("ref", "project")
|
#unique_together = ("ref", "project")
|
||||||
permissions = (
|
permissions = (
|
||||||
("view_userstory", "Can view user story"),
|
("view_userstory", "Can view user story"),
|
||||||
)
|
)
|
||||||
|
@ -159,12 +159,6 @@ class UserStory(NeighborsMixin, WatchedMixin, BlockedMixin, models.Model):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Model related signals handlers
|
|
||||||
@receiver(models.signals.pre_save, sender=UserStory, dispatch_uid="user_story_ref_handler")
|
|
||||||
def us_ref_handler(sender, instance, **kwargs):
|
|
||||||
if not instance.id and instance.project:
|
|
||||||
instance.ref = ref_uniquely(instance.project, "last_us_ref", instance.__class__)
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(models.signals.post_save, sender=UserStory,
|
@receiver(models.signals.post_save, sender=UserStory,
|
||||||
dispatch_uid="user_story_create_role_points_handler")
|
dispatch_uid="user_story_create_role_points_handler")
|
||||||
|
|
|
@ -36,7 +36,7 @@ router.register(r"user-storage", StorageEntriesViewSet, base_name="user-storage"
|
||||||
|
|
||||||
# Resolver & Search
|
# Resolver & Search
|
||||||
from taiga.base.searches.api import SearchViewSet
|
from taiga.base.searches.api import SearchViewSet
|
||||||
from taiga.base.resolver.api import ResolverViewSet
|
from taiga.projects.references.api import ResolverViewSet
|
||||||
|
|
||||||
router.register(r"resolver", ResolverViewSet, base_name="resolver")
|
router.register(r"resolver", ResolverViewSet, base_name="resolver")
|
||||||
router.register(r"search", SearchViewSet, base_name="search")
|
router.register(r"search", SearchViewSet, base_name="search")
|
||||||
|
|
Loading…
Reference in New Issue