task_service.rb 4.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
# TaskService class
#
# Used for creating tasks on task queue after certain user action
#
# Ex.
#   TaskService.new.new_issue(issue, current_user)
#
class TaskService
  # When create an issue we should:
  #
  #  * creates a pending task for assignee if issue is assigned
  #
  def new_issue(issue, current_user)
14
    new_issuable(issue, current_user)
15 16
  end

17 18 19 20 21
  # When close an issue we should:
  #
  #  * mark all pending tasks related to the target for the current user as done
  #
  def close_issue(issue, current_user)
22
    mark_pending_tasks_as_done(issue, current_user)
23 24
  end

25 26 27 28 29
  # When we reassign an issue we should:
  #
  #  * creates a pending task for new assignee if issue is assigned
  #
  def reassigned_issue(issue, current_user)
30 31 32 33 34 35 36 37 38 39 40
    reassigned_issuable(issue, current_user)
  end

  # When create a merge request we should:
  #
  #  * creates a pending task for assignee if merge request is assigned
  #
  def new_merge_request(merge_request, current_user)
    new_issuable(merge_request, current_user)
  end

41 42 43 44 45
  # When close a merge request we should:
  #
  #  * mark all pending tasks related to the target for the current user as done
  #
  def close_merge_request(merge_request, current_user)
46
    mark_pending_tasks_as_done(merge_request, current_user)
47 48 49
  end

  # When we reassign a merge request we should:
50 51 52 53 54
  #
  #  * creates a pending task for new assignee if merge request is assigned
  #
  def reassigned_merge_request(merge_request, current_user)
    reassigned_issuable(merge_request, current_user)
55 56
  end

57 58 59 60 61
  # When merge a merge request we should:
  #
  #  * mark all pending tasks related to the target for the current user as done
  #
  def merge_merge_request(merge_request, current_user)
62
    mark_pending_tasks_as_done(merge_request, current_user)
63 64
  end

65 66 67 68
  # When we mark a task as done we should:
  #
  #  * mark all pending tasks related to the target for the user as done
  #
69
  def mark_pending_tasks_as_done(target, user)
70
    pending_tasks(user, target.project, target).update_all(state: :done)
71 72
  end

73 74 75 76 77 78 79
  # When create a note we should:
  #
  #  * mark all pending tasks related to the noteable for the note author as done
  #
  def new_note(note)
    # Skip system notes, like status changes and cross-references
    unless note.system
80 81 82 83 84 85 86 87 88 89 90
      project = note.project
      target  = note.noteable
      author  = note.author

      mark_pending_tasks_as_done(target, author)

      mentioned_users = build_mentioned_users(project, note, author)

      mentioned_users.each do |user|
        create_task(project, target, author, user, Task::MENTIONED, note)
      end
91 92 93
    end
  end

94 95 96 97 98 99 100
  # When update a note we should:
  #
  #  * mark all pending tasks related to the noteable for the current user as done
  #
  def update_note(note, current_user)
    # Skip system notes, like status changes and cross-references
    unless note.system
101
      mark_pending_tasks_as_done(note.noteable, current_user)
102 103 104
    end
  end

105 106
  private

107
  def create_task(project, target, author, user, action, note = nil)
108 109 110 111 112 113
    attributes = {
      project: project,
      user_id: user.id,
      author_id: author.id,
      target_id: target.id,
      target_type: target.class.name,
114 115
      action: action,
      note: note
116 117 118 119
    }

    Task.create(attributes)
  end
120

121 122 123 124 125 126 127 128 129 130 131 132
  def build_mentioned_users(project, target, author)
    mentioned_users = target.mentioned_users.select do |user|
      user.can?(:read_project, project)
    end

    mentioned_users.delete(author)
    mentioned_users.delete(target.assignee) if target.respond_to?(:assignee)

    mentioned_users.uniq
  end

  def pending_tasks(user, project, target)
133 134
    user.tasks.pending.where(project: project, target: target)
  end
135

136 137 138 139 140 141 142 143 144 145 146 147 148
  def new_issuable(issuable, current_user)
    project = issuable.project
    target  = issuable
    author  = issuable.author

    if target.is_assigned? && target.assignee != current_user
      create_task(project, target, author, target.assignee, Task::ASSIGNED)
    end

    mentioned_users = build_mentioned_users(project, target, author)

    mentioned_users.each do |mentioned_user|
      create_task(project, target, author, mentioned_user, Task::MENTIONED)
149 150 151 152 153 154 155 156
    end
  end

  def reassigned_issuable(issuable, user)
    if issuable.is_assigned?
      create_task(issuable.project, issuable, user, issuable.assignee, Task::ASSIGNED)
    end
  end
157
end