lib/eco/api/common/people/person_entry.rb in eco-helpers-0.8.3 vs lib/eco/api/common/people/person_entry.rb in eco-helpers-0.8.4
- old
+ new
@@ -1,10 +1,11 @@
module Eco
module API
module Common
module People
class PersonEntry
+
# This class is meant to provide a common interface to access entries of source data that come in different formats.
# @note
# - if `data` is a `Person` object, its behaviour is `serialise`.
# - if `data` is **not** a `Person` object, it does a `parse`.
# - currently **in rework**, so there may be subtle differences that make it temporarily unstable (yet it is reliable).
@@ -15,25 +16,25 @@
# @param logger [Common::Session::Logger, ::Logger] object to manage logs.
def initialize(data, person_parser:, attr_map:, dependencies: {}, logger: ::Logger.new(IO::NULL))
raise "Constructor needs a PersonParser. Given: #{parser}" if !person_parser.is_a?(Eco::API::Common::People::PersonParser)
raise "Expecting Mapper object. Given: #{attr_map}" if attr_map && !attr_map.is_a?(Eco::Data::Mapper)
- @source = data
+ @source = data
@person_parser = person_parser
- @deps = dependencies
- @logger = logger
- @attr_map = attr_map
+ @deps = dependencies
+ @logger = logger
+ @attr_map = attr_map
@emap = PersonEntryAttributeMapper.new(@source, person_parser: @person_parser, attr_map: @attr_map, logger: @logger)
if parsing?
@external_entry = data
- @serialized_entry = mapped_entry(@external_entry)
- @internal_entry = internal_entry(@serialized_entry)
+ @serialized_entry = _mapped_entry(@external_entry)
+ @internal_entry = _internal_entry(@serialized_entry)
else # SERIALIZING
@person = data
- @internal_entry = internal_entry(@person)
- @serialized_entry = mapped_entry(@internal_entry)
+ @internal_entry = _internal_entry(@person)
+ @serialized_entry = _mapped_entry(@internal_entry)
#@external_entry = external_entry
end
end
# To know if currently the object is in parse or serialize mode.
@@ -97,11 +98,11 @@
# @param person [Person] the person we want to set the core values to.
# @param exclude [String, Array<String>] core attributes that should not be set/changed to the person.
def set_core(person, exclude: nil)
scoped_attrs = @emap.core_attrs - into_a(exclude)
@internal_entry.slice(*scoped_attrs).each do |attr, value|
- set_to_core(person, attr, value)
+ _set_to_core(person, attr, value)
end
end
# Setter to fill in all the schema `details` fields of the `Person` that are present in the `Entry`.
# @note it only sets those details properties defined in the entry.
@@ -110,11 +111,11 @@
# @param exclude [String, Array<String>] schema field attributes that should not be set/changed to the person.
def set_details(person, exclude: nil)
person.add_details(@person_parser.schema) if !person.details || !person.details.schema_id
scoped_attrs = @emap.details_attrs - into_a(exclude)
@internal_entry.slice(*scoped_attrs).each do |attr, value|
- set_to_details(person, attr, value)
+ _set_to_details(person, attr, value)
end
end
# Setter to fill in the `account` properties of the `Person` that are present in the `Entry`.
# @note it only sets those account properties defined in the entry.
@@ -124,11 +125,11 @@
def set_account(person, exclude: nil)
person.account = {} if !person.account
person.account.permissions_preset = nil unless person.account.permissions_preset = "custom"
scoped_attrs = @emap.account_attrs - into_a(exclude)
@internal_entry.slice(*scoped_attrs).each do |attr, value|
- set_to_account(person, attr, value)
+ _set_to_account(person, attr, value)
end
end
# Entry represented in a `Hash` with **external** attribute names and values thereof.
# @note normally used to obtain a **serialized entry**.
@@ -146,18 +147,54 @@
hash[ext_attr] = @serialized_entry[attr]
end
end
end
+ def internal_entry
+ @internal_entry
+ end
+
+ def doc
+ return @person.doc if instance_variable_defined?(:@person) && @person
+
+ core_attrs = @emap.core_attrs
+ details_attrs = @emap.details_attrs
+ account_attrs = @emap.account_attrs
+
+ internal_entry.slice(*core_attrs).tap do |core_hash|
+ unless details_attrs.empty?
+ schema_id = @person_parser.schema.id
+ details_fields = @person_parser.schema.doc["fields"].each_with_object([]) do |fld, flds|
+ if details_attrs.include?(fld.alt_id)
+ flds << fld.merge("value" => internal_entry[fld.alt_id]).slice("id", "alt_id", "type", "name", "shared", "multiple", "value")
+ end
+ end
+ core_hash.merge!({
+ "details" => {
+ "schema_id" => schema_id,
+ "fields" => details_fields
+ }
+ })
+ end
+
+ unless account_attrs.empty?
+ account_hash = internal_entry.slice(*account_attrs)
+ core_hash.merge!({
+ "account" => account_hash
+ })
+ end
+ end
+ end
+
private
- def set_to_core(person, attr, value)
+ def _set_to_core(person, attr, value)
value = value&.downcase if attr == "email"
person.send("#{attr}=", value&.strip)
end
- def set_to_account(person, attr, value)
+ def _set_to_account(person, attr, value)
return if !person.account
multiple = ["policy_group_ids", "filter_tags"].include?(attr)
if multiple
value = @person_parser.parse(:multiple, value)
value = value.map { |v| v&.upcase } if attr == "filter_tags"
@@ -167,11 +204,11 @@
end
person.account.send("#{attr}=", value)
end
- def set_to_details(person, attr, value)
+ def _set_to_details(person, attr, value)
return if !person.details
unless field = person.details.get_field(attr)
fatal("Field '#{attr}' does not exist in details of schema: '#{person.details.schema_id}'")
end
value = nil if value.to_s.empty?
@@ -182,22 +219,22 @@
end
person.details[attr] = value
end
- def get_from_core (person, attr)
+ def _get_from_core (person, attr)
person.send(attr)
end
- def get_from_account (person, attr)
+ def _get_from_account (person, attr)
return nil if !person.account
multiple = ["policy_group_ids", "filter_tags"].include?(attr)
value = person.account.send(attr)
@person_parser.serialize(:multiple, value) if multiple
end
- def get_from_details(person, attr)
+ def _get_from_details(person, attr)
return nil if !person.details || !person&.details&.schema_id
unless field = person.details.get_field(attr)
fatal("Field '#{attr}' does not exist in details of schema: '#{person.details.schema_id}'")
end
value = person.details[attr]
@@ -208,20 +245,20 @@
# MAPPED ENTRY (when and where applicable)
# To obtain an entry with internal names but external values.
# @param data [Hash] external or raw entry (when parsing) or internal or parsed entry (when serializing).
# @return [Hash] entry with **internal names** and **external values**.
- def mapped_entry(data)
- return aliased_entry(data) if parsing?
- serialized_entry(data)
+ def _mapped_entry(data)
+ return _aliased_entry(data) if parsing?
+ _serialized_entry(data)
end
# Parsing helper that aliases attribute names (from internal to external names)
# @note **Parse**: here we aliase internal attribute names into external ones.
# @param ext_entry [Hash] entry in raw, with **external** names and values.
# @return [Hash] entry with **internal names** and **external values**.
- def aliased_entry(ext_entry)
+ def _aliased_entry(ext_entry)
aliased_hash = @emap.aliased_attrs.map do |attr|
[attr, ext_entry[@emap.to_external(attr)]]
end.to_h
ext_entry.slice(*@emap.direct_attrs).merge(aliased_hash)
@@ -236,11 +273,11 @@
# @note **Serializing**:
# 1. here we tranform internal into external **values**.
# 2. when running the serializers, it overrides existing keys.
# @param unserialized_entry [Hash] entry with **internal** names and values.
# @return [Hash] entry with **internal names** and **external values**.
- def serialized_entry(unserialized_entry)
+ def _serialized_entry(unserialized_entry)
serial_attrs = @person_parser.defined_attrs.reduce({}) do |serial_hash, attr|
deps = @deps[attr] || {}
serial_attr = @person_parser.serialize(attr, @person, deps: deps)
serial_hash.merge(hash_attr(attr, serial_attr))
end
@@ -248,19 +285,19 @@
end
# To obtain an entry with internal names but external values.
# @param data [Hash, Ecoportal::API::V1::Person] alised_entry (when parsing) or person (when serializing).
# @return [Hash] the `internal entry` with the **internal** attributes names and values.
- def internal_entry(data)
- return parsed_entry(data) if parsing?
- unserialized_entry(data)
+ def _internal_entry(data)
+ return _parsed_entry(data) if parsing?
+ _unserialized_entry(data)
end
# Parsing helper that just **parses the values** that have a parser/serializer defined.
# @param aliased_entry [Hash] the entry with the _internal attribute_ names but the _external values_.
# @return [Hash] the `internal entry` with the **internal** attributes names and values.
- def parsed_entry(aliased_entry)
+ def _parsed_entry(aliased_entry)
parsed = @person_parser.defined_attrs.map do |attr|
value = @person_parser.parse(attr, aliased_entry)
[attr, value]
end.to_h
aliased_entry.merge(parsed)
@@ -272,22 +309,22 @@
# - `core` -> _overrides_ -> `account` -> _overrides_ -> `details`
# - to keep things consistent, the `internal entry` hash has keys in this order:
# - `core`, `account`, `details`.
# @param person [Ecoportal::API::V1::Person] the `Person` object to transform into an _internal entry_.
# @return [Hash] the `internal entry` with the **internal** attributes names and values.
- def unserialized_entry(person)
+ def _unserialized_entry(person)
core_hash = @person_parser.target_attrs_core.reduce({}) do |hash, attr|
- value = get_from_core(person, attr)
+ value = _get_from_core(person, attr)
hash.merge(hash_attr(attr, value))
end
details_hash = @person_parser.target_attrs_details.reduce({}) do |hash, attr|
- value = get_from_details(person, attr)
+ value = _get_from_details(person, attr)
hash.merge(hash_attr(attr, value))
end
account_hash = @person_parser.target_attrs_account.reduce({}) do |hash, attr|
- value = get_from_account(person, attr)
+ value = _get_from_account(person, attr)
hash.merge(hash_attr(attr, value))
end
# merge by core overriding account and details
rh = details_hash.merge(account_hash).merge(core_hash)