# 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) #