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.

191 lines
4.8 KiB

4 years ago
4 years ago
4 years ago
4 years ago
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 Task(g *gin.RouterGroup, db database.Database) {
  13. l := services.Loader{DB: db}
  14. g.GET("/", handler("tasks", func(c *gin.Context) (interface{}, error) {
  15. filter := models.TaskFilter{}
  16. if setting := c.Query("active"); setting != "" {
  17. active := setting == "true"
  18. filter.Active = &active
  19. }
  20. if setting := c.Query("expiring"); setting != "" {
  21. expiring := setting == "true"
  22. filter.Expiring = &expiring
  23. }
  24. return l.ListTasks(c, filter)
  25. }))
  26. g.GET("/:id", handler("task", func(c *gin.Context) (interface{}, error) {
  27. return l.FindTask(c, c.Param("id"))
  28. }))
  29. g.POST("/", handler("task", func(c *gin.Context) (interface{}, error) {
  30. createdTime := time.Now()
  31. task := models.Task{}
  32. err := c.BindJSON(&task)
  33. if err != nil {
  34. return nil, slerrors.BadRequest("Invalid JSON")
  35. }
  36. if task.EndTime != nil && task.EndTime.Before(createdTime) {
  37. return nil, slerrors.BadRequest("Task end time must be later than current time.")
  38. }
  39. if task.ItemAmount <= 0 {
  40. return nil, slerrors.BadRequest("Item amount cannot be zero or negative.")
  41. }
  42. project, err := l.FindProject(c.Request.Context(), task.ProjectID)
  43. if err != nil {
  44. return nil, err
  45. }
  46. item, err := l.FindItem(c.Request.Context(), task.ItemID)
  47. if err != nil {
  48. return nil, err
  49. }
  50. task.ID = generate.TaskID()
  51. task.UserID = auth.UserID(c)
  52. task.CreatedTime = time.Now().UTC()
  53. task.ItemID = item.ID
  54. task.ProjectID = project.ID
  55. err = db.Tasks().Insert(c.Request.Context(), task)
  56. if err != nil {
  57. return nil, err
  58. }
  59. return &models.TaskResult{
  60. Task: task,
  61. Logs: []*models.Log{},
  62. Item: &item.Item,
  63. CompletedAmount: 0,
  64. }, nil
  65. }))
  66. g.PUT("/:id", handler("task", func(c *gin.Context) (interface{}, error) {
  67. update := models.TaskUpdate{}
  68. err := c.BindJSON(&update)
  69. if err != nil {
  70. return nil, slerrors.BadRequest("Invalid JSON")
  71. }
  72. task, err := l.FindTask(c.Request.Context(), c.Param("id"))
  73. if err != nil {
  74. return nil, err
  75. }
  76. if update.ProjectID != nil && *update.ProjectID != task.ProjectID {
  77. project, err := l.FindProject(c.Request.Context(), *update.ProjectID)
  78. if err != nil {
  79. return nil, slerrors.NotFound("Destination project")
  80. }
  81. // Delete any links that would have been ran over.
  82. err = db.Tasks().DeleteLink(c.Request.Context(), models.TaskLink{
  83. TaskID: task.ID,
  84. ProjectID: project.ID,
  85. })
  86. if err != nil {
  87. return nil, slerrors.BadRequest(err.Error())
  88. }
  89. task.ProjectID = project.ID
  90. }
  91. task.Update(update)
  92. if task.EndTime != nil && task.EndTime.Before(task.CreatedTime) {
  93. return nil, slerrors.BadRequest("Task end time must be later than it was created.")
  94. }
  95. if task.ItemAmount <= 0 {
  96. return nil, slerrors.BadRequest("Item amount cannot be zero or negative.")
  97. }
  98. err = db.Tasks().Update(c.Request.Context(), task.Task)
  99. if err != nil {
  100. return nil, err
  101. }
  102. return task, nil
  103. }))
  104. g.PUT("/:id/link/:project_id", handler("taskLink", func(c *gin.Context) (interface{}, error) {
  105. task, err := l.FindTask(c.Request.Context(), c.Param("id"))
  106. if err != nil {
  107. return nil, err
  108. }
  109. project, err := l.FindProject(c.Request.Context(), c.Param("project_id"))
  110. if err != nil {
  111. return nil, err
  112. }
  113. if task.ProjectID == project.ID {
  114. return nil, slerrors.BadRequest("You cannot link a task within its own project")
  115. }
  116. err = db.Tasks().CreateLink(c.Request.Context(), models.TaskLink{
  117. TaskID: task.ID,
  118. ProjectID: project.ID,
  119. })
  120. return &models.TaskLink{
  121. TaskID: task.ID,
  122. ProjectID: project.ID,
  123. }, nil
  124. }))
  125. g.DELETE("/:id/link/:project_id", handler("taskLink", func(c *gin.Context) (interface{}, error) {
  126. task, err := l.FindTask(c.Request.Context(), c.Param("id"))
  127. if err != nil {
  128. return nil, err
  129. }
  130. project, err := l.FindProject(c.Request.Context(), c.Param("project_id"))
  131. if err != nil {
  132. return nil, err
  133. }
  134. err = db.Tasks().DeleteLink(c.Request.Context(), models.TaskLink{
  135. TaskID: task.ID,
  136. ProjectID: project.ID,
  137. })
  138. if err != nil {
  139. return nil, err
  140. }
  141. return &models.TaskLink{
  142. TaskID: task.ID,
  143. ProjectID: project.ID,
  144. }, nil
  145. }))
  146. g.DELETE("/:id", handler("task", func(c *gin.Context) (interface{}, error) {
  147. task, err := l.FindTask(c.Request.Context(), c.Param("id"))
  148. if err != nil {
  149. return nil, err
  150. }
  151. if len(task.Logs) > 0 {
  152. return nil, slerrors.Forbidden("cannot delete tasks with logs.")
  153. }
  154. err = db.Tasks().Delete(c.Request.Context(), task.Task)
  155. if err != nil {
  156. return nil, err
  157. }
  158. return task, nil
  159. }))
  160. }