@@ -14,27 +14,21 @@ 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 len (issue .Projects ) == 0 {
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 ).Find (& issue .Projects )
2721 }
2822 return err
2923}
3024
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
25+ func (issue * Issue ) projectIDs (ctx context.Context ) []int64 {
26+ var ids []int64
27+ if err := db .GetEngine (ctx ).Table ("project_issue" ).Where ("issue_id=?" , issue .ID ).Cols ("project_id" ).Find (& ids ); err != nil {
28+ return nil
3629 }
37- return ip .ProjectID
30+
31+ return ids
3832}
3933
4034// ProjectColumnID return project column id if issue was assigned to one
@@ -96,17 +90,52 @@ func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column, opts *Is
9690
9791// IssueAssignOrRemoveProject changes the project associated with an issue
9892// If newProjectID is 0, the issue is removed from the project
99- func IssueAssignOrRemoveProject (ctx context.Context , issue * Issue , doer * user_model.User , newProjectID , newColumnID int64 ) error {
93+ func IssueAssignOrRemoveProject (ctx context.Context , issue * Issue , doer * user_model.User , newProjectIDs [] int64 , newColumnID int64 ) error {
10094 return db .WithTx (ctx , func (ctx context.Context ) error {
101- oldProjectID := issue .projectID (ctx )
95+ oldProjectIDs := issue .projectIDs (ctx )
10296
10397 if err := issue .LoadRepo (ctx ); err != nil {
10498 return err
10599 }
106100
107- // Only check if we add a new project and not remove it.
108- if newProjectID > 0 {
109- newProject , err := project_model .GetProjectByID (ctx , newProjectID )
101+ projectDB := db .GetEngine (ctx ).Where ("project_issue.issue_id=?" , issue .ID )
102+ newProjectIDs , oldProjectIDs := util .DiffSlice (oldProjectIDs , newProjectIDs )
103+
104+ if len (oldProjectIDs ) > 0 {
105+ if _ , err := projectDB .Where ("issue_id=?" , issue .ID ).In ("project_id" , oldProjectIDs ).Delete (& project_model.ProjectIssue {}); err != nil {
106+ return err
107+ }
108+ for _ , pID := range oldProjectIDs {
109+ if _ , err := CreateComment (ctx , & CreateCommentOptions {
110+ Type : CommentTypeProject ,
111+ Doer : doer ,
112+ Repo : issue .Repo ,
113+ Issue : issue ,
114+ OldProjectID : pID ,
115+ ProjectID : 0 ,
116+ }); err != nil {
117+ return err
118+ }
119+ }
120+ return nil
121+ }
122+
123+ res := struct {
124+ MaxSorting int64
125+ IssueCount int64
126+ }{}
127+ if _ , err := projectDB .Select ("max(sorting) as max_sorting, count(*) as issue_count" ).Table ("project_issue" ).
128+ In ("project_id" , newProjectIDs ).
129+ And ("project_board_id=?" , newColumnID ).
130+ Get (& res ); err != nil {
131+ return err
132+ }
133+ newSorting := util .Iif (res .IssueCount > 0 , res .MaxSorting + 1 , 0 )
134+
135+ pi := make ([]* project_model.ProjectIssue , 0 , len (newProjectIDs ))
136+
137+ for _ , pID := range newProjectIDs {
138+ newProject , err := project_model .GetProjectByID (ctx , pID )
110139 if err != nil {
111140 return err
112141 }
@@ -119,48 +148,34 @@ func IssueAssignOrRemoveProject(ctx context.Context, issue *Issue, doer *user_mo
119148 return err
120149 }
121150 newColumnID = newDefaultColumn .ID
151+ if newColumnID == 0 {
152+ panic ("newColumnID must not be zero" ) // shouldn't happen
153+ }
122154 }
123- }
124155
125- if _ , err := db .GetEngine (ctx ).Where ("project_issue.issue_id=?" , issue .ID ).Delete (& project_model.ProjectIssue {}); err != nil {
126- return err
127- }
156+ pi = append (pi , & project_model.ProjectIssue {
157+ IssueID : issue .ID ,
158+ ProjectID : pID ,
159+ ProjectColumnID : newColumnID ,
160+ Sorting : newSorting ,
161+ })
128162
129- if oldProjectID > 0 || newProjectID > 0 {
130163 if _ , err := CreateComment (ctx , & CreateCommentOptions {
131164 Type : CommentTypeProject ,
132165 Doer : doer ,
133166 Repo : issue .Repo ,
134167 Issue : issue ,
135- OldProjectID : oldProjectID ,
136- ProjectID : newProjectID ,
168+ OldProjectID : 0 ,
169+ ProjectID : pID ,
137170 }); err != nil {
138171 return err
139172 }
140173 }
141- if newProjectID == 0 {
142- return nil
143- }
144- if newColumnID == 0 {
145- panic ("newColumnID must not be zero" ) // shouldn't happen
146- }
147174
148- res := struct {
149- MaxSorting int64
150- IssueCount int64
151- }{}
152- if _ , err := db .GetEngine (ctx ).Select ("max(sorting) as max_sorting, count(*) as issue_count" ).Table ("project_issue" ).
153- Where ("project_id=?" , newProjectID ).
154- And ("project_board_id=?" , newColumnID ).
155- Get (& res ); err != nil {
156- return err
175+ if len (pi ) > 0 {
176+ return db .Insert (ctx , pi )
157177 }
158- newSorting := util .Iif (res .IssueCount > 0 , res .MaxSorting + 1 , 0 )
159- return db .Insert (ctx , & project_model.ProjectIssue {
160- IssueID : issue .ID ,
161- ProjectID : newProjectID ,
162- ProjectColumnID : newColumnID ,
163- Sorting : newSorting ,
164- })
178+
179+ return nil
165180 })
166181}
0 commit comments