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.
 
 
 
 
 
 

149 lines
3.8 KiB

package api
import (
"github.com/gin-gonic/gin"
"github.com/gissleh/stufflog/database"
"github.com/gissleh/stufflog/internal/auth"
"github.com/gissleh/stufflog/internal/generate"
"github.com/gissleh/stufflog/internal/slerrors"
"github.com/gissleh/stufflog/models"
"github.com/gissleh/stufflog/services"
"time"
)
func Task(g *gin.RouterGroup, db database.Database) {
l := services.Loader{DB: db}
g.GET("/", handler("tasks", func(c *gin.Context) (interface{}, error) {
filter := models.TaskFilter{}
if setting := c.Query("active"); setting != "" {
active := setting == "true"
filter.Active = &active
}
if setting := c.Query("expiring"); setting != "" {
expiring := setting == "true"
filter.Expiring = &expiring
}
return l.ListTasks(c, filter)
}))
g.GET("/:id", handler("task", func(c *gin.Context) (interface{}, error) {
return l.FindTask(c, c.Param("id"))
}))
g.POST("/", handler("task", func(c *gin.Context) (interface{}, error) {
createdTime := time.Now()
task := models.Task{}
err := c.BindJSON(&task)
if err != nil {
return nil, slerrors.BadRequest("Invalid JSON")
}
if task.EndTime != nil && task.EndTime.Before(createdTime) {
return nil, slerrors.BadRequest("Task end time must be later than current time.")
}
if task.ItemAmount <= 0 {
return nil, slerrors.BadRequest("Item amount cannot be zero or negative.")
}
project, err := l.FindProject(c.Request.Context(), task.ProjectID)
if err != nil {
return nil, err
}
item, err := l.FindItem(c.Request.Context(), task.ItemID)
if err != nil {
return nil, err
}
task.ID = generate.TaskID()
task.UserID = auth.UserID(c)
task.CreatedTime = time.Now().UTC()
task.ItemID = item.ID
task.ProjectID = project.ID
err = db.Tasks().Insert(c.Request.Context(), task)
if err != nil {
return nil, err
}
return &models.TaskResult{
Task: task,
Logs: []*models.Log{},
Item: &item.Item,
CompletedAmount: 0,
}, nil
}))
g.PUT("/:id", handler("task", func(c *gin.Context) (interface{}, error) {
update := models.TaskUpdate{}
err := c.BindJSON(&update)
if err != nil {
return nil, slerrors.BadRequest("Invalid JSON")
}
task, err := l.FindTask(c.Request.Context(), c.Param("id"))
if err != nil {
return nil, err
}
if update.ItemID != nil && *update.ItemID != task.ItemID {
_, err := l.FindItem(c.Request.Context(), *update.ItemID)
if err != nil {
return nil, err
}
logs, err := l.ListLogs(c.Request.Context(), models.LogFilter{
TaskIDs: []string{task.ID},
})
if err != nil {
return nil, err
}
if len(logs) > 0 {
return nil, slerrors.Forbidden("You cannot change the item if the task has logs.")
}
}
if update.ProjectID != nil && *update.ProjectID != task.ProjectID {
project, err := l.FindProject(c.Request.Context(), *update.ProjectID)
if err != nil {
return nil, slerrors.NotFound("Destination project")
}
task.ProjectID = project.ID
}
task.Update(update)
if task.EndTime != nil && task.EndTime.Before(task.CreatedTime) {
return nil, slerrors.BadRequest("Task end time must be later than it was created.")
}
if task.ItemAmount <= 0 {
return nil, slerrors.BadRequest("Item amount cannot be zero or negative.")
}
err = db.Tasks().Update(c.Request.Context(), task.Task)
if err != nil {
return nil, err
}
return task, nil
}))
g.DELETE("/:id", handler("task", func(c *gin.Context) (interface{}, error) {
task, err := l.FindTask(c.Request.Context(), c.Param("id"))
if err != nil {
return nil, err
}
if len(task.Logs) > 0 {
return nil, slerrors.Forbidden("cannot delete tasks with logs.")
}
err = db.Tasks().Delete(c.Request.Context(), task.Task)
if err != nil {
return nil, err
}
return task, nil
}))
}