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.
- checksums.yaml +4 -4
- data/.gitignore +19 -0
- data/.yardopts +2 -2
- data/Gemfile +6 -0
- data/Rakefile +27 -0
- data/eco-helpers.gemspec +9 -6
- data/lib/eco/api.rb +2 -1
- data/lib/eco/api/common/people.rb +1 -1
- data/lib/eco/api/common/people/base_parser.rb +31 -1
- data/lib/eco/api/common/people/default_parsers.rb +5 -1
- data/lib/eco/api/common/people/default_parsers/csv_parser.rb +37 -0
- data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +0 -1
- data/lib/eco/api/common/people/entries.rb +14 -18
- data/lib/eco/api/common/people/entry_factory.rb +97 -9
- data/lib/eco/api/common/people/person_entry.rb +147 -206
- data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +212 -0
- data/lib/eco/api/common/people/person_factory.rb +10 -12
- data/lib/eco/api/common/people/person_parser.rb +97 -37
- data/lib/eco/api/common/session/base_session.rb +1 -2
- data/lib/eco/api/common/session/file_manager.rb +1 -1
- data/lib/eco/api/organization.rb +2 -1
- data/lib/eco/api/organization/people.rb +54 -22
- data/lib/eco/api/organization/person_schemas.rb +54 -0
- data/lib/eco/api/organization/policy_groups.rb +5 -9
- data/lib/eco/api/organization/{presets.rb → presets_factory.rb} +1 -1
- data/lib/eco/api/policies.rb +10 -0
- data/lib/eco/api/policies/base_policy.rb +14 -0
- data/lib/eco/api/policies/policy.rb +20 -0
- data/lib/eco/api/policies/used_policies.rb +37 -0
- data/lib/eco/api/session.rb +36 -34
- data/lib/eco/api/session/batch.rb +94 -44
- data/lib/eco/api/session/batch_job.rb +108 -48
- data/lib/eco/api/session/batch_jobs.rb +4 -5
- data/lib/eco/api/session/batch_status.rb +70 -11
- data/lib/eco/api/session/config.rb +22 -5
- data/lib/eco/api/session/config/files.rb +10 -1
- data/lib/eco/api/session/config/people.rb +18 -5
- data/lib/eco/api/session/config/policies.rb +29 -0
- data/lib/eco/api/session/config/use_cases.rb +3 -7
- data/lib/eco/api/session/job_groups.rb +9 -10
- data/lib/eco/api/usecases.rb +2 -1
- data/lib/eco/api/usecases/base_case.rb +7 -2
- data/lib/eco/api/usecases/default_cases/change_email_case.rb +4 -2
- data/lib/eco/api/usecases/default_cases/create_case.rb +2 -1
- data/lib/eco/api/usecases/default_cases/create_details_case.rb +3 -1
- data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +4 -2
- data/lib/eco/api/usecases/default_cases/hris_case.rb +20 -13
- data/lib/eco/api/usecases/default_cases/new_email_case.rb +3 -1
- data/lib/eco/api/usecases/default_cases/new_id_case.rb +4 -2
- data/lib/eco/api/usecases/default_cases/recover_db_case.rb +9 -5
- data/lib/eco/api/usecases/default_cases/remove_account_case.rb +4 -2
- data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +4 -2
- data/lib/eco/api/usecases/default_cases/to_csv_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +2 -2
- data/lib/eco/api/usecases/default_cases/update_case.rb +16 -2
- data/lib/eco/api/usecases/default_cases/update_details_case.rb +3 -1
- data/lib/eco/api/usecases/default_cases/upsert_case.rb +25 -3
- data/lib/eco/api/usecases/use_case.rb +23 -140
- data/lib/eco/api/usecases/use_case_chain.rb +95 -0
- data/lib/eco/api/usecases/use_case_io.rb +117 -0
- data/lib/eco/api/usecases/use_group.rb +25 -5
- data/lib/eco/common/base_cli_backup.rb +1 -0
- data/lib/eco/language/models.rb +1 -1
- data/lib/eco/language/models/collection.rb +42 -31
- data/lib/eco/language/models/parser_serializer.rb +68 -0
- data/lib/eco/version.rb +1 -1
- metadata +93 -38
- data/lib/eco/api/common/people/types.rb +0 -47
- data/lib/eco/api/usecases/case_data.rb +0 -13
- data/lib/eco/language/models/attribute_parser.rb +0 -38
- data/lib/eco/lexic/dictionary.rb +0 -33
- data/lib/eco/lexic/dictionary/dictionary.txt +0 -355484
- data/lib/eco/lexic/dictionary/tags.json +0 -38
@@ -16,8 +16,7 @@ module Eco
|
|
16
16
|
|
17
17
|
def initialize(e)
|
18
18
|
raise "Expected object Eco::API::Common::Session::Environment. Given: #{e.class}" unless e.is_a?(Environment)
|
19
|
-
|
20
|
-
self.environment = e #if e.is_a?(Environment)
|
19
|
+
self.environment = e
|
21
20
|
end
|
22
21
|
|
23
22
|
def session
|
data/lib/eco/api/organization.rb
CHANGED
@@ -6,7 +6,8 @@ module Eco
|
|
6
6
|
end
|
7
7
|
|
8
8
|
require_relative 'organization/tag_tree'
|
9
|
-
require_relative 'organization/
|
9
|
+
require_relative 'organization/presets_factory'
|
10
10
|
require_relative 'organization/preferences'
|
11
11
|
require_relative 'organization/people'
|
12
12
|
require_relative 'organization/policy_groups'
|
13
|
+
require_relative 'organization/person_schemas'
|
@@ -2,7 +2,6 @@ module Eco
|
|
2
2
|
module API
|
3
3
|
module Organization
|
4
4
|
class People < Eco::Language::Models::Collection
|
5
|
-
|
6
5
|
# build the shortcuts of Collection
|
7
6
|
attr_collection :id, :external_id, :email, :name, :supervisor_id
|
8
7
|
attr_presence :account, :details
|
@@ -16,7 +15,7 @@ module Eco
|
|
16
15
|
end
|
17
16
|
|
18
17
|
def [](id_or_ext)
|
19
|
-
|
18
|
+
id(id_or_ext) || external_id(id_or_ext)
|
20
19
|
end
|
21
20
|
|
22
21
|
def id(*args)
|
@@ -28,32 +27,65 @@ module Eco
|
|
28
27
|
end
|
29
28
|
|
30
29
|
def users
|
31
|
-
|
30
|
+
account_present(true)
|
32
31
|
end
|
33
32
|
|
34
33
|
def contacts
|
35
|
-
|
34
|
+
details_present(true)
|
36
35
|
end
|
37
36
|
|
38
37
|
def non_users
|
39
|
-
|
38
|
+
account_present(false)
|
40
39
|
end
|
41
40
|
|
42
|
-
|
41
|
+
# It searches a person using the paramters given.
|
42
|
+
# @param id [String] the `internal id` of the person
|
43
|
+
# @param external_id [String] the `exernal_id` of the person
|
44
|
+
# @param email [String] the `email` of the person
|
45
|
+
# @param strict [Boolean] if should perform a `soft` or a `strict` search. `strict` will avoid repeated email addresses.
|
46
|
+
# @return [Person, nil] the person we were searching, or `nil` if not found.
|
47
|
+
def person(id: nil, external_id: nil, email: nil, strict: false)
|
43
48
|
init_caches
|
44
49
|
pers = @by_id[id]&.first if id
|
45
|
-
pers = @by_external_id[external_id&.strip]&.first
|
46
|
-
|
47
|
-
|
48
|
-
|
50
|
+
pers = @by_external_id[external_id&.strip]&.first if !pers && !external_id.to_s.strip.empty?
|
51
|
+
|
52
|
+
# strict prevents taking existing user for searched person with same email
|
53
|
+
# specially useful if the organisation ensures all have external id (no need for email search)
|
54
|
+
if !pers && (!strict || external_id.to_s.strip.empty?)
|
55
|
+
# person still not found and either not strict or no external_id provided
|
56
|
+
pers = @by_users_email[email&.downcase.strip]&.first if !email.to_s.strip.empty?
|
57
|
+
|
58
|
+
if !pers && !strict && !email.to_s.strip.empty?
|
59
|
+
candidates = @by_non_users_email[email&.downcase.strip] || []
|
60
|
+
raise "Too many non-user candidates (#{candiates.length}) with email '#{email}'" if candidates.length > 1
|
61
|
+
pers = candidates.first
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
pers = @by_external_id[email&.downcase.strip]&.first if !pers && !email.to_s.strip.empty?
|
66
|
+
|
49
67
|
pers
|
50
68
|
end
|
51
69
|
|
52
|
-
def find(object)
|
53
|
-
id
|
70
|
+
def find(object, strict: false)
|
71
|
+
id = object.respond_to?("id")? object.send("id") : nil
|
54
72
|
external_id = object.respond_to?("external_id")? object.send("external_id") : nil
|
55
|
-
email
|
56
|
-
person(id: id, external_id: external_id, email: email)
|
73
|
+
email = object.respond_to?("email")? object.send("email") : nil
|
74
|
+
person(id: id, external_id: external_id, email: email, strict: strict)
|
75
|
+
end
|
76
|
+
|
77
|
+
def uniq(include_unsearchable: false)
|
78
|
+
init_caches
|
79
|
+
unsearchable = []
|
80
|
+
newFrom to_a.each_with_object([]) do |person, people|
|
81
|
+
if found = find(person)
|
82
|
+
people << found
|
83
|
+
else
|
84
|
+
unsearchable << person
|
85
|
+
end
|
86
|
+
end.tap do |people|
|
87
|
+
people << unsearchable if include_unsearchable
|
88
|
+
end
|
57
89
|
end
|
58
90
|
|
59
91
|
def exclude(object)
|
@@ -64,15 +96,15 @@ module Eco
|
|
64
96
|
discarded = list.map do |person|
|
65
97
|
find(person)
|
66
98
|
end.compact
|
67
|
-
newFrom
|
99
|
+
newFrom to_a - discarded
|
68
100
|
end
|
69
101
|
|
70
102
|
def email_id_maps
|
71
|
-
|
103
|
+
users.group_by(:email).transform_values { |person| person.id }
|
72
104
|
end
|
73
105
|
|
74
106
|
def group_by_supervisor
|
75
|
-
|
107
|
+
to_h(:supervisor_id)
|
76
108
|
end
|
77
109
|
|
78
110
|
# only those that are present
|
@@ -89,7 +121,7 @@ module Eco
|
|
89
121
|
sup_ids - (sup_ids & self.ids)
|
90
122
|
end
|
91
123
|
|
92
|
-
def to_h(attr)
|
124
|
+
def to_h(attr = "id")
|
93
125
|
super(attr || "id")
|
94
126
|
end
|
95
127
|
|
@@ -103,10 +135,10 @@ module Eco
|
|
103
135
|
|
104
136
|
def init_caches
|
105
137
|
return if @caches_init
|
106
|
-
@by_id
|
107
|
-
@by_external_id
|
108
|
-
@by_users_email
|
109
|
-
@by_non_users_email =
|
138
|
+
@by_id = to_h
|
139
|
+
@by_external_id = to_h('external_id')
|
140
|
+
@by_users_email = users.to_h('email')
|
141
|
+
@by_non_users_email = non_users.to_h('email')
|
110
142
|
@caches_init = true
|
111
143
|
end
|
112
144
|
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module Organization
|
4
|
+
class PersonSchemas < Eco::Language::Models::Collection
|
5
|
+
# build the shortcuts of Collection
|
6
|
+
attr_collection :id, :name
|
7
|
+
|
8
|
+
def initialize(schemas = [], klass: Ecoportal::API::Internal::PersonSchema)
|
9
|
+
@klass = Ecoportal::API::Internal::PersonSchema
|
10
|
+
@caches_init = false
|
11
|
+
super(schemas, klass: @klass)
|
12
|
+
init_caches
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_id(name)
|
16
|
+
case name
|
17
|
+
when Enumerable
|
18
|
+
name.map do |n|
|
19
|
+
schema(n)&.id
|
20
|
+
end.compact
|
21
|
+
else
|
22
|
+
schema(name)&.id
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_name(id)
|
27
|
+
schema(id)&.name
|
28
|
+
end
|
29
|
+
|
30
|
+
def schema(id_name)
|
31
|
+
@by_id.fetch(schema_id(id_name), nil)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def schema_name(id_name)
|
37
|
+
(@by_id[id_name] || @by_name[id_name&.downcase])&.name&.downcase
|
38
|
+
end
|
39
|
+
|
40
|
+
def schema_id(id_name)
|
41
|
+
(@by_name[id_name&.downcase] || @by_id[id_name])&.id
|
42
|
+
end
|
43
|
+
|
44
|
+
def init_caches
|
45
|
+
return if @caches_init
|
46
|
+
@by_id = self.map { |pg| [pg.id, pg] }.to_h
|
47
|
+
@by_name = self.map { |pg| [pg.name&.downcase, pg] }.to_h
|
48
|
+
@caches_init = true
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -5,10 +5,8 @@ module Eco
|
|
5
5
|
# build the shortcuts of Collection
|
6
6
|
attr_collection :id, :name
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
def initialize(policy_groups = [], klass: INTERNAL::PolicyGroup)
|
11
|
-
@klass = INTERNAL::PolicyGroup
|
8
|
+
def initialize(policy_groups = [], klass: Ecoportal::API::Internal::PolicyGroup)
|
9
|
+
@klass = Ecoportal::API::Internal::PolicyGroup
|
12
10
|
@caches_init = false
|
13
11
|
super(policy_groups, klass: @klass)
|
14
12
|
init_caches
|
@@ -16,7 +14,7 @@ module Eco
|
|
16
14
|
|
17
15
|
def to_id(name)
|
18
16
|
case name
|
19
|
-
when
|
17
|
+
when Enumerable
|
20
18
|
name.map do |n|
|
21
19
|
policy_group(n)&.id
|
22
20
|
end.compact
|
@@ -54,13 +52,11 @@ module Eco
|
|
54
52
|
private
|
55
53
|
|
56
54
|
def policy_group_name(id_name)
|
57
|
-
@by_id
|
58
|
-
@by_name.fetch(id_name&.downcase, nil)&.name&.downcase
|
55
|
+
(@by_id[id_name] || @by_name[id_name&.downcase])&.name&.downcase
|
59
56
|
end
|
60
57
|
|
61
58
|
def policy_group_id(id_name)
|
62
|
-
@by_name
|
63
|
-
@by_id.fetch(id_name, nil)&.id
|
59
|
+
(@by_name[id_name&.downcase] || @by_id[id_name])&.id
|
64
60
|
end
|
65
61
|
|
66
62
|
def init_caches
|
@@ -5,7 +5,7 @@ module Eco
|
|
5
5
|
class PresetsFactory
|
6
6
|
ABILITIES = File.join(__dir__, 'presets_values.json')
|
7
7
|
DEFAULT_CUSTOM = 'presets_custom.json'
|
8
|
-
DEFAULT_MAP
|
8
|
+
DEFAULT_MAP = 'presets_map.json'
|
9
9
|
|
10
10
|
def initialize(presets_custom: DEFAULT_CUSTOM, presets_map: DEFAULT_MAP, enviro: nil, policy_groups: nil)
|
11
11
|
@abilities = JSON.load(File.open(ABILITIES))
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module Policies
|
4
|
+
class BasePolicy < Eco::API::UseCases::BaseCase
|
5
|
+
|
6
|
+
def initialize(policies, **options)
|
7
|
+
raise "Expected UsedPolicies. Given: #{policies.class}" unless policies.is_a?(UsedPolicies)
|
8
|
+
super(policies, **options)
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module Policies
|
4
|
+
class Policy < Eco::API::UseCases::UseCase
|
5
|
+
TYPES = [:transform]
|
6
|
+
|
7
|
+
def initialize(name, type: :transform, root:, options: {}, &block)
|
8
|
+
raise "Undefine usecase type #{type}. Please, use any of #{TYPES}" unless self.class.valid_type?(type)
|
9
|
+
super(name, type: type, root: root, options: options, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def root=(value)
|
13
|
+
raise "Root should be a UsedPolicies object. Given: #{value}" if !value.is_a?(UsedPolicies)
|
14
|
+
@root = value
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module Policies
|
4
|
+
class UsedPolicies < Eco::API::UseCases::UseGroup
|
5
|
+
|
6
|
+
attr_reader :policies
|
7
|
+
|
8
|
+
def add(policy)
|
9
|
+
raise "Expected Policy object. Given: #{policy}" if !policy || !policy.is_a?(Policy)
|
10
|
+
super(policy)
|
11
|
+
end
|
12
|
+
|
13
|
+
def define(name, type: :transform, &block)
|
14
|
+
Policy.new(name, type: type, root: self, &block).tap do |policy|
|
15
|
+
add(policy)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# TODO: decide if policies deal with queue or single person
|
20
|
+
def launch(people:, session:, options: {})
|
21
|
+
|
22
|
+
args = {
|
23
|
+
people: people,
|
24
|
+
session: session,
|
25
|
+
options: options
|
26
|
+
}
|
27
|
+
|
28
|
+
items.map do |policy|
|
29
|
+
session.logger.debug("UsedPolicies: going to process '#{policy.name}' policy")
|
30
|
+
policy.launch(**args)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/eco/api/session.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
module Eco
|
2
2
|
module API
|
3
3
|
class Session < Common::Session::BaseSession
|
4
|
-
attr_reader :batch, :policy_groups
|
5
|
-
attr_accessor :schema, :schemas_hash
|
6
|
-
attr_reader :tagtree
|
4
|
+
attr_reader :batch, :policy_groups, :tagtree
|
7
5
|
attr_reader :job_groups
|
8
|
-
|
9
|
-
|
10
|
-
#alias_method :org, :organization
|
6
|
+
attr_reader :schemas
|
7
|
+
attr_accessor :schema
|
11
8
|
|
12
9
|
def initialize(init = {})
|
13
10
|
e = init
|
@@ -24,13 +21,9 @@ module Eco
|
|
24
21
|
|
25
22
|
@use_cases = Eco::API::UseCases::DefaultCases.new.merge(config.usecases.use_group)
|
26
23
|
|
27
|
-
@schemas
|
28
|
-
@schemas_hash = @schemas.map do |sch|
|
29
|
-
[[sch.id, sch], [sch.name.downcase, sch]]
|
30
|
-
end.flatten(1).to_h
|
31
|
-
|
24
|
+
@schemas = config.schemas
|
32
25
|
self.schema = config.people.default_schema || @schemas.first
|
33
|
-
@policy_groups =
|
26
|
+
@policy_groups = config.policy_groups
|
34
27
|
|
35
28
|
@tagtree = nil
|
36
29
|
if tree_file = config.dig('org', 'tagtree')
|
@@ -50,10 +43,9 @@ module Eco
|
|
50
43
|
end
|
51
44
|
|
52
45
|
def self.configure
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
conf
|
46
|
+
Session::Config.new.tap do |conf|
|
47
|
+
yield(conf) if block_given?
|
48
|
+
end
|
57
49
|
end
|
58
50
|
|
59
51
|
# TASKS & JOBS
|
@@ -99,9 +91,9 @@ module Eco
|
|
99
91
|
def schema=(value)
|
100
92
|
case value
|
101
93
|
when String
|
102
|
-
|
103
|
-
|
104
|
-
|
94
|
+
unless @schema = @schemas.schema(value)
|
95
|
+
fatal "The schema with id or name '#{value}' does not exist"
|
96
|
+
end
|
105
97
|
when Ecoportal::API::V1::PersonSchema
|
106
98
|
@schema = value
|
107
99
|
else
|
@@ -109,16 +101,24 @@ module Eco
|
|
109
101
|
return
|
110
102
|
end
|
111
103
|
|
112
|
-
@person_factory
|
104
|
+
@person_factory = Eco::API::Common::People::PersonFactory.new(schema: @schema)
|
105
|
+
|
106
|
+
# TODO: check PersonEntry#to_internal and #to_external in init_attr_trackers
|
107
|
+
# => when attr_map is avoided, it doesn't work as it should
|
108
|
+
if map_file = config.people.fields_mapper
|
109
|
+
mappings = map_file ? file_manager.load_json(map_file) : []
|
110
|
+
else
|
111
|
+
mappings = []
|
112
|
+
end
|
113
|
+
attr_map = Eco::Data::Mapper.new(mappings)
|
113
114
|
|
114
|
-
|
115
|
-
|
116
|
-
@entry_factory = Eco::API::Common::People::EntryFactory.new({
|
117
|
-
schema: @schema,
|
115
|
+
@entry_factory = Eco::API::Common::People::EntryFactory.new({
|
116
|
+
schema: @schema,
|
118
117
|
person_parser: config.people.parser,
|
119
|
-
|
120
|
-
logger:
|
118
|
+
attr_map: attr_map,
|
119
|
+
logger: logger
|
121
120
|
})
|
121
|
+
self
|
122
122
|
end
|
123
123
|
|
124
124
|
def new_preset(input)
|
@@ -140,14 +140,16 @@ module Eco
|
|
140
140
|
@entry_factory.new(data, dependencies: dependencies)
|
141
141
|
end
|
142
142
|
|
143
|
+
def entries(*args)
|
144
|
+
@entry_factory.entries(*args)
|
145
|
+
end
|
146
|
+
|
147
|
+
def export(*args)
|
148
|
+
@entry_factory.export(*args)
|
149
|
+
end
|
150
|
+
|
143
151
|
def csv_entries(file)
|
144
|
-
|
145
|
-
if Eco::API::Common::Session::FileManager.file_exists?(file)
|
146
|
-
CSV.foreach(file, headers: true, encoding: Eco::API::Common::Session::FileManager.encoding(file)).with_index do |row, i|
|
147
|
-
rows.push(row)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
@entry_factory.entries(rows)
|
152
|
+
return entries(file: file, format: :csv)
|
151
153
|
end
|
152
154
|
|
153
155
|
def discarded_entries
|
@@ -160,7 +162,7 @@ module Eco
|
|
160
162
|
args = { session: self }.merge(params)
|
161
163
|
fatal("Undefined usecase '#{name}' of type '#{type.to_s}'") if !@use_cases.defined?(name, type: type)
|
162
164
|
logger.debug("Session: going to process '#{name}' defined case")
|
163
|
-
@use_cases.case(name, type: type).
|
165
|
+
@use_cases.case(name, type: type).launch(**args)
|
164
166
|
end
|
165
167
|
|
166
168
|
end
|