Class: MOCO::Sync
- Inherits:
-
Object
- Object
- MOCO::Sync
- Defined in:
- lib/moco/sync.rb
Overview
Match and map projects and tasks between MOCO instances and sync activities
Instance Attribute Summary collapse
-
#dry_run ⇒ Object
Returns the value of attribute dry_run.
-
#project_mapping ⇒ Object
readonly
Returns the value of attribute project_mapping.
-
#project_match_threshold ⇒ Object
Returns the value of attribute project_match_threshold.
-
#source_projects ⇒ Object
readonly
Returns the value of attribute source_projects.
-
#target_projects ⇒ Object
readonly
Returns the value of attribute target_projects.
-
#task_mapping ⇒ Object
readonly
Returns the value of attribute task_mapping.
-
#task_match_threshold ⇒ Object
Returns the value of attribute task_match_threshold.
Instance Method Summary collapse
-
#initialize(source_instance_api, target_instance_api, **args) ⇒ Sync
constructor
A new instance of Sync.
-
#sync(&callbacks) ⇒ Object
rubocop:todo Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity.
Constructor Details
#initialize(source_instance_api, target_instance_api, **args) ⇒ Sync
Returns a new instance of Sync.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/moco/sync.rb', line 12 def initialize(source_instance_api, target_instance_api, **args) @source_api = source_instance_api @target_api = target_instance_api @project_match_threshold = args.fetch(:project_match_threshold, 0.8) @task_match_threshold = args.fetch(:task_match_threshold, 0.45) @filters = args.fetch(:filters, {}) @dry_run = args.fetch(:dry_run, false) @project_mapping = {} @task_mapping = {} fetch_assigned_projects build_initial_mappings end |
Instance Attribute Details
#dry_run ⇒ Object
Returns the value of attribute dry_run.
10 11 12 |
# File 'lib/moco/sync.rb', line 10 def dry_run @dry_run end |
#project_mapping ⇒ Object (readonly)
Returns the value of attribute project_mapping.
9 10 11 |
# File 'lib/moco/sync.rb', line 9 def project_mapping @project_mapping end |
#project_match_threshold ⇒ Object
Returns the value of attribute project_match_threshold.
10 11 12 |
# File 'lib/moco/sync.rb', line 10 def project_match_threshold @project_match_threshold end |
#source_projects ⇒ Object (readonly)
Returns the value of attribute source_projects.
9 10 11 |
# File 'lib/moco/sync.rb', line 9 def source_projects @source_projects end |
#target_projects ⇒ Object (readonly)
Returns the value of attribute target_projects.
9 10 11 |
# File 'lib/moco/sync.rb', line 9 def target_projects @target_projects end |
#task_mapping ⇒ Object (readonly)
Returns the value of attribute task_mapping.
9 10 11 |
# File 'lib/moco/sync.rb', line 9 def task_mapping @task_mapping end |
#task_match_threshold ⇒ Object
Returns the value of attribute task_match_threshold.
10 11 12 |
# File 'lib/moco/sync.rb', line 10 def task_match_threshold @task_match_threshold end |
Instance Method Details
#sync(&callbacks) ⇒ Object
rubocop:todo Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
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 |
# File 'lib/moco/sync.rb', line 28 def sync(&callbacks) results = [] source_activities_r = @source_api.get_activities(@filters.fetch(:source, {})) target_activities_r = @target_api.get_activities(@filters.fetch(:target, {})) source_activities_grouped = source_activities_r.group_by(&:date).transform_values do |activities| activities.group_by(&:project) end target_activities_grouped = target_activities_r.group_by(&:date).transform_values do |activities| activities.group_by(&:project) end source_activities_grouped.each do |date, activities_by_project| activities_by_project.each do |project, source_activities| target_activities = target_activities_grouped.fetch(date, {}).fetch(@project_mapping[project.id], []) next if source_activities.empty? || target_activities.empty? matches = calculate_matches(source_activities, target_activities) matches.sort_by! { |match| -match[:score] } used_source_activities = [] used_target_activities = [] matches.each do |match| source_activity, target_activity = match[:activity] score = match[:score] next if used_source_activities.include?(source_activity) || used_target_activities.include?(target_activity) best_score = score best_match = target_activity expected_target_activity = get_expected_target_activity(source_activity) case best_score when 100 # 100 - perfect match found, nothing needs doing callbacks&.call(:equal, source_activity, expected_target_activity) when 60...100 # >=60 <100 - match with some differences expected_target_activity.to_h.except(:id, :user, :customer).each do |k, v| best_match.send("#{k}=", v) end callbacks&.call(:update, source_activity, best_match) unless @dry_run results << @target_api.update_activity(best_match) callbacks&.call(:updated, source_activity, best_match, results.last) end when 0...60 # <60 - no good match found, create new entry callbacks&.call(:create, source_activity, expected_target_activity) unless @dry_run results << @target_api.create_activity(expected_target_activity) callbacks&.call(:created, source_activity, best_match, results.last) end end used_source_activities << source_activity used_target_activities << target_activity end end end results end |