mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 12:26:05 +01:00 
			
		
		
		
	Move issue change status from models to service (#8691)
This commit is contained in:
		@@ -674,45 +674,6 @@ func (issue *Issue) ChangeStatus(doer *User, isClosed bool) (err error) {
 | 
				
			|||||||
	if err = sess.Commit(); err != nil {
 | 
						if err = sess.Commit(); err != nil {
 | 
				
			||||||
		return fmt.Errorf("Commit: %v", err)
 | 
							return fmt.Errorf("Commit: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	sess.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mode, _ := AccessLevel(issue.Poster, issue.Repo)
 | 
					 | 
				
			||||||
	if issue.IsPull {
 | 
					 | 
				
			||||||
		if err = issue.loadPullRequest(sess); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// Merge pull request calls issue.changeStatus so we need to handle separately.
 | 
					 | 
				
			||||||
		apiPullRequest := &api.PullRequestPayload{
 | 
					 | 
				
			||||||
			Index:       issue.Index,
 | 
					 | 
				
			||||||
			PullRequest: issue.PullRequest.APIFormat(),
 | 
					 | 
				
			||||||
			Repository:  issue.Repo.APIFormat(mode),
 | 
					 | 
				
			||||||
			Sender:      doer.APIFormat(),
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if isClosed {
 | 
					 | 
				
			||||||
			apiPullRequest.Action = api.HookIssueClosed
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			apiPullRequest.Action = api.HookIssueReOpened
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		err = PrepareWebhooks(issue.Repo, HookEventPullRequest, apiPullRequest)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		apiIssue := &api.IssuePayload{
 | 
					 | 
				
			||||||
			Index:      issue.Index,
 | 
					 | 
				
			||||||
			Issue:      issue.APIFormat(),
 | 
					 | 
				
			||||||
			Repository: issue.Repo.APIFormat(mode),
 | 
					 | 
				
			||||||
			Sender:     doer.APIFormat(),
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if isClosed {
 | 
					 | 
				
			||||||
			apiIssue.Action = api.HookIssueClosed
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			apiIssue.Action = api.HookIssueReOpened
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		err = PrepareWebhooks(issue.Repo, HookEventIssues, apiIssue)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Error("PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		go HookQueue.Add(issue.Repo.ID)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -157,7 +157,6 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *models.User, issue *mo
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		mode, _ := models.AccessLevelUnit(doer, issue.Repo, models.UnitTypeIssues)
 | 
							mode, _ := models.AccessLevelUnit(doer, issue.Repo, models.UnitTypeIssues)
 | 
				
			||||||
 | 
					 | 
				
			||||||
		apiIssue := &api.IssuePayload{
 | 
							apiIssue := &api.IssuePayload{
 | 
				
			||||||
			Index:      issue.Index,
 | 
								Index:      issue.Index,
 | 
				
			||||||
			Issue:      issue.APIFormat(),
 | 
								Issue:      issue.APIFormat(),
 | 
				
			||||||
@@ -221,3 +220,45 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(doer *models.User, issue *model
 | 
				
			|||||||
		go models.HookQueue.Add(issue.RepoID)
 | 
							go models.HookQueue.Add(issue.RepoID)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *webhookNotifier) NotifyIssueChangeStatus(doer *models.User, issue *models.Issue, isClosed bool) {
 | 
				
			||||||
 | 
						mode, _ := models.AccessLevel(issue.Poster, issue.Repo)
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						if issue.IsPull {
 | 
				
			||||||
 | 
							if err = issue.LoadPullRequest(); err != nil {
 | 
				
			||||||
 | 
								log.Error("LoadPullRequest: %v", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Merge pull request calls issue.changeStatus so we need to handle separately.
 | 
				
			||||||
 | 
							apiPullRequest := &api.PullRequestPayload{
 | 
				
			||||||
 | 
								Index:       issue.Index,
 | 
				
			||||||
 | 
								PullRequest: issue.PullRequest.APIFormat(),
 | 
				
			||||||
 | 
								Repository:  issue.Repo.APIFormat(mode),
 | 
				
			||||||
 | 
								Sender:      doer.APIFormat(),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if isClosed {
 | 
				
			||||||
 | 
								apiPullRequest.Action = api.HookIssueClosed
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								apiPullRequest.Action = api.HookIssueReOpened
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err = models.PrepareWebhooks(issue.Repo, models.HookEventPullRequest, apiPullRequest)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							apiIssue := &api.IssuePayload{
 | 
				
			||||||
 | 
								Index:      issue.Index,
 | 
				
			||||||
 | 
								Issue:      issue.APIFormat(),
 | 
				
			||||||
 | 
								Repository: issue.Repo.APIFormat(mode),
 | 
				
			||||||
 | 
								Sender:     doer.APIFormat(),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if isClosed {
 | 
				
			||||||
 | 
								apiIssue.Action = api.HookIssueClosed
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								apiIssue.Action = api.HookIssueReOpened
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err = models.PrepareWebhooks(issue.Repo, models.HookEventIssues, apiIssue)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Error("PrepareWebhooks [is_pull: %v, is_closed: %v]: %v", issue.IsPull, isClosed, err)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							go models.HookQueue.Add(issue.Repo.ID)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -254,7 +254,7 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
 | 
				
			|||||||
	notification.NotifyNewIssue(issue)
 | 
						notification.NotifyNewIssue(issue)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if form.Closed {
 | 
						if form.Closed {
 | 
				
			||||||
		if err := issue.ChangeStatus(ctx.User, true); err != nil {
 | 
							if err := issue_service.ChangeStatus(issue, ctx.User, true); err != nil {
 | 
				
			||||||
			if models.IsErrDependenciesLeft(err) {
 | 
								if models.IsErrDependenciesLeft(err) {
 | 
				
			||||||
				ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies")
 | 
									ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies")
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
@@ -381,7 +381,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if form.State != nil {
 | 
						if form.State != nil {
 | 
				
			||||||
		if err = issue.ChangeStatus(ctx.User, api.StateClosed == api.StateType(*form.State)); err != nil {
 | 
							if err = issue_service.ChangeStatus(issue, ctx.User, api.StateClosed == api.StateType(*form.State)); err != nil {
 | 
				
			||||||
			if models.IsErrDependenciesLeft(err) {
 | 
								if models.IsErrDependenciesLeft(err) {
 | 
				
			||||||
				ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies")
 | 
									ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies")
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
@@ -389,8 +389,6 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
 | 
				
			|||||||
			ctx.Error(500, "ChangeStatus", err)
 | 
								ctx.Error(500, "ChangeStatus", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		notification.NotifyIssueChangeStatus(ctx.User, issue, api.StateClosed == api.StateType(*form.State))
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Refetch from database to assign some automatic values
 | 
						// Refetch from database to assign some automatic values
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -448,7 +448,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if form.State != nil {
 | 
						if form.State != nil {
 | 
				
			||||||
		if err = issue.ChangeStatus(ctx.User, api.StateClosed == api.StateType(*form.State)); err != nil {
 | 
							if err = issue_service.ChangeStatus(issue, ctx.User, api.StateClosed == api.StateType(*form.State)); err != nil {
 | 
				
			||||||
			if models.IsErrDependenciesLeft(err) {
 | 
								if models.IsErrDependenciesLeft(err) {
 | 
				
			||||||
				ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this pull request because it still has open dependencies")
 | 
									ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this pull request because it still has open dependencies")
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
@@ -456,8 +456,6 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
 | 
				
			|||||||
			ctx.Error(500, "ChangeStatus", err)
 | 
								ctx.Error(500, "ChangeStatus", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		notification.NotifyIssueChangeStatus(ctx.User, issue, api.StateClosed == api.StateType(*form.State))
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Refetch from database
 | 
						// Refetch from database
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1185,7 +1185,7 @@ func UpdateIssueStatus(ctx *context.Context) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	for _, issue := range issues {
 | 
						for _, issue := range issues {
 | 
				
			||||||
		if issue.IsClosed != isClosed {
 | 
							if issue.IsClosed != isClosed {
 | 
				
			||||||
			if err := issue.ChangeStatus(ctx.User, isClosed); err != nil {
 | 
								if err := issue_service.ChangeStatus(issue, ctx.User, isClosed); err != nil {
 | 
				
			||||||
				if models.IsErrDependenciesLeft(err) {
 | 
									if models.IsErrDependenciesLeft(err) {
 | 
				
			||||||
					ctx.JSON(http.StatusPreconditionFailed, map[string]interface{}{
 | 
										ctx.JSON(http.StatusPreconditionFailed, map[string]interface{}{
 | 
				
			||||||
						"error": "cannot close this issue because it still has open dependencies",
 | 
											"error": "cannot close this issue because it still has open dependencies",
 | 
				
			||||||
@@ -1195,8 +1195,6 @@ func UpdateIssueStatus(ctx *context.Context) {
 | 
				
			|||||||
				ctx.ServerError("ChangeStatus", err)
 | 
									ctx.ServerError("ChangeStatus", err)
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			notification.NotifyIssueChangeStatus(ctx.User, issue, isClosed)
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ctx.JSON(200, map[string]interface{}{
 | 
						ctx.JSON(200, map[string]interface{}{
 | 
				
			||||||
@@ -1286,7 +1284,7 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) {
 | 
				
			|||||||
				ctx.Flash.Info(ctx.Tr("repo.pulls.open_unmerged_pull_exists", pr.Index))
 | 
									ctx.Flash.Info(ctx.Tr("repo.pulls.open_unmerged_pull_exists", pr.Index))
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				isClosed := form.Status == "close"
 | 
									isClosed := form.Status == "close"
 | 
				
			||||||
				if err := issue.ChangeStatus(ctx.User, isClosed); err != nil {
 | 
									if err := issue_service.ChangeStatus(issue, ctx.User, isClosed); err != nil {
 | 
				
			||||||
					log.Error("ChangeStatus: %v", err)
 | 
										log.Error("ChangeStatus: %v", err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if models.IsErrDependenciesLeft(err) {
 | 
										if models.IsErrDependenciesLeft(err) {
 | 
				
			||||||
@@ -1300,15 +1298,12 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) {
 | 
				
			|||||||
						return
 | 
											return
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
 | 
					 | 
				
			||||||
					if err := stopTimerIfAvailable(ctx.User, issue); err != nil {
 | 
										if err := stopTimerIfAvailable(ctx.User, issue); err != nil {
 | 
				
			||||||
						ctx.ServerError("CreateOrStopIssueStopwatch", err)
 | 
											ctx.ServerError("CreateOrStopIssueStopwatch", err)
 | 
				
			||||||
						return
 | 
											return
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					log.Trace("Issue [%d] status changed to closed: %v", issue.ID, issue.IsClosed)
 | 
										log.Trace("Issue [%d] status changed to closed: %v", issue.ID, issue.IsClosed)
 | 
				
			||||||
 | 
					 | 
				
			||||||
					notification.NotifyIssueChangeStatus(ctx.User, issue, isClosed)
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								services/issue/status.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								services/issue/status.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					// Copyright 2019 The Gitea Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package issue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/notification"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ChangeStatus changes issue status to open or closed.
 | 
				
			||||||
 | 
					func ChangeStatus(issue *models.Issue, doer *models.User, isClosed bool) (err error) {
 | 
				
			||||||
 | 
						err = issue.ChangeStatus(doer, isClosed)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						notification.NotifyIssueChangeStatus(doer, issue, isClosed)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user