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
@@ -3,135 +3,163 @@ module Eco
|
|
3
3
|
module Common
|
4
4
|
module People
|
5
5
|
class PersonEntry
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
6
|
+
# This class is meant to provide a common interface to access entries of source data that come in different formats.
|
7
|
+
# @note
|
8
|
+
# - if `data` is a `Person` object, its behaviour is `serialise`.
|
9
|
+
# - if `data` is **not** a `Person` object, it does a `parse`.
|
10
|
+
# - currently **in rework**, so there may be subtle differences that make it temporarily unstable (yet it is reliable).
|
11
|
+
# @param data [Hash, Person] `Person` object to be serialized or hashed entry (`CSV::Row` is accepted).
|
12
|
+
# @param person_parser [Common::People::PersonParser] parser/serializer of person attributes (it contains a set of attribute parsers).
|
13
|
+
# @param attr_map [Eco::Data::Mapper] mapper to translate attribute names from _external_ to _internal_ names and _vice versa_.
|
14
|
+
# @param dependencies [Hash] hash where _keys_ are internal attribute names. It is mostly used to deliver final dependencies to attribute parsers/serializers.
|
15
|
+
# @param logger [Common::Session::Logger, ::Logger] object to manage logs.
|
16
|
+
def initialize(data, person_parser:, attr_map:, dependencies: {}, logger: ::Logger.new(IO::NULL))
|
17
|
+
raise "Constructor needs a PersonParser. Given: #{parser}" if !person_parser.is_a?(Eco::API::Common::People::PersonParser)
|
18
|
+
raise "Expecting Mapper object. Given: #{attr_map}" if attr_map && !attr_map.is_a?(Eco::Data::Mapper)
|
19
|
+
|
20
|
+
@source = data
|
21
|
+
@person_parser = person_parser
|
22
|
+
@deps = dependencies
|
23
|
+
@logger = logger
|
24
|
+
@attr_map = attr_map
|
25
|
+
@emap = PersonEntryAttributeMapper.new(@source, person_parser: @person_parser, attr_map: @attr_map, logger: @logger)
|
17
26
|
|
18
27
|
if parsing?
|
19
|
-
|
20
|
-
@
|
21
|
-
|
22
|
-
|
23
|
-
@
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
else
|
28
|
-
# SERIALIZING
|
29
|
-
@person = data
|
30
|
-
@int_row = internal_entry(@person)
|
31
|
-
@aliased_entry = mapped_entry(@int_row)
|
32
|
-
@int_attrs = @parser.all_attrs
|
28
|
+
@external_entry = data
|
29
|
+
@serialized_entry = mapped_entry(@external_entry)
|
30
|
+
@internal_entry = internal_entry(@serialized_entry)
|
31
|
+
else # SERIALIZING
|
32
|
+
@person = data
|
33
|
+
@internal_entry = internal_entry(@person)
|
34
|
+
@serialized_entry = mapped_entry(@internal_entry)
|
35
|
+
#@external_entry = external_entry
|
33
36
|
end
|
34
|
-
|
35
|
-
@core_attrs = @parser.target_attrs_core(@int_attrs)
|
36
|
-
@details_attrs = @parser.target_attrs_details(@int_attrs)
|
37
|
-
@account_attrs = @parser.target_attrs_account(@int_attrs)
|
38
37
|
end
|
39
38
|
|
39
|
+
# To know if currently the object is in parse or serialize mode.
|
40
|
+
# @return [Boolean] returns `true` if we are **parsing**, `false` otherwise.
|
40
41
|
def parsing?
|
41
|
-
|
42
|
+
!@source.is_a?(Ecoportal::API::Internal::Person)
|
42
43
|
end
|
43
44
|
|
45
|
+
# To know if currently the object is in parse or serialize mode.
|
46
|
+
# @return [Boolean] returns `true` if we are **serializing**, `false` otherwise.
|
44
47
|
def serializing?
|
45
48
|
!parsing?
|
46
49
|
end
|
47
50
|
|
48
|
-
#
|
49
|
-
|
51
|
+
# @return [String, nil] the _internal id_ of this person if defined.
|
50
52
|
def id
|
51
|
-
@
|
53
|
+
@internal_entry["id"]
|
52
54
|
end
|
53
55
|
|
56
|
+
# @return [String, nil] the _external id_ of this person if defined.
|
54
57
|
def external_id
|
55
|
-
@
|
58
|
+
@internal_entry["external_id"]
|
56
59
|
end
|
57
60
|
|
61
|
+
# @return [String, nil] the _name_ of this person if defined.
|
58
62
|
def name
|
59
|
-
@
|
63
|
+
@internal_entry["name"]
|
60
64
|
end
|
61
65
|
|
66
|
+
# @return [String, nil] the _email_ of this person if defined.
|
62
67
|
def email
|
63
|
-
@
|
68
|
+
@internal_entry["email"]
|
64
69
|
end
|
65
70
|
|
71
|
+
# @return [String, nil] the _supervisor id_ of this person if defined.
|
66
72
|
def supervisor_id
|
67
|
-
@
|
73
|
+
@internal_entry["supervisor_id"]
|
68
74
|
end
|
69
75
|
|
70
76
|
def supervisor_id=(value)
|
71
|
-
@
|
77
|
+
@internal_entry["supervisor_id"] = value
|
72
78
|
end
|
73
79
|
|
80
|
+
# Provides a reference of this person.
|
81
|
+
# @return [String] string summary of this person identity.
|
74
82
|
def to_s(options)
|
75
83
|
options = into_a(options)
|
76
84
|
case
|
77
85
|
when options.include?(:identify)
|
78
86
|
"'#{name}' ('#{external_id}': '#{email}')"
|
79
87
|
else
|
80
|
-
@
|
88
|
+
@internal_entry.each.map do |k, v|
|
81
89
|
"'#{k}': '#{v.to_json}'"
|
82
90
|
end.join(" | ")
|
83
91
|
end
|
84
92
|
end
|
85
93
|
|
86
|
-
#
|
94
|
+
# Setter to fill in all the `core` properties of the `Person` that are present in the `Entry`.
|
95
|
+
# @note it only sets those core properties defined in the entry.
|
96
|
+
# Meaning that if an core property is not present in the entry, this will not be set on the target person.
|
97
|
+
# @param person [Person] the person we want to set the core values to.
|
98
|
+
# @param exclude [String, Array<String>] core attributes that should not be set/changed to the person.
|
87
99
|
def set_core(person, exclude: nil)
|
88
|
-
scoped_attrs = @core_attrs - into_a(exclude)
|
89
|
-
@
|
100
|
+
scoped_attrs = @emap.core_attrs - into_a(exclude)
|
101
|
+
@internal_entry.slice(*scoped_attrs).each do |attr, value|
|
90
102
|
set_to_core(person, attr, value)
|
91
103
|
end
|
92
104
|
end
|
93
105
|
|
106
|
+
# Setter to fill in all the schema `details` fields of the `Person` that are present in the `Entry`.
|
107
|
+
# @note it only sets those details properties defined in the entry.
|
108
|
+
# Meaning that if an details property is not present in the entry, this will not be set on the target person.
|
109
|
+
# @param person [Person] the person we want to set the schema fields' values to.
|
110
|
+
# @param exclude [String, Array<String>] schema field attributes that should not be set/changed to the person.
|
94
111
|
def set_details(person, exclude: nil)
|
95
|
-
person.add_details(@
|
96
|
-
scoped_attrs = @details_attrs - into_a(exclude)
|
97
|
-
@
|
112
|
+
person.add_details(@person_parser.schema) if !person.details || !person.details.schema_id
|
113
|
+
scoped_attrs = @emap.details_attrs - into_a(exclude)
|
114
|
+
@internal_entry.slice(*scoped_attrs).each do |attr, value|
|
98
115
|
set_to_details(person, attr, value)
|
99
116
|
end
|
100
117
|
end
|
101
118
|
|
119
|
+
# Setter to fill in the `account` properties of the `Person` that are present in the `Entry`.
|
120
|
+
# @note it only sets those account properties defined in the entry.
|
121
|
+
# Meaning that if an account property is not present in the entry, this will not be set on the target person.
|
122
|
+
# @param person [Person] the person we want to set the account values to.
|
123
|
+
# @param exclude [String, Array<String>] account properties that should not be set/changed to the person.
|
102
124
|
def set_account(person, exclude: nil)
|
103
125
|
person.account = {} if !person.account
|
104
126
|
person.account.permissions_preset = nil unless person.account.permissions_preset = "custom"
|
105
|
-
scoped_attrs = @account_attrs - into_a(exclude)
|
106
|
-
@
|
127
|
+
scoped_attrs = @emap.account_attrs - into_a(exclude)
|
128
|
+
@internal_entry.slice(*scoped_attrs).each do |attr, value|
|
107
129
|
set_to_account(person, attr, value)
|
108
130
|
end
|
109
131
|
end
|
110
132
|
|
111
|
-
#
|
112
|
-
|
113
|
-
|
114
|
-
|
133
|
+
# Entry represented in a `Hash` with **external** attribute names and values thereof.
|
134
|
+
# @note normally used to obtain a **serialized entry**.
|
135
|
+
# @return [Hash] with **external** names and values.
|
136
|
+
def to_hash
|
137
|
+
external_entry
|
115
138
|
end
|
116
139
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
140
|
+
# Entry represented in a `Hash` with **external** attribute names and values thereof.
|
141
|
+
# @note normally used to obtain a **serialized entry**.
|
142
|
+
# @return [Hash] with **external** names and values.
|
143
|
+
def external_entry
|
144
|
+
@emap.all_attrs.each_with_object({}) do |attr, hash|
|
145
|
+
unless hash.key?(ext_attr = @emap.to_external(attr))
|
146
|
+
hash[ext_attr] = @serialized_entry[attr]
|
147
|
+
end
|
148
|
+
end
|
121
149
|
end
|
122
150
|
|
123
151
|
private
|
124
152
|
|
125
|
-
def set_to_core
|
153
|
+
def set_to_core(person, attr, value)
|
126
154
|
value = value&.downcase if attr == "email"
|
127
155
|
person.send("#{attr}=", value&.strip)
|
128
156
|
end
|
129
157
|
|
130
|
-
def set_to_account
|
158
|
+
def set_to_account(person, attr, value)
|
131
159
|
return if !person.account
|
132
160
|
multiple = ["policy_group_ids", "filter_tags"].include?(attr)
|
133
161
|
if multiple
|
134
|
-
value = @
|
162
|
+
value = @person_parser.parse(:multiple, value)
|
135
163
|
value = value.map { |v| v&.upcase } if attr == "filter_tags"
|
136
164
|
# preserve previous order
|
137
165
|
current = into_a(person.account.send(attr))
|
@@ -141,85 +169,62 @@ module Eco
|
|
141
169
|
person.account.send("#{attr}=", value)
|
142
170
|
end
|
143
171
|
|
144
|
-
def set_to_details
|
172
|
+
def set_to_details(person, attr, value)
|
145
173
|
return if !person.details
|
146
|
-
field = person.details.get_field(attr)
|
147
|
-
|
148
|
-
|
174
|
+
unless field = person.details.get_field(attr)
|
175
|
+
fatal("Field '#{attr}' does not exist in details of schema: '#{person.details.schema_id}'")
|
176
|
+
end
|
177
|
+
value = nil if value.to_s.empty?
|
178
|
+
value = @person_parser.parse(:multiple, value) if field.multiple
|
149
179
|
|
150
|
-
if @
|
151
|
-
value = @
|
180
|
+
if @person_parser.defined?(field.type.to_sym)
|
181
|
+
value = @person_parser.parse(field.type.to_sym, value, deps: {"attr" => attr})
|
152
182
|
end
|
153
183
|
|
154
184
|
person.details[attr] = value
|
155
185
|
end
|
156
186
|
|
157
|
-
def get_from_core
|
187
|
+
def get_from_core (person, attr)
|
158
188
|
person.send(attr)
|
159
189
|
end
|
160
190
|
|
161
191
|
def get_from_account (person, attr)
|
162
|
-
return
|
192
|
+
return nil if !person.account
|
163
193
|
multiple = ["policy_group_ids", "filter_tags"].include?(attr)
|
164
194
|
value = person.account.send(attr)
|
165
|
-
@
|
195
|
+
@person_parser.serialize(:multiple, value) if multiple
|
166
196
|
end
|
167
197
|
|
168
|
-
def get_from_details
|
169
|
-
return
|
170
|
-
field = person.details.get_field(attr)
|
171
|
-
|
198
|
+
def get_from_details(person, attr)
|
199
|
+
return nil if !person.details || !person&.details&.schema_id
|
200
|
+
unless field = person.details.get_field(attr)
|
201
|
+
fatal("Field '#{attr}' does not exist in details of schema: '#{person.details.schema_id}'")
|
202
|
+
end
|
172
203
|
value = person.details[attr]
|
173
|
-
value = @
|
174
|
-
value = @
|
204
|
+
value = @person_parser.serialize(:date, value) if field.type == "date"
|
205
|
+
value = @person_parser.serialize(:multiple, value) if field.multiple
|
175
206
|
value
|
176
207
|
end
|
177
208
|
|
178
|
-
# INIT
|
179
|
-
|
180
|
-
# when parsing:
|
181
|
-
def init_attr_trackers
|
182
|
-
# internal <-> external attributes
|
183
|
-
int_aliased = @parser.all_attrs.select { |attr| to_external(attr) }
|
184
|
-
ext_alias = int_aliased.map { |attr| to_external(attr) }
|
185
|
-
|
186
|
-
# virtual attrs (non native internal attr that require aliasing):
|
187
|
-
ext_vi_aliased = attributes(@raw_entry).select do |attr|
|
188
|
-
!ext_alias.include?(attr) && @mapper.external?(attr)
|
189
|
-
end
|
190
|
-
|
191
|
-
int_vi_aliased = ext_vi_aliased.map { |attr| @mapper.to_internal(attr) }
|
192
|
-
@aliased_attrs = int_aliased + int_vi_aliased
|
193
|
-
|
194
|
-
int_unlinked = @parser.undefined_attrs.select { |attr| !to_external(attr) }
|
195
|
-
# those with parser or alias:
|
196
|
-
int_linked = @parser.all_attrs - int_unlinked
|
197
|
-
|
198
|
-
ext_aliased = ext_alias + ext_vi_aliased
|
199
|
-
# those that are direct external to internal:
|
200
|
-
ext_direct = attributes(@raw_entry) - ext_aliased
|
201
|
-
# to avoid collisions between internal names:
|
202
|
-
@direct_attrs = ext_direct - int_linked
|
203
|
-
end
|
204
|
-
|
205
209
|
# MAPPED ENTRY (when and where applicable)
|
206
|
-
#
|
210
|
+
# To obtain an entry with internal names but external values.
|
211
|
+
# @param data [Hash] external or raw entry (when parsing) or internal or parsed entry (when serializing).
|
212
|
+
# @return [Hash] entry with **internal names** and **external values**.
|
207
213
|
def mapped_entry(data)
|
208
214
|
return aliased_entry(data) if parsing?
|
209
215
|
serialized_entry(data)
|
210
216
|
end
|
211
217
|
|
212
|
-
#
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
[attr, raw_data[attr]]
|
218
|
+
# Parsing helper that aliases attribute names (from internal to external names)
|
219
|
+
# @note **Parse**: here we aliase internal attribute names into external ones.
|
220
|
+
# @param ext_entry [Hash] entry in raw, with **external** names and values.
|
221
|
+
# @return [Hash] entry with **internal names** and **external values**.
|
222
|
+
def aliased_entry(ext_entry)
|
223
|
+
aliased_hash = @emap.aliased_attrs.map do |attr|
|
224
|
+
[attr, ext_entry[@emap.to_external(attr)]]
|
220
225
|
end.to_h
|
221
226
|
|
222
|
-
|
227
|
+
ext_entry.slice(*@emap.direct_attrs).merge(aliased_hash)
|
223
228
|
end
|
224
229
|
|
225
230
|
def hash_attr(attr, value)
|
@@ -227,106 +232,69 @@ module Eco
|
|
227
232
|
{ attr => value }
|
228
233
|
end
|
229
234
|
|
230
|
-
#
|
235
|
+
# Serializing helper that serializes values (from internal to external values).
|
236
|
+
# @note **Serializing**:
|
237
|
+
# 1. here we tranform internal into external **values**.
|
238
|
+
# 2. when running the serializers, it overrides existing keys.
|
239
|
+
# @param unserialized_entry [Hash] entry with **internal** names and values.
|
240
|
+
# @return [Hash] entry with **internal names** and **external values**.
|
231
241
|
def serialized_entry(unserialized_entry)
|
232
|
-
serial_attrs = @
|
242
|
+
serial_attrs = @person_parser.defined_attrs.reduce({}) do |serial_hash, attr|
|
233
243
|
deps = @deps[attr] || {}
|
234
|
-
serial_attr = @
|
244
|
+
serial_attr = @person_parser.serialize(attr, @person, deps: deps)
|
235
245
|
serial_hash.merge(hash_attr(attr, serial_attr))
|
236
246
|
end
|
237
247
|
unserialized_entry.merge(serial_attrs)
|
238
248
|
end
|
239
249
|
|
240
|
-
#
|
250
|
+
# To obtain an entry with internal names but external values.
|
251
|
+
# @param data [Hash, Ecoportal::API::V1::Person] alised_entry (when parsing) or person (when serializing).
|
252
|
+
# @return [Hash] the `internal entry` with the **internal** attributes names and values.
|
241
253
|
def internal_entry(data)
|
242
254
|
return parsed_entry(data) if parsing?
|
243
255
|
unserialized_entry(data)
|
244
256
|
end
|
245
257
|
|
246
|
-
#
|
258
|
+
# Parsing helper that just **parses the values** that have a parser/serializer defined.
|
259
|
+
# @param aliased_entry [Hash] the entry with the _internal attribute_ names but the _external values_.
|
260
|
+
# @return [Hash] the `internal entry` with the **internal** attributes names and values.
|
247
261
|
def parsed_entry(aliased_entry)
|
248
|
-
parsed = @
|
249
|
-
value = @
|
262
|
+
parsed = @person_parser.defined_attrs.map do |attr|
|
263
|
+
value = @person_parser.parse(attr, aliased_entry)
|
250
264
|
[attr, value]
|
251
265
|
end.to_h
|
252
266
|
aliased_entry.merge(parsed)
|
253
267
|
end
|
254
268
|
|
255
|
-
#
|
269
|
+
# Serializing helper that just creates the _internal entry_ out of a `Person` object.
|
270
|
+
# @note
|
271
|
+
# - when unnesting attributes, the overriding precedence for collisions is
|
272
|
+
# - `core` -> _overrides_ -> `account` -> _overrides_ -> `details`
|
273
|
+
# - to keep things consistent, the `internal entry` hash has keys in this order:
|
274
|
+
# - `core`, `account`, `details`.
|
275
|
+
# @param person [Ecoportal::API::V1::Person] the `Person` object to transform into an _internal entry_.
|
276
|
+
# @return [Hash] the `internal entry` with the **internal** attributes names and values.
|
256
277
|
def unserialized_entry(person)
|
257
|
-
core_hash = @
|
278
|
+
core_hash = @person_parser.target_attrs_core.reduce({}) do |hash, attr|
|
258
279
|
value = get_from_core(person, attr)
|
259
280
|
hash.merge(hash_attr(attr, value))
|
260
281
|
end
|
261
282
|
|
262
|
-
details_hash = @
|
283
|
+
details_hash = @person_parser.target_attrs_details.reduce({}) do |hash, attr|
|
263
284
|
value = get_from_details(person, attr)
|
264
285
|
hash.merge(hash_attr(attr, value))
|
265
286
|
end
|
266
287
|
|
267
|
-
account_hash = @
|
288
|
+
account_hash = @person_parser.target_attrs_account.reduce({}) do |hash, attr|
|
268
289
|
value = get_from_account(person, attr)
|
269
290
|
hash.merge(hash_attr(attr, value))
|
270
291
|
end
|
271
292
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
def to_internal(value)
|
278
|
-
return value if !@mapper
|
279
|
-
attr = value
|
280
|
-
case value
|
281
|
-
when Array
|
282
|
-
return value.map do |v|
|
283
|
-
to_internal(v)
|
284
|
-
end.compact
|
285
|
-
when String
|
286
|
-
case
|
287
|
-
when @mapper.external?(value)
|
288
|
-
attr = @mapper.to_internal(value)
|
289
|
-
when @mapper.external?(value.strip)
|
290
|
-
unless cached_warning("external", "spaces", value)
|
291
|
-
logger.warn("The external person field name '#{value}' contains additional spaces in the reference file")
|
292
|
-
end
|
293
|
-
attr = @mapper.to_internal(value.strip)
|
294
|
-
when @mapper.internal?(value) || @mapper.internal?(value.strip) || @mapper.internal?(value.strip.downcase)
|
295
|
-
unless cached_warning("external", "reversed", value)
|
296
|
-
logger.warn("The mapper [external, internal] attribute names may be declared reversedly for EXTERNAL attribute: '#{value}'")
|
297
|
-
end
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
return nil unless @parser.all_attrs.include?(attr)
|
302
|
-
end
|
303
|
-
|
304
|
-
def to_external(value)
|
305
|
-
return value if !@mapper
|
306
|
-
attr = value
|
307
|
-
case value
|
308
|
-
when Array
|
309
|
-
return value.map do |v|
|
310
|
-
to_external(v)
|
311
|
-
end.compact
|
312
|
-
when String
|
313
|
-
case
|
314
|
-
when @mapper.internal?(value)
|
315
|
-
attr = @mapper.to_external(value)
|
316
|
-
when @mapper.internal?(value.strip)
|
317
|
-
unless cached_warning("internal", "spaces", value)
|
318
|
-
logger.warn("The internal person field name '#{value}' contains additional spaces in the reference file")
|
319
|
-
end
|
320
|
-
attr = @mapper.to_external(value.strip)
|
321
|
-
when @mapper.external?(value) || @mapper.external?(value.strip) || @mapper.external?(value.strip.downcase)
|
322
|
-
unless cached_warning("internal", "reversed", value)
|
323
|
-
logger.warn("The mapper [external, internal] attribute names may be declared reversedly for INTERNAL attribute: '#{value}'")
|
324
|
-
end
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
return nil unless !@raw_entry || attributes(@raw_entry).include?(attr)
|
329
|
-
attr
|
293
|
+
# merge by core overriding account and details
|
294
|
+
rh = details_hash.merge(account_hash).merge(core_hash)
|
295
|
+
# resort hash keys
|
296
|
+
sorted_keys = core_hash.keys | account_hash.keys | details_hash.keys
|
297
|
+
sorted_keys.reduce({}) {|h,k| h[k] = rh[k]; h}
|
330
298
|
end
|
331
299
|
|
332
300
|
# LOGGER
|
@@ -334,16 +302,6 @@ module Eco
|
|
334
302
|
@logger || ::Logger.new(IO::NULL)
|
335
303
|
end
|
336
304
|
|
337
|
-
def cached_warning(*args)
|
338
|
-
unless exists = !!@@cached_warnings.dig(*args)
|
339
|
-
args.reduce(@@cached_warnings) do |cache, level|
|
340
|
-
cache[level] = {} if !cache.key?(level)
|
341
|
-
cache[level]
|
342
|
-
end
|
343
|
-
end
|
344
|
-
exists
|
345
|
-
end
|
346
|
-
|
347
305
|
def fatal(msg)
|
348
306
|
logger.fatal(msg)
|
349
307
|
exit
|
@@ -356,23 +314,6 @@ module Eco
|
|
356
314
|
value
|
357
315
|
end
|
358
316
|
|
359
|
-
def attributes(value)
|
360
|
-
case value
|
361
|
-
when CSV::Row
|
362
|
-
value&.headers
|
363
|
-
when Hash
|
364
|
-
value&.keys
|
365
|
-
when PersonEntry
|
366
|
-
@parser.target_attrs_core
|
367
|
-
else
|
368
|
-
[]
|
369
|
-
end
|
370
|
-
end
|
371
|
-
|
372
|
-
def is_person?(value)
|
373
|
-
value.is_a?(Ecoportal::API::Internal::Person)
|
374
|
-
end
|
375
|
-
|
376
317
|
end
|
377
318
|
end
|
378
319
|
end
|