vikunja-api/pkg/models/list_task_readall.go

155 lines
4.6 KiB
Go

/*
* Copyright (c) 2018 the Vikunja Authors. All rights reserved.
* Use of this source code is governed by a LPGLv3-style
* license that can be found in the LICENSE file.
*/
package models
import (
"code.vikunja.io/web"
"sort"
"time"
)
// SortBy declares constants to sort
type SortBy int
// These are possible sort options
const (
SortTasksByUnsorted SortBy = -1
SortTasksByDueDateAsc = iota
SortTasksByDueDateDesc
SortTasksByPriorityAsc
SortTasksByPriorityDesc
)
// ReadAll gets all tasks for a user
// @Summary Get tasks
// @Description Returns all tasks on any list the user has access to.
// @tags task
// @Accept json
// @Produce json
// @Param p query int false "The page number. Used for pagination. If not provided, the first page of results is returned."
// @Param s query string false "Search tasks by task text."
// @Param sort query string false "The sorting parameter. Possible values to sort by are priority, prioritydesc, priorityasc, duedate, duedatedesc, duedateasc."
// @Param startdate query int false "The start date parameter to filter by. Expects a unix timestamp. If no end date, but a start date is specified, the end date is set to the current time."
// @Param enddate query int false "The end date parameter to filter by. Expects a unix timestamp. If no start date, but an end date is specified, the start date is set to the current time."
// @Security JWTKeyAuth
// @Success 200 {array} models.ListTask "The tasks"
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/all [get]
func (t *ListTask) ReadAll(search string, a web.Auth, page int) (interface{}, error) {
var sortby SortBy
switch t.Sorting {
case "priority":
sortby = SortTasksByPriorityDesc
case "prioritydesc":
sortby = SortTasksByPriorityDesc
case "priorityasc":
sortby = SortTasksByPriorityAsc
case "duedate":
sortby = SortTasksByDueDateDesc
case "duedatedesc":
sortby = SortTasksByDueDateDesc
case "duedateasc":
sortby = SortTasksByDueDateAsc
default:
sortby = SortTasksByUnsorted
}
return GetTasksByUser(search, &User{ID: a.GetID()}, page, sortby, time.Unix(t.StartDateSortUnix, 0), time.Unix(t.EndDateSortUnix, 0))
}
//GetTasksByUser returns all tasks for a user
func GetTasksByUser(search string, u *User, page int, sortby SortBy, startDate time.Time, endDate time.Time) ([]*ListTask, error) {
// Get all lists
lists, err := getRawListsForUser("", u, page)
if err != nil {
return nil, err
}
// Get all list IDs and get the tasks
var listIDs []int64
for _, l := range lists {
listIDs = append(listIDs, l.ID)
}
var orderby string
switch sortby {
case SortTasksByPriorityDesc:
orderby = "priority desc"
case SortTasksByPriorityAsc:
orderby = "priority asc"
case SortTasksByDueDateDesc:
orderby = "due_date_unix desc"
case SortTasksByDueDateAsc:
orderby = "due_date_unix asc"
}
taskMap := make(map[int64]*ListTask)
// Then return all tasks for that lists
if startDate.Unix() != 0 || endDate.Unix() != 0 {
startDateUnix := time.Now().Unix()
if startDate.Unix() != 0 {
startDateUnix = startDate.Unix()
}
endDateUnix := time.Now().Unix()
if endDate.Unix() != 0 {
endDateUnix = endDate.Unix()
}
if err := x.In("list_id", listIDs).
Where("text LIKE ?", "%"+search+"%").
And("((due_date_unix BETWEEN ? AND ?) OR "+
"(start_date_unix BETWEEN ? and ?) OR "+
"(end_date_unix BETWEEN ? and ?))", startDateUnix, endDateUnix, startDateUnix, endDateUnix, startDateUnix, endDateUnix).
And("(parent_task_id = 0 OR parent_task_id IS NULL)").
OrderBy(orderby).
Find(&taskMap); err != nil {
return nil, err
}
} else {
if err := x.In("list_id", listIDs).
Where("text LIKE ?", "%"+search+"%").
And("(parent_task_id = 0 OR parent_task_id IS NULL)").
OrderBy(orderby).
Find(&taskMap); err != nil {
return nil, err
}
}
tasks, err := addMoreInfoToTasks(taskMap)
if err != nil {
return nil, err
}
// Because the list is sorted by id which we don't want (since we're dealing with maps)
// we have to manually sort the tasks again here.
sortTasks(tasks, sortby)
return tasks, err
}
func sortTasks(tasks []*ListTask, by SortBy) {
switch by {
case SortTasksByPriorityDesc:
sort.Slice(tasks, func(i, j int) bool {
return tasks[i].Priority > tasks[j].Priority
})
case SortTasksByPriorityAsc:
sort.Slice(tasks, func(i, j int) bool {
return tasks[i].Priority < tasks[j].Priority
})
case SortTasksByDueDateDesc:
sort.Slice(tasks, func(i, j int) bool {
return tasks[i].DueDateUnix > tasks[j].DueDateUnix
})
case SortTasksByDueDateAsc:
sort.Slice(tasks, func(i, j int) bool {
return tasks[i].DueDateUnix < tasks[j].DueDateUnix
})
}
}