mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-06-24 10:00:50 +00:00
Mail assignee when issue/pull request is assigned (#8546)
* Send email to assigned user * Only send mail if enabled * Mail also when assigned through API * Need to refactor functions from models to issue service * Refer to issue index rather than ID * Disable email notifications completly at initalization if global disable * Check of user enbled mail shall be in mail notification function only * Initialize notifications from routers init function. * Use the assigned comment when sending assigned mail * Refactor so that assignees always added as separate step when new issue/pr. * Check error from AddAssignees * Check if user can be assiged to issue or pull request * Missing return * Refactor of CanBeAssigned check. CanBeAssigned shall have same check as UI. * Clarify function names (toggle rather than update/change), and clean up. * Fix review comments. * Flash error if assignees was not added when creating issue/pr * Generate error if assignee users doesn't exist
This commit is contained in:
parent
c34e58fc00
commit
6aa3f8bc29
23 changed files with 333 additions and 216 deletions
|
@ -896,7 +896,6 @@ type NewIssueOptions struct {
|
|||
Repo *Repository
|
||||
Issue *Issue
|
||||
LabelIDs []int64
|
||||
AssigneeIDs []int64
|
||||
Attachments []string // In UUID format.
|
||||
IsPull bool
|
||||
}
|
||||
|
@ -918,40 +917,7 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Keep the old assignee id thingy for compatibility reasons
|
||||
if opts.Issue.AssigneeID > 0 {
|
||||
isAdded := false
|
||||
// Check if the user has already been passed to issue.AssigneeIDs, if not, add it
|
||||
for _, aID := range opts.AssigneeIDs {
|
||||
if aID == opts.Issue.AssigneeID {
|
||||
isAdded = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isAdded {
|
||||
opts.AssigneeIDs = append(opts.AssigneeIDs, opts.Issue.AssigneeID)
|
||||
}
|
||||
}
|
||||
|
||||
// Check for and validate assignees
|
||||
if len(opts.AssigneeIDs) > 0 {
|
||||
for _, assigneeID := range opts.AssigneeIDs {
|
||||
user, err := getUserByID(e, assigneeID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getUserByID [user_id: %d, repo_id: %d]: %v", assigneeID, opts.Repo.ID, err)
|
||||
}
|
||||
valid, err := canBeAssigned(e, user, opts.Repo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("canBeAssigned [user_id: %d, repo_id: %d]: %v", assigneeID, opts.Repo.ID, err)
|
||||
}
|
||||
if !valid {
|
||||
return ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: opts.Repo.Name}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Milestone and assignee validation should happen before insert actual object.
|
||||
// Milestone validation should happen before insert actual object.
|
||||
if _, err := e.SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
|
||||
Where("repo_id=?", opts.Issue.RepoID).
|
||||
Insert(opts.Issue); err != nil {
|
||||
|
@ -976,14 +942,6 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Insert the assignees
|
||||
for _, assigneeID := range opts.AssigneeIDs {
|
||||
err = opts.Issue.changeAssignee(e, doer, assigneeID, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if opts.IsPull {
|
||||
_, err = e.Exec("UPDATE `repository` SET num_pulls = num_pulls + 1 WHERE id = ?", opts.Issue.RepoID)
|
||||
} else {
|
||||
|
@ -1041,11 +999,11 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
|
|||
}
|
||||
|
||||
// NewIssue creates new issue with labels for repository.
|
||||
func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []int64, uuids []string) (err error) {
|
||||
func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
|
||||
// Retry several times in case INSERT fails due to duplicate key for (repo_id, index); see #7887
|
||||
i := 0
|
||||
for {
|
||||
if err = newIssueAttempt(repo, issue, labelIDs, assigneeIDs, uuids); err == nil {
|
||||
if err = newIssueAttempt(repo, issue, labelIDs, uuids); err == nil {
|
||||
return nil
|
||||
}
|
||||
if !IsErrNewIssueInsert(err) {
|
||||
|
@ -1059,7 +1017,7 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []in
|
|||
return fmt.Errorf("NewIssue: too many errors attempting to insert the new issue. Last error was: %v", err)
|
||||
}
|
||||
|
||||
func newIssueAttempt(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []int64, uuids []string) (err error) {
|
||||
func newIssueAttempt(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
|
@ -1071,7 +1029,6 @@ func newIssueAttempt(repo *Repository, issue *Issue, labelIDs []int64, assigneeI
|
|||
Issue: issue,
|
||||
LabelIDs: labelIDs,
|
||||
Attachments: uuids,
|
||||
AssigneeIDs: assigneeIDs,
|
||||
}); err != nil {
|
||||
if IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) {
|
||||
return err
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue