Added status and lanes to boards, added method to assess urgency of tickets
This commit is contained in:
parent
8fc629eb2f
commit
dafe6a56b6
@ -1,6 +1,7 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
import uuid
|
import uuid
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
class Status(models.Model):
|
class Status(models.Model):
|
||||||
@ -41,6 +42,7 @@ class Label(models.Model):
|
|||||||
class Lane(models.Model):
|
class Lane(models.Model):
|
||||||
"""
|
"""
|
||||||
Defines "swim-lanes" which are intra-board groupings for tickets
|
Defines "swim-lanes" which are intra-board groupings for tickets
|
||||||
|
Can be used in different ways - either as priority
|
||||||
"""
|
"""
|
||||||
# Metadata
|
# Metadata
|
||||||
order_key = models.SmallIntegerField(
|
order_key = models.SmallIntegerField(
|
||||||
@ -79,6 +81,20 @@ class Board(models.Model):
|
|||||||
max_length=16,
|
max_length=16,
|
||||||
unique=True,
|
unique=True,
|
||||||
)
|
)
|
||||||
|
statuses = models.ManyToManyField(
|
||||||
|
# Valid statuses for tickets on this board
|
||||||
|
# Requires validation to ensure ticket statuses are legal
|
||||||
|
Status,
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
lanes = models.ManyToManyField(
|
||||||
|
# Valid lanes for tickets on this board
|
||||||
|
# Requires validation to ensure ticket lanes are legal
|
||||||
|
Lane,
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Ticket(models.Model):
|
class Ticket(models.Model):
|
||||||
@ -102,9 +118,6 @@ class Ticket(models.Model):
|
|||||||
null=True,
|
null=True,
|
||||||
related_name="created_tickets",
|
related_name="created_tickets",
|
||||||
)
|
)
|
||||||
order_key = models.SmallIntegerField(
|
|
||||||
default=0,
|
|
||||||
)
|
|
||||||
visible = models.BooleanField(
|
visible = models.BooleanField(
|
||||||
default=True,
|
default=True,
|
||||||
)
|
)
|
||||||
@ -112,7 +125,7 @@ class Ticket(models.Model):
|
|||||||
class Meta:
|
class Meta:
|
||||||
get_latest_by = "created_date"
|
get_latest_by = "created_date"
|
||||||
order_with_respect_to = "parent"
|
order_with_respect_to = "parent"
|
||||||
ordering = ["order_key", "title"]
|
ordering = ["lane", "priority", "title"]
|
||||||
|
|
||||||
# Data
|
# Data
|
||||||
title = models.CharField(
|
title = models.CharField(
|
||||||
@ -121,8 +134,10 @@ class Ticket(models.Model):
|
|||||||
details = models.TextField(
|
details = models.TextField(
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
users = models.ManyToManyField(
|
users = models.ManyToManyField(
|
||||||
|
# Relevant users to this ticket
|
||||||
|
# No fussing around with "assignee" vs "watcher" vs "reporter" ad nauseam
|
||||||
|
# If the ticket is relevant to a user, add them to the users list. Simple.
|
||||||
get_user_model(),
|
get_user_model(),
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
@ -132,6 +147,10 @@ class Ticket(models.Model):
|
|||||||
end_datetime = models.DateTimeField(
|
end_datetime = models.DateTimeField(
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
|
priority = models.SmallIntegerField(
|
||||||
|
# Lower priority = more important
|
||||||
|
default=1,
|
||||||
|
)
|
||||||
|
|
||||||
# Context Data
|
# Context Data
|
||||||
parent = models.ForeignKey(
|
parent = models.ForeignKey(
|
||||||
@ -143,23 +162,32 @@ class Ticket(models.Model):
|
|||||||
null=True,
|
null=True,
|
||||||
related_name="children",
|
related_name="children",
|
||||||
)
|
)
|
||||||
status = models.ForeignKey(
|
# N.B. Labels are global where status and lane are within the context of a board
|
||||||
Status,
|
|
||||||
on_delete=models.SET_NULL,
|
|
||||||
null=True,
|
|
||||||
)
|
|
||||||
labels = models.ManyToManyField(
|
labels = models.ManyToManyField(
|
||||||
Label,
|
Label,
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
)
|
)
|
||||||
|
board = models.ForeignKey(
|
||||||
|
Board,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
)
|
||||||
|
status = models.ForeignKey(
|
||||||
|
Status,
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
lane = models.ForeignKey(
|
lane = models.ForeignKey(
|
||||||
Lane,
|
Lane,
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
null=True,
|
null=True,
|
||||||
)
|
)
|
||||||
board = models.ForeignKey(
|
|
||||||
Board,
|
# Methods
|
||||||
on_delete=models.CASCADE,
|
def get_urgency(self):
|
||||||
)
|
"""Returns the product of priority and proximity to due-date"""
|
||||||
|
if not self.end_datetime:
|
||||||
|
return self.priority
|
||||||
|
else:
|
||||||
|
return self.priority * (self.end_datetime - datetime.datetime.now())
|
||||||
|
Loading…
Reference in New Issue
Block a user