From 3d52e139b13ad077286f2f9f46b7e98f43ad9564 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Sat, 20 Feb 2016 11:59:59 -0200 Subject: Rename Tasks to Todos --- app/services/todo_service.rb | 170 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 app/services/todo_service.rb (limited to 'app/services/todo_service.rb') diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb new file mode 100644 index 00000000000..dc270602ebc --- /dev/null +++ b/app/services/todo_service.rb @@ -0,0 +1,170 @@ +# TodoService class +# +# Used for creating todos after certain user actions +# +# Ex. +# TodoService.new.new_issue(issue, current_user) +# +class TodoService + # When create an issue we should: + # + # * create a todo for assignee if issue is assigned + # * create a todo for each mentioned user on issue + # + def new_issue(issue, current_user) + new_issuable(issue, current_user) + end + + # When update an issue we should: + # + # * mark all pending todos related to the issue for the current user as done + # + def update_issue(issue, current_user) + create_mention_todos(issue.project, issue, current_user) + end + + # When close an issue we should: + # + # * mark all pending todos related to the target for the current user as done + # + def close_issue(issue, current_user) + mark_pending_todos_as_done(issue, current_user) + end + + # When we reassign an issue we should: + # + # * create a pending todo for new assignee if issue is assigned + # + def reassigned_issue(issue, current_user) + create_assignment_todo(issue, current_user) + end + + # When create a merge request we should: + # + # * creates a pending todo for assignee if merge request is assigned + # * create a todo for each mentioned user on merge request + # + def new_merge_request(merge_request, current_user) + new_issuable(merge_request, current_user) + end + + # When update a merge request we should: + # + # * create a todo for each mentioned user on merge request + # + def update_merge_request(merge_request, current_user) + create_mention_todos(merge_request.project, merge_request, current_user) + end + + # When close a merge request we should: + # + # * mark all pending todos related to the target for the current user as done + # + def close_merge_request(merge_request, current_user) + mark_pending_todos_as_done(merge_request, current_user) + end + + # When we reassign a merge request we should: + # + # * creates a pending todo for new assignee if merge request is assigned + # + def reassigned_merge_request(merge_request, current_user) + create_assignment_todo(merge_request, current_user) + end + + # When merge a merge request we should: + # + # * mark all pending todos related to the target for the current user as done + # + def merge_merge_request(merge_request, current_user) + mark_pending_todos_as_done(merge_request, current_user) + end + + # When create a note we should: + # + # * mark all pending todos related to the noteable for the note author as done + # * create a todo for each mentioned user on note + # + def new_note(note, current_user) + handle_note(note, current_user) + end + + # When update a note we should: + # + # * mark all pending todos related to the noteable for the current user as done + # * create a todo for each new user mentioned on note + # + def update_note(note, current_user) + handle_note(note, current_user) + end + + # When marking pending todos as done we should: + # + # * mark all pending todos related to the target for the current user as done + # + def mark_pending_todos_as_done(target, user) + pending_todos(user, target.project, target).update_all(state: :done) + end + + private + + def create_todos(project, target, author, users, action, note = nil) + Array(users).each do |user| + next if pending_todos(user, project, target).exists? + + Todo.create( + project: project, + user_id: user.id, + author_id: author.id, + target_id: target.id, + target_type: target.class.name, + action: action, + note: note + ) + end + end + + def new_issuable(issuable, author) + create_assignment_todo(issuable, author) + create_mention_todos(issuable.project, issuable, author) + end + + def handle_note(note, author) + # Skip system notes, like status changes and cross-references + return if note.system + + project = note.project + target = note.noteable + + mark_pending_todos_as_done(target, author) + create_mention_todos(project, target, author, note) + end + + def create_assignment_todo(issuable, author) + if issuable.assignee && issuable.assignee != author + create_todos(issuable.project, issuable, author, issuable.assignee, Todo::ASSIGNED) + end + end + + def create_mention_todos(project, issuable, author, note = nil) + mentioned_users = filter_mentioned_users(project, note || issuable, author) + create_todos(project, issuable, author, mentioned_users, Todo::MENTIONED, note) + end + + def filter_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.uniq + end + + def pending_todos(user, project, target) + user.todos.pending.where( + project_id: project.id, + target_id: target.id, + target_type: target.class.name + ) + end +end -- cgit v1.2.1