include DocumentParser class RemoteCensusApi def call(document_type, document_number, date_of_birth, postal_code) response = nil get_document_number_variants(document_type, document_number).each do |variant| response = Response.new(get_response_body(document_type, variant, date_of_birth, postal_code)) return response if response.valid? end response end class Response def initialize(body) @body = body end def extract_value(path_value) path = parse_response_path(path_value) return nil if path.blank? @body.dig(*path) end def valid? path_value = Setting["remote_census.response.valid"] extract_value(path_value).present? end def date_of_birth path_value = Setting["remote_census.response.date_of_birth"] str = extract_value(path_value) return nil if str.blank? day, month, year = str.match(/(\d\d?)\D(\d\d?)\D(\d\d\d?\d?)/)[1..3] return nil if day.blank? || month.blank? || year.blank? Time.zone.local(year.to_i, month.to_i, day.to_i).to_date end def postal_code path_value = Setting["remote_census.response.postal_code"] extract_value(path_value) end def district_code path_value = Setting["remote_census.response.district"] extract_value(path_value) end def gender path_value = Setting["remote_census.response.gender"] case extract_value(path_value) when "Male", "VarĂ³n" "male" when "Female", "Mujer" "female" end end def name path_value_name = Setting["remote_census.response.name"] path_value_surname = Setting["remote_census.response.surname"] "#{extract_value(path_value_name)} #{extract_value(path_value_surname)}" end def parse_response_path(path_value) path_value.split(".").map(&:to_sym) if path_value.present? end end private def get_response_body(document_type, document_number, date_of_birth, postal_code) if end_point_defined? request = request(document_type, document_number, date_of_birth, postal_code) client.call(Setting["remote_census.request.method_name"].to_sym, message: request).body else stubbed_invalid_response end end def client @client = Savon.client(wsdl: Setting["remote_census.general.endpoint"]) end def request(document_type, document_number, date_of_birth, postal_code) structure = JSON.parse(Setting["remote_census.request.structure"]) fill_in(structure, Setting["remote_census.request.document_type"], document_type) fill_in(structure, Setting["remote_census.request.document_number"], document_number) fill_in(structure, Setting["remote_census.request.postal_code"], postal_code) if date_of_birth.present? fill_in(structure, Setting["remote_census.request.date_of_birth"], I18n.l(date_of_birth, format: :default)) end structure end def fill_in(structure, path_value, value) path = parse_request_path(path_value) update_value(structure, path, value) if path.present? end def parse_request_path(path_value) path_value.split(".") if path_value.present? end def update_value(structure, path, value) *path, final_key = path to_set = path.empty? ? structure : structure.dig(*path) return unless to_set to_set[final_key] = value end def end_point_defined? Setting["remote_census.general.endpoint"].present? end def stubbed_invalid_response {} end end