|
|
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" "sort" "strings" "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 }
tasks, err := l.ListTasks(c, filter) if err != nil { return nil, err }
sort.Sort( models.TaskSorter{ Fields: strings.Split(c.Query("sort"), ","), Data: tasks, }, )
return tasks, nil }))
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.LogWithSecondaryItem{}, 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.ProjectID != nil && *update.ProjectID != task.ProjectID { project, err := l.FindProject(c.Request.Context(), *update.ProjectID) if err != nil { return nil, slerrors.NotFound("Destination project") }
// Delete any links that would have been ran over.
err = db.Tasks().DeleteLink(c.Request.Context(), models.TaskLink{ TaskID: task.ID, ProjectID: project.ID, }) if err != nil { return nil, slerrors.BadRequest(err.Error()) }
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.PUT("/:id/link/:project_id", handler("taskLink", func(c *gin.Context) (interface{}, error) { task, err := l.FindTask(c.Request.Context(), c.Param("id")) if err != nil { return nil, err }
project, err := l.FindProject(c.Request.Context(), c.Param("project_id")) if err != nil { return nil, err }
if task.ProjectID == project.ID { return nil, slerrors.BadRequest("You cannot link a task within its own project") }
err = db.Tasks().CreateLink(c.Request.Context(), models.TaskLink{ TaskID: task.ID, ProjectID: project.ID, })
return &models.TaskLink{ TaskID: task.ID, ProjectID: project.ID, }, nil }))
g.DELETE("/:id/link/:project_id", handler("taskLink", func(c *gin.Context) (interface{}, error) { task, err := l.FindTask(c.Request.Context(), c.Param("id")) if err != nil { return nil, err }
project, err := l.FindProject(c.Request.Context(), c.Param("project_id")) if err != nil { return nil, err }
err = db.Tasks().DeleteLink(c.Request.Context(), models.TaskLink{ TaskID: task.ID, ProjectID: project.ID, }) if err != nil { return nil, err }
return &models.TaskLink{ TaskID: task.ID, ProjectID: project.ID, }, 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 })) }
|