base
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
# Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# See the LICENSE file for details.
|
||||
|
||||
# Python imports
|
||||
import pytz
|
||||
|
||||
# Django imports
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
# Module imports
|
||||
from .project import ProjectBaseModel
|
||||
|
||||
|
||||
def get_default_filters():
|
||||
return {
|
||||
"priority": None,
|
||||
"state": None,
|
||||
"state_group": None,
|
||||
"assignees": None,
|
||||
"created_by": None,
|
||||
"labels": None,
|
||||
"start_date": None,
|
||||
"target_date": None,
|
||||
"subscriber": None,
|
||||
}
|
||||
|
||||
|
||||
def get_default_display_filters():
|
||||
return {
|
||||
"group_by": None,
|
||||
"order_by": "-created_at",
|
||||
"type": None,
|
||||
"sub_issue": True,
|
||||
"show_empty_groups": True,
|
||||
"layout": "list",
|
||||
"calendar_date_range": "",
|
||||
}
|
||||
|
||||
|
||||
def get_default_display_properties():
|
||||
return {
|
||||
"assignee": True,
|
||||
"attachment_count": True,
|
||||
"created_on": True,
|
||||
"due_date": True,
|
||||
"estimate": True,
|
||||
"key": True,
|
||||
"labels": True,
|
||||
"link": True,
|
||||
"priority": True,
|
||||
"start_date": True,
|
||||
"state": True,
|
||||
"sub_issue_count": True,
|
||||
"updated_on": True,
|
||||
}
|
||||
|
||||
|
||||
class Cycle(ProjectBaseModel):
|
||||
name = models.CharField(max_length=255, verbose_name="Cycle Name")
|
||||
description = models.TextField(verbose_name="Cycle Description", blank=True)
|
||||
start_date = models.DateTimeField(verbose_name="Start Date", blank=True, null=True)
|
||||
end_date = models.DateTimeField(verbose_name="End Date", blank=True, null=True)
|
||||
owned_by = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="owned_by_cycle",
|
||||
)
|
||||
view_props = models.JSONField(default=dict)
|
||||
sort_order = models.FloatField(default=65535)
|
||||
external_source = models.CharField(max_length=255, null=True, blank=True)
|
||||
external_id = models.CharField(max_length=255, blank=True, null=True)
|
||||
progress_snapshot = models.JSONField(default=dict)
|
||||
archived_at = models.DateTimeField(null=True)
|
||||
logo_props = models.JSONField(default=dict)
|
||||
# timezone
|
||||
TIMEZONE_CHOICES = tuple(zip(pytz.common_timezones, pytz.common_timezones))
|
||||
timezone = models.CharField(max_length=255, default="UTC", choices=TIMEZONE_CHOICES)
|
||||
version = models.IntegerField(default=1)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Cycle"
|
||||
verbose_name_plural = "Cycles"
|
||||
db_table = "cycles"
|
||||
ordering = ("-created_at",)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self._state.adding:
|
||||
smallest_sort_order = Cycle.objects.filter(project=self.project).aggregate(
|
||||
smallest=models.Min("sort_order")
|
||||
)["smallest"]
|
||||
|
||||
if smallest_sort_order is not None:
|
||||
self.sort_order = smallest_sort_order - 10000
|
||||
|
||||
super(Cycle, self).save(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
"""Return name of the cycle"""
|
||||
return f"{self.name} <{self.project.name}>"
|
||||
|
||||
|
||||
class CycleIssue(ProjectBaseModel):
|
||||
"""
|
||||
Cycle Issues
|
||||
"""
|
||||
|
||||
issue = models.ForeignKey("db.Issue", on_delete=models.CASCADE, related_name="issue_cycle")
|
||||
cycle = models.ForeignKey(Cycle, on_delete=models.CASCADE, related_name="issue_cycle")
|
||||
|
||||
class Meta:
|
||||
unique_together = ["issue", "cycle", "deleted_at"]
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
fields=["cycle", "issue"],
|
||||
condition=models.Q(deleted_at__isnull=True),
|
||||
name="cycle_issue_when_deleted_at_null",
|
||||
)
|
||||
]
|
||||
verbose_name = "Cycle Issue"
|
||||
verbose_name_plural = "Cycle Issues"
|
||||
db_table = "cycle_issues"
|
||||
ordering = ("-created_at",)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.cycle}"
|
||||
|
||||
|
||||
class CycleUserProperties(ProjectBaseModel):
|
||||
cycle = models.ForeignKey("db.Cycle", on_delete=models.CASCADE, related_name="cycle_user_properties")
|
||||
user = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="cycle_user_properties",
|
||||
)
|
||||
filters = models.JSONField(default=get_default_filters)
|
||||
display_filters = models.JSONField(default=get_default_display_filters)
|
||||
display_properties = models.JSONField(default=get_default_display_properties)
|
||||
rich_filters = models.JSONField(default=dict)
|
||||
|
||||
class Meta:
|
||||
unique_together = ["cycle", "user", "deleted_at"]
|
||||
constraints = [
|
||||
models.UniqueConstraint(
|
||||
fields=["cycle", "user"],
|
||||
condition=models.Q(deleted_at__isnull=True),
|
||||
name="cycle_user_properties_unique_cycle_user_when_deleted_at_null",
|
||||
)
|
||||
]
|
||||
verbose_name = "Cycle User Property"
|
||||
verbose_name_plural = "Cycle User Properties"
|
||||
db_table = "cycle_user_properties"
|
||||
ordering = ("-created_at",)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.cycle.name} {self.user.email}"
|
||||
Reference in New Issue
Block a user