Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

issue_project.go 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package issues
  4. import (
  5. "context"
  6. "fmt"
  7. "code.gitea.io/gitea/models/db"
  8. project_model "code.gitea.io/gitea/models/project"
  9. user_model "code.gitea.io/gitea/models/user"
  10. )
  11. // LoadProject load the project the issue was assigned to
  12. func (issue *Issue) LoadProject(ctx context.Context) (err error) {
  13. if issue.Project == nil {
  14. var p project_model.Project
  15. has, err := db.GetEngine(ctx).Table("project").
  16. Join("INNER", "project_issue", "project.id=project_issue.project_id").
  17. Where("project_issue.issue_id = ?", issue.ID).Get(&p)
  18. if err != nil {
  19. return err
  20. } else if has {
  21. issue.Project = &p
  22. }
  23. }
  24. return err
  25. }
  26. func (issue *Issue) LoadProjectIssue(ctx context.Context) (err error) {
  27. if issue.Project == nil {
  28. return nil
  29. }
  30. if issue.ProjectIssue != nil {
  31. return nil
  32. }
  33. issue.ProjectIssue, err = project_model.GetProjectIssueByIssueID(ctx, issue.ID)
  34. if err != nil {
  35. return err
  36. }
  37. return issue.ProjectIssue.LoadProjectBoard(ctx)
  38. }
  39. func (issue *Issue) projectID(ctx context.Context) int64 {
  40. var ip project_model.ProjectIssue
  41. has, err := db.GetEngine(ctx).Where("issue_id=?", issue.ID).Get(&ip)
  42. if err != nil || !has {
  43. return 0
  44. }
  45. return ip.ProjectID
  46. }
  47. // ProjectBoardID return project board id if issue was assigned to one
  48. func (issue *Issue) ProjectBoardID(ctx context.Context) int64 {
  49. var ip project_model.ProjectIssue
  50. has, err := db.GetEngine(ctx).Where("issue_id=?", issue.ID).Get(&ip)
  51. if err != nil || !has {
  52. return 0
  53. }
  54. return ip.ProjectBoardID
  55. }
  56. // LoadIssuesFromBoard load issues assigned to this board
  57. func LoadIssuesFromBoard(ctx context.Context, b *project_model.Board) (IssueList, error) {
  58. issueList, err := Issues(ctx, &IssuesOptions{
  59. ProjectBoardID: b.ID,
  60. ProjectID: b.ProjectID,
  61. SortType: "project-column-sorting",
  62. })
  63. if err != nil {
  64. return nil, err
  65. }
  66. if b.Default {
  67. issues, err := Issues(ctx, &IssuesOptions{
  68. ProjectBoardID: db.NoConditionID,
  69. ProjectID: b.ProjectID,
  70. SortType: "project-column-sorting",
  71. })
  72. if err != nil {
  73. return nil, err
  74. }
  75. issueList = append(issueList, issues...)
  76. }
  77. if err := issueList.LoadComments(ctx); err != nil {
  78. return nil, err
  79. }
  80. return issueList, nil
  81. }
  82. // LoadIssuesFromBoardList load issues assigned to the boards
  83. func LoadIssuesFromBoardList(ctx context.Context, bs project_model.BoardList) (map[int64]IssueList, error) {
  84. issuesMap := make(map[int64]IssueList, len(bs))
  85. for i := range bs {
  86. il, err := LoadIssuesFromBoard(ctx, bs[i])
  87. if err != nil {
  88. return nil, err
  89. }
  90. issuesMap[bs[i].ID] = il
  91. }
  92. return issuesMap, nil
  93. }
  94. // ChangeProjectAssign changes the project associated with an issue
  95. func ChangeProjectAssign(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID int64) error {
  96. ctx, committer, err := db.TxContext(ctx)
  97. if err != nil {
  98. return err
  99. }
  100. defer committer.Close()
  101. if err := addUpdateIssueProject(ctx, issue, doer, newProjectID); err != nil {
  102. return err
  103. }
  104. return committer.Commit()
  105. }
  106. func addUpdateIssueProject(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID int64) error {
  107. oldProjectID := issue.projectID(ctx)
  108. newBoardID := int64(0)
  109. if err := issue.LoadRepo(ctx); err != nil {
  110. return err
  111. }
  112. // Only check if we add a new project and not remove it.
  113. if newProjectID > 0 {
  114. newProject, err := project_model.GetProjectByID(ctx, newProjectID)
  115. if err != nil {
  116. return err
  117. }
  118. if newProject.RepoID != issue.RepoID && newProject.OwnerID != issue.Repo.OwnerID {
  119. return fmt.Errorf("issue's repository is not the same as project's repository")
  120. }
  121. newBoard, err := newProject.GetDefaultBoard(ctx)
  122. if err != nil {
  123. return err
  124. }
  125. newBoardID = newBoard.ID
  126. }
  127. if _, err := db.GetEngine(ctx).Where("project_issue.issue_id=?", issue.ID).Delete(&project_model.ProjectIssue{}); err != nil {
  128. return err
  129. }
  130. if oldProjectID > 0 || newProjectID > 0 {
  131. if _, err := CreateComment(ctx, &CreateCommentOptions{
  132. Type: CommentTypeProject,
  133. Doer: doer,
  134. Repo: issue.Repo,
  135. Issue: issue,
  136. OldProjectID: oldProjectID,
  137. ProjectID: newProjectID,
  138. }); err != nil {
  139. return err
  140. }
  141. }
  142. return db.Insert(ctx, &project_model.ProjectIssue{
  143. IssueID: issue.ID,
  144. ProjectID: newProjectID,
  145. ProjectBoardID: newBoardID,
  146. })
  147. }