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

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
}))
}