Class: Issues::UpdateService
- Inherits:
-
BaseService
- Object
- BaseContainerService
- IssuableBaseService
- BaseService
- Issues::UpdateService
- Defined in:
- app/services/issues/update_service.rb
Direct Known Subclasses
Constant Summary collapse
- WORK_ITEM_DESCRIPTION_FIELDS =
%w[ description description_html cached_markdown_version last_edited_by_id last_edited_at lock_version ].freeze
Constants inherited from BaseService
BaseService::EpicAssignmentError, BaseService::NO_REBALANCING_NEEDED
Constants included from Gitlab::Utils::UsageData
Gitlab::Utils::UsageData::DISTRIBUTED_HLL_FALLBACK, Gitlab::Utils::UsageData::FALLBACK, Gitlab::Utils::UsageData::HISTOGRAM_FALLBACK, Gitlab::Utils::UsageData::MAX_BUCKET_SIZE
Instance Attribute Summary
Attributes inherited from BaseContainerService
#container, #current_user, #group, #params, #project
Instance Method Summary collapse
- #before_update(issue, skip_spam_check: false) ⇒ Object
- #change_issue_duplicate(issue) ⇒ Object
- #change_work_item_type(issue) ⇒ Object
- #execute(issue) ⇒ Object
- #handle_assignee_changes(issue, old_assignees) ⇒ Object
- #handle_changes(issue, options) ⇒ Object
- #handle_task_changes(issuable) ⇒ Object
-
#initialize(container:, current_user: nil, params: {}, perform_spam_check: false) ⇒ UpdateService
constructor
NOTE: For Issues::UpdateService, we default perform_spam_check to false, because spam_checking is not necessary in many cases, and we don’t want to require every caller to explicitly pass it to disable spam checking.
- #move_issue_to_new_container(issue) ⇒ Object
- #update(issue) ⇒ Object
Methods inherited from BaseService
#available_callbacks, #close_service, constructor_container_arg, #execute_hooks, #hook_data, #rebalance_if_needed, #reopen_service
Methods included from Gitlab::Utils::Override
#extended, extensions, #included, #method_added, #override, #prepended, #queue_verification, verify!
Methods included from IssueTypeHelpers
Methods included from IncidentManagement::UsageData
Methods included from Gitlab::Utils::UsageData
#add, #add_metric, #alt_usage_data, #average, #count, #distinct_count, #estimate_batch_distinct_count, #histogram, #maximum_id, #measure_duration, #metrics_collection_metadata, #minimum_id, #redis_usage_data, #sum, #track_usage_event, #with_finished_at, #with_metadata, #with_prometheus_client
Methods inherited from IssuableBaseService
Methods inherited from BaseContainerService
#group_container?, #namespace_container?, #project_container?, #project_group, #root_ancestor
Methods included from BaseServiceUtility
#deny_visibility_level, #event_service, #log_error, #log_info, #notification_service, #system_hook_service, #todo_service, #visibility_level
Methods included from Gitlab::Allowable
Constructor Details
#initialize(container:, current_user: nil, params: {}, perform_spam_check: false) ⇒ UpdateService
NOTE: For Issues::UpdateService, we default perform_spam_check to false, because spam_checking is not necessary in many cases, and we don’t want to require every caller to explicitly pass it to disable spam checking.
12 13 14 15 |
# File 'app/services/issues/update_service.rb', line 12 def initialize(container:, current_user: nil, params: {}, perform_spam_check: false) super(container: container, current_user: current_user, params: params) @perform_spam_check = perform_spam_check end |
Instance Method Details
#before_update(issue, skip_spam_check: false) ⇒ Object
30 31 32 33 34 35 36 |
# File 'app/services/issues/update_service.rb', line 30 def before_update(issue, skip_spam_check: false) change_work_item_type(issue) return if skip_spam_check || !perform_spam_check issue.check_for_spam(user: current_user, action: :update) end |
#change_issue_duplicate(issue) ⇒ Object
93 94 95 96 97 98 99 100 101 102 |
# File 'app/services/issues/update_service.rb', line 93 def change_issue_duplicate(issue) canonical_issue_id = params.delete(:canonical_issue_id) return unless canonical_issue_id canonical_issue = Issue.find_by_id(canonical_issue_id) if canonical_issue Issues::DuplicateService.new(container: project, current_user: current_user).execute(issue, canonical_issue) end end |
#change_work_item_type(issue) ⇒ Object
38 39 40 41 42 43 44 45 46 |
# File 'app/services/issues/update_service.rb', line 38 def change_work_item_type(issue) return unless params[:issue_type].present? type_id = find_work_item_type_id(params[:issue_type]) # For custom types we need to use the abstraction layer so pass the work item type object # See https://gitlab.com/groups/gitlab-org/-/work_items/20291 issue.work_item_type_id = type_id end |
#execute(issue) ⇒ Object
17 18 19 20 21 22 |
# File 'app/services/issues/update_service.rb', line 17 def execute(issue) handle_move_between_ids(issue) change_issue_duplicate(issue) move_issue_to_new_container(issue) || clone_issue(issue) || update_task_event(issue) || update(issue) end |
#handle_assignee_changes(issue, old_assignees) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'app/services/issues/update_service.rb', line 75 def handle_assignee_changes(issue, old_assignees) return if issue.assignees == old_assignees create_assignee_note(issue, old_assignees) Gitlab::ResourceEvents::AssignmentEventRecorder.new(parent: issue, old_assignees: old_assignees).record notification_service.async.reassigned_issue(issue, current_user, old_assignees) todo_service.reassigned_assignable(issue, current_user, old_assignees) track_incident_action(current_user, issue, :incident_assigned) execute_flow_triggers(issue, issue.assignees - old_assignees, :assign) GraphqlTriggers.issuable_assignees_updated(issue) end |
#handle_changes(issue, options) ⇒ Object
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 |
# File 'app/services/issues/update_service.rb', line 48 def handle_changes(issue, ) super old_associations = .fetch(:old_associations, {}) old_labels = old_associations.fetch(:labels, []) old_mentioned_users = old_associations.fetch(:mentioned_users, []) old_assignees = old_associations.fetch(:assignees, []) old_severity = old_associations[:severity] if has_changes?(issue, old_labels: old_labels, old_assignees: old_assignees) todo_service.resolve_todos_for_target(issue, current_user) end if issue.previous_changes.include?('title') || issue.previous_changes.include?('description') todo_service.update_issue(issue, current_user, old_mentioned_users) end handle_assignee_changes(issue, old_assignees) handle_confidential_change(issue) handle_added_labels(issue, old_labels) handle_added_mentions(issue, old_mentioned_users) handle_severity_change(issue, old_severity) handle_escalation_status_change(issue) handle_issue_type_change(issue) handle_date_changes(issue) end |
#handle_task_changes(issuable) ⇒ Object
88 89 90 91 |
# File 'app/services/issues/update_service.rb', line 88 def handle_task_changes(issuable) todo_service.resolve_todos_for_target(issuable, current_user) todo_service.update_issue(issuable, current_user) end |
#move_issue_to_new_container(issue) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'app/services/issues/update_service.rb', line 104 def move_issue_to_new_container(issue) target_container = params.delete(:target_container) return unless target_container && issue.can_move?(current_user, target_container) && !move_to_same_container?(issue, target_container) update(issue) move_service_container = target_container.is_a?(Project) ? target_container.project_namespace : target_container ::WorkItems::DataSync::MoveService.new( work_item: issue, current_user: current_user, target_namespace: move_service_container ).execute[:work_item] end |
#update(issue) ⇒ Object
24 25 26 27 28 |
# File 'app/services/issues/update_service.rb', line 24 def update(issue) create_merge_request_from_quick_action super end |