@@ -14,27 +14,24 @@ import (
14
14
15
15
// LoadProject load the project the issue was assigned to
16
16
func (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" ).
20
19
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 )
27
22
}
28
23
return err
29
24
}
30
25
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
36
32
}
37
- return ip .ProjectID
33
+
34
+ return ips
38
35
}
39
36
40
37
// 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
96
93
}
97
94
98
95
// 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 {
100
97
ctx , committer , err := db .TxContext (ctx )
101
98
if err != nil {
102
99
return err
103
100
}
104
101
defer committer .Close ()
105
102
106
- if err := addUpdateIssueProject (ctx , issue , doer , newProjectID ); err != nil {
103
+ if err := addUpdateIssueProject (ctx , issue , doer , newProjectID , action ); err != nil {
107
104
return err
108
105
}
109
106
110
107
return committer .Commit ()
111
108
}
112
109
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 {
116
111
if err := issue .LoadRepo (ctx ); err != nil {
117
112
return err
118
113
}
119
114
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
+ }
125
167
}
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
+ }
128
176
}
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
- }
134
177
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
+ }
145
189
}
146
190
}
147
191
148
- return db .Insert (ctx , & project_model.ProjectIssue {
149
- IssueID : issue .ID ,
150
- ProjectID : newProjectID ,
151
- })
192
+ return nil
152
193
}
0 commit comments