eco-helpers 0.6.17 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +19 -0
  3. data/.yardopts +2 -2
  4. data/Gemfile +6 -0
  5. data/Rakefile +27 -0
  6. data/eco-helpers.gemspec +9 -6
  7. data/lib/eco/api.rb +2 -1
  8. data/lib/eco/api/common/people.rb +1 -1
  9. data/lib/eco/api/common/people/base_parser.rb +31 -1
  10. data/lib/eco/api/common/people/default_parsers.rb +5 -1
  11. data/lib/eco/api/common/people/default_parsers/csv_parser.rb +37 -0
  12. data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +0 -1
  13. data/lib/eco/api/common/people/entries.rb +14 -18
  14. data/lib/eco/api/common/people/entry_factory.rb +97 -9
  15. data/lib/eco/api/common/people/person_entry.rb +147 -206
  16. data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +212 -0
  17. data/lib/eco/api/common/people/person_factory.rb +10 -12
  18. data/lib/eco/api/common/people/person_parser.rb +97 -37
  19. data/lib/eco/api/common/session/base_session.rb +1 -2
  20. data/lib/eco/api/common/session/file_manager.rb +1 -1
  21. data/lib/eco/api/organization.rb +2 -1
  22. data/lib/eco/api/organization/people.rb +54 -22
  23. data/lib/eco/api/organization/person_schemas.rb +54 -0
  24. data/lib/eco/api/organization/policy_groups.rb +5 -9
  25. data/lib/eco/api/organization/{presets.rb → presets_factory.rb} +1 -1
  26. data/lib/eco/api/policies.rb +10 -0
  27. data/lib/eco/api/policies/base_policy.rb +14 -0
  28. data/lib/eco/api/policies/policy.rb +20 -0
  29. data/lib/eco/api/policies/used_policies.rb +37 -0
  30. data/lib/eco/api/session.rb +36 -34
  31. data/lib/eco/api/session/batch.rb +94 -44
  32. data/lib/eco/api/session/batch_job.rb +108 -48
  33. data/lib/eco/api/session/batch_jobs.rb +4 -5
  34. data/lib/eco/api/session/batch_status.rb +70 -11
  35. data/lib/eco/api/session/config.rb +22 -5
  36. data/lib/eco/api/session/config/files.rb +10 -1
  37. data/lib/eco/api/session/config/people.rb +18 -5
  38. data/lib/eco/api/session/config/policies.rb +29 -0
  39. data/lib/eco/api/session/config/use_cases.rb +3 -7
  40. data/lib/eco/api/session/job_groups.rb +9 -10
  41. data/lib/eco/api/usecases.rb +2 -1
  42. data/lib/eco/api/usecases/base_case.rb +7 -2
  43. data/lib/eco/api/usecases/default_cases/change_email_case.rb +4 -2
  44. data/lib/eco/api/usecases/default_cases/create_case.rb +2 -1
  45. data/lib/eco/api/usecases/default_cases/create_details_case.rb +3 -1
  46. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +4 -2
  47. data/lib/eco/api/usecases/default_cases/hris_case.rb +20 -13
  48. data/lib/eco/api/usecases/default_cases/new_email_case.rb +3 -1
  49. data/lib/eco/api/usecases/default_cases/new_id_case.rb +4 -2
  50. data/lib/eco/api/usecases/default_cases/recover_db_case.rb +9 -5
  51. data/lib/eco/api/usecases/default_cases/remove_account_case.rb +4 -2
  52. data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +4 -2
  53. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +2 -2
  54. data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +2 -2
  55. data/lib/eco/api/usecases/default_cases/update_case.rb +16 -2
  56. data/lib/eco/api/usecases/default_cases/update_details_case.rb +3 -1
  57. data/lib/eco/api/usecases/default_cases/upsert_case.rb +25 -3
  58. data/lib/eco/api/usecases/use_case.rb +23 -140
  59. data/lib/eco/api/usecases/use_case_chain.rb +95 -0
  60. data/lib/eco/api/usecases/use_case_io.rb +117 -0
  61. data/lib/eco/api/usecases/use_group.rb +25 -5
  62. data/lib/eco/common/base_cli_backup.rb +1 -0
  63. data/lib/eco/language/models.rb +1 -1
  64. data/lib/eco/language/models/collection.rb +42 -31
  65. data/lib/eco/language/models/parser_serializer.rb +68 -0
  66. data/lib/eco/version.rb +1 -1
  67. metadata +93 -38
  68. data/lib/eco/api/common/people/types.rb +0 -47
  69. data/lib/eco/api/usecases/case_data.rb +0 -13
  70. data/lib/eco/language/models/attribute_parser.rb +0 -38
  71. data/lib/eco/lexic/dictionary.rb +0 -33
  72. data/lib/eco/lexic/dictionary/dictionary.txt +0 -355484
  73. data/lib/eco/lexic/dictionary/tags.json +0 -38
@@ -8,8 +8,10 @@ module Eco
8
8
  @cases.define("new-email", type: :sync) do |entries, people, session, options|
9
9
  job = session.job_group("main").new("update", type: :update, sets: :core)
10
10
 
11
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
12
+
11
13
  entries.each.with_index do |entry, i|
12
- if person = people.find(entry)
14
+ if person = people.find(entry, strict: strict_search)
13
15
  person.email = entry.email
14
16
  job.add(person)
15
17
  else
@@ -5,11 +5,13 @@ module Eco
5
5
  class NewIdCase < BaseCase
6
6
 
7
7
  def process
8
- @cases.define("new-id", type: :sync) do |entries, people, session|
8
+ @cases.define("new-id", type: :sync) do |entries, people, session, options|
9
9
  job = session.job_group("main").new("update", type: :update, sets: :core)
10
10
 
11
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
12
+
11
13
  entries.each.with_index do |entry, i|
12
- if person = people.find(entry)
14
+ if person = people.find(entry, strict: strict_search)
13
15
  person.external_id = entry.external_id
14
16
  job.add(person)
15
17
  else
@@ -14,15 +14,15 @@ module Eco
14
14
  update = session.job_group("main").new("update", type: :update, sets: [:core, :details, :account])
15
15
  remove = session.job_group("main").new("remove", type: :delete, sets: [:core, :details, :account])
16
16
 
17
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
17
18
  pgs = session.policy_groups
18
19
 
19
20
  if options.dig(:include, :delete)
20
21
  people.exclude(entries).map {|person| remove.add(person)}
21
22
  end
22
23
 
23
-
24
24
  entries.each.with_index do |entry, i|
25
- create = ! (person = people.find(entry))
25
+ create = ! (person = people.find(entry, strict: strict_search))
26
26
 
27
27
  if create && !options.dig(:include, :create)
28
28
  session.logger.error("Entry(#{i}) - this person does not exist: #{entry.email}")
@@ -32,11 +32,15 @@ module Eco
32
32
  unless options.dig(:exclude, :core)
33
33
  person.external_id = entry.external_id
34
34
  person.name = entry.name
35
- person.email = entry.email unless (options.dig(:exclude, :email))
36
- person.supervisor_id = entry.supervisor_id
35
+ person.email = entry.email unless options.dig(:exclude, :email)
36
+ person.supervisor_id = entry.supervisor_id unless options.dig(:exclude, :supervisor)
37
+ end
38
+
39
+ unless options.dig(:exclude, :account)
40
+ person.account = entry.account
41
+ person.account&.send_invites = options[:send_invites] if options.key?(:send_invites)
37
42
  end
38
43
 
39
- person.account = entry.account unless options.dig(:exclude, :account)
40
44
  person.details = entry.details unless options.dig(:exclude, :details)
41
45
 
42
46
  creation.add(person) if create
@@ -14,11 +14,13 @@ module Eco
14
14
  end
15
15
  end
16
16
 
17
- @cases.define("remove-account", type: :sync) do |entries, people, session|
17
+ @cases.define("remove-account", type: :sync) do |entries, people, session, options|
18
18
  update = session.job_group("main").new("update", type: :update, sets: [:core, :account])
19
19
 
20
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
21
+
20
22
  entries.each.with_index do |entry, i|
21
- if person = people.find(entry)
23
+ if person = people.find(entry, strict: strict_search)
22
24
  person.account = nil
23
25
  update.add(person)
24
26
  else
@@ -5,11 +5,13 @@ module Eco
5
5
  class SetSupervisorCase < BaseCase
6
6
 
7
7
  def process
8
- @cases.define("set-supervisor", type: :sync) do |entries, people, session|
8
+ @cases.define("set-supervisor", type: :sync) do |entries, people, session, options|
9
9
  job = session.job_group("main").new("update", type: :update, sets: :core)
10
10
 
11
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
12
+
11
13
  entries.each.with_index do |entry, i|
12
- person = people.find(entry)
14
+ person = people.find(entry, strict: strict_search)
13
15
 
14
16
  if !person
15
17
  session.logger.error("Entry(#{i}) - this person does not exist: #{entry.to_s(:identify)}")
@@ -18,8 +18,8 @@ module Eco
18
18
 
19
19
  session.logger.info("going to create file: #{file}")
20
20
  CSV.open(file, "w") do |csv|
21
- deps = {"supervisor_id" => {people: people}}
22
- entry = session.new_entry(people.first, dependencies: deps)
21
+ deps = {"supervisor_id" => {people: people}}
22
+ entry = session.new_entry(people.first, dependencies: deps)
23
23
  header = entry.to_hash.keys
24
24
 
25
25
  if options.dig(:nice_header)
@@ -20,8 +20,8 @@ module Eco
20
20
 
21
21
  session.logger.info("going to create file: #{file}")
22
22
  CSV.open(file, "w") do |csv|
23
- deps = {"supervisor_id" => {people: people}}
24
- header = session.new_entry(people.first, dependencies: deps).to_hash.keys
23
+ deps = {"supervisor_id" => {people: people}}
24
+ header = session.new_entry(people.first, dependencies: deps).to_hash.keys
25
25
  header += abilities
26
26
 
27
27
  csv << header
@@ -5,13 +5,24 @@ module Eco
5
5
  class UpdateCase < BaseCase
6
6
 
7
7
  def process
8
+ #opts = CLI::Options.new do |p|
9
+ # p.option :exclude, "Allows to exclude certain options"
10
+ # p.suboption :exclude, :core, "Excludes core details from the update.", optional: true
11
+ # p.suboption :exclude, :details, "Excludes schema details from the update.", optional: true
12
+ # p.suboption :exclude, :account, "Excludes account details from the update.", optional: true
13
+ # p.suboption :exclude, :email, "Excludes core email from the update.", optional: true
14
+ # p.suboption :exclude, :supervisor, "Excludes supervisor_id from the update.", optional: true
15
+ # p.suboption :exclude, :abilities, "Excludes the abilities from the update.", optional: true
16
+ #end
17
+
8
18
  @cases.define("update", type: :sync) do |entries, people, session, options|
9
19
  update = session.job_group("main").new("update", type: :update, sets: [:core, :details, :account])
10
20
 
21
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
11
22
  pgs = session.policy_groups
12
23
 
13
24
  entries.each.with_index do |entry, i|
14
- if person = people.find(entry)
25
+ if person = people.find(entry, strict: strict_search)
15
26
  core_excluded = ["supervisor_id"]
16
27
  core_excluded.push("email") if options.dig(:exclude, :email)
17
28
  entry.set_core(person, exclude: core_excluded) unless options.dig(:exclude, :core)
@@ -27,7 +38,7 @@ module Eco
27
38
  final: person.account.policy_group_ids
28
39
  )
29
40
 
30
- person.account.permissions_custom = session.new_preset(person) unless options.dig(:exclude, :abilities)
41
+ person.account.permissions_custom = session.new_preset(person) unless !create && options.dig(:exclude, :abilities)
31
42
 
32
43
  if session.tagtree
33
44
  person.account.filter_tags = session.tagtree.user_tags(
@@ -41,6 +52,9 @@ module Eco
41
52
  tags = person.account.filter_tags
42
53
  person.account.default_tag = tags.first unless tags.length > 1
43
54
  end
55
+
56
+ person.account&.send_invites = options[:send_invites] if options.key?(:send_invites)
57
+
44
58
  end
45
59
  update.add(person)
46
60
  else
@@ -8,8 +8,10 @@ module Eco
8
8
  @cases.define("update-details", type: :sync) do |entries, people, session, options|
9
9
  job = session.job_group("main").new("update", type: :update, sets: [:core, :details])
10
10
 
11
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
12
+
11
13
  entries.each.with_index do |entry, i|
12
- if person = people.find(entry)
14
+ if person = people.find(entry, strict: strict_search)
13
15
  core_excluded = ["supervisor_id"]
14
16
  core_excluded.push("email") if options.dig(:exclude, :email)
15
17
  entry.set_core(person, exclude: core_excluded) unless options.dig(:exclude, :core)
@@ -8,11 +8,13 @@ module Eco
8
8
  @cases.define("upsert", type: :sync) do |entries, people, session, options|
9
9
  creation = session.job_group("main").new("create", type: :create, sets: [:core, :details, :account])
10
10
  update = session.job_group("main").new("update", type: :update, sets: [:core, :details, :account])
11
+ supers = session.job_group("post").new("supers", type: :update, sets: :core)
11
12
 
13
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
12
14
  pgs = session.policy_groups
13
15
 
14
16
  entries.each.with_index do |entry, i|
15
- create = ! (person = people.find(entry))
17
+ create = ! (person = people.find(entry, strict: strict_search))
16
18
  person = session.new_person if create
17
19
 
18
20
  core_excluded = ["supervisor_id"]
@@ -25,14 +27,14 @@ module Eco
25
27
  ini_tags = person.account&.filter_tags || []
26
28
  entry.set_account(person)
27
29
 
28
- person.account.send_invites = false if options.key?(:send_invites) && !options(:send_invites)
30
+ person.account.send_invites = options[:send_invites] if options.key?(:send_invites)
29
31
 
30
32
  person.account.policy_group_ids = pgs.user_pg_ids(
31
33
  initial: ini_pg_ids,
32
34
  final: person.account.policy_group_ids
33
35
  )
34
36
 
35
- person.account.permissions_custom = session.new_preset(person) unless options.dig(:exclude, :abilities)
37
+ person.account.permissions_custom = session.new_preset(person) unless !create && options.dig(:exclude, :abilities)
36
38
 
37
39
  if session.tagtree
38
40
  person.account.filter_tags = session.tagtree.user_tags(
@@ -46,10 +48,30 @@ module Eco
46
48
  tags = person.account.filter_tags
47
49
  person.account.default_tag = tags.first unless tags.length > 1
48
50
  end
51
+
49
52
  end
50
53
 
51
54
  creation.add(person) if create
52
55
  update.add(person) unless create
56
+
57
+ # set supervisor
58
+ unless options.dig(:exclude, :core) || options.dig(:exclude, :supervisor)
59
+ if !(sup_id = entry.supervisor_id)
60
+ person.supervisor_id = nil
61
+ else
62
+ if supervisor = people.person(id: sup_id, external_id: sup_id, email: sup_id)
63
+ person.supervisor_id = supervisor.id
64
+ else
65
+ # delay setting supervisor if does not exit
66
+ supers.add(person) do |person|
67
+ person.consolidate!
68
+ person.supervisor_id = sup_id
69
+ person
70
+ end
71
+ end
72
+ end
73
+ end
74
+
53
75
  end
54
76
  end
55
77
  end
@@ -10,164 +10,47 @@ module Eco
10
10
  transform: [:people, :session],
11
11
  export: [:people, :session, :options]
12
12
  }
13
- MAX_CHAINS = 70
14
- @@num_chains = 0
15
13
 
16
- attr_reader :name, :type, :times_used
14
+ attr_reader :name, :type, :times_launched
15
+
16
+ class << self
17
+ def valid_type?(type)
18
+ TYPES.include?(type)
19
+ end
20
+
21
+ def type_params(type)
22
+ raise "Invalid type '#{type.to_s}'" if !valid_type?(type)
23
+ TYPE_PARAMS[type]
24
+ end
25
+ end
17
26
 
18
27
  def initialize(name, type:, root:, options: {}, &block)
28
+ raise "Undefine usecase type #{type}. Please, use any of #{TYPES}" unless self.class.valid_type?(type)
19
29
 
20
30
  self.root = root
21
- @case = block
22
- @name = name
23
- @type = type
24
- @options = options
25
-
26
- @chains = []
27
- @resolved_chains = nil
28
- @times_used = 0
31
+ @case = block
32
+ @name = name
33
+ @type = type
34
+ @options = options
35
+ @times_launched = 0
29
36
  end
30
37
 
31
38
  def root=(value)
32
- raise "You cannot change root UseGroup once the chains have been resolved" if @resolved_chains
33
39
  raise "Root should be a UseGroup. Given: #{value}" if !value.is_a?(UseGroup)
34
40
  @root = value
35
41
  end
36
42
 
37
- def use(preserve_chains: false, recursive: false)
38
- newcase = UseCase.new(@name, type: @type, root: @root, options: @options, &@case)
39
- if preserve_chains
40
- chain_use = {preserve_chains: recursive, recursive: recursive}
41
- @chains = @chains.map do |usecase|
42
- if usecase.respond_to? :call
43
- Proc.new do |usegroup|
44
- usecase = usecase.call(usegroup)
45
- usecase.use(chain_use).chain_to(newcase)
46
- usecase
47
- end
48
- else
49
- usecase.use(chain_use).chain_to(newcase)
50
- usecase
51
- end
52
- end
53
- end
54
- newcase
55
- end
56
-
57
- def process(input: nil, people: nil, session:, options: {})
58
- raise "This case has been already used. To create multiple instances of same use case, use 'use' method" if @done
59
- validate_args(input: input, people: people, session: session, options: options)
60
-
61
- opts = options&.dup
62
- opts = @options.merge(opts || {})
43
+ def launch(input: nil, people: nil, session:, options: {})
44
+ data = UseCaseIO.new(usecase: self, input: input, people: people, session: session, options: options)
63
45
 
64
- case @type
65
- when :import
66
- out = input = @case.call(input, session, opts)
67
- when :filter
68
- out = people = @case.call(people, session, opts)
69
- when :transform
70
- out = jobs = into_a(@case.call(people, session, opts))
71
- when :sync
72
- out = jobs = into_a(@case.call(input, people, session, opts))
73
- when :export
74
- out = stat = @case.call(people, session, opts)
75
- end
76
- @times_used += 1
46
+ data.output = @case.call(data.params)
47
+ @times_launched += 1
77
48
 
78
49
  data_model = {
79
50
  self => {
80
- data: { input: input, people: people, session: session, options: opts, output: out }
51
+ io: data
81
52
  }
82
53
  }
83
- post_usecase(data_model)
84
- end
85
-
86
- def chain(usecase = nil)
87
- @@num_chains += 1
88
- raise "Reached maximum number of chained use cases (#{MAX_CHAINS}). Looks like a recursive cyclic chain 'use'" if @@num_chains >= MAX_CHAINS
89
- raise "A UseCase can only be chained with another UseCase" if usecase && !usecase.is_a?(UseCase)
90
- raise "Missuse. Please use either parameter or block but not both" if block_given? && usecase
91
- usecase = block_given?? Proc.new : usecase
92
- @chains.push(usecase)
93
- self
94
- end
95
-
96
- def self.valid_type(type)
97
- TYPES.include?(type)
98
- end
99
-
100
- def self.type_params(type)
101
- raise "Invalid type '#{type.to_s}'" if !valid_type?(type)
102
- TYPE_PARAMS[type]
103
- end
104
-
105
- protected
106
-
107
- def chain_to(usecase)
108
- raise "A UseCase can only be chained with another UseCase" if usecase && !usecase.is_a?(UseCase)
109
- usecase.chain(self)
110
- end
111
-
112
- def resolved_chains(use_group = nil)
113
- return @resolved_chains if @resolved_chains
114
- raise "Only UseGroup object can resolve chains. Given: #{use_group} " if use_group && !use_group.is_a?(UseGroup)
115
-
116
- use_group = use_group || @root
117
- @resolved_chains = @chains.map do |usecase|
118
- usecase = usecase.call(use_group) if usecase.respond_to? :call
119
- raise "A UseCase can only be chained with another UseCase" if usecase && !usecase.is_a?(UseCase)
120
- usecase.resolved_chains(use_group)
121
- usecase
122
- end
123
- @resolved_chains
124
- end
125
-
126
- private
127
-
128
- def post_usecase(data_model)
129
- return data_model if resolved_chains.empty?
130
- data_model[self][:chains] = {} unless data_model[self][:chains]
131
-
132
- resolved_chains.each do |usecase|
133
- # chained cases use same params as parent case (out of simplicity)
134
- params = data_model[self][:data].slice(*ALL_PARAMS) #TYPE_PARAMS[usecase.type])
135
- data_model[self][:chains].merge(usecase.process(params))
136
- end
137
- data_model
138
- end
139
-
140
- def validate_args(input:, people:, session:, options:)
141
- case
142
- when !session.is_a?(Eco::API::Session)
143
- raise "A UseCase needs a Session object. Given: #{session}"
144
- when input_required? && !input
145
- raise "UseCase of type '#{@type.to_s}' requires a valid input. None given"
146
- when people_required? && !people.is_a?(Eco::API::Organization::People)
147
- raise "UseCase of type '#{@type.to_s}' requires a People object. Given: #{people}"
148
- when !options || (options && !options.is_a?(Hash))
149
- raise "To inject dependencies via ':options' it should be a Hash object. Given: #{options}"
150
- when options_required? && !options
151
- raise "UseCase of type '#{@type.to_s}' requires a Hash ':options' object."
152
- end
153
- true
154
- end
155
-
156
- def input_required?
157
- [:import, :sync].include?(@type)
158
- end
159
-
160
- def people_required?
161
- [:filter, :transform, :sync, :export].include?(@type)
162
- end
163
-
164
- def options_required?
165
- [:filter].include?(@type)
166
- end
167
-
168
- def into_a(value)
169
- value = [].push(value) unless value.is_a?(Array)
170
- value
171
54
  end
172
55
 
173
56
  end
@@ -0,0 +1,95 @@
1
+ module Eco
2
+ module API
3
+ module UseCases
4
+ class UseCaseChain < UseCase
5
+ MAX_CHAINS = 70
6
+ @@num_chains = 0
7
+
8
+ def initialize(name, type:, root:, options: {}, &block)
9
+ super(name, type: type, root: root, options: options, &block)
10
+ @chains = []
11
+ @resolved_chains = nil
12
+ end
13
+
14
+ def root=(value)
15
+ raise "You cannot change root UseGroup once the chains have been resolved" if @resolved_chains
16
+ super(value)
17
+ end
18
+
19
+ def use(preserve_chains: false, recursive: false)
20
+ UseCase.new(@name, type: @type, root: @root, options: @options, &@case).tap do |newcase|
21
+ if preserve_chains
22
+ chain_use = {preserve_chains: recursive, recursive: recursive}
23
+ @chains = @chains.map do |usecase|
24
+ if usecase.respond_to? :call
25
+ Proc.new do |usegroup|
26
+ usecase = usecase.call(usegroup)
27
+ usecase.use(chain_use).chain_to(newcase)
28
+ usecase
29
+ end
30
+ elsif usecase.is_a?(UseCase)
31
+ usecase.use(chain_use).chain_to(newcase)
32
+ usecase
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def launch(input: nil, people: nil, session:, options: {})
40
+ data_model = super(input: input, people: people, session: session, options: options)
41
+ launch_chain(data_model)
42
+ end
43
+
44
+ def chain(usecase = nil)
45
+ @@num_chains += 1
46
+ raise "Reached maximum number of chained use cases (#{MAX_CHAINS}). Looks like a recursive cyclic chain 'use'" if @@num_chains >= MAX_CHAINS
47
+ raise "A UseCase can only be chained with another UseCase" if usecase && !usecase.is_a?(UseCase)
48
+ raise "Missuse. Please use either parameter or block but not both" if block_given? && usecase
49
+ usecase = block_given?? Proc.new : usecase
50
+ @chains.push(usecase)
51
+ self
52
+ end
53
+
54
+ protected
55
+
56
+ def chain_to(usecase)
57
+ raise "A UseCase can only be chained with another UseCase" if usecase && !usecase.is_a?(UseCase)
58
+ usecase.chain(self)
59
+ end
60
+
61
+ def resolved_chains(use_group = nil)
62
+ return @resolved_chains if @resolved_chains
63
+ raise "Only UseGroup object can resolve chains. Given: #{use_group} " if use_group && !use_group.is_a?(UseGroup)
64
+
65
+ use_group = use_group || @root
66
+ @resolved_chains = @chains.map do |usecase|
67
+ usecase = usecase.call(use_group) if usecase.respond_to? :call
68
+ raise "A UseCase can only be chained with another UseCase" if usecase && !usecase.is_a?(UseCase)
69
+ usecase.resolved_chains(use_group)
70
+ usecase
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def launch_chain(data_model)
77
+ return data_model if resolved_chains.empty?
78
+
79
+ data_model.tap do |dm|
80
+ dm[self][:chains] ||= {}
81
+
82
+ resolved_chains.each do |usecase|
83
+ # chained cases use same params as parent case (out of simplicity)
84
+ data_chain = dm[self][:io].chain(usecase: usecase)
85
+ keyed_data = data_chain.params(keyed: true)
86
+ dm[self][:chains].merge(usecase.launch(keyed_data))
87
+ end
88
+ end
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+ end
95
+ end