2022-03-29 22:16:31 +08:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2022-11-27 13:20:29 -05:00
// SPDX-License-Identifier: MIT
2022-03-29 22:16:31 +08:00
package project
import (
"context"
"fmt"
"code.gitea.io/gitea/models/db"
2022-06-16 04:51:34 +02:00
"code.gitea.io/gitea/modules/log"
2022-03-29 22:16:31 +08:00
)
// ProjectIssue saves relation from issue to a project
type ProjectIssue struct { //revive:disable-line:exported
ID int64 ` xorm:"pk autoincr" `
IssueID int64 ` xorm:"INDEX" `
ProjectID int64 ` xorm:"INDEX" `
// If 0, then it has not been added to a specific board in the project
ProjectBoardID int64 ` xorm:"INDEX" `
2022-05-06 22:25:59 +08:00
// the sorting order on the board
Sorting int64 ` xorm:"NOT NULL DEFAULT 0" `
2022-03-29 22:16:31 +08:00
}
func init ( ) {
db . RegisterModel ( new ( ProjectIssue ) )
}
2022-05-20 22:08:52 +08:00
func deleteProjectIssuesByProjectID ( ctx context . Context , projectID int64 ) error {
_ , err := db . GetEngine ( ctx ) . Where ( "project_id=?" , projectID ) . Delete ( & ProjectIssue { } )
2022-03-29 22:16:31 +08:00
return err
}
// NumIssues return counter of all issues assigned to a project
2023-09-29 14:12:54 +02:00
func ( p * Project ) NumIssues ( ctx context . Context ) int {
c , err := db . GetEngine ( ctx ) . Table ( "project_issue" ) .
2022-03-29 22:16:31 +08:00
Where ( "project_id=?" , p . ID ) .
GroupBy ( "issue_id" ) .
Cols ( "issue_id" ) .
Count ( )
if err != nil {
2022-06-16 04:51:34 +02:00
log . Error ( "NumIssues: %v" , err )
2022-03-29 22:16:31 +08:00
return 0
}
return int ( c )
}
// NumClosedIssues return counter of closed issues assigned to a project
2023-09-29 14:12:54 +02:00
func ( p * Project ) NumClosedIssues ( ctx context . Context ) int {
c , err := db . GetEngine ( ctx ) . Table ( "project_issue" ) .
2022-03-29 22:16:31 +08:00
Join ( "INNER" , "issue" , "project_issue.issue_id=issue.id" ) .
Where ( "project_issue.project_id=? AND issue.is_closed=?" , p . ID , true ) .
Cols ( "issue_id" ) .
Count ( )
if err != nil {
2022-06-16 04:51:34 +02:00
log . Error ( "NumClosedIssues: %v" , err )
2022-03-29 22:16:31 +08:00
return 0
}
return int ( c )
}
// NumOpenIssues return counter of open issues assigned to a project
2023-09-29 14:12:54 +02:00
func ( p * Project ) NumOpenIssues ( ctx context . Context ) int {
c , err := db . GetEngine ( ctx ) . Table ( "project_issue" ) .
2022-03-29 22:16:31 +08:00
Join ( "INNER" , "issue" , "project_issue.issue_id=issue.id" ) .
2022-06-16 04:51:34 +02:00
Where ( "project_issue.project_id=? AND issue.is_closed=?" , p . ID , false ) .
Cols ( "issue_id" ) .
Count ( )
2022-03-29 22:16:31 +08:00
if err != nil {
2022-06-16 04:51:34 +02:00
log . Error ( "NumOpenIssues: %v" , err )
2022-03-29 22:16:31 +08:00
return 0
}
return int ( c )
}
// MoveIssuesOnProjectBoard moves or keeps issues in a column and sorts them inside that column
2023-09-29 14:12:54 +02:00
func MoveIssuesOnProjectBoard ( ctx context . Context , board * Board , sortedIssueIDs map [ int64 ] int64 ) error {
return db . WithTx ( ctx , func ( ctx context . Context ) error {
2022-03-29 22:16:31 +08:00
sess := db . GetEngine ( ctx )
issueIDs := make ( [ ] int64 , 0 , len ( sortedIssueIDs ) )
for _ , issueID := range sortedIssueIDs {
issueIDs = append ( issueIDs , issueID )
}
count , err := sess . Table ( new ( ProjectIssue ) ) . Where ( "project_id=?" , board . ProjectID ) . In ( "issue_id" , issueIDs ) . Count ( )
if err != nil {
return err
}
if int ( count ) != len ( sortedIssueIDs ) {
return fmt . Errorf ( "all issues have to be added to a project first" )
}
for sorting , issueID := range sortedIssueIDs {
_ , err = sess . Exec ( "UPDATE `project_issue` SET project_board_id=?, sorting=? WHERE issue_id=?" , board . ID , sorting , issueID )
if err != nil {
return err
}
}
return nil
} )
}
2022-06-20 12:02:49 +02:00
func ( b * Board ) removeIssues ( ctx context . Context ) error {
_ , err := db . GetEngine ( ctx ) . Exec ( "UPDATE `project_issue` SET project_board_id = 0 WHERE project_board_id = ? " , b . ID )
2022-03-29 22:16:31 +08:00
return err
}