summaryrefslogtreecommitdiff
path: root/app/services/issues/move_service.rb
blob: 25f970f0801b7bd3a798196e62dc7a62dee94873 (plain)
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
96
97
98
99
module Issues
  class MoveService < Issues::BaseService
    def initialize(project, current_user, params, issue, new_project_id)
      super(project, current_user, params)

      @issue_old = issue
      @issue_new = issue.dup
      @project_old = @project
      @project_new = Project.find(new_project_id) if new_project_id
    end

    def execute
      return unless move?

      ActiveRecord::Base.transaction do
        # New issue tasks
        #
        create_new_issue
        rewrite_notes
        add_moved_from_note

        # Old issue tasks
        #
        add_moved_to_note
        close_old_issue
      end

      # Notifications
      #
      notify_participants

      @issue_new
    end

    def move?
      @project_new && can_move?
    end

    private

    def can_move?
      can?(@current_user, :admin_issue, @project_old) &&
        can?(@current_user, :admin_issue, @project_new)
    end

    def create_new_issue
      @issue_new.iid = nil
      @issue_new.project = @project_new
      @issue_new.labels = []
      @issue_new.milestone = nil
      @issue_new.description = rewrite_references(@issue_old)
      @issue_new.save!
    end

    def rewrite_notes
      @issue_old.notes.find_each do |note|
        new_note = note.dup
        new_params = { project: @project_new, noteable: @issue_new,
                       note: rewrite_references(new_note) }

        new_note.update(new_params)
      end
    end

    def close_old_issue
      @issue_old.update(state: :closed)
    end

    def notify_participants
    end

    def add_moved_from_note
      SystemNoteService.noteable_moved(:from, @issue_new, @project_new,
                                       @issue_old, @current_user)
    end

    def add_moved_to_note
      SystemNoteService.noteable_moved(:to, @issue_old, @project_old,
                                       @issue_new, @current_user)
    end

    def rewrite_references(noteable)
      content = noteable_content(noteable).dup
      unfolder = Gitlab::Gfm::ReferenceUnfolder.new(content, @project_old)
      unfolder.unfold(@project_new)
    end

    def noteable_content(noteable)
      case noteable
      when Issue
        noteable.description
      when Note
        noteable.note
      else
        raise 'Unexpected noteable while moving an issue'
      end
    end
  end
end