class Officing::Residence include ActiveModel::Model include ActiveModel::Dates include ActiveModel::Validations::Callbacks attr_accessor :user, :officer, :document_number, :document_type, :year_of_birth, :date_of_birth, :postal_code before_validation :retrieve_census_data validates :document_number, presence: true validates :document_type, presence: true validates :date_of_birth, presence: true, if: -> { Setting.force_presence_date_of_birth? } validates :postal_code, presence: true, if: -> { Setting.force_presence_postal_code? } validates :year_of_birth, presence: true, unless: -> { Setting.force_presence_date_of_birth? } validate :allowed_age validate :local_residence def initialize(attrs = {}) self.date_of_birth = parse_date("date_of_birth", attrs) attrs = remove_date("date_of_birth", attrs) super clean_document_number end def save return false unless valid? if user_exists? self.user = find_user_by_document user.update!(verified_at: Time.current) else user_params = { document_number: document_number, document_type: document_type, geozone: geozone, date_of_birth: response_date_of_birth.in_time_zone.to_datetime, gender: gender, residence_verified_at: Time.current, verified_at: Time.current, erased_at: Time.current, password: random_password, terms_of_service: "1", email: nil } self.user = User.create!(user_params) end end def save! validate! && save end def store_failed_census_call FailedCensusCall.create( user: user, document_number: document_number, document_type: document_type, date_of_birth: date_of_birth, postal_code: postal_code, year_of_birth: year_of_birth, poll_officer: officer ) end def user_exists? find_user_by_document.present? end def find_user_by_document User.find_by(document_number: document_number, document_type: document_type) end def local_residence return if errors.any? unless residency_valid? store_failed_census_call errors.add(:local_residence, false) end end def allowed_age return if errors[:year_of_birth].any? return unless @census_api_response.valid? unless allowed_age? errors.add(:year_of_birth, I18n.t("verification.residence.new.error_not_allowed_age")) end end def allowed_age? Age.in_years(response_date_of_birth) >= User.minimum_required_age end def geozone Geozone.find_by(census_code: district_code) end def district_code @census_api_response.district_code end def gender @census_api_response.gender end def response_date_of_birth @census_api_response.date_of_birth end private def retrieve_census_data @census_api_response = CensusCaller.new.call(document_type, document_number, date_of_birth, postal_code) end def residency_valid? @census_api_response.valid? && valid_year_of_birth? end def valid_year_of_birth? return true if Setting.force_presence_date_of_birth? @census_api_response.date_of_birth.year.to_s == year_of_birth.to_s end def clean_document_number self.document_number = document_number.gsub(/[^a-z0-9]+/i, "").upcase if document_number.present? end def random_password (0...20).map { ("a".."z").to_a[rand(26)] }.join end end