eco-helpers 1.4.0 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +150 -2
- data/LICENSE +21 -0
- data/eco-helpers.gemspec +11 -10
- data/lib/eco/api.rb +3 -0
- data/lib/eco/api/common.rb +5 -1
- data/lib/eco/api/common/base_loader.rb +54 -0
- data/lib/eco/api/common/class_auto_loader.rb +109 -0
- data/lib/eco/api/common/class_helpers.rb +33 -0
- data/lib/eco/api/common/class_hierarchy.rb +1 -1
- data/lib/eco/api/common/class_meta_basics.rb +16 -0
- data/lib/eco/api/common/loaders.rb +13 -0
- data/lib/eco/api/common/loaders/error_handler.rb +41 -0
- data/lib/eco/api/common/loaders/parser.rb +127 -0
- data/lib/eco/api/common/loaders/policy.rb +25 -0
- data/lib/eco/api/common/loaders/use_case.rb +40 -0
- data/lib/eco/api/common/people/default_parsers.rb +5 -10
- data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +13 -23
- data/lib/eco/api/common/people/default_parsers/csv_parser.rb +20 -35
- data/lib/eco/api/common/people/default_parsers/date_parser.rb +15 -26
- data/lib/eco/api/common/people/default_parsers/freemium_parser.rb +20 -0
- data/lib/eco/api/common/people/default_parsers/login_providers_parser.rb +26 -0
- data/lib/eco/api/common/people/default_parsers/multi_parser.rb +15 -27
- data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +14 -19
- data/lib/eco/api/common/people/default_parsers/policy_groups_parser.rb +31 -0
- data/lib/eco/api/common/people/default_parsers/send_invites_parser.rb +15 -24
- data/lib/eco/api/common/people/entries.rb +54 -24
- data/lib/eco/api/common/people/entry_factory.rb +18 -15
- data/lib/eco/api/common/people/person_attribute_parser.rb +29 -12
- data/lib/eco/api/common/people/person_entry.rb +308 -216
- data/lib/eco/api/common/people/person_entry_attribute_mapper.rb +5 -2
- data/lib/eco/api/common/people/person_parser.rb +52 -19
- data/lib/eco/api/common/session/base_session.rb +3 -6
- data/lib/eco/api/common/session/environment.rb +2 -23
- data/lib/eco/api/common/session/logger.rb +4 -0
- data/lib/eco/api/common/version_patches/ecoportal_api/external_person.rb +2 -0
- data/lib/eco/api/common/version_patches/ecoportal_api/internal_person.rb +9 -1
- data/lib/eco/api/common/version_patches/exception.rb +24 -2
- data/lib/eco/api/custom.rb +13 -0
- data/lib/eco/api/custom/error_handler.rb +20 -0
- data/lib/eco/api/custom/namespace.rb +7 -0
- data/lib/eco/api/custom/parser.rb +50 -0
- data/lib/eco/api/custom/policy.rb +28 -0
- data/lib/eco/api/custom/use_case.rb +16 -0
- data/lib/eco/api/error.rb +1 -0
- data/lib/eco/api/error/handlers.rb +10 -3
- data/lib/eco/api/microcases.rb +35 -0
- data/lib/eco/api/microcases/account_excluded.rb +24 -0
- data/lib/eco/api/microcases/append_usergroups.rb +19 -0
- data/lib/eco/api/microcases/core_excluded.rb +20 -0
- data/lib/eco/api/microcases/fix_default_group.rb +34 -0
- data/lib/eco/api/microcases/fix_filter_tags.rb +42 -0
- data/lib/eco/api/microcases/people_cache.rb +17 -0
- data/lib/eco/api/microcases/people_load.rb +59 -0
- data/lib/eco/api/microcases/people_refresh.rb +31 -0
- data/lib/eco/api/microcases/people_search.rb +65 -0
- data/lib/eco/api/microcases/refresh_abilities.rb +19 -0
- data/lib/eco/api/microcases/refresh_default_tag.rb +27 -0
- data/lib/eco/api/microcases/s3upload_targets.rb +39 -0
- data/lib/eco/api/microcases/set_account.rb +20 -0
- data/lib/eco/api/microcases/set_core.rb +18 -0
- data/lib/eco/api/microcases/set_core_with_supervisor.rb +23 -0
- data/lib/eco/api/microcases/set_supervisor.rb +30 -0
- data/lib/eco/api/microcases/strict_search.rb +19 -0
- data/lib/eco/api/microcases/with_each.rb +27 -0
- data/lib/eco/api/microcases/with_each_leaver.rb +24 -0
- data/lib/eco/api/microcases/with_each_present.rb +30 -0
- data/lib/eco/api/microcases/with_each_starter.rb +30 -0
- data/lib/eco/api/microcases/with_each_subordinate.rb +34 -0
- data/lib/eco/api/microcases/with_supervisor.rb +36 -0
- data/lib/eco/api/organization/people.rb +72 -35
- data/lib/eco/api/organization/presets_factory.rb +13 -4
- data/lib/eco/api/organization/presets_reference.json +9 -1
- data/lib/eco/api/organization/presets_values.json +4 -1
- data/lib/eco/api/policies.rb +11 -7
- data/lib/eco/api/session.rb +62 -29
- data/lib/eco/api/session/batch.rb +2 -45
- data/lib/eco/api/session/batch/base_policy.rb +7 -6
- data/lib/eco/api/session/batch/errors.rb +28 -4
- data/lib/eco/api/session/batch/feedback.rb +7 -1
- data/lib/eco/api/session/batch/job.rb +40 -23
- data/lib/eco/api/session/batch/jobs.rb +9 -4
- data/lib/eco/api/session/batch/jobs_groups.rb +1 -1
- data/lib/eco/api/session/batch/request_stats.rb +91 -58
- data/lib/eco/api/session/batch/status.rb +35 -31
- data/lib/eco/api/session/config.rb +106 -44
- data/lib/eco/api/session/config/api.rb +132 -7
- data/lib/eco/api/session/config/apis.rb +24 -25
- data/lib/eco/api/session/config/logger.rb +2 -2
- data/lib/eco/api/session/config/post_launch.rb +1 -1
- data/lib/eco/api/session/config/workflow.rb +8 -7
- data/lib/eco/api/usecases.rb +47 -33
- data/lib/eco/api/usecases/backup/append_usergroups_case.rb +36 -0
- data/lib/eco/api/usecases/backup/create_case.rb +104 -0
- data/lib/eco/api/usecases/backup/create_details_case.rb +31 -0
- data/lib/eco/api/usecases/backup/create_details_with_supervisor_case.rb +48 -0
- data/lib/eco/api/usecases/backup/hris_case.rb +124 -0
- data/lib/eco/api/usecases/backup/set_default_tag_case.rb +49 -0
- data/lib/eco/api/usecases/backup/set_supervisor_case.rb +41 -0
- data/lib/eco/api/usecases/backup/transfer_account_case.rb +90 -0
- data/lib/eco/api/usecases/backup/update_case.rb +112 -0
- data/lib/eco/api/usecases/backup/update_details_case.rb +64 -0
- data/lib/eco/api/usecases/backup/upsert_case.rb +114 -0
- data/lib/eco/api/usecases/base_case.rb +2 -0
- data/lib/eco/api/usecases/base_io.rb +3 -3
- data/lib/eco/api/usecases/default_cases.rb +23 -53
- data/lib/eco/api/usecases/default_cases/append_usergroups_case.rb +10 -31
- data/lib/eco/api/usecases/default_cases/change_email_case.rb +23 -47
- data/lib/eco/api/usecases/default_cases/codes_to_tags_case.rb +56 -43
- data/lib/eco/api/usecases/default_cases/create_case.rb +15 -101
- data/lib/eco/api/usecases/default_cases/create_details_case.rb +11 -26
- data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +12 -43
- data/lib/eco/api/usecases/default_cases/delete_sync_case.rb +11 -0
- data/lib/eco/api/usecases/default_cases/delete_trans_case.rb +14 -0
- data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +10 -21
- data/lib/eco/api/usecases/default_cases/hris_case.rb +23 -120
- data/lib/eco/api/usecases/default_cases/new_email_case.rb +10 -23
- data/lib/eco/api/usecases/default_cases/new_id_case.rb +11 -25
- data/lib/eco/api/usecases/default_cases/new_id_case0.rb +14 -0
- data/lib/eco/api/usecases/default_cases/org_data_convert_case.rb +83 -0
- data/lib/eco/api/usecases/default_cases/refresh_abilities_case.rb +30 -0
- data/lib/eco/api/usecases/default_cases/refresh_case.rb +7 -20
- data/lib/eco/api/usecases/default_cases/reinvite_sync_case.rb +11 -0
- data/lib/eco/api/usecases/default_cases/reinvite_trans_case.rb +17 -0
- data/lib/eco/api/usecases/default_cases/remove_account_sync_case.rb +11 -0
- data/lib/eco/api/usecases/default_cases/remove_account_trans_case.rb +17 -0
- data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +9 -19
- data/lib/eco/api/usecases/default_cases/restore_db_case.rb +92 -0
- data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +32 -40
- data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +15 -33
- data/lib/eco/api/usecases/default_cases/switch_supervisor_case.rb +66 -57
- data/lib/eco/api/usecases/default_cases/to_csv_case.rb +36 -44
- data/lib/eco/api/usecases/default_cases/to_csv_detailed_case.rb +40 -55
- data/lib/eco/api/usecases/default_cases/transfer_account_case.rb +264 -84
- data/lib/eco/api/usecases/default_cases/update_case.rb +15 -109
- data/lib/eco/api/usecases/default_cases/update_details_case.rb +14 -61
- data/lib/eco/api/usecases/default_cases/upsert_case.rb +16 -111
- data/lib/eco/api/usecases/use_case_io.rb +9 -9
- data/lib/eco/cli/config.rb +10 -2
- data/lib/eco/cli/config/default.rb +2 -1
- data/lib/eco/cli/config/default/input_filters.rb +58 -0
- data/lib/eco/cli/config/default/options.rb +60 -25
- data/lib/eco/cli/config/default/people.rb +4 -4
- data/lib/eco/cli/config/default/people_filters.rb +108 -0
- data/lib/eco/cli/config/default/usecases.rb +69 -32
- data/lib/eco/cli/config/default/workflow.rb +37 -27
- data/lib/eco/cli/config/filters.rb +50 -0
- data/lib/eco/cli/config/filters/input_filters.rb +29 -0
- data/lib/eco/cli/config/filters/people_filters.rb +29 -0
- data/lib/eco/cli/config/help.rb +49 -0
- data/lib/eco/cli/config/options_set.rb +17 -1
- data/lib/eco/cli/config/use_cases.rb +79 -53
- data/lib/eco/cli/scripting.rb +10 -2
- data/lib/eco/cli/scripting/args_helpers.rb +25 -15
- data/lib/eco/cli/scripting/argument.rb +1 -0
- data/lib/eco/cli/scripting/arguments.rb +1 -1
- data/lib/eco/csv.rb +8 -3
- data/lib/eco/csv/table.rb +1 -1
- data/lib/eco/data/crypto/encryption.rb +3 -0
- data/lib/eco/data/files/helpers.rb +6 -1
- data/lib/eco/language/match.rb +19 -9
- data/lib/eco/language/match_modifier.rb +13 -5
- data/lib/eco/language/models/collection.rb +77 -56
- data/lib/eco/language/models/parser_serializer.rb +39 -15
- data/lib/eco/version.rb +1 -1
- metadata +149 -63
- data/lib/eco/api/session/task.rb +0 -175
- data/lib/eco/api/usecases/default_case.rb +0 -19
- data/lib/eco/api/usecases/default_cases/delete_case.rb +0 -32
- data/lib/eco/api/usecases/default_cases/recover_db_case.rb +0 -98
- data/lib/eco/api/usecases/default_cases/refresh_presets_case.rb +0 -26
- data/lib/eco/api/usecases/default_cases/reinvite_case.rb +0 -41
- data/lib/eco/api/usecases/default_cases/remove_account_case.rb +0 -38
- data/lib/eco/cli/config/default/filters.rb +0 -70
- data/lib/eco/cli/config/people_filters.rb +0 -38
@@ -9,7 +9,7 @@ module Eco
|
|
9
9
|
# - if `data` is a `Person` object, its behaviour is `serialise`.
|
10
10
|
# - if `data` is **not** a `Person` object, it does a `parse`.
|
11
11
|
# - currently **in rework**, so there may be subtle differences that make it temporarily unstable (yet it is reliable).
|
12
|
-
# @param data [Hash, Person] `Person` object to be serialized or hashed entry (`CSV::Row` is accepted).
|
12
|
+
# @param data [Hash, Ecoportal::API::V1::Person] `Person` object to be serialized or hashed entry (`CSV::Row` is accepted).
|
13
13
|
# @param person_parser [Common::People::PersonParser] parser/serializer of person attributes (it contains a set of attribute parsers).
|
14
14
|
# @param attr_map [Eco::Data::Mapper] mapper to translate attribute names from _external_ to _internal_ names and _vice versa_.
|
15
15
|
# @param dependencies [Hash] hash where _keys_ are internal attribute names. It is mostly used to deliver final dependencies to attribute parsers/serializers.
|
@@ -26,17 +26,43 @@ module Eco
|
|
26
26
|
@emap = PersonEntryAttributeMapper.new(@source, person_parser: @person_parser, attr_map: @attr_map, logger: @logger)
|
27
27
|
|
28
28
|
if parsing?
|
29
|
-
@external_entry = data
|
30
|
-
@
|
31
|
-
@internal_entry =
|
29
|
+
@external_entry = __external_entry(data)
|
30
|
+
@mapped_entry = __mapped_entry(@external_entry)
|
31
|
+
@internal_entry = __internal_entry(@mapped_entry)
|
32
|
+
@final_entry = __final_entry(@internal_entry)
|
32
33
|
else # SERIALIZING
|
33
34
|
@person = data
|
34
|
-
@
|
35
|
-
@
|
36
|
-
|
35
|
+
@final_entry = __final_entry(@person)
|
36
|
+
@internal_entry = __internal_entry(@final_entry)
|
37
|
+
@mapped_entry = __mapped_entry(@internal_entry)
|
38
|
+
@external_entry = __external_entry(@mapped_entry)
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
42
|
+
# Generates a new entry
|
43
|
+
# @return [PersonEntry]
|
44
|
+
def new(data)
|
45
|
+
self.class.new(data, person_parser: @person_parser, attr_map: @attr_map, dependencies: @deps, logger: @logger)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @note completely serialized entry.
|
49
|
+
# @return [Hash] entry `Hash` with **external** attribute names, and values and types thereof.
|
50
|
+
def external_entry
|
51
|
+
@external_entry
|
52
|
+
end
|
53
|
+
|
54
|
+
# @note just one step away from being completely parsed (only types parsing pending).
|
55
|
+
# @return [Hash] entry `Hash` with **internal** attribute names and values, but **external** types.
|
56
|
+
def internal_entry
|
57
|
+
@internal_entry
|
58
|
+
end
|
59
|
+
|
60
|
+
# @note values ready to be set to a person.
|
61
|
+
# @return [Hash] entry `Hash` with **internal** attribute names, values and types.
|
62
|
+
def final_entry
|
63
|
+
@final_entry
|
64
|
+
end
|
65
|
+
|
40
66
|
# To know if currently the object is in parse or serialize mode.
|
41
67
|
# @return [Boolean] returns `true` if we are **parsing**, `false` otherwise.
|
42
68
|
def parsing?
|
@@ -49,73 +75,83 @@ module Eco
|
|
49
75
|
!parsing?
|
50
76
|
end
|
51
77
|
|
78
|
+
# @note `Eco::API::Common::People::EntryFactory#entries` adds this `idx`
|
79
|
+
# @return [Integer] the entry number in the input file
|
80
|
+
def idx
|
81
|
+
final_entry["idx"]
|
82
|
+
end
|
83
|
+
|
52
84
|
# @return [String, nil] the _internal id_ of this person if defined.
|
53
85
|
def id
|
54
|
-
|
86
|
+
final_entry["id"]
|
55
87
|
end
|
56
88
|
|
57
89
|
def id?
|
58
|
-
|
90
|
+
final_entry.key?("id")
|
59
91
|
end
|
60
92
|
|
61
93
|
# @return [String, nil] the _external id_ of this person if defined.
|
62
94
|
def external_id
|
63
|
-
|
95
|
+
final_entry["external_id"]
|
64
96
|
end
|
65
97
|
|
66
98
|
def external_id?
|
67
|
-
|
99
|
+
final_entry.key?("external_id")
|
68
100
|
end
|
69
101
|
|
70
102
|
# @return [String, nil] the _name_ of this person if defined.
|
71
103
|
def name
|
72
|
-
|
104
|
+
final_entry["name"]
|
73
105
|
end
|
74
106
|
|
75
107
|
def name?
|
76
|
-
|
108
|
+
final_entry.key?("name")
|
77
109
|
end
|
78
110
|
|
79
111
|
# @return [String, nil] the _email_ of this person if defined.
|
80
112
|
def email
|
81
|
-
|
113
|
+
final_entry["email"]
|
82
114
|
end
|
83
115
|
|
84
116
|
def email?
|
85
|
-
|
117
|
+
final_entry.key?("email")
|
86
118
|
end
|
87
119
|
|
88
120
|
# @return [String, nil] the _supervisor id_ of this person if defined.
|
89
121
|
def supervisor_id
|
90
|
-
|
122
|
+
final_entry["supervisor_id"]
|
91
123
|
end
|
92
124
|
|
93
125
|
def supervisor_id=(value)
|
94
|
-
|
126
|
+
final_entry["supervisor_id"] = value
|
95
127
|
end
|
96
128
|
|
97
129
|
def supervisor_id?
|
98
|
-
|
130
|
+
final_entry.key?("supervisor_id")
|
99
131
|
end
|
100
132
|
|
101
133
|
def filter_tags
|
102
|
-
|
134
|
+
final_entry["filter_tags"] || []
|
103
135
|
end
|
104
136
|
|
105
137
|
def filter_tags?
|
106
|
-
|
138
|
+
final_entry.key?("filter_tags")
|
139
|
+
end
|
140
|
+
|
141
|
+
def policy_group_ids
|
142
|
+
final_entry["policy_group_ids"] || []
|
107
143
|
end
|
108
144
|
|
109
145
|
def policy_group_ids?
|
110
|
-
|
146
|
+
final_entry.key?("policy_group_ids")
|
111
147
|
end
|
112
148
|
|
113
149
|
def default_tag?
|
114
|
-
|
150
|
+
final_entry.key?("default_tag")
|
115
151
|
end
|
116
152
|
|
117
153
|
def default_tag
|
118
|
-
|
154
|
+
final_entry["default_tag"]
|
119
155
|
end
|
120
156
|
|
121
157
|
# Provides a reference of this person.
|
@@ -124,9 +160,10 @@ module Eco
|
|
124
160
|
options = into_a(options)
|
125
161
|
case
|
126
162
|
when options.include?(:identify)
|
127
|
-
"'#{
|
163
|
+
str_id = id ? "id: '#{id}'; " : ""
|
164
|
+
"(row: #{idx}) '#{name}' (#{str_id}ext_id: '#{external_id}'; email: '#{email}')"
|
128
165
|
else
|
129
|
-
|
166
|
+
final_entry.each.map do |k, v|
|
130
167
|
"'#{k}': '#{v.to_json}'"
|
131
168
|
end.join(" | ")
|
132
169
|
end
|
@@ -135,257 +172,302 @@ module Eco
|
|
135
172
|
# Setter to fill in all the `core` properties of the `Person` that are present in the `Entry`.
|
136
173
|
# @note it only sets those core properties defined in the entry.
|
137
174
|
# Meaning that if an core property is not present in the entry, this will not be set on the target person.
|
138
|
-
# @param person [Person] the person we want to set the core values to.
|
175
|
+
# @param person [Ecoportal::API::V1::Person] the person we want to set the core values to.
|
139
176
|
# @param exclude [String, Array<String>] core attributes that should not be set/changed to the person.
|
140
177
|
def set_core(person, exclude: nil)
|
141
178
|
scoped_attrs = @emap.core_attrs - into_a(exclude)
|
142
|
-
@
|
143
|
-
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
# Setter to fill in all the schema `details` fields of the `Person` that are present in the `Entry`.
|
148
|
-
# @note it only sets those details properties defined in the entry.
|
149
|
-
# Meaning that if an details property is not present in the entry, this will not be set on the target person.
|
150
|
-
# @param person [Person] the person we want to set the schema fields' values to.
|
151
|
-
# @param exclude [String, Array<String>] schema field attributes that should not be set/changed to the person.
|
152
|
-
def set_details(person, exclude: nil)
|
153
|
-
person.add_details(@person_parser.schema) if !person.details || !person.details.schema_id
|
154
|
-
scoped_attrs = @emap.details_attrs - into_a(exclude)
|
155
|
-
@internal_entry.slice(*scoped_attrs).each do |attr, value|
|
156
|
-
_set_to_details(person, attr, value)
|
179
|
+
@final_entry.slice(*scoped_attrs).each do |attr, value|
|
180
|
+
set_part(person, attr, value)
|
157
181
|
end
|
158
182
|
end
|
159
183
|
|
160
184
|
# Setter to fill in the `account` properties of the `Person` that are present in the `Entry`.
|
161
185
|
# @note it only sets those account properties defined in the entry.
|
162
186
|
# Meaning that if an account property is not present in the entry, this will not be set on the target person.
|
163
|
-
# @param person [Person] the person we want to set the account values to.
|
187
|
+
# @param person [Ecoportal::API::Internal::Person] the person we want to set the account values to.
|
164
188
|
# @param exclude [String, Array<String>] account properties that should not be set/changed to the person.
|
165
189
|
def set_account(person, exclude: nil)
|
166
190
|
person.account = {} if !person.account
|
167
191
|
person.account.permissions_preset = nil unless person.account.permissions_preset = "custom"
|
168
192
|
scoped_attrs = @emap.account_attrs - into_a(exclude)
|
169
|
-
@
|
170
|
-
|
193
|
+
@final_entry.slice(*scoped_attrs).each do |attr, value|
|
194
|
+
set_part(person.account, attr, value)
|
171
195
|
end
|
172
196
|
end
|
173
197
|
|
174
|
-
#
|
175
|
-
# @note
|
176
|
-
#
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
def external_entry
|
185
|
-
@emap.all_attrs.each_with_object({}) do |attr, hash|
|
186
|
-
unless hash.key?(ext_attr = @emap.to_external(attr))
|
187
|
-
hash[ext_attr] = @serialized_entry[attr]
|
188
|
-
end
|
198
|
+
# Setter to fill in all the schema `details` fields of the `Person` that are present in the `Entry`.
|
199
|
+
# @note it only sets those details properties defined in the entry.
|
200
|
+
# Meaning that if an details property is not present in the entry, this will not be set on the target person.
|
201
|
+
# @param person [Ecoportal::API::V1::Person] the person we want to set the schema fields' values to.
|
202
|
+
# @param exclude [String, Array<String>] schema field attributes that should not be set/changed to the person.
|
203
|
+
def set_details(person, exclude: nil)
|
204
|
+
person.add_details(@person_parser.schema) if !person.details || !person.details.schema_id
|
205
|
+
scoped_attrs = @emap.details_attrs - into_a(exclude)
|
206
|
+
@final_entry.slice(*scoped_attrs).each do |attr, value|
|
207
|
+
set_part(person.details, attr, value)
|
189
208
|
end
|
190
209
|
end
|
191
210
|
|
192
|
-
|
193
|
-
|
211
|
+
private
|
212
|
+
|
213
|
+
# @return [Hash] entry in raw: that with **external** names, values and types.
|
214
|
+
def __external_entry(data)
|
215
|
+
return data if parsing?
|
216
|
+
_external_serializing(data)
|
194
217
|
end
|
195
218
|
|
196
|
-
|
197
|
-
|
219
|
+
# @return [Hash] that with **internal** names but **external** values and types.
|
220
|
+
def __mapped_entry(data)
|
221
|
+
return _mapped_parsing(data) if parsing?
|
222
|
+
_mapped_serializing(data)
|
223
|
+
end
|
198
224
|
|
199
|
-
|
200
|
-
|
201
|
-
|
225
|
+
# @return [Hash] that with **internal** names and values, but **external** values and types.
|
226
|
+
def __internal_entry(data)
|
227
|
+
return _internal_parsing(data) if parsing?
|
228
|
+
_internal_serializing(data)
|
229
|
+
end
|
202
230
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
flds << fld.merge("value" => internal_entry[fld.alt_id]).slice("id", "alt_id", "type", "name", "shared", "multiple", "value")
|
209
|
-
end
|
210
|
-
end
|
211
|
-
core_hash.merge!({
|
212
|
-
"details" => {
|
213
|
-
"schema_id" => schema_id,
|
214
|
-
"fields" => details_fields
|
215
|
-
}
|
216
|
-
})
|
217
|
-
end
|
231
|
+
# @return [Hash] that with **internal** names, values and types.
|
232
|
+
def __final_entry(data)
|
233
|
+
return _final_parsing(data) if parsing?
|
234
|
+
_final_serializing(data)
|
235
|
+
end
|
218
236
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
237
|
+
# Serializing helper that maps internal attributes to external attribute names
|
238
|
+
# @note **Serialize**: here we unaliase internal attribute names into external ones.
|
239
|
+
# @param mapped_entry [Hash] that with **internal** names but **external** values and types.
|
240
|
+
# @return [Hash] with **external** names, values and types.
|
241
|
+
def _external_serializing(mapped_entry)
|
242
|
+
target_attrs = @emap.all_attrs | @emap.aliased_attrs
|
243
|
+
rest_keys = mapped_entry.keys - target_attrs
|
244
|
+
target_attrs -= ["send_invites"]
|
245
|
+
external_entry = target_attrs.each_with_object({}) do |attr, hash|
|
246
|
+
unless hash.key?(ext_attr = @emap.to_external(attr))
|
247
|
+
hash[ext_attr] = mapped_entry[attr]
|
224
248
|
end
|
225
249
|
end
|
250
|
+
merge_missing_attrs(external_entry, mapped_entry.slice(*rest_keys))
|
226
251
|
end
|
227
252
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
value = value.map { |v| v&.upcase } if attr == "filter_tags"
|
236
|
-
# preserve previous order
|
237
|
-
current = into_a(person.send(attr))
|
238
|
-
value = (current & value) + (value - current)
|
239
|
-
else
|
240
|
-
value = value&.strip
|
253
|
+
# Parsing helper that aliases attribute names (from internal to external names)
|
254
|
+
# @note **Parse**: here we aliase external attribute names into internal ones.
|
255
|
+
# @param external_entry [Hash] entry in raw, with **external** names and values.
|
256
|
+
# @return [Hash] entry with **internal** names, but still **external** values and types.
|
257
|
+
def _mapped_parsing(external_entry)
|
258
|
+
mapped_hash = @emap.aliased_attrs.each_with_object({}) do |attr, hash|
|
259
|
+
hash[attr] = external_entry[@emap.to_external(attr)]
|
241
260
|
end
|
261
|
+
external_entry.slice(*@emap.direct_attrs).merge(mapped_hash)
|
262
|
+
end
|
242
263
|
|
243
|
-
|
264
|
+
# Serializing helper that **serializes values** that have a parser/serializer defined.
|
265
|
+
# @note **Serializing**:
|
266
|
+
# 1. here we tranform internal into external **values**.
|
267
|
+
# 2. when running the serializers, it overrides existing keys.
|
268
|
+
# @param internal_entry [Hash] entry with **internal** names and values, but **external** types.
|
269
|
+
# @return [Hash] entry with **internal** names and **external** values and types.
|
270
|
+
def _mapped_serializing(internal_entry)
|
271
|
+
internal_entry.merge(_serialize_values(internal_entry, :internal))
|
244
272
|
end
|
245
273
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
274
|
+
# Parsing helper that just **parses the values** that have a parser/serializer defined.
|
275
|
+
# @note this entry will still miss the type parsing (i.e. to `Array` if `multiple`)
|
276
|
+
# @param mapped_entry [Hash] the entry with the _internal attribute_ names but the _external values_.
|
277
|
+
# @return [Hash] the `internal entry` with the **internal** attributes names and values.
|
278
|
+
def _internal_parsing(mapped_entry)
|
279
|
+
mapped_entry.merge(_parse_values(mapped_entry, :internal))
|
280
|
+
end
|
281
|
+
|
282
|
+
# Serializing helper that just creates the _internal entry_ out of a _parsed entry_ (serializes the type).
|
283
|
+
# @param final_entry [Hash] the entry with all _internal_ (attributes, values and types)
|
284
|
+
# @return [Hash] the `internal entry` with the **internal** attributes names and values, but external types.
|
285
|
+
def _internal_serializing(final_entry)
|
286
|
+
final_entry = final_entry.merge(_serialize_values(final_entry, :final))
|
287
|
+
core_account = @person_parser.target_attrs_account + @person_parser.target_attrs_core
|
288
|
+
core_account_hash = core_account.reduce({}) do |hash, attr|
|
289
|
+
hash.merge(hash_attr(attr, _serialize_type(attr, final_entry[attr])))
|
290
|
+
end
|
291
|
+
details_hash = @person_parser.target_attrs_details.reduce({}) do |hash, attr|
|
292
|
+
hash.merge(hash_attr(attr, _serialize_type(attr, final_entry[attr], schema: @person_parser.schema)))
|
293
|
+
end
|
294
|
+
merging(core_account_hash, details_hash) do |internal_entry|
|
295
|
+
merge_missing_attrs(internal_entry, final_entry)
|
254
296
|
end
|
255
|
-
|
256
|
-
person.account.send("#{attr}=", value)
|
257
297
|
end
|
258
298
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
299
|
+
# Parsing helper where attributes with custom parsers are already parsed, but
|
300
|
+
# it finishes to parse the types (i.e. to `Array` if `multiple`)
|
301
|
+
# @param internal_entry [Hash] the entry with the **internal** _attribute_ names and values but the **external** types.
|
302
|
+
# @return [Hash] the `parsed entry` with the **internal** final attributes names, values and types.
|
303
|
+
def _final_parsing(internal_entry)
|
304
|
+
core_account = @emap.account_attrs + @emap.core_attrs
|
305
|
+
core_account_hash = internal_entry.slice(*core_account).each_with_object({}) do |(attr, value), hash|
|
306
|
+
hash[attr] = _parse_type(attr, value)
|
263
307
|
end
|
264
|
-
value = nil if value.to_s.empty?
|
265
|
-
value = @person_parser.parse(:multiple, value) if field.multiple
|
266
308
|
|
267
|
-
|
268
|
-
|
309
|
+
details_hash = internal_entry.slice(*@emap.details_attrs).each_with_object({}) do |(attr, value), hash|
|
310
|
+
hash[attr] = _parse_type(attr, value, schema: @person_parser.schema)
|
269
311
|
end
|
270
312
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
person.send(attr)
|
313
|
+
merging(core_account_hash, details_hash) do |final_entry|
|
314
|
+
final_entry = merge_missing_attrs(final_entry, internal_entry)
|
315
|
+
final_entry.merge(_parse_values(final_entry, :final))
|
316
|
+
end
|
276
317
|
end
|
277
318
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
319
|
+
# Serializing helper that just creates the _parsed entry_ out of a `Person` object.
|
320
|
+
# @note
|
321
|
+
# - when unnesting attributes, the overriding precedence for collisions is
|
322
|
+
# - `core` -> _overrides_ -> `account` -> _overrides_ -> `details`
|
323
|
+
# - to keep things consistent, the `internal entry` hash has keys in this order:
|
324
|
+
# - `core`, `account`, `details`.
|
325
|
+
# @param person [Ecoportal::API::V1::Person] the `Person` object to transform into a _parsed entry_.
|
326
|
+
# @return [Hash] the `parsed entry` with the **internal** attributes names and internal typed values.
|
327
|
+
def _final_serializing(person)
|
328
|
+
core_hash = @person_parser.target_attrs_core.reduce({}) do |hash, attr|
|
329
|
+
hash.merge(hash_attr(attr, get_part(person, attr)))
|
330
|
+
end
|
331
|
+
account_hash = @person_parser.target_attrs_account.reduce({}) do |hash, attr|
|
332
|
+
hash.merge(hash_attr(attr, get_part(person.account, attr)))
|
333
|
+
end
|
334
|
+
details_hash = @person_parser.target_attrs_details.reduce({}) do |hash, attr|
|
335
|
+
hash.merge(hash_attr(attr, get_part(person.details, attr)))
|
336
|
+
end
|
337
|
+
merging(core_hash, account_hash, details_hash) do |final_entry|
|
338
|
+
final_entry["Has account?"] = !!person.account
|
339
|
+
final_entry.merge(_serialize_values(person, :person))
|
340
|
+
end
|
284
341
|
end
|
285
342
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
343
|
+
# HELPERS
|
344
|
+
def _serialize_values(entry, phase = :person)
|
345
|
+
@person_parser.active_attrs(entry, phase, process: :serialize).each_with_object({}) do |attr, hash|
|
346
|
+
data = entry.is_a?(Hash)? entry.merge(hash) : entry
|
347
|
+
serial_attr = @person_parser.serialize(attr, data, phase, deps: @deps[attr] || {})
|
348
|
+
hash.merge!(hash_attr(attr, serial_attr))
|
290
349
|
end
|
291
|
-
value = person.details[attr]
|
292
|
-
value = @person_parser.serialize(:date, value) if field.type == "date"
|
293
|
-
value = @person_parser.serialize(:multiple, value) if field.multiple
|
294
|
-
value
|
295
350
|
end
|
296
351
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
return _aliased_entry(data) if parsing?
|
303
|
-
_serialized_entry(data)
|
352
|
+
def _parse_values(entry, phase = :internal)
|
353
|
+
@person_parser.active_attrs(entry, phase).each_with_object({}) do |attr, hash|
|
354
|
+
parsed_attr = @person_parser.parse(attr, entry.merge(hash), phase)
|
355
|
+
hash.merge!(hash_attr(attr, parsed_attr))
|
356
|
+
end
|
304
357
|
end
|
305
358
|
|
306
|
-
#
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
359
|
+
# Transforms each **typed** value into its `String` version
|
360
|
+
def _serialize_type(attr, value, schema: nil)
|
361
|
+
case
|
362
|
+
when !!schema
|
363
|
+
unless field = schema[attr]
|
364
|
+
fatal("Field '#{attr}' does not exist in details of schema: '#{schema.name}'")
|
365
|
+
end
|
366
|
+
value = @person_parser.serialize(:multiple, value) if field.multiple
|
367
|
+
if @person_parser.defined?(field.type.to_sym)
|
368
|
+
value = @person_parser.serialize(field.type.to_sym, value, deps: {"attr" => attr})
|
369
|
+
end
|
370
|
+
value
|
371
|
+
when ["policy_group_ids", "filter_tags", "login_provider_ids", "starred_ids"].include?(attr)
|
372
|
+
@person_parser.serialize(:multiple, value)
|
373
|
+
when ["freemium", "accept_eula"].include?(attr)
|
374
|
+
@person_parser.serialize(:boolean, value)
|
375
|
+
when ["subordinates"].include?(attr)
|
376
|
+
@person_parser.serialize(:number, value)
|
377
|
+
else
|
378
|
+
value
|
379
|
+
end
|
316
380
|
end
|
317
381
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
382
|
+
# Transforms each `String` value into its **typed** version
|
383
|
+
def _parse_type(attr, value, schema: nil)
|
384
|
+
value = value.strip if value.is_a?(String)
|
385
|
+
value = nil if value.to_s.strip.empty?
|
386
|
+
case
|
387
|
+
when !!schema
|
388
|
+
unless field = schema[attr]
|
389
|
+
fatal("Field '#{attr}' does not exist in details of schema: '#{schema.name}'")
|
390
|
+
end
|
391
|
+
value = @person_parser.parse(:multiple, value) if field.multiple
|
322
392
|
|
323
|
-
|
324
|
-
|
325
|
-
# 1. here we tranform internal into external **values**.
|
326
|
-
# 2. when running the serializers, it overrides existing keys.
|
327
|
-
# @param unserialized_entry [Hash] entry with **internal** names and values.
|
328
|
-
# @return [Hash] entry with **internal names** and **external values**.
|
329
|
-
def _serialized_entry(unserialized_entry)
|
330
|
-
serial_attrs = @person_parser.defined_attrs.reduce({}) do |serial_hash, attr|
|
331
|
-
deps = @deps[attr] || {}
|
332
|
-
serial_attr = @person_parser.serialize(attr, @person, deps: deps)
|
333
|
-
serial_hash.merge(hash_attr(attr, serial_attr))
|
334
|
-
end
|
335
|
-
unserialized_entry.merge(serial_attrs).tap do |hash|
|
336
|
-
if hash.key?("filter_tags") && hash["filter_tags"].is_a?(Array)
|
337
|
-
hash["filter_tags"] = @person_parser.serialize(:multiple, hash["filter_tags"])
|
393
|
+
if @person_parser.defined?(field.type.to_sym)
|
394
|
+
value = @person_parser.parse(field.type.to_sym, value, deps: {"attr" => attr})
|
338
395
|
end
|
396
|
+
value
|
397
|
+
when attr == "email"
|
398
|
+
value = value.strip.downcase if value
|
399
|
+
value
|
400
|
+
when ["policy_group_ids", "filter_tags", "login_provider_ids", "starred_ids"].include?(attr)
|
401
|
+
value = @person_parser.parse(:multiple, value)
|
402
|
+
value = (attr == "filter_tags")? value.compact.map(&:upcase) : value
|
403
|
+
value
|
404
|
+
when ["freemium", "accept_eula"].include?(attr)
|
405
|
+
@person_parser.parse(:boolean, value)
|
406
|
+
when ["subordinates"].include?(attr)
|
407
|
+
@person_parser.parse(:number, value)
|
408
|
+
else
|
409
|
+
value
|
339
410
|
end
|
340
411
|
end
|
341
412
|
|
342
|
-
#
|
343
|
-
# @
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
413
|
+
# Merges multiple hashes giving overriding perference to the first ones.
|
414
|
+
# @return [Hash] with well sorted keys, as they came in the order of the input hashes.
|
415
|
+
def merging(*hashes)
|
416
|
+
sorted_keys = hashes.map {|h| h.keys}.flatten.uniq
|
417
|
+
rev_hash = hashes.reverse.each_with_object({}) {|h, out| out.merge!(h)}
|
418
|
+
merged = sorted_keys.each_with_object({}) do |k, h|
|
419
|
+
h[k] = rev_hash[k]
|
420
|
+
end
|
421
|
+
merged = yield(merged) if block_given?
|
422
|
+
merged
|
348
423
|
end
|
349
424
|
|
350
|
-
#
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
parsed = @person_parser.active_attrs(aliased_entry).each_with_object({}) do |attr, hash|
|
355
|
-
hash[attr] = @person_parser.parse(attr, aliased_entry.merge(hash))
|
356
|
-
end
|
357
|
-
aliased_entry.merge(parsed)
|
425
|
+
# Adds to `dest_entry` the `keys` it misses from `source_entry`
|
426
|
+
def merge_missing_attrs(dest_entry, source_entry)
|
427
|
+
keys_rest = source_entry.keys - dest_entry.keys
|
428
|
+
dest_entry.merge(source_entry.slice(*keys_rest))
|
358
429
|
end
|
359
430
|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
# - `core`, `account`, `details`.
|
366
|
-
# @param person [Ecoportal::API::V1::Person] the `Person` object to transform into an _internal entry_.
|
367
|
-
# @return [Hash] the `internal entry` with the **internal** attributes names and values.
|
368
|
-
def _unserialized_entry(person)
|
369
|
-
core_hash = @person_parser.target_attrs_core.reduce({}) do |hash, attr|
|
370
|
-
value = _get_from_core(person, attr)
|
371
|
-
hash.merge(hash_attr(attr, value))
|
372
|
-
end
|
431
|
+
def into_a(value)
|
432
|
+
value = [] if value == nil
|
433
|
+
value = [].push(value) unless value.is_a?(Array)
|
434
|
+
value
|
435
|
+
end
|
373
436
|
|
374
|
-
|
375
|
-
|
376
|
-
|
437
|
+
def get_part(obj, attr)
|
438
|
+
return unless obj
|
439
|
+
case obj
|
440
|
+
when Ecoportal::API::V1::PersonDetails
|
441
|
+
#unless field = obj.get_field(attr)
|
442
|
+
# fatal("Field '#{attr}' does not exist in details of schema: '#{obj.schema_id}'")
|
443
|
+
#end
|
444
|
+
obj[attr]
|
445
|
+
else
|
446
|
+
obj.send(attr)
|
377
447
|
end
|
448
|
+
end
|
378
449
|
|
379
|
-
|
380
|
-
|
381
|
-
|
450
|
+
def set_part(obj, attr, value)
|
451
|
+
return unless obj
|
452
|
+
begin
|
453
|
+
case obj
|
454
|
+
when Ecoportal::API::V1::PersonDetails
|
455
|
+
unless field = obj.get_field(attr)
|
456
|
+
fatal("Field '#{attr}' does not exist in details of schema: '#{obj.schema_id}'")
|
457
|
+
end
|
458
|
+
obj[attr] = value
|
459
|
+
else
|
460
|
+
obj.send("#{attr}=", value)
|
461
|
+
end
|
462
|
+
rescue Exception => e
|
463
|
+
raise e.append_message " -- Entry #{to_s(:identify)}"
|
382
464
|
end
|
465
|
+
end
|
383
466
|
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
sorted_keys.reduce({}) {|h,k| h[k] = rh[k]; h}
|
467
|
+
# @return [Hash] `value` if it was a `Hash`, and `{ attr => value}` otherwise
|
468
|
+
def hash_attr(attr, value)
|
469
|
+
return value if value.is_a?(Hash)
|
470
|
+
{ attr => value }
|
389
471
|
end
|
390
472
|
|
391
473
|
# LOGGER
|
@@ -398,11 +480,21 @@ module Eco
|
|
398
480
|
raise msg
|
399
481
|
end
|
400
482
|
|
401
|
-
#
|
402
|
-
def
|
403
|
-
|
404
|
-
|
405
|
-
|
483
|
+
# Function to debug faste
|
484
|
+
def print_models
|
485
|
+
print_it = Proc.new do |name, model|
|
486
|
+
puts "#{name}:"
|
487
|
+
pp model
|
488
|
+
puts "*" * 30
|
489
|
+
end
|
490
|
+
|
491
|
+
fin = Proc.new {|x_| print_it.call("final_entry", @final_entry) }
|
492
|
+
int = Proc.new {|x_| print_it.call("internal_entry", @internal_entry) }
|
493
|
+
mad = Proc.new {|x_| print_it.call("mapped_entry", @mapped_entry) }
|
494
|
+
ext = Proc.new {|x_| print_it.call("external_entry", @external_entry) }
|
495
|
+
|
496
|
+
call_order = parsing? ? [ext, mad, int, fin] : [fin, int, mad, ext]
|
497
|
+
call_order.each {|proc| proc.call}
|
406
498
|
end
|
407
499
|
|
408
500
|
end
|