126 lines
3.9 KiB
Go
126 lines
3.9 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type Task struct {
|
|
ID uint `json:"id" gorm:"primaryKey"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
|
|
|
|
Title string `json:"title" gorm:"not null"`
|
|
Description string `json:"description"`
|
|
Status string `json:"status" gorm:"default:'todo'"` // todo, in_progress, review, done
|
|
Priority string `json:"priority" gorm:"default:'medium'"` // low, medium, high, urgent
|
|
DueDate *time.Time `json:"due_date"`
|
|
CompletedAt *time.Time `json:"completed_at"`
|
|
Position int `json:"position" gorm:"default:0"` // For ordering in kanban board
|
|
|
|
// Foreign Keys
|
|
ProjectID uint `json:"project_id" gorm:"not null"`
|
|
AssignedToID *uint `json:"assigned_to_id"`
|
|
CreatedByID uint `json:"created_by_id" gorm:"not null"`
|
|
|
|
// Relationships
|
|
Project Project `json:"project" gorm:"foreignKey:ProjectID"`
|
|
AssignedTo *User `json:"assigned_to" gorm:"foreignKey:AssignedToID"`
|
|
CreatedBy User `json:"created_by" gorm:"foreignKey:CreatedByID"`
|
|
Comments []Comment `json:"comments" gorm:"foreignKey:TaskID"`
|
|
Files []FileUpload `json:"files" gorm:"foreignKey:TaskID"`
|
|
Subtasks []Subtask `json:"subtasks" gorm:"foreignKey:ParentTaskID"`
|
|
Labels []Label `json:"labels" gorm:"many2many:task_labels"`
|
|
}
|
|
|
|
type Subtask struct {
|
|
ID uint `json:"id" gorm:"primaryKey"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
|
|
|
|
Title string `json:"title" gorm:"not null"`
|
|
Description string `json:"description"`
|
|
Status string `json:"status" gorm:"default:'todo'"` // todo, in_progress, done
|
|
Position int `json:"position" gorm:"default:0"`
|
|
CompletedAt *time.Time `json:"completed_at"`
|
|
|
|
// Foreign Keys
|
|
ParentTaskID uint `json:"parent_task_id" gorm:"not null"`
|
|
AssignedToID *uint `json:"assigned_to_id"`
|
|
|
|
// Relationships
|
|
ParentTask Task `json:"parent_task" gorm:"foreignKey:ParentTaskID"`
|
|
AssignedTo *User `json:"assigned_to" gorm:"foreignKey:AssignedToID"`
|
|
}
|
|
|
|
type Label struct {
|
|
ID uint `json:"id" gorm:"primaryKey"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
|
|
|
|
Name string `json:"name" gorm:"not null"`
|
|
Color string `json:"color" gorm:"default:'#6b7280'"` // Hex color
|
|
|
|
// Foreign Keys
|
|
ProjectID uint `json:"project_id" gorm:"not null"`
|
|
|
|
// Relationships
|
|
Project Project `json:"project" gorm:"foreignKey:ProjectID"`
|
|
Tasks []Task `json:"tasks" gorm:"many2many:task_labels"`
|
|
}
|
|
|
|
type Comment struct {
|
|
ID uint `json:"id" gorm:"primaryKey"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
|
|
|
|
Content string `json:"content" gorm:"not null"`
|
|
|
|
// Foreign Keys
|
|
TaskID uint `json:"task_id" gorm:"not null"`
|
|
UserID uint `json:"user_id" gorm:"not null"`
|
|
|
|
// Relationships
|
|
Task Task `json:"task" gorm:"foreignKey:TaskID"`
|
|
User User `json:"user" gorm:"foreignKey:UserID"`
|
|
}
|
|
|
|
// IsOverdue checks if the task is overdue
|
|
func (t *Task) IsOverdue() bool {
|
|
if t.DueDate == nil {
|
|
return false
|
|
}
|
|
return t.Status != "done" && t.DueDate.Before(time.Now())
|
|
}
|
|
|
|
// GetCompletionPercentage returns the completion percentage based on subtasks
|
|
func (t *Task) GetCompletionPercentage() int {
|
|
if len(t.Subtasks) == 0 {
|
|
if t.Status == "done" {
|
|
return 100
|
|
}
|
|
return 0
|
|
}
|
|
|
|
completed := 0
|
|
for _, subtask := range t.Subtasks {
|
|
if subtask.Status == "done" {
|
|
completed++
|
|
}
|
|
}
|
|
|
|
return (completed * 100) / len(t.Subtasks)
|
|
}
|
|
|
|
// MarkAsCompleted marks the task as completed
|
|
func (t *Task) MarkAsCompleted() {
|
|
t.Status = "done"
|
|
now := time.Now()
|
|
t.CompletedAt = &now
|
|
}
|