143 lines
3.4 KiB
Ruby
143 lines
3.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Class Phone
|
|
#
|
|
class Phone < ApplicationRecord
|
|
include Encryptable
|
|
|
|
TWILIO_CHANNELS = %w[call sms].freeze
|
|
DEFAULT_COUNTRY_CODE_COUNT = 2
|
|
|
|
belongs_to :user
|
|
|
|
enum state: { pending: 0, verified: 1, rejected: 2, replaced: 3 }
|
|
enum step: { access_phone: 0, owner_phone: 1, telephone: 2 }
|
|
enum category: { mobile: 0, landline: 1 }
|
|
|
|
attr_encrypted :number
|
|
validates :number, phone: true
|
|
|
|
before_create :generate_code
|
|
before_validation :parse_country
|
|
before_validation :sanitize_number
|
|
|
|
before_save :save_number_index
|
|
after_commit :start_phone_kyc_verification, on: %i[create update]
|
|
scope :verified, -> { where.not(validated_at: nil) }
|
|
|
|
# validate :validate_phone_number
|
|
|
|
def validate_phone_number
|
|
return errors.add(:number, 'number is not a phone') if number.match(/\A..(9)\d+/) && self.phone?
|
|
end
|
|
|
|
#FIXME: Clean code below
|
|
class << self
|
|
def sanitize(unsafe_phone)
|
|
unsafe_phone.to_s.gsub(/\D/, '')
|
|
end
|
|
|
|
def parse(unsafe_phone)
|
|
Phonelib.parse self.sanitize(unsafe_phone)
|
|
end
|
|
|
|
def valid?(unsafe_phone)
|
|
parse(unsafe_phone).valid?
|
|
end
|
|
|
|
def valid_number(unsafe_phone)
|
|
parse(unsafe_phone).national.gsub(/\s+/, "").delete_prefix("0")
|
|
end
|
|
|
|
def international(unsafe_phone)
|
|
parse(unsafe_phone).international(false)
|
|
end
|
|
|
|
def find_by_number(number, attrs={})
|
|
attrs.merge!(number_index: SaltedCrc32.generate_hash(number))
|
|
find_by(attrs)
|
|
end
|
|
|
|
def find_by_number!(number)
|
|
find_by!(number_index: SaltedCrc32.generate_hash(number))
|
|
end
|
|
end
|
|
|
|
def sub_masked_number
|
|
code_count = parse_code&.length
|
|
code_count = DEFAULT_COUNTRY_CODE_COUNT unless code_count
|
|
|
|
if number.present?
|
|
number.sub(/(?<=\A.{#{code_count}})(.*)(?=.{4}\z)/) { |match| '*' * match.length }
|
|
else
|
|
number
|
|
end
|
|
end
|
|
|
|
def check_owner_ship
|
|
jibit = JibitService.new
|
|
response = jibit.mobile_info(self.national_number, self.user.verified_profile.national_code)
|
|
|
|
JSON.parse(response.body).dig('matched').present?
|
|
end
|
|
|
|
def national_number
|
|
return if number.blank?
|
|
|
|
::Phonelib.parse(number).national.delete(' ').rjust(11, '0')
|
|
end
|
|
|
|
private
|
|
|
|
def start_phone_kyc_verification
|
|
::KycService.phone_label_update(self)
|
|
end
|
|
|
|
def generate_code
|
|
self.code = rand.to_s[2..6]
|
|
end
|
|
|
|
def parse_country
|
|
# data = Phonelib.parse(number)
|
|
self.country = "IR"
|
|
end
|
|
|
|
def parse_code
|
|
data = Phonelib.parse(number)
|
|
data.country_code
|
|
end
|
|
|
|
def sanitize_number
|
|
self.number = Phone.sanitize(number)
|
|
end
|
|
|
|
def save_number_index
|
|
self.number_index = SaltedCrc32.generate_hash(number) if number.present?
|
|
end
|
|
end
|
|
|
|
# == Schema Information
|
|
# Schema version: 20210425062048
|
|
#
|
|
# Table name: phones
|
|
#
|
|
# id :bigint not null, primary key
|
|
# user_id :integer unsigned, not null
|
|
# country :string(255) not null
|
|
# code :string(5)
|
|
# number_encrypted :string(255) not null
|
|
# number_index :bigint not null
|
|
# validated_at :datetime
|
|
# created_at :datetime not null
|
|
# updated_at :datetime not null
|
|
# category :integer not null
|
|
# state :integer default("pending")
|
|
# step :integer default("access_phone")
|
|
#
|
|
# Indexes
|
|
#
|
|
# index_phones_on_number_index (number_index)
|
|
# index_phones_on_user_id (user_id)
|
|
#
|