summaryrefslogtreecommitdiff
path: root/app/services/milestones/transfer_service.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/milestones/transfer_service.rb')
-rw-r--r--app/services/milestones/transfer_service.rb84
1 files changed, 84 insertions, 0 deletions
diff --git a/app/services/milestones/transfer_service.rb b/app/services/milestones/transfer_service.rb
new file mode 100644
index 00000000000..1efbfed4853
--- /dev/null
+++ b/app/services/milestones/transfer_service.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+# Milestones::TransferService class
+#
+# Used for recreating the missing group milestones at project level when
+# transferring a project to a new namespace
+#
+module Milestones
+ class TransferService
+ attr_reader :current_user, :old_group, :project
+
+ def initialize(current_user, old_group, project)
+ @current_user = current_user
+ @old_group = old_group
+ @project = project
+ end
+
+ def execute
+ return unless old_group.present?
+
+ Milestone.transaction do
+ milestones_to_transfer.find_each do |milestone|
+ new_milestone = find_or_create_milestone(milestone)
+
+ update_issues_milestone(milestone.id, new_milestone&.id)
+ update_merge_requests_milestone(milestone.id, new_milestone&.id)
+ end
+ end
+ end
+
+ private
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def milestones_to_transfer
+ Milestone.from_union([
+ group_milestones_applied_to_issues,
+ group_milestones_applied_to_merge_requests
+ ])
+ .reorder(nil)
+ .distinct
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def group_milestones_applied_to_issues
+ Milestone.joins(:issues)
+ .where(
+ issues: { project_id: project.id },
+ group_id: old_group.id
+ )
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def group_milestones_applied_to_merge_requests
+ Milestone.joins(:merge_requests)
+ .where(
+ merge_requests: { target_project_id: project.id },
+ group_id: old_group.id
+ )
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def find_or_create_milestone(milestone)
+ params = milestone.attributes.slice('title', 'description', 'start_date', 'due_date')
+
+ FindOrCreateService.new(project, current_user, params).execute
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def update_issues_milestone(old_milestone_id, new_milestone_id)
+ Issue.where(project: project, milestone_id: old_milestone_id)
+ .update_all(milestone_id: new_milestone_id)
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def update_merge_requests_milestone(old_milestone_id, new_milestone_id)
+ MergeRequest.where(project: project, milestone_id: old_milestone_id)
+ .update_all(milestone_id: new_milestone_id)
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+end