Add error in case a task was added to a bucket which has its limit already exceeded

This commit is contained in:
kolaente 2020-09-04 13:29:07 +02:00
parent c6e392c56b
commit 6b24ec5eaa
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
3 changed files with 57 additions and 2 deletions

View File

@ -134,3 +134,4 @@ This document describes the different errors Vikunja can return.
| 10001 | 404 | The bucket does not exist. |
| 10002 | 400 | The bucket does not belong to that list. |
| 10003 | 412 | You cannot remove the last bucket on a list. |
| 10004 | 412 | You cannot add the task to this bucket as it already exceeded the limit of tasks it can hold. |

View File

@ -1334,3 +1334,32 @@ func (err ErrCannotRemoveLastBucket) HTTPError() web.HTTPError {
Message: "You cannot remove the last bucket on this list.",
}
}
// ErrBucketLimitExceeded represents an error where a task is being created or moved to a bucket which has its limit already exceeded.
type ErrBucketLimitExceeded struct {
BucketID int64
Limit int64
TaskID int64 // may be 0
}
// IsErrBucketLimitExceeded checks if an error is ErrBucketLimitExceeded.
func IsErrBucketLimitExceeded(err error) bool {
_, ok := err.(ErrBucketLimitExceeded)
return ok
}
func (err ErrBucketLimitExceeded) Error() string {
return fmt.Sprintf("Cannot add a task to this bucket because it would exceed the limit [BucketID: %d, Limit: %d, TaskID: %d]", err.BucketID, err.Limit, err.TaskID)
}
// ErrCodeBucketLimitExceeded holds the unique world-error code of this error
const ErrCodeBucketLimitExceeded = 10004
// HTTPError holds the http error description
func (err ErrBucketLimitExceeded) HTTPError() web.HTTPError {
return web.HTTPError{
HTTPCode: http.StatusPreconditionFailed,
Code: ErrCodeBucketLimitExceeded,
Message: "You cannot add the task to this bucket as it already exceeded the limit of tasks it can hold.",
}
}

View File

@ -608,12 +608,37 @@ func createTask(s *xorm.Session, t *Task, a web.Auth, updateAssignees bool) (err
}
// Get the default bucket and move the task there
var bucket *Bucket
if t.BucketID == 0 {
defaultBucket, err := getDefaultBucket(s, t.ListID)
bucket, err = getDefaultBucket(s, t.ListID)
if err != nil {
return err
}
t.BucketID = defaultBucket.ID
t.BucketID = bucket.ID
} else {
// We need the bucket to check if it has more tasks than the limit allows
bucket, err = getBucketByID(s, t.BucketID)
if err != nil {
return err
}
}
// Check the limit
if bucket.Limit > 0 {
type currentTasks struct {
count int64
}
taskCount := &currentTasks{}
_, err = s.
Table("tasks").
Where("bucket_id = ?", bucket.ID).
Count(taskCount)
if err != nil {
return err
}
if taskCount.count >= bucket.Limit {
return ErrBucketLimitExceeded{TaskID: t.ID, BucketID: bucket.ID, Limit: bucket.Limit}
}
}
// Get the index for this task