diff --git a/src/yak/models.py b/src/yak/models.py index 095b6ea..c1aa149 100644 --- a/src/yak/models.py +++ b/src/yak/models.py @@ -1,6 +1,7 @@ from django.db import models from django.contrib.auth import get_user_model import uuid +import datetime class Status(models.Model): @@ -41,6 +42,7 @@ class Label(models.Model): class Lane(models.Model): """ Defines "swim-lanes" which are intra-board groupings for tickets + Can be used in different ways - either as priority """ # Metadata order_key = models.SmallIntegerField( @@ -79,6 +81,20 @@ class Board(models.Model): max_length=16, 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): @@ -102,9 +118,6 @@ class Ticket(models.Model): null=True, related_name="created_tickets", ) - order_key = models.SmallIntegerField( - default=0, - ) visible = models.BooleanField( default=True, ) @@ -112,7 +125,7 @@ class Ticket(models.Model): class Meta: get_latest_by = "created_date" order_with_respect_to = "parent" - ordering = ["order_key", "title"] + ordering = ["lane", "priority", "title"] # Data title = models.CharField( @@ -121,8 +134,10 @@ class Ticket(models.Model): details = models.TextField( blank=True, ) - 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(), blank=True, ) @@ -132,6 +147,10 @@ class Ticket(models.Model): end_datetime = models.DateTimeField( blank=True, ) + priority = models.SmallIntegerField( + # Lower priority = more important + default=1, + ) # Context Data parent = models.ForeignKey( @@ -143,23 +162,32 @@ class Ticket(models.Model): null=True, related_name="children", ) - status = models.ForeignKey( - Status, - on_delete=models.SET_NULL, - null=True, - ) + # N.B. Labels are global where status and lane are within the context of a board labels = models.ManyToManyField( Label, on_delete=models.SET_NULL, blank=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, on_delete=models.SET_NULL, null=True, ) - board = models.ForeignKey( - Board, - on_delete=models.CASCADE, - ) + + # Methods + 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())