1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
# frozen_string_literal: true
module WorkItems
module DataSync
class MoveService < ::WorkItems::DataSync::BaseService
private
def verify_work_item_action_permission
verify_can_move_work_item(work_item, target_namespace)
end
def data_sync_action
move_work_item
end
def verify_can_move_work_item(work_item, target_namespace)
unless work_item.namespace.instance_of?(target_namespace.class)
error_message = s_('MoveWorkItem|Cannot move work item between Projects and Groups.')
return error(error_message, :unprocessable_entity)
end
unless work_item.supports_move_and_clone?
error_message = format(s_('MoveWorkItem|Cannot move work items of \'%{issue_type}\' type.'),
{ issue_type: work_item.work_item_type.name })
return error(error_message, :unprocessable_entity)
end
unless work_item.can_move?(current_user, target_namespace)
error_message = s_('MoveWorkItem|Cannot move work item due to insufficient permissions!')
return error(error_message, :unprocessable_entity)
end
if target_namespace.pending_delete? # rubocop:disable Style/GuardClause -- does not read right with other checks above
error_message = s_('MoveWorkItem|Cannot move work item to target namespace as it is pending deletion.')
return error(error_message, :unprocessable_entity)
end
success({})
end
def move_work_item
create_response = WorkItems::DataSync::Handlers::CopyDataHandler.new(
work_item: work_item,
target_namespace: target_namespace,
current_user: current_user,
target_work_item_type: work_item.work_item_type,
params: params.merge(operation: :move),
overwritten_params: {
moved_issue: true
}
).execute
return create_response unless create_response.success? && create_response[:work_item].present?
# this service is based on Issues::CloseService#execute, which does not provide a clear return, so we'll skip
# handling it for now. This will be moved to a cleanup service that would be more result oriented where we can
# handle the service response status
WorkItems::DataSync::Handlers::CleanupDataHandler.new(
work_item: work_item, current_user: current_user, params: params
).execute
new_work_item = create_response[:work_item]
# this may need to be moved inside `BaseCopyDataService` so that this would be the first system note after
# move action started, followed by some other system notes related to which data is removed, replaced, changed
# etc during the move operation.
move_system_notes(new_work_item)
create_response
end
def move_system_notes(new_work_item)
SystemNoteService.noteable_moved(
new_work_item,
new_work_item.project,
work_item,
current_user,
direction: :from
)
SystemNoteService.noteable_moved(
work_item,
work_item.project,
new_work_item,
current_user,
direction: :to
)
end
end
end
end
|