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

4 years ago
4 years ago
4 years ago
  1. package api
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "github.com/gissleh/stufflog/database"
  5. "github.com/gissleh/stufflog/internal/auth"
  6. "github.com/gissleh/stufflog/internal/generate"
  7. "github.com/gissleh/stufflog/internal/slerrors"
  8. "github.com/gissleh/stufflog/models"
  9. "github.com/gissleh/stufflog/services"
  10. "time"
  11. )
  12. func Goal(g *gin.RouterGroup, db database.Database) {
  13. l := services.Loader{DB: db}
  14. g.GET("/", handler("goals", func(c *gin.Context) (interface{}, error) {
  15. filter := models.GoalFilter{}
  16. if value := c.Query("minTime"); value != "" {
  17. minTime, err := time.Parse(time.RFC3339Nano, value)
  18. if err != nil {
  19. return nil, slerrors.BadRequest("Invalid minTime")
  20. }
  21. minTime = minTime.UTC()
  22. filter.MinTime = &minTime
  23. } else {
  24. lastMonth := time.Now().Add(-30 * 24 * time.Hour).UTC()
  25. filter.MinTime = &lastMonth
  26. }
  27. if value := c.Query("maxTime"); value != "" {
  28. maxTime, err := time.Parse(time.RFC3339Nano, value)
  29. if err != nil {
  30. return nil, slerrors.BadRequest("Invalid maxTime")
  31. }
  32. maxTime = maxTime.UTC()
  33. filter.MaxTime = &maxTime
  34. }
  35. if value := c.Query("includesTime"); value != "" {
  36. includesTime, err := time.Parse(time.RFC3339Nano, value)
  37. if err != nil {
  38. return nil, slerrors.BadRequest("Invalid includesTime")
  39. }
  40. includesTime = includesTime.UTC()
  41. filter.IncludesTime = &includesTime
  42. }
  43. return l.ListGoals(c.Request.Context(), filter)
  44. }))
  45. g.GET("/:id", handler("goal", func(c *gin.Context) (interface{}, error) {
  46. return l.FindGoal(c.Request.Context(), c.Param("id"))
  47. }))
  48. g.POST("/", handler("goal", func(c *gin.Context) (interface{}, error) {
  49. goal := models.Goal{}
  50. err := c.BindJSON(&goal)
  51. if err != nil {
  52. return nil, slerrors.BadRequest("Invalid JSON")
  53. }
  54. goal.ID = generate.GoalID()
  55. goal.UserID = auth.UserID(c)
  56. if goal.Amount <= 0 {
  57. return nil, slerrors.BadRequest("Goal amount must be more than 0.")
  58. }
  59. if goal.StartTime.IsZero() {
  60. return nil, slerrors.BadRequest("Start time must be set.")
  61. }
  62. if goal.EndTime.IsZero() {
  63. return nil, slerrors.BadRequest("End time must be set.")
  64. }
  65. if !goal.EndTime.After(goal.StartTime) {
  66. return nil, slerrors.BadRequest("Start time must be before end time.")
  67. }
  68. goal.StartTime = goal.StartTime.UTC()
  69. goal.EndTime = goal.EndTime.UTC()
  70. group, err := db.Groups().Find(c.Request.Context(), goal.GroupID)
  71. if err != nil {
  72. return nil, err
  73. }
  74. goal.GroupID = group.ID
  75. if goal.ItemID != nil {
  76. item, err := l.FindItem(c.Request.Context(), *goal.ItemID)
  77. if err != nil {
  78. return nil, slerrors.BadRequest("Item could not be found.")
  79. }
  80. if item.GroupID != goal.GroupID {
  81. return nil, slerrors.BadRequest("Item is not in group.")
  82. }
  83. }
  84. err = db.Goals().Insert(c.Request.Context(), goal)
  85. if err != nil {
  86. return nil, err
  87. }
  88. return l.FindGoal(c.Request.Context(), goal.ID)
  89. }))
  90. g.PUT("/:id", handler("goal", func(c *gin.Context) (interface{}, error) {
  91. update := models.GoalUpdate{}
  92. err := c.BindJSON(&update)
  93. if err != nil {
  94. return nil, slerrors.BadRequest("Invalid JSON")
  95. }
  96. goal, err := l.FindGoal(c.Request.Context(), c.Param("id"))
  97. if err != nil {
  98. return nil, err
  99. }
  100. goal.StartTime = goal.StartTime.UTC()
  101. goal.EndTime = goal.EndTime.UTC()
  102. goal.Update(update)
  103. if goal.Amount <= 0 {
  104. return nil, slerrors.BadRequest("Goal amount must be more than 0.")
  105. }
  106. if !goal.EndTime.After(goal.StartTime) {
  107. return nil, slerrors.BadRequest("Start time must be before end time.")
  108. }
  109. if goal.ItemID != nil && update.ItemID != nil {
  110. item, err := l.FindItem(c.Request.Context(), *goal.ItemID)
  111. if err != nil {
  112. return nil, slerrors.BadRequest("Item could not be found.")
  113. }
  114. if item.GroupID != goal.GroupID {
  115. return nil, slerrors.BadRequest("Item is not in group.")
  116. }
  117. }
  118. err = db.Goals().Update(c.Request.Context(), goal.Goal)
  119. if err != nil {
  120. return nil, err
  121. }
  122. return goal, nil
  123. }))
  124. g.DELETE("/:id", handler("goal", func(c *gin.Context) (interface{}, error) {
  125. goal, err := l.FindGoal(c.Request.Context(), c.Param("id"))
  126. if err != nil {
  127. return nil, err
  128. }
  129. err = db.Goals().Delete(c.Request.Context(), goal.Goal)
  130. if err != nil {
  131. return nil, err
  132. }
  133. return goal, nil
  134. }))
  135. }