eco-helpers 0.6.17 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -2,33 +2,71 @@ module Eco
2
2
  module API
3
3
  class Session
4
4
  class BatchStatus < Common::Session::BaseSession
5
- attr_reader :queue, :method
5
+ TYPES = [:exact, :search]
6
+
7
+ attr_reader :queue, :method, :type
6
8
  attr_reader :root
7
9
 
8
- def initialize(e, queue:, method:)
10
+ class << self
11
+ def valid_type?(value)
12
+ TYPES.include?(value)
13
+ end
14
+ end
15
+
16
+ def initialize(e, queue:, method:, type: :exact)
9
17
  super(e)
10
18
  fatal("In batch operations you must batch an array. Received: #{queue}") unless queue && queue.is_a?(Array)
11
19
 
20
+ self.type = type
12
21
  @method = method
13
- @queue = queue
14
- @hash = @queue.each_with_index.map do |entry, i|
22
+ @queue = queue
23
+ @hash = @queue.each_with_index.map do |entry, i|
15
24
  [entry, i]
16
25
  end.to_h
17
- @responses = Array(0..@queue.length-1)
26
+ @responses = []
27
+ @person_match = []
28
+ @people_match = Array.new(@queue.length, [])
18
29
  end
19
30
 
20
31
  def root=(object)
21
32
  @root = object
22
33
  end
23
34
 
35
+ def type=(value)
36
+ fatal("Invalid :type '#{value}. You must specify type: as one of #{TYPES} ") unless self.class.valid_type?(value)
37
+ @type = value
38
+ end
39
+
24
40
  def [](key)
25
41
  @responses[to_index(key)]
26
42
  end
27
43
 
44
+
28
45
  def []=(key, response)
29
46
  @responses[to_index(key)] = response
30
47
  end
31
48
 
49
+ def person(key)
50
+ return self[key].result if success?(key)
51
+ nil
52
+ end
53
+
54
+ def person_match(key)
55
+ @person_match[to_index(key)]
56
+ end
57
+
58
+ def set_person_match(key, person)
59
+ @person_match[to_index(key)] = person
60
+ end
61
+
62
+ def people_match(key)
63
+ @people_match[to_index(key)]
64
+ end
65
+
66
+ def set_people_match(key, people)
67
+ @people_match[to_index(key)] = people
68
+ end
69
+
32
70
  def received?(key)
33
71
  !!self[key]
34
72
  end
@@ -38,16 +76,37 @@ module Eco
38
76
  end
39
77
 
40
78
  def people
41
- fatal "This batch wasn't a 'get'. Can't obtain people without 'get' method" unless method == "get"
42
- out = Array(0..queue.length-1)
43
- @responses.each_with_index do |respose, i|
44
- out[i] = response.result
79
+ fatal "This batch wasn't a 'get'. Can't obtain people without 'get' method" unless method == :get
80
+ if type == :exact
81
+ out = Array(queue.length)
82
+ @responses.each_with_index do |respose, i|
83
+ out[i] = response.result
84
+ end
85
+ elsif type == :search
86
+ out = []
87
+ queue.each_with_index.map do |entry, i|
88
+ pers = person(entry)
89
+ pers ||= person_match(entry)
90
+ out += pers ? [pers] : people_match(entry)
91
+ end
45
92
  end
46
93
  out
47
94
  end
48
95
 
49
96
  def error_queries
50
97
  queue.each_with_index.map do |query,i|
98
+ unless self[i]
99
+ pp "Error: query with no response. You might have duplicated entries in your queue.\n"
100
+ msg = "Queue length: #{queue.length}\n"
101
+ msg += "Query with no response. Person: #{person_ref(query)}\n"
102
+ queue.map do |entry|
103
+ if entry.id == query.id || entry.external_id == query.external_id || entry.email == query.email
104
+ msg += "It could be this peson entry: #{person_ref(entry)}\n"
105
+ end
106
+ end
107
+ raise msg
108
+ end
109
+
51
110
  self[i].success? ? nil : query
52
111
  end.compact
53
112
  end
@@ -95,8 +154,8 @@ module Eco
95
154
  def print_errors(sort: :by_status)
96
155
  strs = str_errors(sort: sort)
97
156
  if strs.length > 0
98
- logger.error(strs.join("\n"))
99
- #strs.each {|str| logger.error(str)}
157
+ logger.info()
158
+ logger.error("There were #{strs.length} errors:\n" + strs.join("\n"))
100
159
  else
101
160
  logger.info("There were no errors for the current batch '#{method}'!! ;)")
102
161
  end
@@ -43,6 +43,10 @@ module Eco
43
43
  self["usecases"] ||= Session::Config::UseCases.new(root: self)
44
44
  end
45
45
 
46
+ def api_policies
47
+ self["api_policies"] ||= Session::Config::Policies.new(root: self)
48
+ end
49
+
46
50
  # LOGGER
47
51
  def log_console_level=(value)
48
52
  logger.console_level= value
@@ -103,11 +107,6 @@ module Eco
103
107
  apis.api(logger)
104
108
  end
105
109
 
106
- def policy_groups
107
- policy_groups = api&.policy_groups.to_a.compact
108
- Eco::API::Organization::PolicyGroups.new(policy_groups)
109
- end
110
-
111
110
  # FILES
112
111
  def working_directory=(path)
113
112
  files.working_directory = path
@@ -130,6 +129,18 @@ module Eco
130
129
  org["tagtree"] = file
131
130
  end
132
131
 
132
+ def policy_groups
133
+ return @policy_groups if instance_variable_defined?(:@policy_groups)
134
+ pgs = api&.policy_groups.to_a
135
+ @policy_groups = Eco::API::Organization::PolicyGroups.new(pgs)
136
+ end
137
+
138
+ def schemas
139
+ return @schemas if instance_variable_defined?(:@schemas)
140
+ schs = api&.person_schemas.to_a
141
+ @schemas = Eco::API::Organization::PersonSchemas.new(schs)
142
+ end
143
+
133
144
  # PEOPLE
134
145
  def discarded_people_file=(value)
135
146
  people.discarded_file = value
@@ -171,6 +182,11 @@ module Eco
171
182
  usecases.add(&block)
172
183
  end
173
184
 
185
+ # API POLICIES
186
+ def policies(&block)
187
+ api_policies.add(&block)
188
+ end
189
+
174
190
  end
175
191
  end
176
192
  end
@@ -184,3 +200,4 @@ require_relative 'config/s3_storage'
184
200
  require_relative 'config/files'
185
201
  require_relative 'config/people'
186
202
  require_relative 'config/use_cases'
203
+ require_relative 'config/policies'
@@ -6,7 +6,8 @@ module Eco
6
6
 
7
7
  def initialize(root:)
8
8
  super(nil)
9
- @root = root
9
+ @root = root
10
+ @validations = {}
10
11
  end
11
12
 
12
13
  def working_directory=(path)
@@ -25,6 +26,14 @@ module Eco
25
26
  self["timestamp_pattern"]
26
27
  end
27
28
 
29
+ def add_validation(format)
30
+ raise "Block must be given" unless block_given?
31
+ @validations[format] = Proc.new
32
+ end
33
+
34
+ def validate(format, input)
35
+ @validations[format].call(input) if @validations.key?(format)
36
+ end
28
37
  end
29
38
  end
30
39
  end
@@ -19,6 +19,15 @@ module Eco
19
19
  self["cache"]
20
20
  end
21
21
 
22
+ # specifies if people search should be strict or not
23
+ def strict_search=(value)
24
+ self["strict_search"] = !!value
25
+ end
26
+
27
+ def strict_search?
28
+ self["strict_search"]
29
+ end
30
+
22
31
  # api queried logs
23
32
  def requests_folder=(folder)
24
33
  self["requests_folder"] = folder
@@ -71,19 +80,23 @@ module Eco
71
80
  self["presets_map"]
72
81
  end
73
82
 
74
- # CUSTOM PERSON PARSERS
83
+ # Defines an `ParserSerializer` for a `PersonParser` of certain `format`
84
+ # @param format [Symbol] the target format this parser/serializer is made for.
75
85
  def add_parser(format: :csv)
76
- new_parsers = Eco::API::Common::People::PersonParser.new
77
- yield(new_parsers, config)
78
-
79
86
  parsers[format] ||= Eco::API::Common::People::PersonParser.new
80
- parsers[format] = parsers[format] ? parsers[format].merge(new_parsers) : new_parsers
87
+ parsers[format].tap do |prs|
88
+ yield(prs, config)
89
+ end
81
90
  end
82
91
 
92
+ # @return [Hash] with defined pairs format `key` and Person parsers.
83
93
  def parsers
84
94
  self["parsers"] ||= {}
85
95
  end
86
96
 
97
+ # The person parser/serializer for a given format (default `csv`).
98
+ # @param format [Symbol] the format this parser/serializer recognizes.
99
+ # @return [Eco::API::Common::People::PersonParser] parser/serializer for the defined `format`.
87
100
  def parser(format: :csv)
88
101
  parsers[format]
89
102
  end
@@ -0,0 +1,29 @@
1
+ module Eco
2
+ module API
3
+ class Session
4
+ class Config
5
+ class Policies < Hash
6
+ attr_reader :config
7
+
8
+ def initialize(root:)
9
+ super(nil)
10
+ @root = root
11
+ @config = @root
12
+ end
13
+
14
+ # API POLICIES
15
+ def add
16
+ policies.tap do |group|
17
+ yield(group, config)
18
+ end
19
+ end
20
+
21
+ def policies
22
+ self["used_policies"] ||= Eco::API::Policies::UsedPolicies.new
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -13,13 +13,9 @@ module Eco
13
13
 
14
14
  # CUSTOM USE CASES
15
15
  def add
16
- new_group = Eco::API::UseCases::UseGroup.new
17
- yield(new_group, config)
18
-
19
- self["use_group"] ||= Eco::API::UseCases::UseGroup.new
20
- group = self["use_group"]
21
- group = group ? group.merge(new_group) : group
22
- self["use_group"] = group
16
+ use_group.tap do |group|
17
+ yield(group, config)
18
+ end
23
19
  end
24
20
 
25
21
  def use_group
@@ -26,18 +26,17 @@ module Eco
26
26
  def new(name, order: :last)
27
27
  fatal "Can't create job group named '#{name}' because it already exists." if exists?(name)
28
28
 
29
- group = BatchJobs.new(enviro, name: name)
30
- @groups[name] = group
29
+ BatchJobs.new(enviro, name: name).tap do |group|
30
+ @groups[name] = group
31
31
 
32
- if order == :last
33
- @order.push(group)
34
- else
35
- @order.unshift(group)
36
- end
37
-
38
- @callbacks[group] = Proc.new if block_given?
32
+ if order == :last
33
+ @order.push(group)
34
+ else
35
+ @order.unshift(group)
36
+ end
39
37
 
40
- group
38
+ @callbacks[group] = Proc.new if block_given?
39
+ end
41
40
  end
42
41
 
43
42
  def pending?
@@ -5,8 +5,9 @@ module Eco
5
5
  end
6
6
  end
7
7
 
8
- #require_relative 'usecases/case_data'
9
8
  require_relative 'usecases/base_case'
10
9
  require_relative 'usecases/use_case'
10
+ require_relative 'usecases/use_case_chain'
11
+ require_relative 'usecases/use_case_io'
11
12
  require_relative 'usecases/use_group'
12
13
  require_relative 'usecases/default_cases'
@@ -2,12 +2,17 @@ module Eco
2
2
  module API
3
3
  module UseCases
4
4
  class BaseCase
5
+
5
6
  def initialize(cases, **options)
6
- @cases = cases
7
+ raise "Expected UseGroup. Given: #{cases.class}" unless cases.is_a?(UseGroup)
8
+ @cases = cases
7
9
  @options = options
8
10
  end
9
11
 
10
- def process; end
12
+ def process
13
+ raise "You should reimplement this method"
14
+ end
15
+
11
16
  end
12
17
  end
13
18
  end
@@ -5,13 +5,15 @@ module Eco
5
5
  class ChangeEMailCase < BaseCase
6
6
 
7
7
  def process
8
- @cases.define("change-email", type: :sync) do |entries, people, session|
8
+ @cases.define("change-email", type: :sync) do |entries, people, session, options|
9
9
  remove = session.job_group("main").new("remove account", type: :update, sets: :account)
10
10
  change = session.job_group("main").new("change email", type: :update, sets: :core)
11
11
  add_account = session.job_group("post").new("add account", type: :update, sets: :account)
12
12
 
13
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
14
+
13
15
  entries.each.with_index do |entry, i|
14
- person = people.find(entry)
16
+ person = people.find(entry, strict: strict_search)
15
17
 
16
18
  if !person
17
19
  session.logger.error("Entry(#{i}) - this person does not exist: #{entry.to_s(:identify)}")
@@ -8,10 +8,11 @@ module Eco
8
8
  @cases.define("create", type: :sync) do |entries, people, session, options|
9
9
  creation = session.job_group("main").new("create", type: :create, sets: [:core, :details, :account])
10
10
 
11
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
11
12
  pgs = session.policy_groups
12
13
 
13
14
  entries.each.with_index do |entry, i|
14
- if person = people.find(entry)
15
+ if person = people.find(entry, strict: strict_search)
15
16
  session.logger.error("Entry(#{i}) - this person (id: '#{person.id}') already exists: #{entry.to_s(:identify)}")
16
17
  else
17
18
  person = session.new_person
@@ -8,8 +8,10 @@ module Eco
8
8
  @cases.define("create-details", type: :sync) do |entries, people, session, options|
9
9
  creation = session.job_group("main").new("create", type: :create, 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
  session.logger.error("Entry(#{i}) - this person (id: '#{person.id}') already exists: #{entry.to_s(:identify)}")
14
16
  else
15
17
  person = session.new_person
@@ -6,12 +6,14 @@ module Eco
6
6
 
7
7
  def process
8
8
  # good candidate to do @cases.case("create-details").use.chain(@cases.case("set-supervisor").use)
9
- @cases.define("create-details-with-supervisor", type: :sync) do |entries, people, session|
9
+ @cases.define("create-details-with-supervisor", type: :sync) do |entries, people, session, options|
10
10
  creation = session.job_group("main").new("create", type: :create, sets: [:core, :details])
11
11
  supers = session.job_group("post").new("supers", type: :update, sets: :core)
12
12
 
13
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
14
+
13
15
  entries.each.with_index do |entry, i|
14
- if person = people.find(entry)
16
+ if person = people.find(entry, strict: strict_search)
15
17
  session.logger.error("Entry(#{i}) - this person (id: '#{person.id}') already exists: #{entry.to_s(:identify)}")
16
18
  else
17
19
  person = session.new_person
@@ -24,33 +24,40 @@ module Eco
24
24
  # end
25
25
  #end
26
26
 
27
+ strict_search = session.config.people.strict_search? || options.dig(:search, :strict)
28
+
27
29
  entries.each.with_index do |entry, i|
28
- person = people.find(entry)
30
+ person = people.find(entry, strict: strict_search)
29
31
  person = session.new_person if create = !person
30
32
 
31
33
  entry.set_core(person, exclude: "supervisor_id")
32
34
  entry.set_details(person)
33
35
  entry.set_account(person) #if !remove.people.find(entry)
34
- person.account.permissions_custom = session.new_preset(person)
36
+ person.account.send_invites = options[:send_invites] if options.key?(:send_invites)
37
+
38
+ person.account.permissions_custom = session.new_preset(person) unless !create && options.dig(:exclude, :abilities)
35
39
 
36
40
  person.account.default_tag = person.account.filter_tags.first if person.account.filter_tags.length == 1
37
41
 
42
+
38
43
  creation.add(person) if create
39
44
  update.add(person) unless create
40
45
 
41
46
  # set supervisor
42
- if !(sup_id = entry.supervisor_id)
43
- person.supervisor_id = nil
44
- else
45
- if supervisor = people.person(id: sup_id, external_id: sup_id, email: sup_id)
46
- person.supervisor_id = supervisor.id
47
+ # set supervisor
48
+ unless options.dig(:exclude, :core) || options.dig(:exclude, :supervisor)
49
+ if !(sup_id = entry.supervisor_id)
50
+ person.supervisor_id = nil
47
51
  else
48
- # delay setting supervisor if does not exit
49
- supers.add(person) do |person|
50
- #person = session.new_person(person: person.doc)
51
- person.sync
52
- person.supervisor_id = sup_id
53
- person
52
+ if supervisor = people.person(id: sup_id, external_id: sup_id, email: sup_id)
53
+ person.supervisor_id = supervisor.id
54
+ else
55
+ # delay setting supervisor if does not exit
56
+ supers.add(person) do |person|
57
+ person.consolidate!
58
+ person.supervisor_id = sup_id
59
+ person
60
+ end
54
61
  end
55
62
  end
56
63
  end