Files
Dalan/app/models/phone.rb
2026-08-13 19:56:46 +03:30

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