eco-helpers 2.0.24 → 2.0.29
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +89 -6
- data/lib/eco/api/common.rb +0 -1
- data/lib/eco/api/common/loaders.rb +2 -0
- data/lib/eco/api/common/loaders/base.rb +58 -0
- data/lib/eco/api/common/loaders/case_base.rb +33 -0
- data/lib/eco/api/common/loaders/error_handler.rb +2 -2
- data/lib/eco/api/common/loaders/parser.rb +30 -5
- data/lib/eco/api/common/loaders/policy.rb +1 -1
- data/lib/eco/api/common/loaders/use_case.rb +1 -1
- data/lib/eco/api/common/people/default_parsers/csv_parser.rb +129 -1
- data/lib/eco/api/common/people/entries.rb +83 -14
- data/lib/eco/api/common/people/entry_factory.rb +11 -10
- data/lib/eco/api/common/people/person_attribute_parser.rb +8 -0
- data/lib/eco/api/common/people/person_entry.rb +7 -6
- data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +55 -16
- data/lib/eco/api/common/people/person_factory.rb +4 -2
- data/lib/eco/api/common/people/person_parser.rb +7 -1
- data/lib/eco/api/common/people/supervisor_helpers.rb +1 -1
- data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +0 -8
- data/lib/eco/api/common/version_patches/ecoportal_api/internal_person.rb +0 -8
- data/lib/eco/api/microcases/set_core_with_supervisor.rb +4 -2
- data/lib/eco/api/microcases/set_supervisor.rb +29 -8
- data/lib/eco/api/microcases/with_each.rb +7 -3
- data/lib/eco/api/microcases/with_each_starter.rb +3 -2
- data/lib/eco/api/organization/people.rb +7 -1
- data/lib/eco/api/session.rb +7 -2
- data/lib/eco/api/session/batch.rb +1 -1
- data/lib/eco/api/session/batch/job.rb +9 -1
- data/lib/eco/api/usecases/default_cases/create_case.rb +10 -1
- data/lib/eco/api/usecases/default_cases/create_details_case.rb +10 -1
- data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +10 -1
- data/lib/eco/api/usecases/default_cases/hris_case.rb +25 -1
- data/lib/eco/api/usecases/default_cases/to_csv_case.rb +1 -37
- data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +42 -0
- data/lib/eco/api/usecases/default_cases/upsert_case.rb +10 -1
- data/lib/eco/cli/config/default/input.rb +2 -2
- data/lib/eco/cli/config/default/options.rb +29 -8
- data/lib/eco/cli/config/default/usecases.rb +16 -0
- data/lib/eco/cli/config/default/workflow.rb +7 -4
- data/lib/eco/cli/config/filters.rb +6 -2
- data/lib/eco/cli/config/filters/input_filters.rb +3 -2
- data/lib/eco/cli/config/filters/people_filters.rb +3 -2
- data/lib/eco/cli/config/help.rb +1 -1
- data/lib/eco/cli/config/options_set.rb +6 -4
- data/lib/eco/cli/config/use_cases.rb +6 -3
- data/lib/eco/csv.rb +2 -0
- data/lib/eco/language/models/collection.rb +5 -2
- data/lib/eco/version.rb +1 -1
- metadata +3 -2
- data/lib/eco/api/common/base_loader.rb +0 -72
@@ -5,6 +5,42 @@ module Eco
|
|
5
5
|
# Class meant to offer a _collection_ of entries, normally used to get parsed input data.
|
6
6
|
# @attr_reader entries [Array<Eco::API::Common::PeopleEntry] a pure `Array` object.
|
7
7
|
class Entries < Eco::Language::Models::Collection
|
8
|
+
# Error class that allows to handle cases where multiple entries were found for the same criterion.
|
9
|
+
# @note its main purpose to prevent the false pairing of duplicates or override information between different people.
|
10
|
+
class MultipleSearchResults < StandardError
|
11
|
+
attr_reader :candidates, :property
|
12
|
+
# @param msg [String] the basic message error.
|
13
|
+
# @param candiates [Array<PersonEntry>] the entries that match the same search criterion.
|
14
|
+
# @param property [String] the property of the entry model that triggered the error (base of the search criterion).
|
15
|
+
def initialize(msg, candidates: [], property: "email")
|
16
|
+
@candidates = candidates
|
17
|
+
@property = property
|
18
|
+
super(msg + " " + candidates_summary)
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param with_index [Boolean] to add an index to each candidate description.
|
22
|
+
# @return [Array<String>] the `candidates` identified
|
23
|
+
def identify_candidates(with_index: false)
|
24
|
+
candidates.map.each_with_index do |entry, i|
|
25
|
+
index = with_index ? "#{i}. " : ""
|
26
|
+
"#{index} #{entry.identify}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Person] the `candidate` in the `index` position
|
31
|
+
def candidate(index)
|
32
|
+
candidates[index]
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def candidates_summary
|
38
|
+
lines = ["The following entries have the same '#{property}':"]
|
39
|
+
lines.concat(identify_candidates(with_index: true)).join("\n ")
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
8
44
|
# build the shortcuts of Collection
|
9
45
|
attr_collection :id, :external_id, :email, :name, :supervisor_id
|
10
46
|
|
@@ -54,19 +90,34 @@ module Eco
|
|
54
90
|
# @!group Searchers
|
55
91
|
|
56
92
|
# Search function to find an `entry` based on one of different options
|
93
|
+
# It searches an entry using the parameters given.
|
94
|
+
# @note This is how the search function actually works:
|
95
|
+
# 1. if eP `id` is given, returns the entry (if found), otherwise...
|
96
|
+
# 2. if `external_id` is given, returns the entry (if found), otherwise...
|
97
|
+
# 3. if `strict` is `false` and `email` is given:
|
98
|
+
# - if there is only 1 entry with that email, returns that entry, otherwise...
|
99
|
+
# - if found but, there are many candidate entries, it raises MultipleSearchResults error
|
100
|
+
# - if entry `external_id` matches `email`, returns that entry
|
101
|
+
# @raise MultipleSearchResults if there are multiple entries with the same `email`
|
102
|
+
# and there's no other criteria to find the entry. It only gets to this point if
|
103
|
+
# `external_id` was **not** provided and we are **not** in 'strict' search mode.
|
104
|
+
# However, it could be we were in `strict` mode and `external_id` was not provided.
|
105
|
+
# @param id [String] the `internal id` of the person
|
106
|
+
# @param external_id [String] the `exernal_id` of the person
|
107
|
+
# @param email [String] the `email` of the person
|
108
|
+
# @param strict [Boolean] if should perform a `:soft` or a `:strict` search. `strict` will avoid repeated email addresses.
|
109
|
+
# @return [Entry, nil] the entry we were searching, or `nil` if not found.
|
57
110
|
def entry(id: nil, external_id: nil, email: nil, strict: false)
|
58
111
|
init_caches
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
69
|
-
pers
|
112
|
+
# normalize values
|
113
|
+
ext_id = !external_id.to_s.strip.empty? && external_id.strip
|
114
|
+
email = !email.to_s.strip.empty? && email.downcase.strip
|
115
|
+
|
116
|
+
e = nil
|
117
|
+
e ||= @by_id[id]&.first
|
118
|
+
e ||= @by_external_id[ext_id]&.first
|
119
|
+
e ||= entry_by_email(email) unless strict && ext_id
|
120
|
+
e
|
70
121
|
end
|
71
122
|
|
72
123
|
# Search function to find an `entry` based on one of different options
|
@@ -136,15 +187,33 @@ module Eco
|
|
136
187
|
|
137
188
|
private
|
138
189
|
|
190
|
+
def entry_by_email(email, prevent_multiple_match: false)
|
191
|
+
return nil unless email
|
192
|
+
|
193
|
+
candidates = @by_email[email] || []
|
194
|
+
return candidates.first if candidates.length == 1
|
195
|
+
|
196
|
+
if prevent_multiple_match && !candidates.empty?
|
197
|
+
msg = "Multiple search results match the criteria."
|
198
|
+
raise MultipleSearchResults.new(msg, candidates: candidates, property: "email")
|
199
|
+
end
|
200
|
+
|
201
|
+
@by_external_id[email]&.first
|
202
|
+
end
|
203
|
+
|
139
204
|
def init_caches
|
140
205
|
return if @caches_init
|
141
|
-
@by_id = to_h
|
142
|
-
@by_external_id = to_h('external_id')
|
143
|
-
@by_email = to_h('email')
|
206
|
+
@by_id = no_nil_key(to_h)
|
207
|
+
@by_external_id = no_nil_key(to_h('external_id'))
|
208
|
+
@by_email = no_nil_key(to_h('email'))
|
144
209
|
@array_supers = sort_by_supervisors(@items)
|
145
210
|
@caches_init = true
|
146
211
|
end
|
147
212
|
|
213
|
+
def no_nil_key(hash)
|
214
|
+
hash.tap {|h| h.delete(nil)}
|
215
|
+
end
|
216
|
+
|
148
217
|
end
|
149
218
|
end
|
150
219
|
end
|
@@ -80,21 +80,21 @@ module Eco
|
|
80
80
|
# @param data [Array<Hash>] data to be parsed. It cannot be used alongside with `file:`
|
81
81
|
# @param file [String] absolute or relative path to the input file. It cannot be used alongside with `data:`.
|
82
82
|
# @param format [Symbol] it must be used when you use the option `file:` (i.e. `:xml`, `:csv`), as it specifies the format of the input `file:`.
|
83
|
-
# @param
|
83
|
+
# @param options [Hash] further options.
|
84
|
+
# @option options [String] :encoding optional parameter to read `file:` by expecting certain encoding.
|
85
|
+
# @option options [Boolean] :check_headers signals if the `csv` file headers should be expected.
|
84
86
|
# @return [Eco::API::Common::People::Entries] collection of `Eco::API::Common::People::PersonEntry`.
|
85
|
-
def entries(data: (no_data = true; nil), file: (no_file = true; nil), format: (no_format = true; nil),
|
87
|
+
def entries(data: (no_data = true; nil), file: (no_file = true; nil), format: (no_format = true; nil), **options)
|
86
88
|
fatal("You should at least use data: or file:, but not both") if no_data == no_file
|
87
89
|
fatal("You must specify a valid format: (symbol) when you use file.") if file && no_format
|
88
90
|
fatal("Format should be a Symbol. Given '#{format}'") if format && !format.is_a?(Symbol)
|
89
91
|
fatal("There is no parser/serializer for format ':#{format.to_s}'") unless no_format || @person_parser.defined?(format)
|
90
92
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
kargs.merge!(format: format) unless no_format
|
95
|
-
kargs.merge!(encoding: encoding) if encoding
|
93
|
+
options.merge!(content: data) unless no_data
|
94
|
+
options.merge!(file: file) unless no_file
|
95
|
+
options.merge!(format: format) unless no_format
|
96
96
|
|
97
|
-
Entries.new(to_array_of_hashes(**
|
97
|
+
Entries.new(to_array_of_hashes(**options), klass: PersonEntry, factory: self)
|
98
98
|
end
|
99
99
|
|
100
100
|
def to_array_of_hashes(**kargs)
|
@@ -118,7 +118,8 @@ module Eco
|
|
118
118
|
logger.error("Input data as 'Hash' not supported. Expecting 'Enumerable' or 'String'")
|
119
119
|
exit(1)
|
120
120
|
when String
|
121
|
-
|
121
|
+
deps = {check_headers: true} if kargs[:check_headers]
|
122
|
+
to_array_of_hashes(content: person_parser.parse(format, content, deps: deps || {}))
|
122
123
|
when Enumerable
|
123
124
|
sample = content.to_a.first
|
124
125
|
case sample
|
@@ -164,7 +165,7 @@ module Eco
|
|
164
165
|
|
165
166
|
run = true
|
166
167
|
if Eco::API::Common::Session::FileManager.file_exists?(file)
|
167
|
-
prompt_user("
|
168
|
+
prompt_user("Do you want to overwrite it? (Y/n):", explanation: "The file '#{file}' already exists.", default: "Y") do |response|
|
168
169
|
run = (response == "") || reponse.upcase.start_with?("Y")
|
169
170
|
end
|
170
171
|
end
|
@@ -6,6 +6,14 @@ module Eco
|
|
6
6
|
# Class to define a parser/serializer.
|
7
7
|
class PersonAttributeParser < Eco::Language::Models::ParserSerializer
|
8
8
|
|
9
|
+
# @note
|
10
|
+
# - This was introduced at a later stage and might not be available for certain org-parsers configs
|
11
|
+
# @return [RequiredAttrs]
|
12
|
+
def required_attrs
|
13
|
+
@required_attrs ||= @dependencies[:required_attrs]
|
14
|
+
#@required_attrs ||= RequiredAttrs.new(attr, :unkown, [attr])
|
15
|
+
end
|
16
|
+
|
9
17
|
# @see Eco::Language::Models::ParserSerializer#def_parser
|
10
18
|
# @note
|
11
19
|
# - additionally, you can declare a callback `active:` to determine if when the
|
@@ -188,7 +188,7 @@ module Eco
|
|
188
188
|
# @param person [Ecoportal::API::V1::Person] the person we want to set the core values to.
|
189
189
|
# @param exclude [String, Array<String>] core attributes that should not be set/changed to the person.
|
190
190
|
def set_core(person, exclude: nil)
|
191
|
-
scoped_attrs = @emap.core_attrs - into_a(exclude)
|
191
|
+
scoped_attrs = @emap.core_attrs(@final_entry) - into_a(exclude)
|
192
192
|
@final_entry.slice(*scoped_attrs).each do |attr, value|
|
193
193
|
begin
|
194
194
|
set_part(person, attr, value)
|
@@ -210,7 +210,7 @@ module Eco
|
|
210
210
|
# @param exclude [String, Array<String>] account properties that should not be set/changed to the person.
|
211
211
|
def set_account(person, exclude: nil)
|
212
212
|
person.account = {} if !person.account
|
213
|
-
scoped_attrs = @emap.account_attrs - into_a(exclude)
|
213
|
+
scoped_attrs = @emap.account_attrs(@final_entry) - into_a(exclude)
|
214
214
|
@final_entry.slice(*scoped_attrs).each do |attr, value|
|
215
215
|
set_part(person.account, attr, value)
|
216
216
|
end
|
@@ -224,7 +224,7 @@ module Eco
|
|
224
224
|
# @param exclude [String, Array<String>] schema field attributes that should not be set/changed to the person.
|
225
225
|
def set_details(person, exclude: nil)
|
226
226
|
person.add_details(@person_parser.schema) if !person.details || !person.details.schema_id
|
227
|
-
scoped_attrs = @emap.details_attrs - into_a(exclude)
|
227
|
+
scoped_attrs = @emap.details_attrs(@final_entry) - into_a(exclude)
|
228
228
|
@final_entry.slice(*scoped_attrs).each do |attr, value|
|
229
229
|
set_part(person.details, attr, value)
|
230
230
|
end
|
@@ -326,12 +326,13 @@ module Eco
|
|
326
326
|
# @param internal_entry [Hash] the entry with the **internal** _attribute_ names and values but the **external** types.
|
327
327
|
# @return [Hash] the `parsed entry` with the **internal** final attributes names, values and types.
|
328
328
|
def _final_parsing(internal_entry)
|
329
|
-
|
330
|
-
core_account_hash
|
329
|
+
core_account_attrs = @emap.account_attrs(internal_entry) + @emap.core_attrs(internal_entry)
|
330
|
+
core_account_hash = internal_entry.slice(*core_account_attrs).each_with_object({}) do |(attr, value), hash|
|
331
331
|
hash[attr] = _parse_type(attr, value)
|
332
332
|
end
|
333
333
|
|
334
|
-
|
334
|
+
details_attrs = @emap.details_attrs(internal_entry)
|
335
|
+
details_hash = internal_entry.slice(*details_attrs).each_with_object({}) do |(attr, value), hash|
|
335
336
|
hash[attr] = _parse_type(attr, value, schema: @person_parser.schema)
|
336
337
|
end
|
337
338
|
|
@@ -3,18 +3,11 @@ module Eco
|
|
3
3
|
module Common
|
4
4
|
module People
|
5
5
|
|
6
|
-
# @attr_reader core_attrs [Array<String>] core attributes that are present in the person entry.
|
7
|
-
# @attr_reader details_attrs [Array<String>] schema details attributes that are present in the person entry.
|
8
|
-
# @attr_reader account_attrs [Array<String>] account attributes that are present in the person entry.
|
9
|
-
# @attr_reader all_model_attrs [Array<String>] all the attrs that are present in the person entry.
|
10
|
-
# @attr_reader internal_attrs [Array<String>] all the internally named attributes that the person entry has.
|
11
|
-
# @attr_reader aliased_attrs [Array<String>] only those internal attributes present in the person entry that have an internal/external name mapping.
|
12
6
|
# @attr_reader direct_attrs [Array<String>] only those internal attributes present in the person entry that do **not** have an internal/external name mapping.
|
13
7
|
class PersonEntryAttributeMapper
|
14
8
|
@@cached_warnings = {}
|
15
9
|
|
16
|
-
attr_reader :
|
17
|
-
attr_reader :internal_attrs, :aliased_attrs, :direct_attrs
|
10
|
+
attr_reader :aliased_attrs, :direct_attrs
|
18
11
|
|
19
12
|
# Helper class tied to `PersonEntry` that allows to track which attributes of a person entry are present
|
20
13
|
# and how they should be mapped between internal and external names if applicable.
|
@@ -38,17 +31,64 @@ module Eco
|
|
38
31
|
|
39
32
|
if parsing?
|
40
33
|
@external_entry = data
|
41
|
-
init_attr_trackers
|
42
34
|
else # SERIALIZING
|
43
35
|
@person = data
|
44
|
-
@internal_attrs = @person_parser.all_model_attrs
|
45
|
-
@aliased_attrs = @attr_map.list(:internal)
|
46
36
|
end
|
37
|
+
end
|
47
38
|
|
48
|
-
|
49
|
-
|
50
|
-
@
|
51
|
-
|
39
|
+
# @return [Array<String>] only those internal attributes present in the person entry that have an internal/external name mapping.
|
40
|
+
def aliased_attrs
|
41
|
+
return @aliased_attrs unless !@aliased_attrs
|
42
|
+
if parsing?
|
43
|
+
init_attr_trackers
|
44
|
+
else
|
45
|
+
@aliased_attrs = @attr_map.list(:internal)
|
46
|
+
end
|
47
|
+
@aliased_attrs
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Array<String>] all the internally named attributes that the person entry has.
|
51
|
+
def internal_attrs(data = nil)
|
52
|
+
return @internal_attrs unless data || !@internal_attrs
|
53
|
+
if parsing?
|
54
|
+
init_attr_trackers unless @internal_attrs
|
55
|
+
if data
|
56
|
+
return data.keys & @person_parser.all_model_attrs
|
57
|
+
end
|
58
|
+
else
|
59
|
+
@internal_attrs = @person_parser.all_model_attrs
|
60
|
+
end
|
61
|
+
@internal_attrs
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# @return [Array<String>] all the attrs that are present in the person entry.
|
66
|
+
def all_model_attrs(data = nil)
|
67
|
+
core_attrs(data) | account_attrs(data) | details_attrs(data)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [Array<String>] core attributes that are present in the person entry.
|
71
|
+
def core_attrs(data = nil)
|
72
|
+
return @core_attrs unless data || !@core_attrs
|
73
|
+
@person_parser.target_attrs_core(internal_attrs(data)).tap do |core_attrs|
|
74
|
+
@core_attrs ||= core_attrs
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# @return [Array<String>] schema details attributes that are present in the person entry.
|
79
|
+
def details_attrs(data = nil)
|
80
|
+
return @details_attrs unless data || !@details_attrs
|
81
|
+
@person_parser.target_attrs_details(internal_attrs(data)).tap do |details_attrs|
|
82
|
+
@details_attrs ||= details_attrs
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [Array<String>] account attributes that are present in the person entry.
|
87
|
+
def account_attrs(data = nil)
|
88
|
+
return @account_attrs unless data || !@account_attrs
|
89
|
+
@person_parser.target_attrs_account(internal_attrs(data)).tap do |account_attrs|
|
90
|
+
@account_attrs ||= account_attrs
|
91
|
+
end
|
52
92
|
end
|
53
93
|
|
54
94
|
# To know if currently the object is in parse or serialize mode.
|
@@ -151,7 +191,6 @@ module Eco
|
|
151
191
|
def_unlinked = @person_parser.undefined_model_attrs.select { |attr| !to_external(attr) }
|
152
192
|
# (def) those with parser or alias:
|
153
193
|
def_linked = def_all_attrs - def_unlinked
|
154
|
-
|
155
194
|
# (data) data attributes (actual attributes of the entry)
|
156
195
|
data_attrs = attributes(@external_entry)
|
157
196
|
# (data) attributes of the data that come directly as internal attribute names
|
@@ -10,7 +10,7 @@ module Eco
|
|
10
10
|
|
11
11
|
attr_reader :schema, :schema_attrs
|
12
12
|
|
13
|
-
def initialize(person:
|
13
|
+
def initialize(person: nil, schema: {}, account: {}, modifier: Common::People::PersonModifier.new)
|
14
14
|
@modifier = Common::People::PersonModifier.new(modifier)
|
15
15
|
@person = person
|
16
16
|
@account = account
|
@@ -77,7 +77,9 @@ module Eco
|
|
77
77
|
when Hash
|
78
78
|
JSON.parse(person.to_json)
|
79
79
|
else
|
80
|
-
{
|
80
|
+
{
|
81
|
+
"subordinates" => 0
|
82
|
+
}
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
@@ -59,9 +59,15 @@ module Eco
|
|
59
59
|
|
60
60
|
# @!group Scopping attributes (identifying, presence & active)
|
61
61
|
|
62
|
+
# @return [Array<Eco::API::Common::Loaders::Parser::RequiredAttrs>]
|
63
|
+
def required_attrs
|
64
|
+
@parsers.values_at(*all_attrs(include_defined_parsers: true)).compact.map(&:required_attrs).compact
|
65
|
+
end
|
66
|
+
|
62
67
|
# All the internal name attributes, including _core_, _account_ and _details_.
|
63
68
|
def all_attrs(include_defined_parsers: false)
|
64
|
-
all_model_attrs | defined_model_attrs
|
69
|
+
return all_model_attrs | defined_model_attrs if include_defined_parsers
|
70
|
+
all_model_attrs
|
65
71
|
end
|
66
72
|
|
67
73
|
# Scopes `source_attrs` using the _**core** attributes_.
|
@@ -15,7 +15,7 @@ module Eco
|
|
15
15
|
# Reorders as follows:
|
16
16
|
# 1. supervisors, people with no supervisor or where their supervisor not present
|
17
17
|
# 2. subordinates
|
18
|
-
# @return [Array<
|
18
|
+
# @return [Array<PersonEntry>] `values` sorted by supervisors/subordinates
|
19
19
|
def sort_by_supervisors(values, supervisors_first: true)
|
20
20
|
raise "Expected non hash Enumerable. Given: #{values.class}" if values.is_a?(Hash)
|
21
21
|
return [] unless values && values.is_a?(Enumerable)
|
@@ -5,14 +5,6 @@ module Ecoportal
|
|
5
5
|
class Person
|
6
6
|
attr_accessor :entry
|
7
7
|
|
8
|
-
def reset_details!
|
9
|
-
doc["details"] = JSON.parse(original_doc["details"])
|
10
|
-
end
|
11
|
-
|
12
|
-
def consolidate_details!
|
13
|
-
original_doc["details"] = JSON.parse(doc["details"])
|
14
|
-
end
|
15
|
-
|
16
8
|
def identify(section = :person)
|
17
9
|
if entry && section == :entry
|
18
10
|
entry.to_s(:identify)
|
@@ -3,14 +3,6 @@ module Ecoportal
|
|
3
3
|
class Internal
|
4
4
|
class Person
|
5
5
|
|
6
|
-
def reset_account!
|
7
|
-
doc["account"] = JSON.parse(original_doc["account"])
|
8
|
-
end
|
9
|
-
|
10
|
-
def consolidate_account!
|
11
|
-
original_doc["account"] = JSON.parse(doc["account"])
|
12
|
-
end
|
13
|
-
|
14
6
|
def new?(doc = :initial)
|
15
7
|
ref_doc = (doc == :original) ? original_doc : initial_doc
|
16
8
|
!ref_doc["details"] && !ref_doc["account"]
|
@@ -12,9 +12,11 @@ module Eco
|
|
12
12
|
unless options.dig(:exclude, :core) && !person.new?
|
13
13
|
micro.set_core(entry, person, options)
|
14
14
|
if entry.supervisor_id?
|
15
|
-
micro.set_supervisor(entry.supervisor_id,
|
15
|
+
micro.set_supervisor(person, entry.supervisor_id, people, options) do |unknown_id|
|
16
16
|
# delay setting supervisor if does not exit
|
17
|
-
supers_job.add(person)
|
17
|
+
supers_job.add(person) do |person|
|
18
|
+
micro.set_supervisor(person, unknown_id, people, options)
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
20
22
|
end
|
@@ -1,22 +1,27 @@
|
|
1
1
|
module Eco
|
2
2
|
module API
|
3
3
|
class MicroCases
|
4
|
-
#
|
5
|
-
# @note delaying the setting of a `supervisor_id` can save errors when the supervisor still does not exit.
|
6
|
-
# @param sup_id [nil, String] the **supervisor id** we should set on the `person`.
|
4
|
+
# Unique access point to set the `supervisor_id` value on a person.
|
7
5
|
# @param person [Ecoportal::API::V1::Person] the person we want to update, carrying the changes to be done.
|
8
|
-
# @param
|
6
|
+
# @param sup_id [nil, String] the **supervisor id** we should set on the `person`.
|
7
|
+
# @param people [Eco::API::Organization::People] _People_ involved in the current update.
|
9
8
|
# @param options [Hash] the options.
|
10
9
|
# @yield [supervisor_id] callback when the supervisor_id is **unknown** (not `nil` nor any one's in `people`).
|
11
10
|
# @yieldparam supervisor_id [String] the **unknown** `supervisor_id`.
|
12
|
-
def set_supervisor(
|
11
|
+
def set_supervisor(person, sup_id, people, options)
|
13
12
|
unless options.dig(:exclude, :core) || options.dig(:exclude, :supervisor)
|
14
|
-
|
13
|
+
cur_id = person.supervisor_id
|
14
|
+
cur_super = cur_id && with_supervisor(cur_id, people)
|
15
|
+
micro.with_supervisor(sup_id, people) do |new_super|
|
15
16
|
if !sup_id
|
16
17
|
person.supervisor_id = nil
|
17
|
-
|
18
|
-
|
18
|
+
descrease_subordinates(cur_super)
|
19
|
+
elsif new_super && id = new_super.id
|
20
|
+
person.supervisor_id = id
|
21
|
+
descrease_subordinates(cur_super)
|
22
|
+
increase_subordinates(new_super)
|
19
23
|
elsif !block_given?
|
24
|
+
descrease_subordinates(cur_super)
|
20
25
|
person.supervisor_id = sup_id
|
21
26
|
else
|
22
27
|
yield(sup_id) if block_given?
|
@@ -25,6 +30,22 @@ module Eco
|
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
33
|
+
private
|
34
|
+
|
35
|
+
def descrease_subordinates(person, by = 1)
|
36
|
+
if person.is_a?(Ecoportal::API::V1::Person)
|
37
|
+
person.subordinates -= by
|
38
|
+
#person.subordinates = 0 if person.subordinates < 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def increase_subordinates(person, by = 1)
|
43
|
+
if person.is_a?(Ecoportal::API::V1::Person)
|
44
|
+
#person.subordinates = 0 if person.subordinates < 0
|
45
|
+
person.subordinates += by
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
28
49
|
end
|
29
50
|
end
|
30
51
|
end
|