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.
161 lines
4.2 KiB
161 lines
4.2 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 Goal(g *gin.RouterGroup, db database.Database) {
|
|
l := services.Loader{DB: db}
|
|
|
|
g.GET("/", handler("goals", func(c *gin.Context) (interface{}, error) {
|
|
filter := models.GoalFilter{}
|
|
if value := c.Query("minTime"); value != "" {
|
|
minTime, err := time.Parse(time.RFC3339Nano, value)
|
|
if err != nil {
|
|
return nil, slerrors.BadRequest("Invalid minTime")
|
|
}
|
|
minTime = minTime.UTC()
|
|
|
|
filter.MinTime = &minTime
|
|
} else {
|
|
lastMonth := time.Now().Add(-30 * 24 * time.Hour).UTC()
|
|
filter.MinTime = &lastMonth
|
|
}
|
|
if value := c.Query("maxTime"); value != "" {
|
|
maxTime, err := time.Parse(time.RFC3339Nano, value)
|
|
if err != nil {
|
|
return nil, slerrors.BadRequest("Invalid maxTime")
|
|
}
|
|
maxTime = maxTime.UTC()
|
|
|
|
filter.MaxTime = &maxTime
|
|
}
|
|
if value := c.Query("includesTime"); value != "" {
|
|
includesTime, err := time.Parse(time.RFC3339Nano, value)
|
|
if err != nil {
|
|
return nil, slerrors.BadRequest("Invalid includesTime")
|
|
}
|
|
includesTime = includesTime.UTC()
|
|
|
|
filter.IncludesTime = &includesTime
|
|
}
|
|
|
|
return l.ListGoals(c.Request.Context(), filter)
|
|
}))
|
|
|
|
g.GET("/:id", handler("goal", func(c *gin.Context) (interface{}, error) {
|
|
return l.FindGoal(c.Request.Context(), c.Param("id"))
|
|
}))
|
|
|
|
g.POST("/", handler("goal", func(c *gin.Context) (interface{}, error) {
|
|
goal := models.Goal{}
|
|
err := c.BindJSON(&goal)
|
|
if err != nil {
|
|
return nil, slerrors.BadRequest("Invalid JSON")
|
|
}
|
|
goal.ID = generate.GoalID()
|
|
goal.UserID = auth.UserID(c)
|
|
|
|
if goal.Amount <= 0 {
|
|
return nil, slerrors.BadRequest("Goal amount must be more than 0.")
|
|
}
|
|
if goal.StartTime.IsZero() {
|
|
return nil, slerrors.BadRequest("Start time must be set.")
|
|
}
|
|
if goal.EndTime.IsZero() {
|
|
return nil, slerrors.BadRequest("End time must be set.")
|
|
}
|
|
if !goal.EndTime.After(goal.StartTime) {
|
|
return nil, slerrors.BadRequest("Start time must be before end time.")
|
|
}
|
|
|
|
goal.StartTime = goal.StartTime.UTC()
|
|
goal.EndTime = goal.EndTime.UTC()
|
|
|
|
group, err := db.Groups().Find(c.Request.Context(), goal.GroupID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
goal.GroupID = group.ID
|
|
|
|
if goal.ItemID != nil {
|
|
item, err := l.FindItem(c.Request.Context(), *goal.ItemID)
|
|
if err != nil {
|
|
return nil, slerrors.BadRequest("Item could not be found.")
|
|
}
|
|
if item.GroupID != goal.GroupID {
|
|
return nil, slerrors.BadRequest("Item is not in group.")
|
|
}
|
|
}
|
|
|
|
err = db.Goals().Insert(c.Request.Context(), goal)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return l.FindGoal(c.Request.Context(), goal.ID)
|
|
}))
|
|
|
|
g.PUT("/:id", handler("goal", func(c *gin.Context) (interface{}, error) {
|
|
update := models.GoalUpdate{}
|
|
err := c.BindJSON(&update)
|
|
if err != nil {
|
|
return nil, slerrors.BadRequest("Invalid JSON")
|
|
}
|
|
|
|
goal, err := l.FindGoal(c.Request.Context(), c.Param("id"))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
goal.StartTime = goal.StartTime.UTC()
|
|
goal.EndTime = goal.EndTime.UTC()
|
|
|
|
goal.Update(update)
|
|
|
|
if goal.Amount <= 0 {
|
|
return nil, slerrors.BadRequest("Goal amount must be more than 0.")
|
|
}
|
|
if !goal.EndTime.After(goal.StartTime) {
|
|
return nil, slerrors.BadRequest("Start time must be before end time.")
|
|
}
|
|
|
|
if goal.ItemID != nil && update.ItemID != nil {
|
|
item, err := l.FindItem(c.Request.Context(), *goal.ItemID)
|
|
if err != nil {
|
|
return nil, slerrors.BadRequest("Item could not be found.")
|
|
}
|
|
if item.GroupID != goal.GroupID {
|
|
return nil, slerrors.BadRequest("Item is not in group.")
|
|
}
|
|
}
|
|
|
|
err = db.Goals().Update(c.Request.Context(), goal.Goal)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return goal, nil
|
|
}))
|
|
|
|
g.DELETE("/:id", handler("goal", func(c *gin.Context) (interface{}, error) {
|
|
goal, err := l.FindGoal(c.Request.Context(), c.Param("id"))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = db.Goals().Delete(c.Request.Context(), goal.Goal)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return goal, nil
|
|
}))
|
|
}
|