diff --git a/app/controllers/registrar/contacts_controller.rb b/app/controllers/registrar/contacts_controller.rb index f4ce84d8c..878e29cd2 100644 --- a/app/controllers/registrar/contacts_controller.rb +++ b/app/controllers/registrar/contacts_controller.rb @@ -3,18 +3,61 @@ class Registrar::ContactsController < Registrar::DeppController # EPP controller def index authorize! :view, Depp::Contact - limit, offset = pagination_details - res = depp_current_user.repp_request('contacts', { details: true, limit: limit, offset: offset }) - if res.code == '200' - @response = res.parsed_body.with_indifferent_access - @contacts = @response ? @response[:contacts] : [] - - @paginatable_array = Kaminari.paginate_array( - [], total_count: @response[:total_number_of_records] - ).page(params[:page]).per(limit) + params[:q] ||= {} + params[:q].delete_if { |_k, v| v.blank? } + if params[:q].length == 1 && params[:q][:name_matches].present? + @contacts = Contact.find_by(name: params[:q][:name_matches]) end - flash.now[:epp_results] = [{ 'code' => res.code, 'msg' => res.message }] + + if params[:statuses_contains] + contacts = current_user.registrar.contacts.includes(:registrar).where( + "contacts.statuses @> ?::varchar[]", "{#{params[:statuses_contains].join(',')}}" + ) + else + contacts = current_user.registrar.contacts.includes(:registrar) + end + + normalize_search_parameters do + @q = contacts.search(params[:q]) + @contacts = @q.result.page(params[:page]) + end + + @contacts = @contacts.per(params[:results_per_page]) if params[:results_per_page].to_i > 0 + end + + def download_list + authorize! :view, Depp::Contact + + params[:q] ||= {} + params[:q].delete_if { |_k, v| v.blank? } + if params[:q].length == 1 && params[:q][:name_matches].present? + @contacts = Contact.find_by(name: params[:q][:name_matches]) + end + + if params[:statuses_contains] + contacts = current_user.registrar.contacts.includes(:registrar).where( + "contacts.statuses @> ?::varchar[]", "{#{params[:statuses_contains].join(',')}}" + ) + else + contacts = current_user.registrar.contacts.includes(:registrar) + end + + normalize_search_parameters do + @q = contacts.search(params[:q]) + @contacts = @q.result.page(params[:page]) + end + + @contacts = @contacts.per(params[:results_per_page]) if params[:results_per_page].to_i > 0 + + respond_to do |format| + format.csv { render text: @contacts.to_csv } + format.pdf do + pdf = @contacts.pdf(render_to_string('registrar/contacts/download_list', layout: false)) + send_data pdf, filename: 'contacts.pdf' + end + end + end def new @@ -75,4 +118,18 @@ class Registrar::ContactsController < Registrar::DeppController # EPP controller def init_epp_contact Depp::Contact.user = depp_current_user end + + def normalize_search_parameters + ca_cache = params[:q][:valid_to_lteq] + begin + end_time = params[:q][:valid_to_lteq].try(:to_date) + params[:q][:valid_to_lteq] = end_time.try(:end_of_day) + rescue + logger.warn('Invalid date') + end + + yield + + params[:q][:valid_to_lteq] = ca_cache + end end diff --git a/app/models/contact.rb b/app/models/contact.rb index 1d6f069e5..c933c2751 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -203,6 +203,21 @@ class Contact < ActiveRecord::Base ['DeleteProhibited', SERVER_DELETE_PROHIBITED] ] end + + def to_csv + CSV.generate do |csv| + csv << column_names + all.each do |contact| + csv << contact.attributes.values_at(*column_names) + end + end + end + + def pdf(html) + kit = PDFKit.new(html) + kit.to_pdf + end + end def roid diff --git a/app/models/domain.rb b/app/models/domain.rb index 7858b3d36..8bfc0166b 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -241,7 +241,7 @@ class Domain < ActiveRecord::Base DomainMailer.pending_update_expired_notification_for_new_registrant(domain.id).deliver end if domain.pending_delete? || domain.pending_delete_confirmation? - DomainMailer.pending_delete_expired_notification(domain.id, deliver_emails).deliver + DomainMailer.pending_delete_expired_notification(domain.id, true).deliver end domain.clean_pendings! unless Rails.env.test? diff --git a/app/views/registrar/contacts/download_list.haml b/app/views/registrar/contacts/download_list.haml new file mode 100644 index 000000000..b8944d254 --- /dev/null +++ b/app/views/registrar/contacts/download_list.haml @@ -0,0 +1,30 @@ +!!! +%html + %head + %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"} + %title Contacts + %body + .row + .col-md-12 + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-2'} + =t(:name) + %th{class: 'col-xs-2'} + =t(:id) + %th{class: 'col-xs-2'} + =t(:ident) + %th{class: 'col-xs-2'} + =t(:created_at) + %th{class: 'col-xs-2'} + =t(:registrar) + %tbody + - @contacts.each do |contact| + %tr + %td= contact + %td= contact.code + %td= ident_for(contact) + %td= l(contact.created_at, format: :short) + %td= contact.registrar diff --git a/app/views/registrar/contacts/index.haml b/app/views/registrar/contacts/index.haml index 401df706d..ae93a82fd 100644 --- a/app/views/registrar/contacts/index.haml +++ b/app/views/registrar/contacts/index.haml @@ -2,23 +2,130 @@ = link_to(t(:new), new_registrar_contact_path, class: 'btn btn-primary') = render 'shared/title', name: t(:contacts) -- if @response - .table-responsive - %table.table.table-hover.table-condensed - %thead - %tr - %th{class: 'col-xs-3'}= t(:name) - %th{class: 'col-xs-3'}= t(:id) - %th{class: 'col-xs-3'}= t(:ident) - %th{class: 'col-xs-3'}= t(:actions) - %tbody - - @contacts.each do |c| - %tr - %td= link_to(c[:name], registrar_contact_path(id: c[:code])) - %td= c[:code] - %td= ident_for(c) - %td - = link_to(t(:edit), edit_registrar_contact_path(c[:code]), class: 'btn btn-primary btn-xs') - = link_to(t(:delete), delete_registrar_contact_path(c[:code]), class: 'btn btn-default btn-xs') +.row + .col-md-12 + = search_form_for [:registrar, @q], html: { style: 'margin-bottom: 0;', class: 'js-form', autocomplete: 'off' } do |f| + .row + .col-md-3 + .form-group + = f.label :name + = f.search_field :name_matches, value: params[:q][:name_matches], class: 'form-control', placeholder: t(:name) + .col-md-3 + .form-group + = f.label t(:id) + = f.search_field :code_eq, class: 'form-control', placeholder: t(:id) + .col-md-3 + .form-group + = f.label t(:ident) + = f.search_field :ident_matches, class: 'form-control', placeholder: t(:ident) + .col-md-3 + .form-group + = label_tag t(:ident_type) + = select_tag '[q][ident_type_eq]', options_for_select(Contact::IDENT_TYPES, params[:q][:ident_type_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' } + .row + .col-md-3 + .form-group + = f.label t(:email) + = f.search_field :email_matches, class: 'form-control', placeholder: t(:email) + .col-md-3 + .form-group + = label_tag t(:country) + = select_tag '[q][country_code_eq]', SortedCountry.all_options(params[:q][:country_code_eq]), { include_blank: true, placeholder: t(:choose), class: 'form-control selectize' } + .col-md-3 + .form-group + = f.label t(:is_registrant) + %div + = f.check_box :registrant_domains_id_not_null + .col-md-3 + .form-group + = label_tag t(:contact_type) + = select_tag '[q][domain_contacts_type_in]', options_for_select([['admin', 'AdminDomainContact'], ['tech', 'TechDomainContact']], params[:q][:domain_contacts_type_in]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' } + .row + .col-md-3 + .form-group + = f.label t(:registrar) + = f.select :registrar_id_eq, Registrar.all.map { |x| [x, x.id] }, { include_blank: true }, class: 'form-control selectize', placeholder: t(:choose) + .col-md-3 + .form-group + = f.label t(:created_at_from) + = f.search_field :created_at_gteq, value: params[:q][:created_at_gteq], class: 'form-control datepicker', placeholder: t(:created_at_from) + .col-md-3 + .form-group + = f.label t(:created_at_until) + = f.search_field :created_at_lteq, value: params[:q][:created_at_lteq], class: 'form-control datepicker', placeholder: t(:created_at_until) + .col-md-3 + .form-group + = f.label t(:updated_at) + = f.search_field :updated_at_gteq, value: params[:q][:updated_at_gteq], class: 'form-control datepicker', placeholder: t(:updated_at) + .row + .col-md-6 + .form-group + = label_tag t(:status) + = select_tag :statuses_contains, options_for_select(Contact::STATUSES, params[:statuses_contains]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' } + .col-md-3 + .form-group + = label_tag t(:results_per_page) + = text_field_tag :results_per_page, params[:results_per_page], class: 'form-control', placeholder: t(:results_per_page) + .col-md-3{style: 'padding-top: 25px;'} + %button.btn.btn-primary +   + %span.glyphicon.glyphicon-search +   + %button.btn.btn-default.js-reset-form + = t(:clear_fields) + .row + .col-md-3 + .btn-group{:role => "group"} + %button.btn.btn-default.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", :type => "button"} + Download + %span.caret + %ul.dropdown-menu + %li= link_to 'PDF', download_list_registrar_contacts_path(q: params[:q], format: "pdf") + %li= link_to 'CSV', download_list_registrar_contacts_path(q: params[:q], format: "csv") + .col-md-3 + .col-md-3 + .col-md-3 - = paginate @paginatable_array +%hr +.row + .col-md-12 + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-2'} + = sort_link(@q, 'name', t(:name)) + %th{class: 'col-xs-2'} + = sort_link(@q, 'code', t(:id)) + %th{class: 'col-xs-2'} + = sort_link(@q, 'ident', t(:ident)) + %th{class: 'col-xs-2'} + = sort_link(@q, 'email', t(:created_at)) + %th{class: 'col-xs-2'} + = sort_link(@q, 'registrar_name', t(:registrar)) + %th{class: 'col-xs-2'}= t(:actions) + %tbody + - @contacts.each do |contact| + %tr + %td= link_to(contact.name, registrar_contact_path(id: contact.code)) + %td= contact.code + %td= ident_for(contact) + %td= l(contact.created_at, format: :short) + %td + - if contact.registrar + = contact.registrar + %td + = link_to(t(:edit), edit_registrar_contact_path(contact.code), class: 'btn btn-primary btn-xs') + = link_to(t(:delete), delete_registrar_contact_path(contact.code), class: 'btn btn-default btn-xs') + +.row + .col-md-6 + = paginate @contacts + .col-md-6.text-right + .pagination + = t(:result_count, count: @contacts.total_count) + +:coffee + $(".js-reset-form").on "click", (e) -> + e.preventDefault(); + window.location = "#{registrar_contacts_path}" diff --git a/config/routes.rb b/config/routes.rb index c1cc98697..9dd7faf7d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -74,6 +74,7 @@ Rails.application.routes.draw do collection do get 'check' + get 'download_list' end end