The purpose of the lib folder is to have code that doesn't necessary belong in the application but can be shared with other applications. However, we don't have other applications and, if we did, the way to share code between them would be using a gem or even a git submodule. So having both the `app/` and the `lib/` folders is confusing IMHO, and it causes unnecessary problems with autoloading. So we're moving the `lib/` folder to `app/lib/`. Originally, some of these files were in the `app/services/` folder and then they were moved to the `lib/` folder. We're using `app/lib/` instead of `app/services/` so the upgrade is less confusing. There's an exception, though. The `OmniAuth::Strategies::Wordpress` class needs to be available in the Devise initializer. Since this is an initializer and trying to autoload a class here will be problematic when switching to Zeitwerk, we'll keep the `require` clause on top of the Devise initializer in order to load the file and so it will be loaded even if it isn't in the autoload paths anymore.
130 lines
3.6 KiB
Ruby
130 lines
3.6 KiB
Ruby
class RemoteCensusApi
|
|
include DocumentParser
|
|
|
|
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
|