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.

119 lines
3.2 KiB

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 Project(g *gin.RouterGroup, db database.Database) {
  13. l := services.Loader{DB: db}
  14. g.GET("/", handler("projects", func(c *gin.Context) (interface{}, error) {
  15. filter := models.ProjectFilter{}
  16. if setting := c.Query("active"); setting != "" {
  17. active := setting == "true"
  18. filter.Active = &active
  19. }
  20. if setting := c.Query("include-semi-active"); setting != "" {
  21. filter.IncludeSemiActive = setting == "true"
  22. }
  23. if setting := c.Query("expiring"); setting != "" {
  24. filter.Expiring = setting == "true"
  25. }
  26. if setting := c.Query("favorite"); setting != "" {
  27. favorite := setting == "true"
  28. filter.Favorite = &favorite
  29. }
  30. return l.ListProjects(c, filter)
  31. }))
  32. g.GET("/:id", handler("project", func(c *gin.Context) (interface{}, error) {
  33. return l.FindProject(c, c.Param("id"))
  34. }))
  35. g.POST("/", handler("project", func(c *gin.Context) (interface{}, error) {
  36. project := models.Project{}
  37. err := c.BindJSON(&project)
  38. if err != nil {
  39. return nil, slerrors.BadRequest("Invalid JSON")
  40. }
  41. if project.EndTime != nil && project.EndTime.Before(time.Now()) {
  42. return nil, slerrors.BadRequest("Project end time must be later than current time.")
  43. }
  44. if project.StartTime != nil && (project.EndTime == nil || !project.StartTime.Before(*project.EndTime)) {
  45. return nil, slerrors.BadRequest("Project start time must be before end time.")
  46. }
  47. project.ID = generate.ProjectID()
  48. project.UserID = auth.UserID(c)
  49. project.CreatedTime = time.Now().UTC()
  50. err = db.Projects().Insert(c.Request.Context(), project)
  51. if err != nil {
  52. return nil, err
  53. }
  54. if project.Active && project.StatusTag != nil {
  55. project.StatusTag = nil
  56. }
  57. if project.SubtractAmount < 0 {
  58. project.SubtractAmount = 0
  59. }
  60. return &models.ProjectResult{
  61. Project: project,
  62. Tasks: []*models.TaskResult{},
  63. }, nil
  64. }))
  65. g.PUT("/:id", handler("project", func(c *gin.Context) (interface{}, error) {
  66. update := models.ProjectUpdate{}
  67. err := c.BindJSON(&update)
  68. if err != nil {
  69. return nil, slerrors.BadRequest("Invalid JSON")
  70. }
  71. project, err := l.FindProject(c.Request.Context(), c.Param("id"))
  72. if err != nil {
  73. return nil, err
  74. }
  75. project.Update(update)
  76. if project.StartTime != nil && (project.EndTime == nil || !project.StartTime.Before(*project.EndTime)) {
  77. return nil, slerrors.BadRequest("Project start time must be before end time.")
  78. }
  79. err = db.Projects().Update(c.Request.Context(), project.Project)
  80. if err != nil {
  81. return nil, err
  82. }
  83. return project, nil
  84. }))
  85. g.DELETE("/:id", handler("project", func(c *gin.Context) (interface{}, error) {
  86. project, err := l.FindProject(c.Request.Context(), c.Param("id"))
  87. if err != nil {
  88. return nil, err
  89. }
  90. if len(project.Tasks) > 0 {
  91. return nil, slerrors.Forbidden("cannot delete non-empty projects.")
  92. }
  93. err = db.Projects().Delete(c.Request.Context(), project.Project)
  94. if err != nil {
  95. return nil, err
  96. }
  97. return project, nil
  98. }))
  99. }