2018-07-16 12:31:01 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-02-15 08:41:40 -05:00
|
|
|
module Issues
|
2018-10-29 05:05:47 -04:00
|
|
|
class MoveService < Issuable::Clone::BaseService
|
2022-02-09 07:12:04 -05:00
|
|
|
extend ::Gitlab::Utils::Override
|
|
|
|
|
2017-03-01 06:00:37 -05:00
|
|
|
MoveError = Class.new(StandardError)
|
2016-02-17 09:59:25 -05:00
|
|
|
|
2018-10-29 05:05:47 -04:00
|
|
|
def execute(issue, target_project)
|
|
|
|
@target_project = target_project
|
2016-03-15 05:14:39 -04:00
|
|
|
|
2021-09-27 08:13:56 -04:00
|
|
|
verify_can_move_issue!(issue, target_project)
|
2016-02-17 09:59:25 -05:00
|
|
|
|
2018-10-29 05:05:47 -04:00
|
|
|
super
|
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
|
|
|
|
2020-07-13 14:09:16 -04:00
|
|
|
# Updates old issue sent notifications allowing
|
|
|
|
# to receive service desk emails on the new moved issue.
|
|
|
|
update_service_desk_sent_notifications
|
|
|
|
|
2020-09-28 20:09:59 -04:00
|
|
|
queue_copy_designs
|
|
|
|
|
2018-10-29 05:05:47 -04:00
|
|
|
new_entity
|
2016-02-17 09:59:25 -05:00
|
|
|
end
|
|
|
|
|
2016-02-15 08:41:40 -05:00
|
|
|
private
|
|
|
|
|
2020-09-28 20:09:59 -04:00
|
|
|
attr_reader :target_project
|
|
|
|
|
2021-09-27 08:13:56 -04:00
|
|
|
def verify_can_move_issue!(issue, target_project)
|
|
|
|
unless issue.supports_move_and_clone?
|
|
|
|
raise MoveError, s_('MoveIssue|Cannot move issues of \'%{issue_type}\' type.') % { issue_type: issue.issue_type }
|
|
|
|
end
|
|
|
|
|
|
|
|
unless issue.can_move?(current_user, @target_project)
|
|
|
|
raise MoveError, s_('MoveIssue|Cannot move issue due to insufficient permissions!')
|
|
|
|
end
|
|
|
|
|
|
|
|
if @project == @target_project
|
|
|
|
raise MoveError, s_('MoveIssue|Cannot move issue to project it originates from!')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-07-13 14:09:16 -04:00
|
|
|
def update_service_desk_sent_notifications
|
|
|
|
return unless original_entity.from_service_desk?
|
|
|
|
|
|
|
|
original_entity
|
|
|
|
.sent_notifications.update_all(project_id: new_entity.project_id, noteable_id: new_entity.id)
|
|
|
|
end
|
|
|
|
|
2022-02-09 07:12:04 -05:00
|
|
|
override :update_old_entity
|
2018-10-29 05:05:47 -04:00
|
|
|
def update_old_entity
|
|
|
|
super
|
2018-02-15 05:23:54 -05:00
|
|
|
|
2020-08-20 20:10:44 -04:00
|
|
|
rewrite_related_issues
|
2018-02-15 05:23:54 -05:00
|
|
|
mark_as_moved
|
|
|
|
end
|
|
|
|
|
2022-02-09 07:12:04 -05:00
|
|
|
override :update_new_entity
|
|
|
|
def update_new_entity
|
|
|
|
super
|
|
|
|
|
|
|
|
copy_contacts
|
|
|
|
end
|
|
|
|
|
2018-10-29 05:05:47 -04:00
|
|
|
def create_new_entity
|
|
|
|
new_params = {
|
2021-03-04 07:11:11 -05:00
|
|
|
id: nil,
|
|
|
|
iid: nil,
|
|
|
|
relative_position: relative_position,
|
|
|
|
project: target_project,
|
|
|
|
author: original_entity.author,
|
|
|
|
assignee_ids: original_entity.assignee_ids,
|
|
|
|
moved_issue: true
|
|
|
|
}
|
2016-09-28 15:17:41 -04:00
|
|
|
|
2018-10-29 05:05:47 -04:00
|
|
|
new_params = original_entity.serializable_hash.symbolize_keys.merge(new_params)
|
2022-07-14 08:08:33 -04:00
|
|
|
new_params = new_params.merge(rewritten_old_entity_attributes)
|
2021-06-21 08:07:45 -04:00
|
|
|
# spam checking is not necessary, as no new content is being created. Passing nil for
|
|
|
|
# spam_params will cause SpamActionService to skip checking and return a success response.
|
|
|
|
spam_params = nil
|
2020-09-08 17:08:53 -04:00
|
|
|
|
|
|
|
# Skip creation of system notes for existing attributes of the issue. The system notes of the old
|
|
|
|
# issue are copied over so we don't want to end up with duplicate notes.
|
2021-06-21 08:07:45 -04:00
|
|
|
CreateService.new(project: @target_project, current_user: @current_user, params: new_params, spam_params: spam_params).execute(skip_system_notes: true)
|
2016-04-26 12:20:19 -04:00
|
|
|
end
|
2017-07-07 11:08:49 -04:00
|
|
|
|
2020-09-28 20:09:59 -04:00
|
|
|
def queue_copy_designs
|
2020-10-08 08:08:31 -04:00
|
|
|
return unless original_entity.designs.present?
|
2020-09-28 20:09:59 -04:00
|
|
|
|
|
|
|
response = DesignManagement::CopyDesignCollection::QueueService.new(
|
|
|
|
current_user,
|
|
|
|
original_entity,
|
|
|
|
new_entity
|
|
|
|
).execute
|
|
|
|
|
|
|
|
log_error(response.message) if response.error?
|
|
|
|
end
|
|
|
|
|
2018-10-29 05:05:47 -04:00
|
|
|
def mark_as_moved
|
|
|
|
original_entity.update(moved_to: new_entity)
|
2016-03-24 07:28:43 -04:00
|
|
|
end
|
|
|
|
|
2020-08-20 20:10:44 -04:00
|
|
|
def rewrite_related_issues
|
|
|
|
source_issue_links = IssueLink.for_source_issue(original_entity)
|
|
|
|
source_issue_links.update_all(source_id: new_entity.id)
|
|
|
|
|
|
|
|
target_issue_links = IssueLink.for_target_issue(original_entity)
|
|
|
|
target_issue_links.update_all(target_id: new_entity.id)
|
|
|
|
end
|
|
|
|
|
2022-02-09 07:12:04 -05:00
|
|
|
def copy_contacts
|
|
|
|
return unless original_entity.project.root_ancestor == new_entity.project.root_ancestor
|
|
|
|
|
|
|
|
new_entity.customer_relations_contacts = original_entity.customer_relations_contacts
|
|
|
|
end
|
|
|
|
|
2018-10-29 05:05:47 -04:00
|
|
|
def notify_participants
|
|
|
|
notification_service.async.issue_moved(original_entity, new_entity, @current_user)
|
2016-02-15 08:41:40 -05:00
|
|
|
end
|
|
|
|
|
2018-10-29 05:05:47 -04:00
|
|
|
def add_note_from
|
2020-09-28 20:09:59 -04:00
|
|
|
SystemNoteService.noteable_moved(new_entity, target_project,
|
2018-10-29 05:05:47 -04:00
|
|
|
original_entity, current_user,
|
2016-03-18 09:48:55 -04:00
|
|
|
direction: :from)
|
2016-02-15 08:41:40 -05:00
|
|
|
end
|
|
|
|
|
2018-10-29 05:05:47 -04:00
|
|
|
def add_note_to
|
|
|
|
SystemNoteService.noteable_moved(original_entity, old_project,
|
|
|
|
new_entity, current_user,
|
2016-03-18 09:48:55 -04:00
|
|
|
direction: :to)
|
2016-02-15 08:41:40 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-09-13 09:26:31 -04:00
|
|
|
|
2021-05-11 17:10:21 -04:00
|
|
|
Issues::MoveService.prepend_mod_with('Issues::MoveService')
|