feat: add shared task assignments and quick win sorting
This commit is contained in:
@@ -35,12 +35,24 @@ class User(UserMixin, TimestampMixin, db.Model):
|
||||
backref="default_assigned_user",
|
||||
lazy=True,
|
||||
)
|
||||
secondary_assigned_task_templates = db.relationship(
|
||||
"TaskTemplate",
|
||||
foreign_keys="TaskTemplate.default_assigned_user_secondary_id",
|
||||
backref="default_assigned_user_secondary",
|
||||
lazy=True,
|
||||
)
|
||||
assigned_tasks = db.relationship(
|
||||
"TaskInstance",
|
||||
foreign_keys="TaskInstance.assigned_user_id",
|
||||
backref="assigned_user",
|
||||
lazy=True,
|
||||
)
|
||||
secondary_assigned_tasks = db.relationship(
|
||||
"TaskInstance",
|
||||
foreign_keys="TaskInstance.assigned_user_secondary_id",
|
||||
backref="assigned_user_secondary",
|
||||
lazy=True,
|
||||
)
|
||||
completed_tasks = db.relationship(
|
||||
"TaskInstance",
|
||||
foreign_keys="TaskInstance.completed_by_user_id",
|
||||
@@ -87,6 +99,7 @@ class TaskTemplate(TimestampMixin, db.Model):
|
||||
description = db.Column(db.Text, nullable=True)
|
||||
default_points = db.Column(db.Integer, nullable=False, default=10)
|
||||
default_assigned_user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)
|
||||
default_assigned_user_secondary_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)
|
||||
recurrence_interval_value = db.Column(db.Integer, nullable=True)
|
||||
recurrence_interval_unit = db.Column(db.String(20), nullable=False, default="none")
|
||||
active = db.Column(db.Boolean, nullable=False, default=True)
|
||||
@@ -113,6 +126,7 @@ class QuickWin(TimestampMixin, db.Model):
|
||||
effort = db.Column(db.String(40), nullable=False, index=True)
|
||||
active = db.Column(db.Boolean, nullable=False, default=True)
|
||||
created_by_user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False, index=True)
|
||||
sort_order = db.Column(db.Integer, nullable=False, default=0, index=True)
|
||||
|
||||
|
||||
class TaskInstance(TimestampMixin, db.Model):
|
||||
@@ -121,6 +135,7 @@ class TaskInstance(TimestampMixin, db.Model):
|
||||
title = db.Column(db.String(160), nullable=False)
|
||||
description = db.Column(db.Text, nullable=True)
|
||||
assigned_user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True, index=True)
|
||||
assigned_user_secondary_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True, index=True)
|
||||
due_date = db.Column(db.Date, nullable=False, index=True)
|
||||
status = db.Column(db.String(20), nullable=False, default="open", index=True)
|
||||
completed_at = db.Column(db.DateTime, nullable=True, index=True)
|
||||
@@ -131,21 +146,50 @@ class TaskInstance(TimestampMixin, db.Model):
|
||||
def is_completed(self) -> bool:
|
||||
return self.completed_at is not None
|
||||
|
||||
@property
|
||||
def assigned_users(self) -> list[User]:
|
||||
users: list[User] = []
|
||||
if self.assigned_user:
|
||||
users.append(self.assigned_user)
|
||||
if self.assigned_user_secondary and self.assigned_user_secondary.id not in {user.id for user in users}:
|
||||
users.append(self.assigned_user_secondary)
|
||||
return users
|
||||
|
||||
@property
|
||||
def assigned_user_ids(self) -> list[int]:
|
||||
return [user.id for user in self.assigned_users]
|
||||
|
||||
@property
|
||||
def is_shared_assignment(self) -> bool:
|
||||
return self.assigned_user_id is not None and self.assigned_user_secondary_id is not None
|
||||
|
||||
@property
|
||||
def assignee_label(self) -> str:
|
||||
if not self.assigned_users:
|
||||
return "Ohne Person"
|
||||
return " & ".join(user.name for user in self.assigned_users)
|
||||
|
||||
def compute_status(self, reference_date: date | None = None) -> str:
|
||||
reference_date = reference_date or date.today()
|
||||
if self.completed_at:
|
||||
return "completed"
|
||||
if self.due_date < reference_date:
|
||||
return "overdue"
|
||||
if self.due_date <= reference_date + timedelta(days=2):
|
||||
return "soon"
|
||||
if self.due_date == reference_date:
|
||||
return "due_today"
|
||||
if self.due_date == reference_date + timedelta(days=1):
|
||||
return "due_tomorrow"
|
||||
if self.due_date == reference_date + timedelta(days=2):
|
||||
return "due_day_after_tomorrow"
|
||||
return "open"
|
||||
|
||||
@property
|
||||
def status_label(self) -> str:
|
||||
labels = {
|
||||
"open": "Offen",
|
||||
"soon": "Bald fällig",
|
||||
"due_today": "Bald fällig",
|
||||
"due_tomorrow": "Morgen fällig",
|
||||
"due_day_after_tomorrow": "Übermorgen fällig",
|
||||
"overdue": "Überfällig",
|
||||
"completed": "Erledigt",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user