internetee-registry/app/models/contact.rb
2014-09-19 12:16:44 +03:00

166 lines
4 KiB
Ruby

class Contact < ActiveRecord::Base
# TODO: Foreign contact will get email with activation link/username/temp password
# TODO: Phone number validation, in first phase very minimam in order to support current registries
include EppErrors
has_one :local_address
has_one :international_address
has_one :disclosure, class_name: 'ContactDisclosure'
has_many :domain_contacts
has_many :domains, through: :domain_contacts
belongs_to :created_by, class_name: 'EppUser', foreign_key: :created_by_id
belongs_to :updated_by, class_name: 'EppUser', foreign_key: :updated_by_id
accepts_nested_attributes_for :local_address, :international_address, :disclosure
validates :code, :phone, :email, :ident, presence: true
validate :ident_must_be_valid
validates :phone, format: /\+[0-9]{1,3}\.[0-9]{1,14}?/ # /\+\d{3}\.\d+/
validates :email, format: /@/
validates :code, uniqueness: { message: :epp_id_taken }
delegate :name, to: :international_address
delegate :country, to: :address, prefix: true
delegate :city, to: :address, prefix: true
delegate :street, to: :address, prefix: true
delegate :zip, to: :address, prefix: true
delegate :org_name, to: :address, prefix: true
IDENT_TYPE_ICO = 'ico'
IDENT_TYPES = [
IDENT_TYPE_ICO, # Company registry code (or similar)
'op', # Estonian ID
'passport', # Passport number
'birthday' # Birthday date
]
CONTACT_TYPE_TECH = 'tech'
CONTACT_TYPE_ADMIN = 'admin'
CONTACT_TYPES = [CONTACT_TYPE_TECH, CONTACT_TYPE_ADMIN]
# TEMP METHOD for transaction to STI
def address
international_address
end
##
def ident_must_be_valid
# TODO: Ident can also be passport number or company registry code.
# so have to make changes to validations (and doc/schema) accordingly
return true unless ident.present? && ident_type.present? && ident_type == 'op'
code = Isikukood.new(ident)
errors.add(:ident, 'bad format') unless code.valid?
end
def juridical?
ident_type == IDENT_TYPE_ICO
end
def citizen?
ident_type != IDENT_TYPE_ICO
end
def cr_id
created_by ? created_by.username : nil
end
def up_id
updated_by ? updated_by.username : nil
end
def auth_info_matches(pw)
auth_info == pw
end
# generate random id for contact
#
def generate_code
self.code = SecureRandom.hex(4)
end
# Find a way to use self.domains with contact
def domains_owned
Domain.where(owner_contact_id: id)
end
def relations_with_domain?
return true if domain_contacts.present? || domains_owned.present?
false
end
# should use only in transaction
def destroy_and_clean
clean_up_address
if relations_with_domain?
errors.add(:domains, :exist)
return false
end
destroy
end
def epp_code_map # rubocop:disable Metrics/MethodLength
{
'2302' => [ # Object exists
[:code, :epp_id_taken]
],
'2305' => [ # Association exists
[:domains, :exist]
],
'2005' => [ # Value syntax error
[:phone, :invalid],
[:email, :invalid]
]
}
end
def to_s
name
end
class << self
def extract_attributes(ph, type = :create)
contact_hash = {
phone: ph[:voice],
ident: ph[:ident],
email: ph[:email]
}
contact_hash[:code] = ph[:id] if type == :create
contact_hash[:auth_info] = ph[:authInfo][:pw] if type == :create
contact_hash.delete_if { |_k, v| v.nil? }
end
def check_availability(codes)
codes = [codes] if codes.is_a?(String)
res = []
codes.each do |x|
if Contact.find_by(code: x)
res << { code: x, avail: 0, reason: 'in use' }
else
res << { code: x, avail: 1 }
end
end
res
end
def search_by_query(query)
res = search(code_cont: query).result
res.reduce([]) { |o, v| o << { id: v[:id], display_key: "#{v.name} (#{v.code})" } }
end
end
private
def clean_up_address
address.destroy if address
end
end