Plan stuff. Log stuff.
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.

169 lines
3.9 KiB

4 years ago
4 years ago
4 years ago
  1. package api
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "github.com/gisle/stufflog/database"
  5. "github.com/gisle/stufflog/models"
  6. "github.com/gisle/stufflog/services"
  7. "github.com/gisle/stufflog/slerrors"
  8. "sort"
  9. )
  10. func Period(g *gin.RouterGroup, db database.Database, scoring *services.ScoringService, auth *services.AuthService) {
  11. type resObj struct {
  12. Period *models.Period `json:"period,omitempty"`
  13. Periods []*models.Period `json:"periods,omitempty"`
  14. Activities []*models.Activity `json:"activities,omitempty"`
  15. }
  16. g.Use(auth.GinSessionMiddleware(true))
  17. // GET / – List own periods.
  18. g.GET("/", func(c *gin.Context) {
  19. user := auth.UserFromContext(c)
  20. periods, err := db.Periods().ListUser(c.Request.Context(), *user)
  21. if err != nil {
  22. slerrors.GinRespond(c, err)
  23. return
  24. }
  25. sort.Sort(models.PeriodsByFrom(periods))
  26. c.JSON(200, resObj{Periods: periods})
  27. })
  28. // GET / — Find a period
  29. g.GET("/:id", func(c *gin.Context) {
  30. user := auth.UserFromContext(c)
  31. period, err := db.Periods().FindID(c.Request.Context(), c.Param("id"))
  32. if err != nil {
  33. slerrors.GinRespond(c, err)
  34. return
  35. }
  36. if period.UserID != user.ID {
  37. slerrors.GinRespond(c, slerrors.NotFound("Period"))
  38. return
  39. }
  40. activities := make([]*models.Activity, 0, 8)
  41. activityAdded := make(map[string]bool)
  42. for _, goal := range period.Goals {
  43. if !activityAdded[goal.ActivityID] {
  44. activityAdded[goal.ActivityID] = true
  45. activity, err := db.Activities().FindID(c.Request.Context(), goal.ActivityID)
  46. if err != nil {
  47. slerrors.GinRespond(c, err)
  48. return
  49. }
  50. activities = append(activities, activity)
  51. }
  52. }
  53. c.JSON(200, resObj{Period: period, Activities: activities})
  54. })
  55. // POST / – Create a period
  56. g.POST("/", func(c *gin.Context) {
  57. user := auth.UserFromContext(c)
  58. period := models.Period{}
  59. err := c.BindJSON(&period)
  60. if err != nil {
  61. slerrors.GinRespond(c, &slerrors.SLError{Code: 400, Text: err.Error()})
  62. return
  63. }
  64. period.GenerateIDs()
  65. period.UserID = user.ID
  66. period.Logs = make([]models.Log, 0)
  67. period.ShouldReScore = false
  68. if period.Goals == nil {
  69. period.Goals = make([]models.Goal, 0)
  70. }
  71. err = db.Periods().Insert(c.Request.Context(), period)
  72. if err != nil {
  73. slerrors.GinRespond(c, err)
  74. return
  75. }
  76. c.JSON(200, resObj{Period: &period})
  77. })
  78. // PATCH /:id – Update one Period
  79. g.PATCH("/:id", func(c *gin.Context) {
  80. user := auth.UserFromContext(c)
  81. updates := make([]*models.PeriodUpdate, 0, 8)
  82. err := c.BindJSON(&updates)
  83. if err != nil {
  84. slerrors.GinRespond(c, &slerrors.SLError{Code: 400, Text: err.Error()})
  85. return
  86. }
  87. period, err := db.Periods().FindID(c.Request.Context(), c.Param("id"))
  88. if err != nil {
  89. slerrors.GinRespond(c, err)
  90. return
  91. }
  92. if period.UserID != user.ID {
  93. slerrors.GinRespond(c, slerrors.NotFound("Period"))
  94. return
  95. }
  96. for _, update := range updates {
  97. if update.AddLog != nil {
  98. score, err := scoring.ScoreOne(c.Request.Context(), *period, *update.AddLog)
  99. if err != nil {
  100. slerrors.GinRespond(c, err)
  101. return
  102. }
  103. update.AddLog.Score = score
  104. }
  105. }
  106. period, err = db.Periods().Update(c.Request.Context(), *period, updates)
  107. if err != nil {
  108. slerrors.GinRespond(c, err)
  109. return
  110. }
  111. if period.ShouldReScore {
  112. period, err = scoring.ScoreAll(c.Request.Context(), *period)
  113. if err != nil {
  114. slerrors.GinRespond(c, err)
  115. return
  116. }
  117. }
  118. c.JSON(200, resObj{Period: period})
  119. })
  120. // DELETE /:id – Delete a period
  121. g.DELETE("/:id", func(c *gin.Context) {
  122. user := auth.UserFromContext(c)
  123. period, err := db.Periods().FindID(c.Request.Context(), c.Param("id"))
  124. if err != nil {
  125. slerrors.GinRespond(c, err)
  126. return
  127. }
  128. if period.UserID != user.ID {
  129. slerrors.GinRespond(c, slerrors.NotFound("Period"))
  130. return
  131. }
  132. err = db.Periods().Remove(c.Request.Context(), *period)
  133. if err != nil {
  134. slerrors.GinRespond(c, err)
  135. return
  136. }
  137. c.JSON(200, resObj{Period: period})
  138. })
  139. }