vikunja/pkg/models/bulk_task.go

94 lines
3.3 KiB
Go

// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-present Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package models
import (
"code.vikunja.io/api/pkg/web"
"xorm.io/xorm"
)
// BulkTask represents a bulk task update payload.
type BulkTask struct {
TaskIDs []int64 `json:"task_ids" doc:"The ids of the tasks to update. The user needs write access to every project these tasks belong to, or the whole request is rejected."`
Fields []string `json:"fields" doc:"The names of the task fields to apply from values; only these fields are written, the rest of each task is left untouched."`
Values *Task `json:"values" doc:"The task carrying the values to set. Only the fields named in fields are read from it and applied to every task."`
Tasks []*Task `json:"tasks,omitempty" readOnly:"true" doc:"The updated tasks, returned in the response."`
web.CRUDable `xorm:"-" json:"-"`
web.Permissions `xorm:"-" json:"-"`
}
// CanUpdate checks if the user can update all provided tasks.
func (bt *BulkTask) CanUpdate(s *xorm.Session, a web.Auth) (bool, error) {
tasks, err := GetTasksSimpleByIDs(s, bt.TaskIDs)
if err != nil {
return false, err
}
if len(tasks) == 0 {
return false, ErrBulkTasksNeedAtLeastOne{}
}
// ensure user can write to each involved project
projects := map[int64]struct{}{}
for _, t := range tasks {
projects[t.ProjectID] = struct{}{}
}
for pid := range projects {
p := &Project{ID: pid}
can, err := p.CanWrite(s, a)
if err != nil || !can {
return false, err
}
}
// if tasks are moved to another project, check destination permission
if bt.Values != nil && bt.Values.ProjectID != 0 {
p := &Project{ID: bt.Values.ProjectID}
can, err := p.CanWrite(s, a)
if err != nil || !can {
return false, err
}
}
return true, nil
}
// Update updates multiple tasks at once.
// @Summary Update multiple tasks
// @Description Updates multiple tasks atomically. All provided tasks must be writable by the user.
// @tags task
// @Accept json
// @Produce json
// @Security JWTKeyAuth
// @Param bulkTask body models.BulkTask true "Bulk task update payload"
// @Success 200 {array} models.Task "Updated tasks"
// @Failure 400 {object} web.HTTPError "Invalid request"
// @Failure 403 {object} web.HTTPError "The user does not have access to the tasks"
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/bulk [post]
func (bt *BulkTask) Update(s *xorm.Session, a web.Auth) (err error) {
if bt.Values == nil {
bt.Values = &Task{}
}
tasks, err := updateTasks(s, a, bt.Values, bt.TaskIDs, bt.Fields)
if err != nil {
return err
}
bt.Tasks = tasks
return nil
}