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

183 lines
5.9 KiB
Ruby
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)
#