Initial commit
This commit is contained in:
182
app/models/profile.rb
Normal file
182
app/models/profile.rb
Normal file
@@ -0,0 +1,182 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Profile model
|
||||
# in original version user has only one drafted or submitted at time but can has many verified and rejected
|
||||
# but in my version user can only one verified profile too
|
||||
# only drafted profile editable, so dont send confirm param in creation or update time
|
||||
class Profile < ApplicationRecord
|
||||
include Encryptable
|
||||
|
||||
# acts_as_eventable prefix: 'profile', on: %i[create update]
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :city, required: false
|
||||
|
||||
enum state: { drafted: 0, submitted: 1, verified: 3, rejected: 4 }
|
||||
|
||||
EDITABLE_PARAMS = { drafted: %w[first_name last_name dob address postcode city country metadata national_code] }.freeze
|
||||
OPTIONAL_PARAMS = %w[first_name last_name dob address postcode city country national_code].freeze
|
||||
|
||||
attr_encrypted :first_name
|
||||
attr_encrypted :last_name
|
||||
attr_encrypted :dob
|
||||
attr_encrypted :address
|
||||
attr_encrypted :national_code
|
||||
|
||||
validates :first_name, presence: true,
|
||||
length: 1..255,
|
||||
format: {
|
||||
with: /\A[[:word:]\s\-']+\z/,
|
||||
message: 'only allows letters, digits "-", "\'", and space'
|
||||
},
|
||||
if: proc { |a| a.first_name.present? }
|
||||
validates :last_name, presence: true,
|
||||
length: 1..255,
|
||||
format: {
|
||||
with: /\A[[:word:]\s\-']+\z/,
|
||||
message: 'only allows letters, digits "-", "\'", and space'
|
||||
},
|
||||
if: proc { |a| a.last_name.present? }
|
||||
|
||||
validates :city, presence: false
|
||||
|
||||
validate :validate_country_format, if: ->(p) { p.country.present? }
|
||||
validates :postcode, length: 2..255,
|
||||
format: {
|
||||
with: /\A[[:word:]\s\-]+\z/,
|
||||
message: 'only allows letters, digits, "-" and space'
|
||||
},
|
||||
if: proc { |a| a.postcode.present? }
|
||||
|
||||
validates :address, length: 1..255,
|
||||
format: {
|
||||
with: /\A[[:word:]\s\-\–\,\.~;\/:\#"\\&\')\(]+\z/,
|
||||
message: 'only allows letters, digits "-", "–", "\'", ".", ",", "#", ":", ";", "&" and space'
|
||||
},
|
||||
if: proc { |a| a.address.present? }
|
||||
|
||||
validates :national_code, length: { is: 10 },
|
||||
format: { with: /\A\d+\z/, message: 'Ten Integer only. No sign allowed.' }
|
||||
|
||||
validates :metadata, data_is_json: true
|
||||
validate :profile_state!, on: :create
|
||||
# validate :profile_update!, on: :update
|
||||
validate :dob_not_in_the_future
|
||||
|
||||
after_commit :start_profile_kyc_verification
|
||||
|
||||
scope :kept, -> { joins(:user).where(users: { discarded_at: nil }) }
|
||||
|
||||
before_validation do
|
||||
squish_spaces
|
||||
end
|
||||
|
||||
def full_name
|
||||
"#{first_name} #{last_name}"
|
||||
end
|
||||
|
||||
def reverse_full_name
|
||||
"#{last_name} #{first_name}"
|
||||
end
|
||||
|
||||
def sub_masked_last_name
|
||||
last_name.sub(/(?<=\A.{1})(.*)/) { |match| '*' * match.length } if last_name
|
||||
end
|
||||
|
||||
def sub_masked_national_code
|
||||
national_code.sub(/(?<=\A.{5})(.*)/) { |match| '*' * match.length } if national_code
|
||||
end
|
||||
|
||||
def sub_masked_dob
|
||||
dob.to_s.sub(/(?<=\A.{8})(.*)/) { |match| '*' * match.length } if dob
|
||||
end
|
||||
|
||||
def as_json_for_event_api
|
||||
{
|
||||
user: user.as_json_for_event_api,
|
||||
first_name: first_name,
|
||||
last_name: last_name,
|
||||
dob: format_iso8601_time(dob),
|
||||
address: address,
|
||||
postcode: postcode,
|
||||
city: city,
|
||||
country: country,
|
||||
metadata: metadata,
|
||||
created_at: format_iso8601_time(created_at),
|
||||
updated_at: format_iso8601_time(updated_at)
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def validate_country_format
|
||||
return if ISO3166::Country.find_country_by_alpha2(country) ||
|
||||
ISO3166::Country.find_country_by_alpha3(country)
|
||||
|
||||
errors.add(:country, 'must have alpha2 or alpha3 format')
|
||||
end
|
||||
|
||||
def squish_spaces
|
||||
self.first_name = first_name&.squish
|
||||
self.last_name = last_name&.squish
|
||||
self.postcode = postcode&.squish
|
||||
end
|
||||
|
||||
def profile_state!
|
||||
# No limits for storing drafted and rejected profiles
|
||||
# return if state.in?(%w[drafted rejected])
|
||||
return if state.in?(%w[drafted rejected])
|
||||
|
||||
# This check is actual for profile states [drafted submitted]
|
||||
# User cant create submitted or verified profile, when already had one of them
|
||||
user_profiles_states = user.profiles.pluck(:state)
|
||||
errors.add(:state, :exists, message: 'already exists') unless (user_profiles_states & %w[submitted verified]).empty?
|
||||
end
|
||||
|
||||
def profile_update!
|
||||
# we cant update rejected or verified profile
|
||||
errors.add(:state, :exists, message: 'just edit submitted') if %w[rejected verified].include?(state_was)
|
||||
end
|
||||
|
||||
def start_profile_kyc_verification
|
||||
KycService.profile_step(self)
|
||||
end
|
||||
|
||||
def dob_not_in_the_future
|
||||
return if dob.nil?
|
||||
|
||||
self.dob = dob.to_date
|
||||
return errors.add(:dob, :invalid_format, message: 'invalid date format') unless dob.is_a?(Date)
|
||||
return errors.add(:dob, :invalid, message: 'cant be in future') if dob > Date.current
|
||||
end
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
# Schema version: 20210425062048
|
||||
#
|
||||
# Table name: profiles
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# user_id :bigint
|
||||
# author :string(255)
|
||||
# applicant_id :string(255)
|
||||
# first_name_encrypted :string(1024)
|
||||
# last_name_encrypted :string(1024)
|
||||
# dob_encrypted :string(255)
|
||||
# address_encrypted :string(1024)
|
||||
# postcode :string(255)
|
||||
# city :string(255)
|
||||
# country :string(255)
|
||||
# state :integer default("drafted"), unsigned
|
||||
# metadata :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# national_code_encrypted :string(255)
|
||||
# city_id :bigint
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_profiles_on_city_id (city_id)
|
||||
# index_profiles_on_user_id (user_id)
|
||||
#
|
||||
Reference in New Issue
Block a user