module EgovUtils class Person < ApplicationRecord # This is kept for accepts_nested_attributes_for compatibility, but # overloaded below. has_one :residence, class_name: 'EgovUtils::Address' has_many :addresses has_one :natural_person, dependent: :destroy has_one :legal_person, dependent: :destroy enum person_type: { natural: 1, legal: 16 } validates :person_entity, presence: true before_validation :keep_correct_person_type before_validation :set_person_from_remote_id accepts_nested_attributes_for :residence, :natural_person, :legal_person delegate :fullname, :fullname=, to: :person_entity def initialize(attributes = {}) if attributes&.fetch(:remote_id, nil).present? super(attributes.slice(:remote_id, :person_type)) else super end end def person_entity case person_type when 'natural' natural_person when 'legal' legal_person end end def person_entity=(entity) case person_type when 'natural' self.natural_person = entity self.legal_person = nil when 'legal' self.legal_person = entity self.natural_person = nil end end def residence addresses.last end def residence=(address) addresses << address end def to_s person_entity.to_s end private def set_person_from_remote_id return unless remote_id.present? attributes = if person_type == 'natural' Iszr::NaturalPeople::SearchByRemoteId.run!(remote_id:) else Iszr::LegalPeople::SearchByRemoteId.run!(remote_id:) end.to_h self.person_entity = if person_type == 'natural' NaturalPerson.find_or_initialize_by(attributes.except(:remote_id)) else LegalPerson.find_or_initialize_by(attributes.except(:remote_id)) end self.residence = EgovUtils::Iszr::Addresses::Fetch.run!(remote_id:, person_type:) end def keep_correct_person_type case person_type when 'natural' self.legal_person = nil when 'legal' self.natural_person = nil end end end end