@@ -14,27 +14,24 @@ import (
1414
1515// LoadProject load the project the issue was assigned to
1616func (issue * Issue ) LoadProject (ctx context.Context ) (err error ) {
17- if issue .Project == nil {
18- var p project_model.Project
19- has , err := db .GetEngine (ctx ).Table ("project" ).
17+ if issue .Projects == nil {
18+ err = db .GetEngine (ctx ).Table ("project" ).
2019 Join ("INNER" , "project_issue" , "project.id=project_issue.project_id" ).
21- Where ("project_issue.issue_id = ?" , issue .ID ).Get (& p )
22- if err != nil {
23- return err
24- } else if has {
25- issue .Project = & p
26- }
20+ Where ("project_issue.issue_id = ?" , issue .ID ).OrderBy ("title" ).
21+ Find (& issue .Projects )
2722 }
2823 return err
2924}
3025
31- func (issue * Issue ) projectID (ctx context.Context ) int64 {
32- var ip project_model.ProjectIssue
33- has , err := db .GetEngine (ctx ).Where ("issue_id=?" , issue .ID ).Get (& ip )
34- if err != nil || ! has {
35- return 0
26+
27+ func (issue * Issue ) projectIDs (ctx context.Context ) []int64 {
28+ var ips []int64
29+ if err := db .GetEngine (ctx ).Table ("project_issue" ).Select ("project_id" ).
30+ Where ("issue_id=?" , issue .ID ).Find (& ips ); err != nil {
31+ return nil
3632 }
37- return ip .ProjectID
33+
34+ return ips
3835}
3936
4037// ProjectBoardID return project board id if issue was assigned to one
@@ -96,57 +93,101 @@ func LoadIssuesFromBoardList(ctx context.Context, bs project_model.BoardList) (m
9693}
9794
9895// ChangeProjectAssign changes the project associated with an issue
99- func ChangeProjectAssign (ctx context.Context , issue * Issue , doer * user_model.User , newProjectID int64 ) error {
96+ func ChangeProjectAssign (ctx context.Context , issue * Issue , doer * user_model.User , newProjectID int64 , action string ) error {
10097 ctx , committer , err := db .TxContext (ctx )
10198 if err != nil {
10299 return err
103100 }
104101 defer committer .Close ()
105102
106- if err := addUpdateIssueProject (ctx , issue , doer , newProjectID ); err != nil {
103+ if err := addUpdateIssueProject (ctx , issue , doer , newProjectID , action ); err != nil {
107104 return err
108105 }
109106
110107 return committer .Commit ()
111108}
112109
113- func addUpdateIssueProject (ctx context.Context , issue * Issue , doer * user_model.User , newProjectID int64 ) error {
114- oldProjectID := issue .projectID (ctx )
115-
110+ func addUpdateIssueProject (ctx context.Context , issue * Issue , doer * user_model.User , newProjectID int64 , action string ) error {
116111 if err := issue .LoadRepo (ctx ); err != nil {
117112 return err
118113 }
119114
120- // Only check if we add a new project and not remove it.
121- if newProjectID > 0 {
122- newProject , err := project_model .GetProjectByID (ctx , newProjectID )
123- if err != nil {
124- return err
115+ oldProjectIDs := issue .projectIDs (ctx )
116+
117+ if len (oldProjectIDs ) > 0 {
118+ for _ , i := range oldProjectIDs {
119+ // Only check if we add a new project and not remove it.
120+ if newProjectID > 0 {
121+ newProject , err := project_model .GetProjectByID (ctx , newProjectID )
122+ if err != nil {
123+ return err
124+ }
125+ if newProject .RepoID != issue .RepoID && newProject .OwnerID != issue .Repo .OwnerID {
126+ return fmt .Errorf ("issue's repository is not the same as project's repository" )
127+ }
128+ }
129+
130+ if action == "attach" && newProjectID > 0 {
131+ if err := db .Insert (ctx , & project_model.ProjectIssue {
132+ IssueID : issue .ID ,
133+ ProjectID : newProjectID ,
134+ }); err != nil {
135+ return err
136+ }
137+ i = 0
138+ } else {
139+ if action == "clear" {
140+ if _ , err := db .GetEngine (ctx ).Where ("project_issue.issue_id=?" , issue .ID ).Delete (& project_model.ProjectIssue {}); err != nil {
141+ return err
142+ }
143+ } else {
144+ i = newProjectID
145+ newProjectID = 0
146+ if _ , err := db .GetEngine (ctx ).Where ("project_issue.issue_id=? AND project_issue.project_id=?" , issue .ID , i ).Delete (& project_model.ProjectIssue {}); err != nil {
147+ return err
148+ }
149+ }
150+ }
151+
152+ if i > 0 || newProjectID > 0 {
153+ if _ , err := CreateComment (ctx , & CreateCommentOptions {
154+ Type : CommentTypeProject ,
155+ Doer : doer ,
156+ Repo : issue .Repo ,
157+ Issue : issue ,
158+ OldProjectID : i ,
159+ ProjectID : newProjectID ,
160+ }); err != nil {
161+ return err
162+ }
163+ }
164+ if action != "clear" && newProjectID == 0 || newProjectID > 0 {
165+ break
166+ }
125167 }
126- if newProject .RepoID != issue .RepoID && newProject .OwnerID != issue .Repo .OwnerID {
127- return fmt .Errorf ("issue's repository is not the same as project's repository" )
168+ } else {
169+ if action == "attach" || action == "" {
170+ if err := db .Insert (ctx , & project_model.ProjectIssue {
171+ IssueID : issue .ID ,
172+ ProjectID : newProjectID ,
173+ }); err != nil {
174+ return err
175+ }
128176 }
129- }
130-
131- if _ , err := db .GetEngine (ctx ).Where ("project_issue.issue_id=?" , issue .ID ).Delete (& project_model.ProjectIssue {}); err != nil {
132- return err
133- }
134177
135- if oldProjectID > 0 || newProjectID > 0 {
136- if _ , err := CreateComment (ctx , & CreateCommentOptions {
137- Type : CommentTypeProject ,
138- Doer : doer ,
139- Repo : issue .Repo ,
140- Issue : issue ,
141- OldProjectID : oldProjectID ,
142- ProjectID : newProjectID ,
143- }); err != nil {
144- return err
178+ if newProjectID > 0 {
179+ if _ , err := CreateComment (ctx , & CreateCommentOptions {
180+ Type : CommentTypeProject ,
181+ Doer : doer ,
182+ Repo : issue .Repo ,
183+ Issue : issue ,
184+ OldProjectID : 0 ,
185+ ProjectID : newProjectID ,
186+ }); err != nil {
187+ return err
188+ }
145189 }
146190 }
147191
148- return db .Insert (ctx , & project_model.ProjectIssue {
149- IssueID : issue .ID ,
150- ProjectID : newProjectID ,
151- })
192+ return nil
152193}
0 commit comments