debian-mirror-gitlab/app/services/issues/move_service.rb

166 lines
4.7 KiB
Ruby
Raw Normal View History

2018-11-18 11:00:15 +05:30
# frozen_string_literal: true
2016-06-02 11:05:42 +05:30
module Issues
class MoveService < Issues::BaseService
2017-08-17 22:00:37 +05:30
MoveError = Class.new(StandardError)
2016-06-02 11:05:42 +05:30
def execute(issue, new_project)
@old_issue = issue
@old_project = @project
@new_project = new_project
unless issue.can_move?(current_user, new_project)
raise MoveError, 'Cannot move issue due to insufficient permissions!'
end
if @project == new_project
raise MoveError, 'Cannot move issue to project it originates from!'
end
# Using transaction because of a high resources footprint
# on rewriting notes (unfolding references)
#
ActiveRecord::Base.transaction do
@new_issue = create_new_issue
2018-03-27 19:54:05 +05:30
update_new_issue
update_old_issue
2016-06-02 11:05:42 +05:30
end
notify_participants
@new_issue
end
private
2018-03-27 19:54:05 +05:30
def update_new_issue
rewrite_notes
2018-11-20 20:47:30 +05:30
copy_resource_label_events
2018-03-27 19:54:05 +05:30
rewrite_issue_award_emoji
add_note_moved_from
end
def update_old_issue
add_note_moved_to
close_issue
mark_as_moved
end
2016-06-02 11:05:42 +05:30
def create_new_issue
new_params = { id: nil, iid: nil, label_ids: cloneable_label_ids,
milestone_id: cloneable_milestone_id,
project: @new_project, author: @old_issue.author,
2018-03-27 19:54:05 +05:30
description: rewrite_content(@old_issue.description),
assignee_ids: @old_issue.assignee_ids }
2016-06-02 11:05:42 +05:30
new_params = @old_issue.serializable_hash.symbolize_keys.merge(new_params)
CreateService.new(@new_project, @current_user, new_params).execute
end
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2016-06-02 11:05:42 +05:30
def cloneable_label_ids
2016-11-03 12:29:30 +05:30
params = {
project_id: @new_project.id,
2018-11-08 19:23:39 +05:30
title: @old_issue.labels.pluck(:title),
include_ancestor_groups: true
2016-11-03 12:29:30 +05:30
}
LabelsFinder.new(current_user, params).execute.pluck(:id)
2016-06-02 11:05:42 +05:30
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2016-06-02 11:05:42 +05:30
def cloneable_milestone_id
2017-09-10 17:25:29 +05:30
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-06-02 11:05:42 +05:30
end
def rewrite_notes
2018-03-17 18:26:18 +05:30
@old_issue.notes_with_associations.find_each do |note|
2016-06-02 11:05:42 +05:30
new_note = note.dup
new_params = { project: @new_project, noteable: @new_issue,
note: rewrite_content(new_note.note),
created_at: note.created_at,
updated_at: note.updated_at }
new_note.update(new_params)
2018-03-17 18:26:18 +05:30
rewrite_award_emoji(note, new_note)
2016-06-02 11:05:42 +05:30
end
end
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2018-11-20 20:47:30 +05:30
def copy_resource_label_events
@old_issue.resource_label_events.find_in_batches do |batch|
events = batch.map do |event|
event.attributes
.except('id', 'reference', 'reference_html')
2018-12-05 23:21:45 +05:30
.merge('issue_id' => @new_issue.id, 'action' => ResourceLabelEvent.actions[event.action])
2018-11-20 20:47:30 +05:30
end
Gitlab::Database.bulk_insert(ResourceLabelEvent.table_name, events)
end
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2018-11-20 20:47:30 +05:30
2018-03-17 18:26:18 +05:30
def rewrite_issue_award_emoji
rewrite_award_emoji(@old_issue, @new_issue)
end
def rewrite_award_emoji(old_awardable, new_awardable)
old_awardable.award_emoji.each do |award|
new_award = award.dup
2018-03-17 18:26:18 +05:30
new_award.awardable = new_awardable
new_award.save
end
end
2016-06-02 11:05:42 +05:30
def rewrite_content(content)
return unless content
rewriters = [Gitlab::Gfm::ReferenceRewriter,
Gitlab::Gfm::UploadsRewriter]
rewriters.inject(content) do |text, klass|
rewriter = klass.new(text, @old_project, @current_user)
rewriter.rewrite(@new_project)
end
end
def close_issue
close_service = CloseService.new(@old_project, @current_user)
close_service.execute(@old_issue, notifications: false, system_note: false)
end
def add_note_moved_from
SystemNoteService.noteable_moved(@new_issue, @new_project,
@old_issue, @current_user,
direction: :from)
end
def add_note_moved_to
SystemNoteService.noteable_moved(@old_issue, @old_project,
@new_issue, @current_user,
direction: :to)
end
def mark_as_moved
@old_issue.update(moved_to: @new_issue)
end
def notify_participants
2018-10-15 14:42:47 +05:30
notification_service.async.issue_moved(@old_issue, @new_issue, @current_user)
2016-06-02 11:05:42 +05:30
end
end
end