File: move_service.rb

package info (click to toggle)
gitlab 17.6.5-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 629,368 kB
  • sloc: ruby: 1,915,304; javascript: 557,307; sql: 60,639; xml: 6,509; sh: 4,567; makefile: 1,239; python: 406
file content (95 lines) | stat: -rw-r--r-- 3,303 bytes parent folder | download
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