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" "strings" "time" ) func Log(g *gin.RouterGroup, db database.Database) { l := services.Loader{DB: db} g.GET("/", handler("logs", func(c *gin.Context) (interface{}, error) { filter := models.LogFilter{} 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("groups"); value != "" { filter.ProjectGroupIDs = strings.Split(value, ",") } if value := c.Query("projects"); value != "" { filter.ProjectIDs = strings.Split(value, ",") } if value := c.Query("items"); value != "" { filter.ItemIDs = strings.Split(value, ",") } if value := c.Query("tasks"); value != "" { filter.TaskIDs = strings.Split(value, ",") } return l.ListLogs(c, filter) })) g.GET("/:id", handler("log", func(c *gin.Context) (interface{}, error) { return l.FindLog(c, c.Param("id")) })) g.POST("/", handler("log", func(c *gin.Context) (interface{}, error) { log := models.Log{} err := c.BindJSON(&log) if err != nil { return nil, slerrors.BadRequest("Invalid JSON") } task, err := l.FindTask(c.Request.Context(), log.TaskID) if err != nil { return nil, err } log.ID = generate.LogID() log.UserID = auth.UserID(c) log.TaskID = task.ID log.ItemID = task.ItemID if log.LoggedTime.IsZero() { log.LoggedTime = time.Now().UTC() } else { log.LoggedTime = log.LoggedTime.UTC() } if log.ItemAmount < 0 { return nil, slerrors.BadRequest("Invalid item amount (min: 0).") } if log.SecondaryItemAmount < 0 { return nil, slerrors.BadRequest("Invalid secondary item amount (min: 0).") } if log.SecondaryItemID != nil { _, err := l.FindItem(c.Request.Context(), *log.SecondaryItemID) if err != nil { return nil, slerrors.BadRequest("Item could not be found.") } } err = db.Logs().Insert(c.Request.Context(), log) if err != nil { return nil, err } return l.FindLog(c.Request.Context(), log.ID) })) g.PUT("/:id", handler("log", func(c *gin.Context) (interface{}, error) { update := models.LogUpdate{} err := c.BindJSON(&update) if err != nil { return nil, slerrors.BadRequest("Invalid JSON") } log, err := l.FindLog(c.Request.Context(), c.Param("id")) if err != nil { return nil, err } log.Update(update) if log.SecondaryItemID != nil && update.SecondaryItemID != nil { _, err := l.FindItem(c.Request.Context(), *log.SecondaryItemID) if err != nil { return nil, slerrors.BadRequest("Item could not be found.") } } if log.ItemAmount < 0 { return nil, slerrors.BadRequest("Invalid item amount (min: 0).") } if log.SecondaryItemAmount < 0 { return nil, slerrors.BadRequest("Invalid secondary item amount (min: 0).") } err = db.Logs().Update(c.Request.Context(), log.Log) if err != nil { return nil, err } return log, nil })) g.DELETE("/:id", handler("log", func(c *gin.Context) (interface{}, error) { log, err := l.FindLog(c.Request.Context(), c.Param("id")) if err != nil { return nil, err } err = db.Logs().Delete(c.Request.Context(), log.Log) if err != nil { return nil, err } return log, nil })) }