module Eco module API module Common module People class PersonParser CORE_ATTRS = ["id", "external_id", "email", "name", "supervisor_id"] ACCOUNT_ATTRS = ["policy_group_ids", "filter_tags", "default_tag"] TYPE = [:select, :text, :date, :number, :phone_number, :boolean, :multiple] attr_reader :schema attr_reader :details_attrs, :all_attrs attr_reader :defined_attrs def initialize(schema: nil) #), logger: nil) #self.schema = schema raise "Constructor needs a PersonSchema. Given: #{schema}" if schema && !schema.is_a?(Ecoportal::API::V1::PersonSchema) @details_attrs = [] @parsers = {} if schema @schema = Ecoportal::API::Internal::PersonSchema.new(JSON.parse(schema.doc.to_json)) @details_attrs = @schema&.fields.map { |fld| fld.alt_id } end @all_attrs = CORE_ATTRS + ACCOUNT_ATTRS + @details_attrs #init_default_parsers if @schema end def target_attrs_core(source_attrs = nil) return CORE_ATTRS if !source_attrs scoped_attrs(source_attrs, CORE_ATTRS) end def target_attrs_details(source_attrs = nil) return @details_attrs if ! source_attrs scoped_attrs(source_attrs, @details_attrs) end def target_attrs_account(source_attrs = nil) return ACCOUNT_ATTRS if !source_attrs scoped_attrs(source_attrs, ACCOUNT_ATTRS) end def defined @parsers.keys end def list @parsers.keys end def defined_attrs defined - (defined - all_attrs) end def undefined_attrs all_attrs - defined_attrs end def defined?(attr) !!@parsers[attr] end #def append(attr, dependencies: {}, &bloc) # @parsers[attr] = into_a(parsers[attr]).push(define_parser(attr, dependencies, &bloc)) #end # merges parser overriding self for exisint parsers def merge(parser) return self if !parser raise "Expected a PersonParser object. Given #{parser}" if !parser.is_a?(PersonParser) @parsers.merge!(parser.hash) self end def define_attribute(attr, dependencies: {}, &bloc) @parsers[attr] = define_parser(attr, dependencies, &bloc) self end def parse(attr, source, deps: {}) raise "There is no parser for attribute '#{attr}'" if !self.defined?(attr) @parsers[attr].parse(source, dependencies: deps) end def serialize(attr, object, deps: {}) raise "There is no parser for attribute '#{attr}'" if !self.defined?(attr) @parsers[attr].serialize(object, dependencies: deps) end protected def hash @parsers end private def scoped_attrs(source_attrs, section_attrs) direct_attrs = source_attrs & section_attrs parsed_attrs = @parsers.keys & section_attrs (source_attrs + parsed_attrs) & (direct_attrs + parsed_attrs) end def define_parser(attr, dependencies = {}, &definition) if !valid?(attr) str_attr = (attr.is_a?(Symbol) ? ":" : "") + attr.to_s msg = "The attribute '#{str_attr}' is not part of core, account or target schema, or does not match any type: #{@details_attrs}" raise msg end parser = Eco::Language::Models::AttributeParser.new(attr, dependencies: dependencies) #yield(parser) definition.call(parser) parser end def valid?(attr) (attr.is_a?(Symbol) && valid_type?(attr)) || (attr.is_a?(String) && (!@schema || valid_attr?(attr))) end def valid_attr?(attr) @all_attrs.include?(attr) end def valid_type?(attr) TYPE.include?(attr) end def into_a(value) value = [] if value == nil value = [].push(value) unless value.is_a?(Array) value end end end end end end