You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
4.7 KiB
196 lines
4.7 KiB
package models
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
type Task struct {
|
|
ID string `json:"id" db:"task_id"`
|
|
UserID string `json:"-" db:"user_id"`
|
|
ItemID string `json:"itemId" db:"item_id"`
|
|
ProjectID string `json:"projectId" db:"project_id"`
|
|
ItemAmount int `json:"itemAmount" db:"item_amount"`
|
|
Name string `json:"name" db:"name"`
|
|
Description string `json:"description" db:"description"`
|
|
Icon string `json:"icon" db:"icon"`
|
|
Active bool `json:"active" db:"active"`
|
|
CreatedTime time.Time `json:"createdTime" db:"created_time"`
|
|
EndTime *time.Time `json:"endTime" db:"end_time"`
|
|
StatusTag *string `json:"statusTag" db:"status_tag"`
|
|
}
|
|
|
|
func (task *Task) Update(update TaskUpdate) {
|
|
if update.ItemID != nil {
|
|
task.ItemID = *update.ItemID
|
|
}
|
|
if update.ItemAmount != nil {
|
|
task.ItemAmount = *update.ItemAmount
|
|
}
|
|
if update.Name != nil {
|
|
task.Name = *update.Name
|
|
}
|
|
if update.Description != nil {
|
|
task.Description = *update.Description
|
|
}
|
|
if update.Active != nil {
|
|
task.Active = *update.Active
|
|
}
|
|
if update.EndTime != nil {
|
|
endTimeCopy := update.EndTime.UTC()
|
|
task.EndTime = &endTimeCopy
|
|
}
|
|
if update.ClearEndTime {
|
|
task.EndTime = nil
|
|
}
|
|
if update.StatusTag != nil {
|
|
task.StatusTag = update.StatusTag
|
|
}
|
|
if update.ClearStatusTag {
|
|
task.StatusTag = nil
|
|
}
|
|
if update.ProjectID != nil {
|
|
task.ProjectID = *update.ProjectID
|
|
}
|
|
}
|
|
|
|
type TaskUpdate struct {
|
|
ItemID *string `json:"itemId"`
|
|
ItemAmount *int `json:"itemAmount"`
|
|
Name *string `json:"name"`
|
|
Description *string `json:"description"`
|
|
Active *bool `json:"active"`
|
|
EndTime *time.Time `json:"endTime"`
|
|
ClearEndTime bool `json:"clearEndTime"`
|
|
StatusTag *string `json:"statusTag"`
|
|
ClearStatusTag bool `json:"clearStatusTag"`
|
|
ProjectID *string `json:"projectId"`
|
|
}
|
|
|
|
type TaskLink struct {
|
|
TaskID string `json:"taskId" db:"task_id"`
|
|
ProjectID string `json:"projectId" db:"project_id"`
|
|
}
|
|
|
|
type TaskWithProject struct {
|
|
Task
|
|
Project *Project `json:"project,omitempty"`
|
|
}
|
|
|
|
type TaskResult struct {
|
|
Task
|
|
Item *Item `json:"item"`
|
|
Logs []*LogWithSecondaryItem `json:"logs"`
|
|
CompletedAmount int `json:"completedAmount"`
|
|
Project *Project `json:"project,omitempty"`
|
|
}
|
|
|
|
type TaskFilter struct {
|
|
UserID string
|
|
Active *bool
|
|
Expiring *bool
|
|
IDs []string
|
|
ItemIDs []string
|
|
ProjectIDs []string
|
|
}
|
|
|
|
var taskStatusOrder = []string{"", "to do", "on hold", "completed", "failed", "declined"}
|
|
|
|
type TaskSorter struct {
|
|
Data []*TaskResult
|
|
Fields []string
|
|
}
|
|
|
|
func (s *TaskSorter) Valid() bool {
|
|
for _, field := range s.Fields {
|
|
switch field {
|
|
case "name", "-name", "createdTime", "-createdTime", "amount", "-amount", "status", "-status":
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (s TaskSorter) Len() int {
|
|
return len(s.Data)
|
|
}
|
|
|
|
func (s TaskSorter) Less(i, j int) bool {
|
|
a := s.Data[i]
|
|
b := s.Data[j]
|
|
|
|
for _, field := range s.Fields {
|
|
switch field {
|
|
case "status", "-status":
|
|
as := ""
|
|
if a.StatusTag != nil {
|
|
as = *a.StatusTag
|
|
}
|
|
bs := ""
|
|
if b.StatusTag != nil {
|
|
bs = *b.StatusTag
|
|
}
|
|
|
|
if as != bs {
|
|
asi := 1000
|
|
bsi := 1000
|
|
|
|
for i, sn := range taskStatusOrder {
|
|
if sn == as {
|
|
asi = i
|
|
}
|
|
if sn == bs {
|
|
bsi = i
|
|
}
|
|
}
|
|
|
|
if field == "-status" {
|
|
return asi > bsi
|
|
} else {
|
|
return asi < bsi
|
|
}
|
|
}
|
|
case "amount":
|
|
if a.ItemAmount != b.ItemAmount {
|
|
return a.ItemAmount < b.ItemAmount
|
|
}
|
|
case "-amount":
|
|
if a.ItemAmount != b.ItemAmount {
|
|
return a.ItemAmount > b.ItemAmount
|
|
}
|
|
case "name":
|
|
if a.Name != b.Name {
|
|
return a.Name < b.Name
|
|
}
|
|
case "-name":
|
|
if a.Name != b.Name {
|
|
return a.Name > b.Name
|
|
}
|
|
case "-time":
|
|
return a.CreatedTime.After(b.CreatedTime)
|
|
case "time":
|
|
return a.CreatedTime.Before(b.CreatedTime)
|
|
}
|
|
}
|
|
|
|
return a.CreatedTime.Before(b.CreatedTime)
|
|
}
|
|
|
|
func (s TaskSorter) Swap(i, j int) {
|
|
s.Data[i], s.Data[j] = s.Data[j], s.Data[i]
|
|
}
|
|
|
|
type TaskRepository interface {
|
|
Find(ctx context.Context, id string) (*Task, error)
|
|
List(ctx context.Context, filter TaskFilter) ([]*Task, error)
|
|
ListWithLinks(ctx context.Context, filter TaskFilter) ([]*Task, []*TaskLink, error)
|
|
Insert(ctx context.Context, task Task) error
|
|
Update(ctx context.Context, task Task) error
|
|
CreateLink(ctx context.Context, link TaskLink) error
|
|
DeleteLink(ctx context.Context, link TaskLink) error
|
|
UnlinkTask(ctx context.Context, task Task) error
|
|
UnlinkProject(ctx context.Context, project Project) error
|
|
Delete(ctx context.Context, task Task) error
|
|
}
|