diff --git a/taiga/projects/models.py b/taiga/projects/models.py index b0ecbc7e..01db17a1 100644 --- a/taiga/projects/models.py +++ b/taiga/projects/models.py @@ -18,6 +18,7 @@ import itertools from django.core.exceptions import ValidationError from django.db import models +from django.db.models import signals from django.db.models.loading import get_model from django.conf import settings from django.dispatch import receiver @@ -669,50 +670,63 @@ class ProjectTemplate(models.Model): for permission in permissions: newRoleInstance.permissions.add(permission) - project.default_points = Points.objects.get(name=self.default_options["points"], project=project) - project.default_us_status = UserStoryStatus.objects.get(name=self.default_options["us_status"], project=project) - project.default_task_status = TaskStatus.objects.get(name=self.default_options["task_status"], project=project) - project.default_issue_status = IssueStatus.objects.get(name=self.default_options["issue_status"], project=project) - project.default_issue_type = IssueType.objects.get(name=self.default_options["issue_type"], project=project) - project.default_priority = Priority.objects.get(name=self.default_options["priority"], project=project) - project.default_severity = Severity.objects.get(name=self.default_options["severity"], project=project) + if self.points: + project.default_points = Points.objects.get(name=self.default_options["points"], + project=project) + if self.us_statuses: + project.default_us_status = UserStoryStatus.objects.get(name=self.default_options["us_status"], + project=project) - Membership.objects.create( - user=project.owner, - project=project, - role=project.roles.get(slug=self.default_owner_role), - email=project.owner.email - ) + if self.task_statuses: + project.default_task_status = TaskStatus.objects.get(name=self.default_options["task_status"], + project=project) + if self.issue_statuses: + project.default_issue_status = IssueStatus.objects.get(name=self.default_options["issue_status"], + project=project) + if self.issue_types: + project.default_issue_type = IssueType.objects.get(name=self.default_options["issue_type"], + project=project) + + if self.priorities: + project.default_priority = Priority.objects.get(name=self.default_options["priority"], project=project) + + if self.severities: + project.default_severity = Severity.objects.get(name=self.default_options["severity"], project=project) + + + if self.default_owner_role: + # FIXME: is operation should to be on template apply method? + Membership.objects.create(user=project.owner, + project=project, + role=project.roles.get(slug=self.default_owner_role), + email=project.owner.email) return project # On membership object is created/changed, update # role-points relation. -@receiver(models.signals.post_save, sender=Membership, - dispatch_uid='membership_post_save') +@receiver(signals.post_save, sender=Membership, dispatch_uid='membership_post_save') def membership_post_save(sender, instance, created, **kwargs): instance.project.update_role_points() - if instance.user and instance.project.domain and instance.project.domain.members.filter(user=instance.user).count() == 0: - DomainMember.objects.create( - domain=instance.project.domain, - user=instance.user, - email=instance.email, - is_owner=False, - is_staff=False - ) + exists_user_on_domain = instance.project.domain.members.filter(user=instance.user).exists() + + if instance.user and instance.project.domain and not exists_user_on_domain: + DomainMember.objects.create(domain=instance.project.domain, + user=instance.user, + email=instance.email, + is_owner=False, + is_staff=False) # On membership object is deleted, update role-points relation. -@receiver(models.signals.pre_delete, sender=Membership, - dispatch_uid='membership_pre_delete') +@receiver(signals.pre_delete, sender=Membership, dispatch_uid='membership_pre_delete') def membership_post_delete(sender, instance, using, **kwargs): instance.project.update_role_points() # On membership object is deleted, update watchers of all objects relation. -@receiver(models.signals.post_delete, sender=Membership, - dispatch_uid='update_watchers_on_membership_post_delete') +@receiver(signals.post_delete, sender=Membership, dispatch_uid='update_watchers_on_membership_post_delete') def update_watchers_on_membership_post_delete(sender, instance, using, **kwargs): models = [get_model("userstories", "UserStory"), get_model("tasks", "Task"), @@ -725,7 +739,7 @@ def update_watchers_on_membership_post_delete(sender, instance, using, **kwargs) model.watchers.through.objects.filter(user_id=instance.user_id).delete() -@receiver(models.signals.post_save, sender=Project, dispatch_uid='project_post_save') +@receiver(signals.post_save, sender=Project, dispatch_uid='project_post_save') def project_post_save(sender, instance, created, **kwargs): """ Populate new project dependen default data diff --git a/taiga/projects/references/models.py b/taiga/projects/references/models.py index 96b2c335..009018b4 100644 --- a/taiga/projects/references/models.py +++ b/taiga/projects/references/models.py @@ -56,6 +56,13 @@ def create_sequence(sender, instance, created, **kwargs): if not seq.exists(seqname): seq.create(seqname) + +def delete_sequence(sender, instance, **kwargs): + seqname = make_sequence_name(instance) + if seq.exists(seqname): + seq.delete(seqname) + + def attach_sequence(sender, instance, created, **kwargs): if created: # Create a reference object. This operation should be @@ -72,7 +79,7 @@ models.signals.post_save.connect(create_sequence, sender=Project, dispatch_uid=" 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") - +models.signals.post_delete.connect(delete_sequence, sender=Project, dispatch_uid="refprojdel") diff --git a/tests/factories.py b/tests/factories.py index 7cfe0841..cc39221f 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -24,7 +24,15 @@ class ProjectTemplateFactory(factory.DjangoModelFactory): name = "Template name" slug = settings.DEFAULT_PROJECT_TEMPLATE - default_owner_role = "tester" + + us_statuses = [] + points = [] + task_statuses = [] + issue_statuses = [] + issue_types = [] + priorities = [] + severities = [] + roles = [] class ProjectFactory(factory.DjangoModelFactory): diff --git a/tests/integration/test_project_references_sequences.py b/tests/integration/test_project_references_sequences.py index 040ef222..89b30ff1 100644 --- a/tests/integration/test_project_references_sequences.py +++ b/tests/integration/test_project_references_sequences.py @@ -1,10 +1,20 @@ import pytest +from django.core import management +from .. import factories + + + @pytest.fixture def seq(): from taiga.projects.references import sequences as seq return seq +@pytest.fixture +def refmodels(): + from taiga.projects.references import models + return models + @pytest.mark.django_db def test_sequences(seq): seqname = "foo" @@ -32,3 +42,20 @@ def test_sequences(seq): # Delete after alter seq.delete(seqname) assert not seq.exists(seqname) + + +@pytest.mark.django_db +def test_unique_reference_per_project(seq, refmodels): + # management.call_command("loaddata", "initial_project_templates") + + project = factories.ProjectFactory.create() + seqname = refmodels.make_sequence_name(project) + + assert seqname == "references_project1" + assert seq.exists(seqname) + + assert refmodels.make_unique_reference_id(project, create=True) == 1 + assert refmodels.make_unique_reference_id(project, create=True) == 2 + + project.delete() + assert not seq.exists(seqname)