2016-02-15 08:41:40 -05:00
|
|
|
module Issues
|
|
|
|
class MoveService < Issues::BaseService
|
2017-03-01 06:00:37 -05:00
|
|
|
MoveError = Class.new(StandardError)
|
2016-02-17 09:59:25 -05:00
|
|
|
|
2016-03-18 09:48:55 -04:00
|
|
|
def execute(issue, new_project)
|
|
|
|
@old_issue = issue
|
|
|
|
@old_project = @project
|
|
|
|
@new_project = new_project
|
2016-03-15 05:14:39 -04:00
|
|
|
|
2016-03-18 09:48:55 -04:00
|
|
|
unless issue.can_move?(current_user, new_project)
|
|
|
|
raise MoveError, 'Cannot move issue due to insufficient permissions!'
|
2016-03-15 05:14:39 -04:00
|
|
|
end
|
2016-03-15 06:35:40 -04:00
|
|
|
|
2016-03-18 09:48:55 -04:00
|
|
|
if @project == new_project
|
|
|
|
raise MoveError, 'Cannot move issue to project it originates from!'
|
2016-03-15 06:35:40 -04:00
|
|
|
end
|
2016-02-17 09:59:25 -05:00
|
|
|
|
2016-03-16 05:24:44 -04:00
|
|
|
# Using transaction because of a high resources footprint
|
2016-03-15 06:35:40 -04:00
|
|
|
# on rewriting notes (unfolding references)
|
2016-03-15 05:14:39 -04:00
|
|
|
#
|
2016-03-14 03:25:37 -04:00
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
# New issue tasks
|
|
|
|
#
|
2016-03-18 09:48:55 -04:00
|
|
|
@new_issue = create_new_issue
|
|
|
|
|
2016-03-14 03:25:37 -04:00
|
|
|
rewrite_notes
|
2016-06-01 12:33:49 -04:00
|
|
|
rewrite_award_emoji
|
2016-03-18 09:48:55 -04:00
|
|
|
add_note_moved_from
|
2016-02-22 05:00:40 -05:00
|
|
|
|
2016-03-14 03:25:37 -04:00
|
|
|
# Old issue tasks
|
|
|
|
#
|
2016-03-18 09:48:55 -04:00
|
|
|
add_note_moved_to
|
|
|
|
close_issue
|
2016-03-17 06:11:22 -04:00
|
|
|
mark_as_moved
|
2016-03-14 03:25:37 -04:00
|
|
|
end
|
2016-02-22 05:00:40 -05:00
|
|
|
|
2016-03-15 05:14:39 -04:00
|
|
|
notify_participants
|
2016-02-15 08:41:40 -05:00
|
|
|
|
2016-03-18 09:48:55 -04:00
|
|
|
@new_issue
|
2016-02-17 09:59:25 -05:00
|
|
|
end
|
|
|
|
|
2016-02-15 08:41:40 -05:00
|
|
|
private
|
|
|
|
|
2016-03-14 06:25:04 -04:00
|
|
|
def create_new_issue
|
2016-04-26 12:20:19 -04:00
|
|
|
new_params = { id: nil, iid: nil, label_ids: cloneable_label_ids,
|
2016-04-28 04:52:23 -04:00
|
|
|
milestone_id: cloneable_milestone_id,
|
2016-03-18 09:48:55 -04:00
|
|
|
project: @new_project, author: @old_issue.author,
|
2016-03-24 07:28:43 -04:00
|
|
|
description: rewrite_content(@old_issue.description) }
|
2016-03-14 08:24:56 -04:00
|
|
|
|
2016-05-05 02:59:09 -04:00
|
|
|
new_params = @old_issue.serializable_hash.symbolize_keys.merge(new_params)
|
2016-03-18 09:48:55 -04:00
|
|
|
CreateService.new(@new_project, @current_user, new_params).execute
|
2016-02-15 08:41:40 -05:00
|
|
|
end
|
|
|
|
|
2016-04-26 12:20:19 -04:00
|
|
|
def cloneable_label_ids
|
2016-09-28 15:17:41 -04:00
|
|
|
params = {
|
|
|
|
project_id: @new_project.id,
|
|
|
|
title: @old_issue.labels.pluck(:title)
|
|
|
|
}
|
|
|
|
|
|
|
|
LabelsFinder.new(current_user, params).execute.pluck(:id)
|
2016-04-26 12:20:19 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def cloneable_milestone_id
|
2017-07-07 11:08:49 -04:00
|
|
|
title = @old_issue.milestone&.title
|
|
|
|
return unless title
|
|
|
|
|
|
|
|
if @new_project.group && can?(current_user, :read_group, @new_project.group)
|
|
|
|
group_id = @new_project.group.id
|
|
|
|
end
|
|
|
|
|
|
|
|
params =
|
|
|
|
{ title: title, project_ids: @new_project.id, group_ids: group_id }
|
|
|
|
|
|
|
|
milestones = MilestonesFinder.new(params).execute
|
|
|
|
milestones.first&.id
|
2016-04-26 12:20:19 -04:00
|
|
|
end
|
|
|
|
|
2016-02-15 08:41:40 -05:00
|
|
|
def rewrite_notes
|
2016-03-18 09:48:55 -04:00
|
|
|
@old_issue.notes.find_each do |note|
|
2016-02-22 09:18:39 -05:00
|
|
|
new_note = note.dup
|
2016-03-18 09:48:55 -04:00
|
|
|
new_params = { project: @new_project, noteable: @new_issue,
|
2016-03-24 07:28:43 -04:00
|
|
|
note: rewrite_content(new_note.note),
|
2016-03-23 07:41:53 -04:00
|
|
|
created_at: note.created_at,
|
|
|
|
updated_at: note.updated_at }
|
2016-02-24 09:38:52 -05:00
|
|
|
|
|
|
|
new_note.update(new_params)
|
2016-02-22 05:00:40 -05:00
|
|
|
end
|
2016-02-15 08:41:40 -05:00
|
|
|
end
|
|
|
|
|
2016-06-01 12:33:49 -04:00
|
|
|
def rewrite_award_emoji
|
2016-06-03 10:35:56 -04:00
|
|
|
@old_issue.award_emoji.each do |award|
|
|
|
|
new_award = award.dup
|
|
|
|
new_award.awardable = @new_issue
|
|
|
|
new_award.save
|
|
|
|
end
|
|
|
|
end
|
2016-06-01 12:33:49 -04:00
|
|
|
|
2016-03-24 07:28:43 -04:00
|
|
|
def rewrite_content(content)
|
|
|
|
return unless content
|
|
|
|
|
2016-03-29 07:21:57 -04:00
|
|
|
rewriters = [Gitlab::Gfm::ReferenceRewriter,
|
|
|
|
Gitlab::Gfm::UploadsRewriter]
|
2016-03-24 07:28:43 -04:00
|
|
|
|
2016-03-29 07:21:57 -04:00
|
|
|
rewriters.inject(content) do |text, klass|
|
|
|
|
rewriter = klass.new(text, @old_project, @current_user)
|
2016-03-30 04:42:39 -04:00
|
|
|
rewriter.rewrite(@new_project)
|
2016-03-29 07:21:57 -04:00
|
|
|
end
|
2016-03-24 07:28:43 -04:00
|
|
|
end
|
|
|
|
|
2016-03-18 09:48:55 -04:00
|
|
|
def close_issue
|
|
|
|
close_service = CloseService.new(@old_project, @current_user)
|
|
|
|
close_service.execute(@old_issue, notifications: false, system_note: false)
|
2016-02-15 08:41:40 -05:00
|
|
|
end
|
|
|
|
|
2016-03-18 09:48:55 -04:00
|
|
|
def add_note_moved_from
|
|
|
|
SystemNoteService.noteable_moved(@new_issue, @new_project,
|
|
|
|
@old_issue, @current_user,
|
|
|
|
direction: :from)
|
2016-02-15 08:41:40 -05:00
|
|
|
end
|
|
|
|
|
2016-03-18 09:48:55 -04:00
|
|
|
def add_note_moved_to
|
|
|
|
SystemNoteService.noteable_moved(@old_issue, @old_project,
|
|
|
|
@new_issue, @current_user,
|
|
|
|
direction: :to)
|
2016-02-15 08:41:40 -05:00
|
|
|
end
|
2016-02-23 08:18:54 -05:00
|
|
|
|
2016-03-24 07:28:43 -04:00
|
|
|
def mark_as_moved
|
|
|
|
@old_issue.update(moved_to: @new_issue)
|
2016-02-23 08:18:54 -05:00
|
|
|
end
|
2016-02-24 06:18:46 -05:00
|
|
|
|
2016-03-14 08:24:56 -04:00
|
|
|
def notify_participants
|
2016-03-18 09:48:55 -04:00
|
|
|
notification_service.issue_moved(@old_issue, @new_issue, @current_user)
|
2016-03-14 08:24:56 -04:00
|
|
|
end
|
2016-02-15 08:41:40 -05:00
|
|
|
end
|
|
|
|
end
|