diff --git a/app/models/contact.rb b/app/models/contact.rb index 96365d056..9a4bf7bbd 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -219,6 +219,10 @@ class Contact < ActiveRecord::Base kit.to_pdf end + + def next_id + self.connection.select_value("SELECT nextval('#{self.sequence_name}')") + end end def roid diff --git a/app/models/legacy/contact.rb b/app/models/legacy/contact.rb index 04f8c34a4..fca3a2b23 100644 --- a/app/models/legacy/contact.rb +++ b/app/models/legacy/contact.rb @@ -1,5 +1,12 @@ module Legacy class Contact < Db + IDENT_TYPE_MAP = { + 2 => ::Contact::PRIV, + 3 => ::Contact::PASSPORT, + 4 => ::Contact::ORG, + 6 => ::Contact::BIRTHDAY + } + self.table_name = :contact belongs_to :object_registry, foreign_key: :id belongs_to :object, foreign_key: :id diff --git a/app/models/legacy/contact_history.rb b/app/models/legacy/contact_history.rb new file mode 100644 index 000000000..040ba0dec --- /dev/null +++ b/app/models/legacy/contact_history.rb @@ -0,0 +1,66 @@ +module Legacy + class ContactHistory < Db + self.table_name = :contact_history + self.primary_key = :id + + belongs_to :object_registry, foreign_key: :id + belongs_to :object, foreign_key: :id + belongs_to :contact, foreign_key: :id + belongs_to :history, foreign_key: :historyid + has_one :object_history, foreign_key: :historyid, primary_key: :historyid + + def get_current_contact_object(time, change_param) + x = self + if 4 == x.ssntype + name = x.organization.try(:strip).presence || x.name.try(:strip).presence + else + name = x.name.try(:strip).presence || x.organization.try(:strip).presence + end + + { + code: x.object_registry.name.try(:strip), + phone: x.telephone.try(:strip), + email: [x.email.try(:strip), x.notifyemail.try(:strip)].uniq.select(&:present?).join(', '), + fax: x.fax.try(:strip), + created_at: x.object_registry.try(:crdate), + updated_at: x.object_history.read_attribute(:update).nil? ? x.object_registry.try(:crdate) : x.object_history.read_attribute(:update), + ident: x.ssn.try(:strip), + ident_type: ::Legacy::Contact::IDENT_TYPE_MAP[x.ssntype], + auth_info: x.object_history.authinfopw.try(:strip), + name: name, + registrar_id: ::Registrar.find_by(legacy_id: x.object_history.try(:clid)).try(:id), + creator_str: x.object_registry.try(:registrar).try(:name), + updator_str: x.object_history.try(:registrar).try(:name) ? x.object_history.try(:registrar).try(:name) : x.object_registry.try(:registrar).try(:name), + legacy_id: x.id, + street: [x.street1.try(:strip), x.street2.try(:strip), x.street3.try(:strip)].compact.join(", "), + city: x.city.try(:strip), + zip: x.postalcode.try(:strip), + state: x.stateorprovince.try(:strip), + country_code: x.country.try(:strip), + statuses: ::Legacy::ObjectState.states_for_contact_at(x.id, time) + } + end + + class << self + def changes_dates_for domain_id + sql = %Q{SELECT dh.*, valid_from + FROM contact_history dh JOIN history h ON dh.historyid=h.id where dh.id=#{domain_id};} + # find_by_sql(sql).map{|e| e.attributes.values_at("valid_from") }.flatten.each_with_object({}){|e,h|h[e.try(:to_f)] = [self]} + + hash = {} + find_by_sql(sql).each do |rec| + hash[rec.valid_from.try(:to_time)] = [{id: rec.historyid, klass: self, param: :valid_from}] if rec.valid_from + end + hash + end + + def get_record_at domain_id, rec_id + sql = %Q{SELECT dh.*, h.valid_from, h.valid_to + from contact_history dh JOIN history h ON dh.historyid=h.id + where dh.id=#{domain_id} and dh.historyid = #{rec_id} ;} + find_by_sql(sql).first + end + + end + end +end diff --git a/app/models/legacy/object_state.rb b/app/models/legacy/object_state.rb index f6f89da0b..d39ca3d06 100644 --- a/app/models/legacy/object_state.rb +++ b/app/models/legacy/object_state.rb @@ -88,6 +88,14 @@ module Legacy hash end + def get_current_contact_object(time, param) + d_his = Legacy::ContactHistory.get_record_at(object_id, historyid) + hash = d_his.get_current_contact_object(time, param) + hash[:statuses] = Legacy::ObjectState.states_for_contact_at(object_id, time + 1) + + hash + end + class << self def changes_dates_for domain_id sql = %Q{SELECT distinct t_2.id, state.id state_dot_id, state.*, @@ -127,7 +135,22 @@ module Legacy } arr = find_by_sql(sql).uniq arr.map!(&:name) if arr.any? - arr.present? ? arr : [DomainStatus::OK] + arr.present? ? arr : [::DomainStatus::OK] + end + + + def states_for_contact_at(contact_id, time) + sql = %Q{SELECT state.* + FROM object_history t_2 + JOIN object_state state ON (t_2.historyid >= state.ohid_from + AND (t_2.historyid <= state.ohid_to OR state.ohid_to IS NULL)) + AND t_2.id = state.object_id + WHERE state.object_id=#{contact_id} + AND (valid_from is null or valid_from <= '#{time.to_s}'::TIMESTAMPTZ) + AND (valid_to is null or valid_to >= '#{time}'::TIMESTAMPTZ) + } + + (find_by_sql(sql).uniq.to_a.map(&:name) + [::Contact::OK]).compact.uniq end end end diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake index 94b6b8288..1926237a7 100644 --- a/lib/tasks/import.rake +++ b/lib/tasks/import.rake @@ -754,70 +754,6 @@ namespace :import do puts "-----> Imported zones in #{(Time.zone.now.to_f - start).round(2)} seconds" end - desc 'Import history' - task history_domains: :environment do - Legacy::DomainHistory.uniq.where(id: 294516).pluck(:id).each do |legacy_domain_id| - next if Domain.find_by(legacy_id: legacy_domain_id).versions.where(event: :create).any? - # add here to skip domains whith create history - - # 1. add domain changes - # 2. add states - # compose hash of change time -> Object changes - last_changes = nil - domain = Domain.find_by(legacy_id: legacy_domain_id) - history = Legacy::ObjectState.changes_dates_for(legacy_domain_id) - dom_his = Legacy::DomainHistory.changes_dates_for(legacy_domain_id) - last_domain_action = dom_his.sort.last[1].last # need to identify if we delete - - # merging changes together - dom_his.each do |time, klasses| - if history.has_key?(time) - history[time] = history[time] | klasses - else - history[time] = klasses - end - end - - keys = history.keys.compact.sort - i = 0 - keys.each_with_index do |time| - history[time].each do |orig_history_klass| - changes = {} - responder = orig_history_klass[:klass].get_record_at(legacy_domain_id, orig_history_klass[:id]) - new_attrs = responder.get_current_domain_object(time, orig_history_klass[:param]) - - event = :update - event = :create if i == 0 - if orig_history_klass == last_domain_action && responder.valid_to.present? - event = :destroy - new_attrs = {} - end - - new_attrs.each do |k, v| - if (old_val = last_changes.to_h[k]) != v then changes[k] = [old_val, v] end - end - next if changes.blank? - obj_his = Legacy::ObjectHistory.find_by(historyid: responder.historyid) - user = Registrar.find_by(legacy_id: obj_his.upid || obj_his.clid).try(:api_users).try(:first) - - DomainVersion.create!( - item_type: domain.class, - item_id: domain.id, - event: event, - whodunnit: user.try(:id), - object: last_changes, - object_changes: changes, - created_at: time, - children: {} - ) - - last_changes = new_attrs - i += 1 - end - end - end - - end end def parse_zone_ns_data(domain, zone) diff --git a/lib/tasks/import_history.rake b/lib/tasks/import_history.rake new file mode 100644 index 000000000..862f50001 --- /dev/null +++ b/lib/tasks/import_history.rake @@ -0,0 +1,141 @@ +namespace :import do + desc 'Import contact history' + task history_contacts: :environment do + Legacy::ContactHistory.uniq.pluck(:id).each do |legacy_contact_id| + Contact.transaction do + contact = Contact.find_by(legacy_id: legacy_contact_id) + version_contact = ContactVersion.where("object->>'legacy_id' = '#{legacy_contact_id}'").first + contact ||= Contact.new(id: version_contact.object["id"], legacy_id: legacy_contact_id) if version_contact + contact ||= Contact.new(id: ::Contact.next_id, legacy_id: legacy_contact_id) + next if contact.versions.where(event: :create).any? + # add here to skip domains whith create history + + # 1. add domain changes + # 2. add states + # compose hash of change time -> Object changes + last_changes = nil + history = Legacy::ObjectState.changes_dates_for(legacy_contact_id) + con_his = Legacy::ContactHistory.changes_dates_for(legacy_contact_id) + last_contact_action = con_his.sort.last[1].last # need to identify if we delete + + # merging changes together + con_his.each do |time, klasses| + if history.has_key?(time) + history[time] = history[time] | klasses + else + history[time] = klasses + end + end + + keys = history.keys.compact.sort + i = 0 + keys.each_with_index do |time| + history[time].each do |orig_history_klass| + changes = {} + responder = orig_history_klass[:klass].get_record_at(legacy_contact_id, orig_history_klass[:id]) + new_attrs = responder.get_current_contact_object(time, orig_history_klass[:param]) + + event = :update + event = :create if i == 0 + if orig_history_klass == last_contact_action && responder.valid_to.present? + event = :destroy + new_attrs = {} + end + + new_attrs.each do |k, v| + if (old_val = last_changes.to_h[k]) != v then changes[k] = [old_val, v] end + end + next if changes.blank? && event != :destroy + obj_his = Legacy::ObjectHistory.find_by(historyid: responder.historyid) + user = Registrar.find_by(legacy_id: obj_his.upid || obj_his.clid).try(:api_users).try(:first) + + ContactVersion.create!( + item_type: contact.class, + item_id: contact.id, + event: event, + whodunnit: user.try(:id), + object: last_changes, + object_changes: changes, + created_at: time, + children: {} + ) + + last_changes = new_attrs + i += 1 + end + end + end + end + end + + + desc 'Import domain history' + task history_domains: :environment do + Domain.transaction do + Legacy::DomainHistory.uniq.where(id: 294516).pluck(:id).each do |legacy_domain_id| + next if Domain.find_by(legacy_id: legacy_domain_id).versions.where(event: :create).any? + # add here to skip domains whith create history + + # 1. add domain changes + # 2. add states + # compose hash of change time -> Object changes + last_changes = nil + domain = Domain.find_by(legacy_id: legacy_domain_id) + history = Legacy::ObjectState.changes_dates_for(legacy_domain_id) + dom_his = Legacy::DomainHistory.changes_dates_for(legacy_domain_id) + last_domain_action = dom_his.sort.last[1].last # need to identify if we delete + + # merging changes together + dom_his.each do |time, klasses| + if history.has_key?(time) + history[time] = history[time] | klasses + else + history[time] = klasses + end + end + + keys = history.keys.compact.sort + i = 0 + keys.each_with_index do |time| + history[time].each do |orig_history_klass| + changes = {} + responder = orig_history_klass[:klass].get_record_at(legacy_domain_id, orig_history_klass[:id]) + new_attrs = responder.get_current_domain_object(time, orig_history_klass[:param]) + + event = :update + event = :create if i == 0 + if orig_history_klass == last_domain_action && responder.valid_to.present? + event = :destroy + new_attrs = {} + end + + new_attrs.each do |k, v| + if (old_val = last_changes.to_h[k]) != v then changes[k] = [old_val, v] end + end + next if changes.blank? && event != :destroy + obj_his = Legacy::ObjectHistory.find_by(historyid: responder.historyid) + user = Registrar.find_by(legacy_id: obj_his.upid || obj_his.clid).try(:api_users).try(:first) + + DomainVersion.create!( + item_type: domain.class, + item_id: domain.id, + event: event, + whodunnit: user.try(:id), + object: last_changes, + object_changes: changes, + created_at: time, + children: {} + ) + + last_changes = new_attrs + i += 1 + end + end + end + end + + end + + + +end \ No newline at end of file