From 9fb4a6d7e6b19f7ba8647b69f0cd378d7a663a52 Mon Sep 17 00:00:00 2001 From: Thiago Youssef Date: Thu, 10 Mar 2022 16:03:53 +0200 Subject: [PATCH] Refactor `admin/contact_version` and `admin/domain_version` csv generation logic --- app/controllers/admin/base_controller.rb | 2 +- .../admin/contact_versions_controller.rb | 16 ---- .../admin/domain_versions_controller.rb | 22 +----- app/helpers/application_helper.rb | 24 ------ app/helpers/object_versions_helper.rb | 76 ------------------- app/models/contact.rb | 7 ++ app/models/version/contact_version.rb | 17 +++++ app/models/version/domain_version.rb | 33 ++++++++ app/services/csv_generator.rb | 17 +++++ app/services/object_versions_parser.rb | 28 +++++++ app/views/admin/contact_versions/index.haml | 6 +- app/views/admin/contact_versions/show.haml | 7 +- app/views/admin/contacts/index.haml | 2 +- .../admin/contacts/partials/_general.haml | 2 +- app/views/admin/domain_versions/archive.haml | 4 +- app/views/admin/domain_versions/show.haml | 4 +- app/views/registrar/contacts/index.html.erb | 2 +- .../registrar/contacts/list_pdf.html.erb | 2 +- .../registrar/contacts/partials/_general.haml | 2 +- 19 files changed, 117 insertions(+), 156 deletions(-) delete mode 100644 app/helpers/object_versions_helper.rb create mode 100644 app/services/csv_generator.rb create mode 100644 app/services/object_versions_parser.rb diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 016c0a750..56806ba3e 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -26,7 +26,7 @@ module Admin respond_to do |format| format.html { render page } format.csv do - raw_csv = @q.result.to_csv + raw_csv = CsvGenerator.generate_csv(@q.result) send_data raw_csv, filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", type: "#{Mime[:csv]}; charset=utf-8" diff --git a/app/controllers/admin/contact_versions_controller.rb b/app/controllers/admin/contact_versions_controller.rb index 534a4192c..2a26035c9 100644 --- a/app/controllers/admin/contact_versions_controller.rb +++ b/app/controllers/admin/contact_versions_controller.rb @@ -1,13 +1,9 @@ module Admin class ContactVersionsController < BaseController include ApplicationHelper - include ObjectVersionsHelper load_and_authorize_resource class: Version::ContactVersion - MODEL = Contact - CSV_HEADER = ['Name', 'ID', 'Ident', 'Registrar', 'Action', 'Created at'].freeze - def index params[:q] ||= {} @@ -71,17 +67,5 @@ module Admin params_copy end - - def render_by_format(page, filename) - respond_to do |format| - format.html { render page } - format.csv do - raw_csv = csv_generate(MODEL, CSV_HEADER, @q.result) - send_data raw_csv, - filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", - type: "#{Mime[:csv]}; charset=utf-8" - end - end - end end end diff --git a/app/controllers/admin/domain_versions_controller.rb b/app/controllers/admin/domain_versions_controller.rb index a7741130f..c82347ff9 100644 --- a/app/controllers/admin/domain_versions_controller.rb +++ b/app/controllers/admin/domain_versions_controller.rb @@ -1,12 +1,7 @@ module Admin class DomainVersionsController < BaseController - include ObjectVersionsHelper - load_and_authorize_resource class: Version::DomainVersion - MODEL = Domain - CSV_HEADER = ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'].freeze - def index params[:q] ||= {} @@ -85,23 +80,10 @@ module Admin def fix_date_params params_copy = params[:q].deep_dup - if params_copy['created_at_lteq'].present? - params_copy['created_at_lteq'] = Date.parse(params_copy['created_at_lteq']) + 1.day - end + created_at = params_copy['created_at_lteq'] + params_copy['created_at_lteq'] = Date.parse(created_at) + 1.day if created_at.present? params_copy end - - def render_by_format(page, filename) - respond_to do |format| - format.html { render page } - format.csv do - raw_csv = csv_generate(MODEL, CSV_HEADER, @q.result) - send_data raw_csv, - filename: "#{filename}_#{Time.zone.now.to_formatted_s(:number)}.csv", - type: "#{Mime[:csv]}; charset=utf-8" - end - end - end end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 3de98b88c..6829040c2 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -9,30 +9,6 @@ module ApplicationHelper "background-image: url(#{image_path("#{unstable_env}.png")});" end - def ident_for(contact) - if contact.is_a? Hash - ident_country_code = contact[:ident_country_code] - ident_type = contact[:ident_type] - ident = contact[:ident] - else - ident_country_code = contact.ident_country_code - ident_type = contact.ident_type - ident = contact.ident - end - - case ident_type - when 'birthday' - "#{ident} [#{ident_country_code} #{ident_type}]" - else - if ident.present? - "#{ident} [#{ident_country_code} #{ident_type}]" - else - "[#{ident_country_code} #{ident_type}]" - end - - end - end - def current_commit_link hash = `git rev-parse --short HEAD` current_repo = `git remote get-url origin`.gsub('com:', 'com/') diff --git a/app/helpers/object_versions_helper.rb b/app/helpers/object_versions_helper.rb deleted file mode 100644 index 68185c442..000000000 --- a/app/helpers/object_versions_helper.rb +++ /dev/null @@ -1,76 +0,0 @@ -module ObjectVersionsHelper - CSV_HEADER = ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'].freeze - - def attach_existing_fields(version, new_object) - version.object_changes.to_h.each do |key, value| - method_name = "#{key}=".to_sym - new_object.public_send(method_name, event_value(version, value)) if new_object.respond_to?(method_name) - end - end - - def only_present_fields(version, model) - field_names = model.column_names - version.object.to_h.select { |key, _value| field_names.include?(key) } - end - - def csv_generate(model, header, versions) - CSV.generate do |csv| - csv << header - versions.each do |version| - attributes = only_present_fields(version, model) - history_object = model.new(attributes) - attach_existing_fields(version, history_object) unless version.event == 'destroy' - - csv << create_row(history_object, version) - end - end - end - - private - - def event_value(version, val) - version.event == 'destroy' ? val.first : val.last - end - - def registrant_name(domain, version) - return domain.registrant.name if domain.registrant - - ver = Version::ContactVersion.where(item_id: domain.registrant_id).last - contact = Contact.all_versions_for([domain.registrant_id], version.created_at).first - - if contact.nil? && ver - merged_obj = ver.object_changes.to_h.transform_values(&:last) - result = ver.object.to_h.merge(merged_obj)&.slice(*Contact&.column_names) - contact = Contact.new(result) - end - - contact.try(:name) || 'Deleted' - end - - def create_row(history_object, version) - if history_object.is_a?(Domain) - domain_history_row(history_object, version) - else - contact_history_row(history_object, version) - end - end - - def contact_history_row(history_object, version) - name = history_object.name - code = history_object.code - ident = ident_for(history_object) - registrar = history_object.registrar - event = version.event - created_at = version.created_at.to_formatted_s(:db) - [name, code, ident, registrar, event, created_at] - end - - def domain_history_row(history_object, version) - name = history_object.name - registrant = registrant_name(history_object, version) - registrar = history_object.registrar - event = version.event - created_at = version.created_at.to_formatted_s(:db) - [name, registrant, registrar, event, created_at] - end -end diff --git a/app/models/contact.rb b/app/models/contact.rb index 84d4ba962..f15637f6f 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -569,4 +569,11 @@ class Contact < ApplicationRecord def deletable? !linked? end + + def ident_human_description + description = "[#{ident_country_code} #{ident_type}]" + description.prepend("#{ident} ") if ident.present? + + description + end end diff --git a/app/models/version/contact_version.rb b/app/models/version/contact_version.rb index 95bd4b677..498e6d468 100644 --- a/app/models/version/contact_version.rb +++ b/app/models/version/contact_version.rb @@ -4,4 +4,21 @@ class Version::ContactVersion < PaperTrail::Version self.table_name = :log_contacts self.sequence_name = :log_contacts_id_seq + + def as_csv_row + contact = ObjectVersionsParser.new(self).parse + + [ + contact.name, + contact.code, + contact.ident_human_description, + contact.registrar, + event, + created_at.to_formatted_s(:db) + ] + end + + def self.csv_header + ['Name', 'ID', 'Ident', 'Registrar', 'Action', 'Created at'].freeze + end end diff --git a/app/models/version/domain_version.rb b/app/models/version/domain_version.rb index 2c6848d4b..240adc866 100644 --- a/app/models/version/domain_version.rb +++ b/app/models/version/domain_version.rb @@ -7,6 +7,18 @@ class Version::DomainVersion < PaperTrail::Version scope :deleted, -> { where(event: 'destroy') } + def as_csv_row + domain = ObjectVersionsParser.new(self).parse + + [ + domain.name, + registrant_name(domain), + domain.registrar, + event, + created_at.to_formatted_s(:db) + ] + end + def self.was_contact_linked?(contact_id) sql = <<-SQL SELECT @@ -43,4 +55,25 @@ class Version::DomainVersion < PaperTrail::Version count_by_sql(sql).nonzero? end + + def self.csv_header + ['Name', 'Registrant', 'Registrar', 'Action', 'Created at'].freeze + end + + private + + def registrant_name(domain) + return domain.registrant.name if domain.registrant + + ver = Version::ContactVersion.where(item_id: domain.registrant_id).last + contact = Contact.all_versions_for([domain.registrant_id], created_at).first + + if contact.nil? && ver + merged_obj = ver.object_changes.to_h.transform_values(&:last) + result = ver.object.to_h.merge(merged_obj)&.slice(*Contact&.column_names) + contact = Contact.new(result) + end + + contact.try(:name) || 'Deleted' + end end diff --git a/app/services/csv_generator.rb b/app/services/csv_generator.rb new file mode 100644 index 000000000..43c116b7e --- /dev/null +++ b/app/services/csv_generator.rb @@ -0,0 +1,17 @@ +class CsvGenerator + def self.generate_csv(objects) + class_name = objects.first.class + return objects.to_csv unless custom_csv(class_name) + + CSV.generate do |csv| + csv << class_name.csv_header + objects.each { |object| csv << object.as_csv_row } + end + end + + private + + def self.custom_csv(class_name) + [Version::DomainVersion, Version::ContactVersion].include?(class_name) + end +end diff --git a/app/services/object_versions_parser.rb b/app/services/object_versions_parser.rb new file mode 100644 index 000000000..5871a6bd6 --- /dev/null +++ b/app/services/object_versions_parser.rb @@ -0,0 +1,28 @@ +class ObjectVersionsParser + def initialize(version) + @version = version + end + + def parse + model = @version.item_type.constantize + attributes = only_present_fields(model) + history_object = model.new(attributes) + attach_existing_fields(history_object) unless @version.event == 'destroy' + + history_object + end + + private + + def attach_existing_fields(history_object) + @version.object_changes.to_h.each do |key, value| + method_name = "#{key}=".to_sym + history_object.public_send(method_name, value.last) if history_object.respond_to?(method_name) + end + end + + def only_present_fields(model) + field_names = model.column_names + @version.object.to_h.select { |key, _value| field_names.include?(key) } + end +end diff --git a/app/views/admin/contact_versions/index.haml b/app/views/admin/contact_versions/index.haml index 4d7a9948d..97c267d30 100644 --- a/app/views/admin/contact_versions/index.haml +++ b/app/views/admin/contact_versions/index.haml @@ -64,14 +64,12 @@ %tbody - @versions.each do |version| - if version - - attributes = only_present_fields(version, Contact) - - contact = Contact.new(attributes) - - attach_existing_fields(version, contact) + - contact = ObjectVersionsParser.new(version).parse %tr %td= link_to(contact.name, admin_contact_version_path(version.id)) %td= contact.code - %td= ident_for(contact) + %td= contact.ident_human_description %td - if contact.registrar = link_to(contact.registrar, admin_registrar_path(contact.registrar)) diff --git a/app/views/admin/contact_versions/show.haml b/app/views/admin/contact_versions/show.haml index 901f5ee1a..57c8c3ccc 100644 --- a/app/views/admin/contact_versions/show.haml +++ b/app/views/admin/contact_versions/show.haml @@ -1,6 +1,5 @@ -- attributes = only_present_fields(@version, Contact) -- contact = Contact.new(attributes) -- attach_existing_fields(@version, contact) +- contact = ObjectVersionsParser.new(@version).parse + = render 'shared/title', name: contact.name .row @@ -23,7 +22,7 @@ %dt= t(:ident) %dd{class: changing_css_class(@version,"ident_country_code", "ident_type", "ident")} - = ident_for(contact) + = contact.ident_human_description - if contact.email.present? %dt= t(:email) diff --git a/app/views/admin/contacts/index.haml b/app/views/admin/contacts/index.haml index 0812913a1..b4198b8cc 100644 --- a/app/views/admin/contacts/index.haml +++ b/app/views/admin/contacts/index.haml @@ -100,7 +100,7 @@ %tr %td= link_to(contact, admin_contact_path(contact)) %td= contact.code - %td= ident_for(contact) + %td= contact.ident_human_description %td= contact.email %td= l(contact.created_at, format: :short) %td diff --git a/app/views/admin/contacts/partials/_general.haml b/app/views/admin/contacts/partials/_general.haml index 2396861fb..4b8d4ec32 100644 --- a/app/views/admin/contacts/partials/_general.haml +++ b/app/views/admin/contacts/partials/_general.haml @@ -14,7 +14,7 @@ %br %dt.left_25= t(:ident) - %dd.left_25= ident_for(@contact) + %dd.left_25= @contact.ident_human_description %dt.left_25= t(:email) %dd.left_25= @contact.email diff --git a/app/views/admin/domain_versions/archive.haml b/app/views/admin/domain_versions/archive.haml index ec2034ed1..85105b9f0 100644 --- a/app/views/admin/domain_versions/archive.haml +++ b/app/views/admin/domain_versions/archive.haml @@ -62,9 +62,7 @@ %tbody - @versions.each do |version| - if version - - attributes = only_present_fields(version, Domain) - - domain = Domain.new(attributes) - - attach_existing_fields(version, domain) unless version.event == 'destroy' + - domain = ObjectVersionsParser.new(version).parse %tr %td= link_to(domain.name, admin_domain_version_path(version.id)) diff --git a/app/views/admin/domain_versions/show.haml b/app/views/admin/domain_versions/show.haml index 11f70599f..ab49dffee 100644 --- a/app/views/admin/domain_versions/show.haml +++ b/app/views/admin/domain_versions/show.haml @@ -1,6 +1,4 @@ -- present_fields = only_present_fields(@version, Domain) -- domain = Domain.new(present_fields) -- attach_existing_fields(@version, domain) unless @version.event == 'destroy' +- domain = ObjectVersionsParser.new(@version).parse - if @version - children = HashWithIndifferentAccess.new(@version.children) diff --git a/app/views/registrar/contacts/index.html.erb b/app/views/registrar/contacts/index.html.erb index 4a7e8759a..35683360e 100644 --- a/app/views/registrar/contacts/index.html.erb +++ b/app/views/registrar/contacts/index.html.erb @@ -44,7 +44,7 @@ <%= contact.code %> - <%= ident_for(contact) %> + <%= contact.ident_human_description %> <%= l(contact.created_at, format: :short) %> diff --git a/app/views/registrar/contacts/list_pdf.html.erb b/app/views/registrar/contacts/list_pdf.html.erb index b9bbb1c0e..52e5956dd 100644 --- a/app/views/registrar/contacts/list_pdf.html.erb +++ b/app/views/registrar/contacts/list_pdf.html.erb @@ -20,7 +20,7 @@ <%= contact %> <%= contact.code %> - <%= ident_for(contact) %> + <%= contact.ident_human_description %> <%= l(contact.created_at, format: :short) %> <%= contact.registrar %> diff --git a/app/views/registrar/contacts/partials/_general.haml b/app/views/registrar/contacts/partials/_general.haml index 5fc8ec027..4e2a92621 100644 --- a/app/views/registrar/contacts/partials/_general.haml +++ b/app/views/registrar/contacts/partials/_general.haml @@ -14,7 +14,7 @@ %br %dt= t(:ident) - %dd= ident_for(@contact) + %dd= @contact.ident_human_description %dt= t(:email) %dd= @contact.email