eco-helpers 1.5.9 → 1.5.14

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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/CHANGELOG.md +58 -0
  4. data/eco-helpers.gemspec +3 -2
  5. data/lib/eco/api/common/people/default_parsers/csv_parser.rb +15 -2
  6. data/lib/eco/api/common/people/person_entry.rb +16 -4
  7. data/lib/eco/api/common/session/logger.rb +9 -1
  8. data/lib/eco/api/common/session/logger/cache.rb +91 -0
  9. data/lib/eco/api/common/session/logger/log.rb +48 -0
  10. data/lib/eco/api/microcases/set_core_with_supervisor.rb +5 -3
  11. data/lib/eco/api/organization/tag_tree.rb +7 -0
  12. data/lib/eco/api/policies.rb +1 -0
  13. data/lib/eco/api/policies/default_policies.rb +12 -0
  14. data/lib/eco/api/policies/default_policies/99_user_access_policy.rb +100 -0
  15. data/lib/eco/api/session.rb +13 -0
  16. data/lib/eco/api/session/batch/errors.rb +12 -2
  17. data/lib/eco/api/session/batch/job.rb +17 -7
  18. data/lib/eco/api/session/config/api.rb +1 -1
  19. data/lib/eco/version.rb +1 -1
  20. metadata +10 -17
  21. data/lib/eco/api/usecases/backup/append_usergroups_case.rb +0 -36
  22. data/lib/eco/api/usecases/backup/create_case.rb +0 -104
  23. data/lib/eco/api/usecases/backup/create_details_case.rb +0 -31
  24. data/lib/eco/api/usecases/backup/create_details_with_supervisor_case.rb +0 -48
  25. data/lib/eco/api/usecases/backup/hris_case.rb +0 -124
  26. data/lib/eco/api/usecases/backup/set_default_tag_case.rb +0 -49
  27. data/lib/eco/api/usecases/backup/set_supervisor_case.rb +0 -41
  28. data/lib/eco/api/usecases/backup/transfer_account_case.rb +0 -90
  29. data/lib/eco/api/usecases/backup/update_case.rb +0 -112
  30. data/lib/eco/api/usecases/backup/update_details_case.rb +0 -64
  31. data/lib/eco/api/usecases/backup/upsert_case.rb +0 -114
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37896bf21f1661d488b3af20ac7ed8ee298536d3e96324308f84459ad0e2abb2
4
- data.tar.gz: 05e8eac1fcb530509af91b62c17e89380f3b5ac0926a3a445bd29a309a440c44
3
+ metadata.gz: 2627cbc4d42e91e131e891cc4248895660a62bab2c331b43ac8ad3cd28b9cdee
4
+ data.tar.gz: fb2c29b13a67114ce8bbfbd16b271519896c201ec58cb9fd37b48db238abb014
5
5
  SHA512:
6
- metadata.gz: 75e90bf526e20a8dde18a64445f07d5bcaadd7038cb5e2070d8e777341a9799f604da94f4aae359772959a7d92da01db658311afa2d765c31882bf59b138dabe
7
- data.tar.gz: 338389f47335ae1f01f683ba3d54974ecce8eb70e90243534d835aa5cede39ab44458a37aa800206c018e023ff0e45eb228c7a52721a3e95801606743ae2b971
6
+ metadata.gz: 6da008ea99e2e6e323afcfbc0be117dd56402b95be100a68d808d3b4e81537def757fb66418fc0028492ea2e12ac74def8d4c6c47a7d05589bac3814ce9e10d9
7
+ data.tar.gz: 78af32b3b9f4725211baf6e458db91c064f49f25814bbda7177fe61af1b453597d658f1d734e155c8ebeb863aabdd36a0b6b81a9fcd972c6d92f2911f05ac11f
data/.yardopts CHANGED
@@ -5,5 +5,6 @@
5
5
  --no-private
6
6
  --output-dir ./doc
7
7
  'lib/**/*.rb'
8
+ CHANGELOG.md
8
9
  -
9
10
  LICENSE
data/CHANGELOG.md CHANGED
@@ -1,6 +1,64 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [1.5.14] - 2021-02-xx
5
+
6
+ ### Added
7
+ - `Eco::API::Policies::DefaultPolicies` policies that are run always (after the custom policies)
8
+ - `Eco::API::Policies::DefaultPolicies::UserAccess`:
9
+ - remove account if there's no `email`
10
+ - provision min user level to those with account (if no usergroup and no abilities)
11
+ - `Eco::API::Session#policies` which merges the default policies to be added/run after the custom policies
12
+ - `Eco::API::Common::Session::Logger`: add caching of logs
13
+ - `Eco::API::Common::Session::Logger::Cache` new class to manage cached logs
14
+ - `Eco::API::Common::Session::Logger::Log` new class to have a trace on logs
15
+ - `Eco::API::Session::Batch::Job#summary` added subjobs (error handlers) summary
16
+
17
+ ### Changed
18
+ - `Eco::API::Session::Batch::Job#launch` it will also run the default api policies before feedback and query launch
19
+ - `Eco::API::Common::People::PersonEntry` add error log when wrong email error is detected
20
+ - previously it would have crashed
21
+
22
+ ### Fixed
23
+
24
+ ## [1.5.13] - 2021-02-01
25
+
26
+ ### Added
27
+ ### Changed
28
+ - upgraded dependency with `ecoportal-api-oozes`
29
+
30
+ ### Fixed
31
+ - `Eco::API::Session::Config::Api` was not including the correct `host`
32
+ - this could have launched an `api` request to `live.ecoportal.com` when targeting `pre.dev`
33
+
34
+ ## [1.5.12] - 2021-02-01
35
+
36
+ ### Added
37
+ - `Eco::API::Common::People::DefaultParsers::CSVParser` when cell content is `Null`, capture `nil` value.
38
+
39
+ ### Changed
40
+ - upgraded `ecoportal-api` dependency
41
+
42
+ ### Fixed
43
+
44
+
45
+ ## [1.5.11] - 2021-01-25
46
+
47
+ ### Added
48
+ - `Eco::API::Organization::TagTree#subtag?` to check if the tag is in any subtree.
49
+
50
+ ### Changed
51
+
52
+ ### Fixed
53
+ - `Eco::API::MicroCases#set_supervisor` shouldn't set it if the entry does not have it.
54
+
55
+ ## [1.5.10] - 2021-01-19
56
+
57
+ ### Added
58
+ ### Changed
59
+ ### Fixed
60
+ - `Eco::API::Session::Batch::Errors#print` show the row number of the input data.
61
+
4
62
  ## [1.5.9] - 2021-01-08
5
63
 
6
64
  ### Added
data/eco-helpers.gemspec CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.summary = %q{eco-helpers to manage people api cases}
14
14
  s.homepage = "https://www.ecoportal.com"
15
15
  s.licenses = %w[MIT]
16
+ s.required_ruby_version = '>= 2.4.4'
16
17
 
17
18
  s.files = `git ls-files -z`.split("\x0").reject do |f|
18
19
  f.match(%r{^(test|spec|features)/})
@@ -28,8 +29,8 @@ Gem::Specification.new do |s|
28
29
  s.add_development_dependency "yard", ">= 0.9.18", "< 0.10"
29
30
  s.add_development_dependency "redcarpet", ">= 3.5.0", "< 3.6"
30
31
 
31
- s.add_dependency 'ecoportal-api', '>= 0.7.3', '< 0.8'
32
- s.add_dependency 'ecoportal-api-oozes', '>= 0.7.2', '< 0.8'
32
+ s.add_dependency 'ecoportal-api', '>= 0.7.4', '< 0.8'
33
+ s.add_dependency 'ecoportal-api-oozes', '>= 0.7.3', '< 0.8'
33
34
  s.add_dependency 'aws-sdk-s3', '>= 1.64.0', '< 2'
34
35
  s.add_dependency 'aws-sdk-ses', '>= 1.29.0', '< 2'
35
36
  s.add_dependency 'dotenv', '>= 2.7.0', '< 2.8'
@@ -5,8 +5,7 @@ class Eco::API::Common::People::DefaultParsers::CSVParser < Eco::API::Common::Lo
5
5
  Eco::CSV.parse(data, headers: true, skip_blanks: true).each_with_object([]) do |row, arr_hash|
6
6
  row_hash = row.headers.uniq.each_with_object({}) do |attr, hash|
7
7
  next if attr.to_s.strip.empty?
8
- value = row[attr]
9
- hash[attr.strip] = value.to_s.empty?? nil : value
8
+ hash[attr.strip] = parse_string(row[attr])
10
9
  end
11
10
  arr_hash.push(row_hash)
12
11
  end
@@ -23,4 +22,18 @@ class Eco::API::Common::People::DefaultParsers::CSVParser < Eco::API::Common::Lo
23
22
  CSV::Table.new(arr_rows).to_csv
24
23
  end
25
24
 
25
+ private
26
+
27
+ def parse_string(value)
28
+ return nil if value.to_s.empty?
29
+ return nil if null?(value)
30
+ value
31
+ end
32
+
33
+ def null?(value)
34
+ return true if !value
35
+ str = value.strip.upcase
36
+ ["NULL"].any? {|token| str == token}
37
+ end
38
+
26
39
  end
@@ -75,7 +75,7 @@ module Eco
75
75
  !parsing?
76
76
  end
77
77
 
78
- # @note `Eco::API::Common::People::EntryFactory#entries` adds this `idx`
78
+ # @note `Eco::API::Common::People::EntryFactory#entries` adds this `idx` (i.e. row number)
79
79
  # @return [Integer] the entry number in the input file
80
80
  def idx
81
81
  final_entry["idx"]
@@ -170,14 +170,25 @@ module Eco
170
170
  end
171
171
 
172
172
  # Setter to fill in all the `core` properties of the `Person` that are present in the `Entry`.
173
- # @note it only sets those core properties defined in the entry.
174
- # Meaning that if an core property is not present in the entry, this will not be set on the target person.
173
+ # @note
174
+ # 1. it only sets those core properties defined in the entry.
175
+ # Meaning that if an core property is not present in the entry, this will not be set on the target person.
176
+ # 2. if there's an incorrect email exception, it blanks the email and logs a warning message
175
177
  # @param person [Ecoportal::API::V1::Person] the person we want to set the core values to.
176
178
  # @param exclude [String, Array<String>] core attributes that should not be set/changed to the person.
177
179
  def set_core(person, exclude: nil)
178
180
  scoped_attrs = @emap.core_attrs - into_a(exclude)
179
181
  @final_entry.slice(*scoped_attrs).each do |attr, value|
180
- set_part(person, attr, value)
182
+ begin
183
+ set_part(person, attr, value)
184
+ rescue Exception => e
185
+ if attr == "email"
186
+ logger.error(e.to_s + " - setting blank email instead.")
187
+ set_part(person, attr, nil)
188
+ else
189
+ raise
190
+ end
191
+ end
181
192
  end
182
193
  end
183
194
 
@@ -460,6 +471,7 @@ module Eco
460
471
  obj.send("#{attr}=", value)
461
472
  end
462
473
  rescue Exception => e
474
+ # add more info to the error
463
475
  raise e.append_message " -- Entry #{to_s(:identify)}"
464
476
  end
465
477
  end
@@ -5,9 +5,12 @@ module Eco
5
5
  class Logger
6
6
  DEFAULT_TIMESTAMP_PATTERN = '%Y-%m-%dT%H:%M:%S'
7
7
 
8
+ attr_reader :cache
9
+
8
10
  def initialize(console_level: nil, file_level: ::Logger::DEBUG, log_file: nil, timestamp_console: false, enviro: nil)
9
11
  raise "Required Environment object (enviro:). Given: #{enviro}" if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
10
12
  @enviro = enviro
13
+ @cache = Logger::Cache.new
11
14
 
12
15
  timestamp_console = fetch_timestamp_console(timestamp_console)
13
16
  @console_logger = ::Logger.new(STDOUT).tap do |_logger|
@@ -21,7 +24,9 @@ module Eco
21
24
  if log_file = fetch_log_file(log_file)
22
25
  @file_logger = ::Logger.new(log_file).tap do |_logger|
23
26
  _logger.formatter = proc do |severity, datetime, progname, msg|
24
- "#{severity.to_s[0]}: #{datetime.strftime(DEFAULT_TIMESTAMP_PATTERN)} > #{msg}\n"
27
+ "#{severity.to_s[0]}: #{datetime.strftime(DEFAULT_TIMESTAMP_PATTERN)} > #{msg}\n".tap do |formatted|
28
+ cache.add(severity, datetime, msg, formatted)
29
+ end
25
30
  end
26
31
  _logger.level = fetch_file_level(file_level)
27
32
  end
@@ -107,3 +112,6 @@ module Eco
107
112
  end
108
113
  end
109
114
  end
115
+
116
+ require_relative "logger/cache"
117
+ require_relative "logger/log"
@@ -0,0 +1,91 @@
1
+ module Eco
2
+ module API
3
+ module Common
4
+ module Session
5
+ class Logger
6
+ class Cache
7
+ LEVELS = ["UNKNOWN", "FATAL", "ERROR", "WARN", "INFO", "DEBUG"]
8
+
9
+ def initialize
10
+ reset
11
+ end
12
+
13
+ def level(level)
14
+ cache[to_level(level)] ||= []
15
+ end
16
+
17
+ def add(level, datetime, message, formatted)
18
+ Logger::Log.new(level, datetime, message, formatted).tap do |log|
19
+ self.level(level).push(log)
20
+ end
21
+ end
22
+
23
+ def cache
24
+ @cache ||= {}
25
+ end
26
+
27
+ def reset(level: nil, start_time: nil, end_time: nil)
28
+ where(start_time, end_time) do |cond|
29
+ to_levels(level).map do |lev|
30
+ self.level(lev).reject(&cond)
31
+ end
32
+ end
33
+ self
34
+ end
35
+
36
+ def logs(level: nil, start_time: nil, end_time: nil)
37
+ where(start_time, end_time) do |cond|
38
+ to_levels(level).map do |lev|
39
+ self.level(lev).select(&cond)
40
+ end.flatten
41
+ end.sort
42
+ end
43
+
44
+ private
45
+
46
+ def where(start_time, end_time)
47
+ tstart = to_datetime(start_time)
48
+ tend = to_datetime(end_time)
49
+ condition = Proc.new do |log|
50
+ next true unless tstart || tend
51
+ log.after?(tstart) && log.before?(tend)
52
+ end
53
+
54
+ yield(condition)
55
+ end
56
+
57
+ def to_datetime(value)
58
+ return nil unless value
59
+ Time.parse(value)
60
+ end
61
+
62
+ def to_levels(value)
63
+ levels = [value].flatten.map {|v| to_level(v)}.compact
64
+ levels = levels.empty?? LEVELS : levels
65
+ end
66
+
67
+ def to_level(value)
68
+ nil_or_upcase(value).tap do |out|
69
+ valid_level!(out)
70
+ end
71
+ end
72
+
73
+ def valid_level!(str)
74
+ return true if !str
75
+ unless LEVELS.any? {|lev| str == lev}
76
+ raise "Unknown level #{str}. Should be one of #{LEVELS}"
77
+ end
78
+ end
79
+
80
+ def nil_or_upcase(value)
81
+ value = value.to_s.upcase if value
82
+ return yield(value) if block_given?
83
+ value
84
+ end
85
+
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,48 @@
1
+ module Eco
2
+ module API
3
+ module Common
4
+ module Session
5
+ class Logger
6
+ class Log
7
+
8
+ attr_accessor :level, :datetime, :message, :formatted
9
+
10
+ def initialize(level, datetime, message, formatted)
11
+ @level = level
12
+ @datetime = datetime
13
+ @message = message
14
+ @formatted = formatted
15
+ end
16
+
17
+ def to_s
18
+ self.formatted
19
+ end
20
+
21
+ def <=>(other)
22
+ self.datetime <=> other.datetime
23
+ end
24
+
25
+ def before?(value)
26
+ return true if !value
27
+ datetime <= to_datetime(value)
28
+ end
29
+
30
+ def after?(value)
31
+ return true if !value
32
+ datetime >= to_datetime(value)
33
+ end
34
+
35
+ private
36
+
37
+ def to_datetime(value)
38
+ return value if value.is_a?(Time)
39
+ return nil unless value
40
+ Time.parse(value)
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -11,9 +11,11 @@ module Eco
11
11
  def set_core_with_supervisor(entry, person, people, supers_job, options)
12
12
  unless options.dig(:exclude, :core) && !person.new?
13
13
  micro.set_core(entry, person, options)
14
- micro.set_supervisor(entry.supervisor_id, person, people, options) do |unkown_id|
15
- # delay setting supervisor if does not exit
16
- supers_job.add(person) {|person| person.supervisor_id = unkown_id}
14
+ if entry.supervisor_id?
15
+ micro.set_supervisor(entry.supervisor_id, person, people, options) do |unkown_id|
16
+ # delay setting supervisor if does not exit
17
+ supers_job.add(person) {|person| person.supervisor_id = unkown_id}
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -68,6 +68,13 @@ module Eco
68
68
  tags - tags(depth: depth)
69
69
  end
70
70
 
71
+ # Verifies if a tag exists in the subtree(s).
72
+ # @param key [String] tag to verify.
73
+ # @return [Boolean]
74
+ def subtag?(key)
75
+ subtags.include?(key&.upcase)
76
+ end
77
+
71
78
  # Verifies if a tag exists in the tree.
72
79
  # @param key [String] tag to verify.
73
80
  # @return [Boolean]
@@ -36,3 +36,4 @@ module Eco
36
36
  end
37
37
 
38
38
  require_relative 'policies/policy'
39
+ require_relative 'policies/default_policies'
@@ -0,0 +1,12 @@
1
+ module Eco
2
+ module API
3
+ class Policies
4
+ class DefaultPolicies < Eco::API::Policies
5
+ autoloads_children_of "Eco::API::Common::Loaders::Policy"
6
+ autoload_namespace "Eco::API::Policies::DefaultPolicies"
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ require_relative 'default_policies/99_user_access_policy'
@@ -0,0 +1,100 @@
1
+ class Eco::API::Policies::DefaultPolicies::UserAccess < Eco::API::Common::Loaders::Policy
2
+ name "default-user-access"
3
+
4
+ attr_reader :session, :options
5
+ attr_accessor :account_removed_count
6
+
7
+ def main(people, session, options, policy, job)
8
+ @session = session; @options = options
9
+
10
+ self.account_removed_count = 0
11
+
12
+ people.each do |person|
13
+ remove_account_when_no_email!(person) if person.email.to_s.empty?
14
+ account.policy_group_ids = [defid] if no_policy_group_ids?(person)
15
+ refresh_abilities!(person.account)
16
+ end
17
+
18
+ warn_account_removal!
19
+ end
20
+
21
+ private
22
+
23
+ def warn_account_removal!
24
+ if account_removed_count > 0
25
+ msg = "Removed account to #{account_removed_count} people"
26
+ session.logger.warn(msg)
27
+ end
28
+ end
29
+
30
+ def remove_account_when_no_email!(person)
31
+ if person.account
32
+ account_removed_count += 1 if had_account?(person)
33
+ person.account = nil
34
+ end
35
+ end
36
+
37
+ def had_account?(person)
38
+ return false if person.new?
39
+ return false if person.account_added?
40
+ return !!person.original_doc["account"]
41
+ end
42
+
43
+ def provision_basic_level!(person)
44
+ if account = person.account
45
+
46
+ unless options.dig(:exclude, :abilities)
47
+ account.permissions_custom = session.new_preset(person)
48
+
49
+ if no_abilities?(person)
50
+ account.permissions_custom = min_abilities
51
+ end
52
+ end
53
+
54
+ end
55
+ end
56
+
57
+ def refresh_abilities!(account)
58
+ return nil unless account
59
+
60
+ end
61
+
62
+ def no_policy_group_ids?(person)
63
+ (account = person.account) && account.policy_group_ids.empty?
64
+ end
65
+
66
+ def no_abilities?(person)
67
+ person.account.permissions_custom &&
68
+ person.account.permissions_custom.values.all?(&:nil?)
69
+ end
70
+
71
+ def min_abilities
72
+ {
73
+ "files" => "upload",
74
+ "data" => nil,
75
+ "reports" => nil,
76
+ "pages" => "create",
77
+ "page_editor" => "basic",
78
+ "registers" => "view",
79
+ "organization" => nil,
80
+ "person_core" => "attach",
81
+ "person_core_edit" => nil,
82
+ "person_core_create" => nil,
83
+ "person_details" => "view",
84
+ "person_account" => nil
85
+ }
86
+ end
87
+
88
+ def defid
89
+ @defid ||= policy_groups.to_id(default_group)
90
+ end
91
+
92
+ def default_group
93
+ session.config.people.default_usergroup
94
+ end
95
+
96
+ def pgs
97
+ session.policy_groups
98
+ end
99
+
100
+ end