eco-helpers 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.rspec +3 -0
- data/README.md +20 -0
- data/eco-helpers.gemspec +34 -0
- data/lib/eco-helpers.rb +15 -0
- data/lib/eco/api.rb +13 -0
- data/lib/eco/api/common.rb +10 -0
- data/lib/eco/api/common/people.rb +17 -0
- data/lib/eco/api/common/people/base_parser.rb +16 -0
- data/lib/eco/api/common/people/default_parsers.rb +40 -0
- data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +28 -0
- data/lib/eco/api/common/people/default_parsers/date_parser.rb +33 -0
- data/lib/eco/api/common/people/default_parsers/multi_parser.rb +33 -0
- data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +23 -0
- data/lib/eco/api/common/people/default_parsers/select_parser.rb +29 -0
- data/lib/eco/api/common/people/entries.rb +120 -0
- data/lib/eco/api/common/people/person_entry.rb +380 -0
- data/lib/eco/api/common/people/person_factory.rb +114 -0
- data/lib/eco/api/common/people/person_modifier.rb +62 -0
- data/lib/eco/api/common/people/person_parser.rb +140 -0
- data/lib/eco/api/common/people/types.rb +47 -0
- data/lib/eco/api/common/session.rb +15 -0
- data/lib/eco/api/common/session/base_session.rb +46 -0
- data/lib/eco/api/common/session/environment.rb +47 -0
- data/lib/eco/api/common/session/file_manager.rb +90 -0
- data/lib/eco/api/common/session/logger.rb +105 -0
- data/lib/eco/api/common/session/mailer.rb +92 -0
- data/lib/eco/api/common/session/s3_uploader.rb +110 -0
- data/lib/eco/api/common/version_patches.rb +11 -0
- data/lib/eco/api/common/version_patches/external_person.rb +11 -0
- data/lib/eco/api/eco_faker.rb +59 -0
- data/lib/eco/api/organization.rb +13 -0
- data/lib/eco/api/organization/account.rb +23 -0
- data/lib/eco/api/organization/people.rb +118 -0
- data/lib/eco/api/organization/policy_groups.rb +51 -0
- data/lib/eco/api/organization/preferences.rb +28 -0
- data/lib/eco/api/organization/preferences_reference.json +23 -0
- data/lib/eco/api/organization/presets.rb +138 -0
- data/lib/eco/api/organization/presets_backup.rb +220 -0
- data/lib/eco/api/organization/presets_values.json +10 -0
- data/lib/eco/api/organization/tag_tree.rb +134 -0
- data/lib/eco/api/organization_old.rb +73 -0
- data/lib/eco/api/session.rb +180 -0
- data/lib/eco/api/session/batch.rb +132 -0
- data/lib/eco/api/session/batch_job.rb +152 -0
- data/lib/eco/api/session/batch_jobs.rb +131 -0
- data/lib/eco/api/session/batch_status.rb +138 -0
- data/lib/eco/api/session/task.rb +92 -0
- data/lib/eco/api/session_config.rb +179 -0
- data/lib/eco/api/session_config/api.rb +47 -0
- data/lib/eco/api/session_config/apis.rb +78 -0
- data/lib/eco/api/session_config/files.rb +30 -0
- data/lib/eco/api/session_config/logger.rb +54 -0
- data/lib/eco/api/session_config/mailer.rb +65 -0
- data/lib/eco/api/session_config/people.rb +89 -0
- data/lib/eco/api/session_config/s3_bucket.rb +62 -0
- data/lib/eco/api/session_config/use_cases.rb +30 -0
- data/lib/eco/api/usecases.rb +12 -0
- data/lib/eco/api/usecases/base_case.rb +14 -0
- data/lib/eco/api/usecases/case_data.rb +13 -0
- data/lib/eco/api/usecases/default_cases.rb +53 -0
- data/lib/eco/api/usecases/default_cases/change_email_case.rb +47 -0
- data/lib/eco/api/usecases/default_cases/create_details_case.rb +29 -0
- data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +49 -0
- data/lib/eco/api/usecases/default_cases/delete_case.rb +20 -0
- data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +24 -0
- data/lib/eco/api/usecases/default_cases/hris_case.rb +67 -0
- data/lib/eco/api/usecases/default_cases/new_email_case.rb +26 -0
- data/lib/eco/api/usecases/default_cases/new_id_case.rb +26 -0
- data/lib/eco/api/usecases/default_cases/refresh_presets.rb +25 -0
- data/lib/eco/api/usecases/default_cases/reinvite_case.rb +22 -0
- data/lib/eco/api/usecases/default_cases/remove_account_case.rb +36 -0
- data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +24 -0
- data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +44 -0
- data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +39 -0
- data/lib/eco/api/usecases/default_cases/to_csv_case.rb +36 -0
- data/lib/eco/api/usecases/default_cases/update_details_case.rb +30 -0
- data/lib/eco/api/usecases/default_cases/upsert_account_case.rb +35 -0
- data/lib/eco/api/usecases/use_case.rb +177 -0
- data/lib/eco/api/usecases/use_group.rb +104 -0
- data/lib/eco/cli.rb +9 -0
- data/lib/eco/cli/input.rb +109 -0
- data/lib/eco/cli/input_multi.rb +137 -0
- data/lib/eco/cli/root.rb +8 -0
- data/lib/eco/cli/session.rb +9 -0
- data/lib/eco/cli/session/batch.rb +9 -0
- data/lib/eco/common.rb +7 -0
- data/lib/eco/common/base_cli.rb +116 -0
- data/lib/eco/common/language.rb +9 -0
- data/lib/eco/data.rb +9 -0
- data/lib/eco/data/crypto.rb +7 -0
- data/lib/eco/data/crypto/encryption.rb +318 -0
- data/lib/eco/data/files.rb +10 -0
- data/lib/eco/data/files/directory.rb +93 -0
- data/lib/eco/data/files/file_pattern.rb +32 -0
- data/lib/eco/data/files/helpers.rb +90 -0
- data/lib/eco/data/mapper.rb +54 -0
- data/lib/eco/data/random.rb +10 -0
- data/lib/eco/data/random/distribution.rb +133 -0
- data/lib/eco/data/random/fake.rb +320 -0
- data/lib/eco/data/random/values.rb +80 -0
- data/lib/eco/language.rb +12 -0
- data/lib/eco/language/curry.rb +28 -0
- data/lib/eco/language/hash_transform.rb +68 -0
- data/lib/eco/language/hash_transform_modifier.rb +114 -0
- data/lib/eco/language/match.rb +30 -0
- data/lib/eco/language/match_modifier.rb +190 -0
- data/lib/eco/language/models.rb +11 -0
- data/lib/eco/language/models/attribute_parser.rb +38 -0
- data/lib/eco/language/models/collection.rb +181 -0
- data/lib/eco/language/models/modifier.rb +68 -0
- data/lib/eco/language/models/wrap.rb +114 -0
- data/lib/eco/language/values_at.rb +159 -0
- data/lib/eco/lexic/dictionary.rb +33 -0
- data/lib/eco/lexic/dictionary/dictionary.txt +355484 -0
- data/lib/eco/lexic/dictionary/tags.json +38 -0
- data/lib/eco/scripting.rb +30 -0
- data/lib/eco/scripting/README.md +11 -0
- data/lib/eco/scripting/arguments.rb +40 -0
- data/lib/eco/tester.rb +97 -0
- data/lib/eco/version.rb +3 -0
- metadata +325 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class HrisCase < BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
@cases.define("hris", type: :sync) do |entries, people, session, options|
|
9
|
+
# IMPORTANT: this two lines ensure that key users are preserved (only manually maintained)
|
10
|
+
#people = people.exclude(session.discarded_entries)
|
11
|
+
#entries = entries.exclude(session.discarded_entries)
|
12
|
+
|
13
|
+
creation = session.job_group("main").new("create", type: :create, sets: [:core, :details, :account])
|
14
|
+
update = session.job_group("main").new("update", type: :update, sets: [:core, :details, :account])
|
15
|
+
supers = session.job_group("post").new("supers", type: :update, sets: :core)
|
16
|
+
#remove = session.job_group("post").new("remove_account", type: :update, sets: :account)
|
17
|
+
|
18
|
+
#people.users.each_with_index do |person, i|
|
19
|
+
# if !entries.find(person)
|
20
|
+
# remove.add(person) do |person|
|
21
|
+
# person.account = nil
|
22
|
+
# person
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#end
|
26
|
+
|
27
|
+
entries.each.with_index do |entry, i|
|
28
|
+
person = people.find(entry)
|
29
|
+
person = session.new_person if create = !person
|
30
|
+
|
31
|
+
entry.set_core(person, exclude: "supervisor_id")
|
32
|
+
entry.set_details(person)
|
33
|
+
entry.set_account(person) #if !remove.people.find(entry)
|
34
|
+
person.account.permissions_custom = session.new_preset(person)
|
35
|
+
|
36
|
+
person.account.default_tag = person.account.filter_tags.first if person.account.filter_tags.length == 1
|
37
|
+
|
38
|
+
creation.add(person) if create
|
39
|
+
update.add(person) unless create
|
40
|
+
|
41
|
+
# 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
|
+
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
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class NewEmailCase < BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
@cases.define("new-email", type: :sync) do |entries, people, session, options|
|
9
|
+
job = session.job_group("main").new("update", type: :update, sets: :core)
|
10
|
+
|
11
|
+
entries.each.with_index do |entry, i|
|
12
|
+
if person = people.find(entry)
|
13
|
+
person.email = entry.email
|
14
|
+
job.add(person)
|
15
|
+
else
|
16
|
+
session.logger.error("Entry(#{i}) - this person does not exist: #{entry.to_s(:identify)}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class NewIdCase < BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
@cases.define("new-id", type: :sync) do |entries, people, session|
|
9
|
+
job = session.job_group("main").new("update", type: :update, sets: :core)
|
10
|
+
|
11
|
+
entries.each.with_index do |entry, i|
|
12
|
+
if person = people.find(entry)
|
13
|
+
person.external_id = entry.external_id
|
14
|
+
job.add(person)
|
15
|
+
else
|
16
|
+
session.logger.error("Entry(#{i}) - this person does not exist: #{entry.to_s(:identify)}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class RefreshPresets < BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
@cases.define("refresh-presets", type: :transform) do |people, session|
|
9
|
+
job = session.job_group("main").new("update", type: :update, sets: :account)
|
10
|
+
|
11
|
+
people = people.users
|
12
|
+
people.each do |person|
|
13
|
+
person.account.permissions_custom = session.new_preset(person)
|
14
|
+
job.add(person)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class ReinviteCase < BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
@cases.define("reinvite", type: :transform) do |people, session|
|
9
|
+
invite = session.job_group("main").new("invite", type: :update, sets: :account)
|
10
|
+
people.users.each do |person|
|
11
|
+
person.account.send_invites = true
|
12
|
+
invite.add(person)
|
13
|
+
end
|
14
|
+
invite
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class RemoveAccountCase < BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
|
9
|
+
@cases.define("remove-account", type: :transform) do |people, session|
|
10
|
+
update = session.job_group("main").new("update", type: :update, sets: [:core, :account])
|
11
|
+
people.users.map do |person|
|
12
|
+
person.account = nil
|
13
|
+
update.add(person)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
@cases.define("remove-account", type: :sync) do |entries, people, session|
|
18
|
+
update = session.job_group("main").new("update", type: :update, sets: [:core, :account])
|
19
|
+
|
20
|
+
entries.each.with_index do |entry, i|
|
21
|
+
if person = people.find(entry)
|
22
|
+
person.account = nil
|
23
|
+
update.add(person)
|
24
|
+
else
|
25
|
+
session.logger.error("Entry(#{i}) - this person does not exist: #{entry.to_s(:identify)}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class ResetLandingPageCase < UseCases::BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
@cases.define("reset-landing-page", type: :transform) do |people, session|
|
9
|
+
job = session.job_group("main").new("update", type: :update, sets: :account)
|
10
|
+
|
11
|
+
people.users.each do |user|
|
12
|
+
user.account.landing_page_id = nil
|
13
|
+
job.add(user)
|
14
|
+
end
|
15
|
+
|
16
|
+
job
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class SetDefaultTagCase < BaseCase
|
6
|
+
# take the deepest tag (the one that is further down in the tree)
|
7
|
+
# different options (several nodes at the same depth):
|
8
|
+
# => take the common node between them (i.e. you have Hamilton and Auckland -> take New Zealand)
|
9
|
+
# => if there's no common node between them, take the `first` (unless they are at top level of the tree)
|
10
|
+
|
11
|
+
def process
|
12
|
+
@cases.define("set-default-tag", type: :transform) do |people, session, options|
|
13
|
+
if !session.tagtree
|
14
|
+
msg = "There is no tagtree definition in the configuration files\n" +
|
15
|
+
"For this usecase to work out you need to define it."
|
16
|
+
session.logger.fatal(msg)
|
17
|
+
exit
|
18
|
+
end
|
19
|
+
|
20
|
+
# IMPORTANT: this two lines ensure that only people to be updated is selected
|
21
|
+
all_people = people
|
22
|
+
people = people.account_present
|
23
|
+
|
24
|
+
if people.length <= 0
|
25
|
+
session.logger.info("There are no people with account... aborting script")
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
|
29
|
+
update = session.job_group("main").new("update", type: :update, sets: :account)
|
30
|
+
|
31
|
+
people.each_with_index do |person, i|
|
32
|
+
#next unless person.id == "5c527ba63f7690001243f5b2"
|
33
|
+
person.account.default_tag = session.tagtree.default_tag(*person.account.filter_tags)
|
34
|
+
update.add(person)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class SetSupervisorCase < BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
@cases.define("set-supervisor", type: :sync) do |entries, people, session|
|
9
|
+
job = session.job_group("main").new("update", type: :update, sets: :core)
|
10
|
+
|
11
|
+
entries.each.with_index do |entry, i|
|
12
|
+
person = people.find(entry)
|
13
|
+
|
14
|
+
if !person
|
15
|
+
session.logger.error("Entry(#{i}) - this person does not exist: #{entry.to_s(:identify)}")
|
16
|
+
else
|
17
|
+
sup_id = entry.supervisor_id
|
18
|
+
supervisor = people.person(id: sup_id, external_id: sup_id, email: sup_id)
|
19
|
+
|
20
|
+
if !supervisor
|
21
|
+
if entry.supervisor_id
|
22
|
+
msg = "Entry(#{i}) - supervisor id #{entry.supervisor_id} does not exist for person: #{entry.to_s(:identify)}"
|
23
|
+
session.logger.warn(msg)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
# set internal id of the supervisor (detect if actually changed)
|
27
|
+
person.supervisor_id = supervisor.id
|
28
|
+
job.add(person)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class ToCsvCase < BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
@cases.define("to-csv", type: :export) do |people, session, options|
|
9
|
+
unless people && !people.empty?
|
10
|
+
session.logger.warn("No source people to create the file... aborting!")
|
11
|
+
next false
|
12
|
+
end
|
13
|
+
|
14
|
+
unless file = options[:file]
|
15
|
+
session.logger.error("Destination file not specified")
|
16
|
+
next false
|
17
|
+
end
|
18
|
+
|
19
|
+
session.logger.info("going to create file: #{file}")
|
20
|
+
CSV.open(file, "w") do |csv|
|
21
|
+
deps = {"supervisor_id" => {people: people}}
|
22
|
+
entry = session.new_entry(people.first, dependencies: deps)
|
23
|
+
csv << entry.to_hash.keys
|
24
|
+
people.each do |person|
|
25
|
+
csv << session.new_entry(person, dependencies: deps).to_hash.values
|
26
|
+
end
|
27
|
+
end
|
28
|
+
true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class UpdateDetailsCase < BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
@cases.define("update-details", type: :sync) do |entries, people, session, options|
|
9
|
+
job = session.job_group("main").new("update", type: :update, sets: [:core, :details])
|
10
|
+
|
11
|
+
entries.each.with_index do |entry, i|
|
12
|
+
if person = people.find(entry)
|
13
|
+
core_excluded = ["supervisor_id"]
|
14
|
+
core_excluded.push("email") if options.dig(:exclude, :email)
|
15
|
+
entry.set_core(person, exclude: core_excluded) unless options.dig(:exclude, :core)
|
16
|
+
entry.set_details(person)
|
17
|
+
|
18
|
+
job.add(person)
|
19
|
+
else
|
20
|
+
session.logger.error("Entry(#{i}) - this person does not exist: #{entry.to_s(:identify)}")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class DefaultCases
|
5
|
+
class UpsertAccountCase < BaseCase
|
6
|
+
|
7
|
+
def process
|
8
|
+
@cases.define("upsert-account", type: :sync) do |entries, people, session, options|
|
9
|
+
creation = session.job_group("main").new("create", type: :create, sets: [:core, :account])
|
10
|
+
update = session.job_group("main").new("update", type: :update, sets: [:core, :account])
|
11
|
+
|
12
|
+
entries.each.with_index do |entry, i|
|
13
|
+
create = false
|
14
|
+
unless person = people.find(entry)
|
15
|
+
create = true
|
16
|
+
person = session.new_person
|
17
|
+
entry.set_core(person)
|
18
|
+
#entry.set_details(person)
|
19
|
+
end
|
20
|
+
|
21
|
+
entry.set_account(person)
|
22
|
+
person.account.permissions_custom = session.new_preset(person)
|
23
|
+
person.account.send_invites = false if options.key?(:send_invites) && !options(:send_invites)
|
24
|
+
|
25
|
+
creation.add(person) if create
|
26
|
+
update.add(person) unless create
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
module Eco
|
2
|
+
module API
|
3
|
+
module UseCases
|
4
|
+
class UseCase
|
5
|
+
TYPES = [:import, :filter, :transform, :sync, :export]
|
6
|
+
ALL_PARAMS = [:input, :people, :session, :options]
|
7
|
+
TYPE_PARAMS = {
|
8
|
+
import: [:input, :session],
|
9
|
+
filter: [:people, :session, :options],
|
10
|
+
transform: [:people, :session],
|
11
|
+
export: [:people, :session, :options]
|
12
|
+
}
|
13
|
+
MAX_CHAINS = 70
|
14
|
+
@@num_chains = 0
|
15
|
+
|
16
|
+
attr_reader :name, :type, :times_used
|
17
|
+
|
18
|
+
def initialize(name, type:, root:, options: {}, &block)
|
19
|
+
|
20
|
+
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
|
29
|
+
end
|
30
|
+
|
31
|
+
def root=(value)
|
32
|
+
raise "You cannot change root UseGroup once the chains have been resolved" if @resolved_chains
|
33
|
+
raise "Root should be a UseGroup. Given: #{value}" if !value.is_a?(UseGroup)
|
34
|
+
@root = value
|
35
|
+
end
|
36
|
+
|
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 || {})
|
63
|
+
|
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
|
77
|
+
|
78
|
+
data_model = {
|
79
|
+
self => {
|
80
|
+
data: { input: input, people: people, session: session, options: opts, output: out }
|
81
|
+
}
|
82
|
+
}
|
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
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|