diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 89ccd9ac6..cc49b3b61 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -59,6 +59,7 @@ class Admin::SettingsController < AdminController :transfer_wait_time, :invoice_number_min, :invoice_number_max, + :days_to_keep_business_registry_cache, :days_to_keep_invoices_active, :days_to_keep_overdue_invoices_active, :days_to_renew_domain_before_expire, diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5d051377d..ac26e61a3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -32,7 +32,7 @@ class ApplicationController < ActionController::Base if registrar_request? registrar_root_url elsif registrant_request? - registrant_root_url + registrant_login_url elsif admin_request? admin_root_url end diff --git a/app/controllers/registrant/contacts_controller.rb b/app/controllers/registrant/contacts_controller.rb new file mode 100644 index 000000000..d3a0ddff8 --- /dev/null +++ b/app/controllers/registrant/contacts_controller.rb @@ -0,0 +1,8 @@ +class Registrant::ContactsController < RegistrantController + + def show + @contact = Contact.find(params[:id]) + authorize! :read, @contact + @contact.valid? + end +end \ No newline at end of file diff --git a/app/controllers/registrant/domains_controller.rb b/app/controllers/registrant/domains_controller.rb index 4bba945a8..bf7ce37bb 100644 --- a/app/controllers/registrant/domains_controller.rb +++ b/app/controllers/registrant/domains_controller.rb @@ -1,5 +1,64 @@ class Registrant::DomainsController < RegistrantController + def index - authorize! :view, :registrant_domains + authorize! :view, :registrant_domains + params[:q] ||= {} + normalize_search_parameters do + @q = domains.search(params[:q]) + @domains = @q.result.page(params[:page]) end -end + @domains = @domains.per(params[:results_per_page]) if params[:results_per_page].to_i > 0 + end + + def show + @domain = Domain.find(params[:id]) + if !(domains.include?(@domain) || @domain.valid?) + redirect_to registrant_domains_path + end + authorize! :read, @domain + end + + def set_domain + @domain = Domain.find(params[:id]) + end + + def download_list + authorize! :view, :registrant_domains + params[:q] ||= {} + normalize_search_parameters do + @q = domains.search(params[:q]) + @domains = @q + end + + respond_to do |format| + format.csv { render text: @domains.result.to_csv } + format.pdf do + pdf = @domains.result.pdf(render_to_string('registrant/domains/download_list', layout: false)) + send_data pdf, filename: 'domains.pdf' + end + end + end + + def domains + ident_cc, ident = @current_user.registrant_ident.split '-' + begin + BusinessRegistryCache.fetch_associated_domains ident, ident_cc + rescue Soap::Arireg::NotAvailableError => error + flash[:notice] = I18n.t(error.json[:message]) + Rails.logger.fatal("[EXCEPTION] #{error.to_s}") + current_user.domains + end + 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 \ No newline at end of file diff --git a/app/controllers/registrant/registrants_controller.rb b/app/controllers/registrant/registrants_controller.rb new file mode 100644 index 000000000..adc1e0b82 --- /dev/null +++ b/app/controllers/registrant/registrants_controller.rb @@ -0,0 +1,8 @@ +class Registrant::RegistrantsController < RegistrantController + + def show + @contact = Registrant.find(params[:id]) + authorize! :read, @contact + @contact.valid? + end +end diff --git a/app/controllers/registrant/registrars_controller.rb b/app/controllers/registrant/registrars_controller.rb new file mode 100644 index 000000000..d0630b73a --- /dev/null +++ b/app/controllers/registrant/registrars_controller.rb @@ -0,0 +1,7 @@ +class Registrant::RegistrarsController < RegistrantController + + def show + @registrar = Registrar.find(params[:id]) + authorize! :read, @registrar + end +end diff --git a/app/controllers/registrant/sessions_controller.rb b/app/controllers/registrant/sessions_controller.rb index f0a292137..91589d510 100644 --- a/app/controllers/registrant/sessions_controller.rb +++ b/app/controllers/registrant/sessions_controller.rb @@ -6,15 +6,10 @@ class Registrant::SessionsController < Devise::SessionsController # rubocop: disable Metrics/AbcSize def id - if Rails.env.development? - sign_in(RegistrantUser.find_or_create_by_idc_data('test'), event: :authentication) - return redirect_to registrant_root_url - end + id_code, id_issuer = request.env['SSL_CLIENT_S_DN'], request.env['SSL_CLIENT_I_DN_O'] + id_code, id_issuer = 'test', RegistrantUser::ACCEPTED_ISSUER if Rails.env.development? - logger.error request.env['SSL_CLIENT_S_DN'] - logger.error request.env['SSL_CLIENT_S_DN'].encoding - logger.error request.env['SSL_CLIENT_I_DN_O'] - @user = RegistrantUser.find_or_create_by_idc_data(request.env['SSL_CLIENT_S_DN'], request.env['SSL_CLIENT_I_DN_O']) + @user = RegistrantUser.find_or_create_by_idc_data(id_code, id_issuer) if @user sign_in(@user, event: :authentication) redirect_to registrant_root_url diff --git a/app/controllers/registrant/whois_controller.rb b/app/controllers/registrant/whois_controller.rb index 71d29dd76..b44a0bb67 100644 --- a/app/controllers/registrant/whois_controller.rb +++ b/app/controllers/registrant/whois_controller.rb @@ -1,5 +1,9 @@ class Registrant::WhoisController < RegistrantController def index authorize! :view, :registrant_whois + + if params[:domain_name].present? + @domain = WhoisRecord.find_by(name: params[:domain_name]); + end end end diff --git a/app/models/ability.rb b/app/models/ability.rb index cf98cb704..61f1edb2e 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -16,7 +16,7 @@ class Ability @user.roles.each { |role| send(role) } if @user.roles when 'ApiUser' @user.roles.each { |role| send(role) } if @user.roles - when 'RegistrantUser' + when 'RegistrantUser' static_registrant end @@ -117,9 +117,11 @@ class Ability end def static_registrant + customer_service can :manage, :registrant_domains can :manage, :registrant_whois can :manage, Depp::Domain + can :manage, Domain end def user diff --git a/app/models/business_registry_cache.rb b/app/models/business_registry_cache.rb new file mode 100644 index 000000000..5ca1e002c --- /dev/null +++ b/app/models/business_registry_cache.rb @@ -0,0 +1,74 @@ + +=begin +The portal for registrants has to offer an overview of the domains the user is related to directly or through an organisation. +Personal relation is defined by matching the personal identification code associated with a domain and the one acquired on +authentication using electronic ID. Association through a business organisation requires a query to business registry. + + * when user logs in the personal identification code is sent to business registry (using XML service) + * business registry returns the list of business registry codes the user is a board member of + * the list is cached for two days (configurable) + * during that time no new queries are made to business registry for that personal identification code + and the cached organisation code listing is used + * user sees the listing of domains that are associated with him/her directly or through registered organisation + * UI of the portal displays the list of organisation codes and names used to fetch additional domains for the user + (currently by clicking on a username in top right corner of the screen). + Also time and date of the query to the business registry is displayed with the list of organisations. + * if the query to the business registry fails for any reason the list of + domains associated directly with the user is still displayed with an error message indicating a problem + with receiving current list business entities. Outdated list of organisations cannot be used. +=end + +class BusinessRegistryCache < ActiveRecord::Base + + # 1. load domains by business + # 2. load domains by person + def associated_domains + domains = [] + + contact_ids = Contact.where(ident_type: 'org', ident: associated_businesses, ident_country_code: 'EE').pluck(:id) + contact_ids += Contact.where(ident_type: 'priv', ident: ident, ident_country_code: ident_country_code).pluck(:id) + + unless contact_ids.blank? + domains = DomainContact.distinct.where(contact_id: contact_ids).pluck(:domain_id) + end + + Domain.includes(:registrar, :registrant).where(id: domains) + end + + class << self + def fetch_associated_domains(ident_code, ident_cc) + fetch_by_ident_and_cc(ident_code, ident_cc).associated_domains + end + + def fetch_by_ident_and_cc(ident_code, ident_cc) + cache = BusinessRegistryCache.where(ident: ident_code, ident_country_code: ident_cc).first_or_initialize + msg_start = "[Ariregister] #{ident_cc}-#{ident_code}:" + + # fetch new data if cache is expired + if cache.retrieved_on && cache.retrieved_on > (Time.zone.now - Setting.days_to_keep_business_registry_cache.days) + Rails.logger.info("#{msg_start} Info loaded from cache") + return cache + end + + cache.attributes = business_registry.associated_businesses(ident_code, ident_cc) + Rails.logger.info("#{msg_start} Info loaded from server") + + cache.save + cache + end + + def business_registry + Soap::Arireg.new + end + + def purge + STDOUT << "#{Time.zone.now.utc} - Starting Purge of old BusinessRegistry data from cache\n" unless Rails.env.test? + purged = 0 + BusinessRegistryCache.where('retrieved_on < ?', + Time.zone.now < Setting.days_to_keep_business_registry_cache.days).each do |br| + br.destroy and purged += 1 + end + STDOUT << "#{Time.zone.now.utc} - Finished purging #{purged} old BusinessRegistry cache items\n" unless Rails.env.test? + end + end +end diff --git a/app/models/domain.rb b/app/models/domain.rb index 2063a2f8c..4bfa76b40 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -754,5 +754,19 @@ class Domain < ActiveRecord::Base DomainMailer.send(action, DomainMailModel.new(self).send(action)).deliver end + + def self.to_csv + CSV.generate do |csv| + csv << column_names + all.each do |domain| + csv << domain.attributes.values_at(*column_names) + end + end + end + + def self.pdf(html) + kit = PDFKit.new(html) + kit.to_pdf + end end # rubocop: enable Metrics/ClassLength diff --git a/app/models/registrant_user.rb b/app/models/registrant_user.rb index 9a69e8acb..413ff1202 100644 --- a/app/models/registrant_user.rb +++ b/app/models/registrant_user.rb @@ -1,4 +1,5 @@ class RegistrantUser < User + ACCEPTED_ISSUER = 'AS Sertifitseerimiskeskus' attr_accessor :idc_data def ability @@ -6,6 +7,19 @@ class RegistrantUser < User end delegate :can?, :cannot?, to: :ability + def ident + registrant_ident.to_s.split("-").last + end + + def domains + ident_cc, ident = registrant_ident.to_s.split '-' + Domain.includes(:registrar, :registrant).where(contacts: { + ident_type: 'priv', + ident: ident, #identity_code, + ident_country_code: ident_cc #country_code + }) + end + def to_s username end @@ -13,11 +27,9 @@ class RegistrantUser < User class << self def find_or_create_by_idc_data(idc_data, issuer_organization) return false if idc_data.blank? - return false if issuer_organization != 'AS Sertifitseerimiskeskus' + return false if issuer_organization != ACCEPTED_ISSUER idc_data.force_encoding('UTF-8') - logger.error(idc_data) - logger.error(idc_data.encoding) identity_code = idc_data.scan(/serialNumber=(\d+)/).flatten.first country = idc_data.scan(/^\/C=(.{2})/).flatten.first first_name = idc_data.scan(%r{/GN=(.+)/serialNumber}).flatten.first diff --git a/app/models/soap/arireg.rb b/app/models/soap/arireg.rb new file mode 100644 index 000000000..422a72dd9 --- /dev/null +++ b/app/models/soap/arireg.rb @@ -0,0 +1,219 @@ +# coding: utf-8 +require 'savon' +=begin + +Estonian Business registry provides information about registered companies via xml (SOAP over HTTPS). + +Note: + The SSL endpoint certificate is self signed. + +Documentation: + http://www.rik.ee/et/e-ariregister/xml-teenus + Specifications are in Eng and Est + User contract required + +Testing: + https://demo-ariregxml.rik.ee:447/testariport/?wsdl + http://demo-ariregxml.rik.ee:81 + https://demo-ariregxml.rik.ee:447 + +Live service: + https://ariregxml.rik.ee/ariport/?wsdl + https://ariregxml.rik.ee/ + +Implements Soap::Arireg # associated_businesses + 8. arireg.paringesindus_v4 + Rights of representation of all persons related to the company (newer) + http://www2.rik.ee/schemas/xtee/arireg/live/paringesindus_v4.xsd + expects personal id code, to fetch list of registered business id codes + returning {ident: person, ident_country_code: ... associated_businesses: [...id_codes...]} + +=end + +# do some SSL set up? +# ssl_version +# ssl_verify_mode +# ssl_cert_key_file +# ssl_cert_key +# ssl_cert_key_password +# ssl_cert_file +# ssl_cert +# ssl_ca_cert_file +# ssl_ca_cert + +module Soap + + class Arireg + + class NotAvailableError < StandardError + attr_accessor :json + def initialize(params) + params[:message] = "#{I18n.t(:business_registry_service_not_available)}" unless params.key? :message + @json = params + + super(params) + end + end + + class << self + attr_accessor :wsdl, :host, :username, :password + end + + def initialize + if self.class.username.nil? + if Rails.application.secrets.key?(:arireg) + arireg = Rails.application.secrets[:arireg].with_indifferent_access + self.class.username = arireg[:username] + self.class.password = arireg[:password] + if self.class.wsdl.nil? # no override of config/environments/* ? + self.class.wsdl = arireg[:wsdl] + self.class.host = arireg[:host] + end + else + self.class.username = ENV['arireg_username'] + self.class.password = ENV['arireg_password'] + end + end + if self.class.wsdl.nil? + self.class.wsdl = ENV['arireg_wsdl'] + self.class.host = ENV['arireg_host'] + end + + # note Savon has error if https w/non-standard port, + # use non-standard force to pre-set endpoint + @client = Savon.client(wsdl: self.class.wsdl, + host: self.class.host, + endpoint: "#{self.class.host}/cgi-bin/consumer_proxy") + @session = nil + end + + # retrieve business id codes for business that a person has a legal role + def associated_businesses(ident, ident_cc = 'EST') + begin + msg = { + 'fyysilise_isiku_kood' => ident, + 'fyysilise_isiku_koodi_riik' => country_code_3(ident_cc) + } + Rails.logger.info "[Ariregister] Request sent with data: #{msg.inspect}" + + response = @client.call :paringesindus_v4, message: body(msg) + content = extract response, :paringesindus_v4_response + Rails.logger.info "[Ariregister] Got response with data: #{content.inspect}" + + if content.present? && content[:ettevotjad].key?(:item) + business_ident = items(content, :ettevotjad).map{|item| item[:ariregistri_kood]} + else + business_ident = [] + end + + { + ident: ident, + ident_country_code: ident_cc, + # ident_type: 'priv', + retrieved_on: Time.now, + associated_businesses: business_ident + } + rescue Savon::SOAPFault => fault + Rails.logger.error "[Ariregister] #{fault} Äriregister arireg #{self.class.username} at #{self.class.host }" + raise NotAvailableError.new(exception: fault) + rescue HTTPI::SSLError => ssl_error + Rails.logger.error "[Ariregister] #{ssl_error} at #{self.class.host}" + raise NotAvailableError.new(exception: ssl_error) + rescue SocketError => sock + Rails.logger.error "[Ariregister] #{sock}" + raise NotAvailableError.new(exception: sock) + end + end + + def debug + @client.globals.log_level :debug + @client.globals.log true + @client.globals.pretty_print_xml true + @debug = true + @client + end + + private + + # add required elements to request + def body(args) + if @session.nil? + args['ariregister_kasutajanimi'] = self.class.username + args['ariregister_parool'] = self.class.password + else + args['ariregister_sessioon'] = @session + end + {keha: args} + end + + # TLA --- three letter acronym required not two letter acronym, transform + def country_code_3(code) + if code.length == 2 + code = CC2X3[code] + raise NotAvailableError.new(message: 'Unrecognized Country') if code.nil? + end + code + end + + def extract(response, element) + # response envelope body has again header/body under element; header is user and password returned + response.hash[:envelope][:body][element][:keha] + end + + def items(content, parent) + items = content[parent][:item] + items.is_a?(Array) ? items : [items] + end + + CC2X3 = {"AF"=>"AFG", "AX"=>"ALA", "AL"=>"ALB", "DZ"=>"DZA", "AS"=>"ASM", + "AD"=>"AND", "AO"=>"AGO", "AI"=>"AIA", "AQ"=>"ATA", "AG"=>"ATG", + "AR"=>"ARG", "AM"=>"ARM", "AW"=>"ABW", "AU"=>"AUS", "AT"=>"AUT", + "AZ"=>"AZE", "BS"=>"BHS", "BH"=>"BHR", "BD"=>"BGD", "BB"=>"BRB", + "BY"=>"BLR", "BE"=>"BEL", "BZ"=>"BLZ", "BJ"=>"BEN", "BM"=>"BMU", + "BT"=>"BTN", "BO"=>"BOL", "BQ"=>"BES", "BA"=>"BIH", "BW"=>"BWA", + "BV"=>"BVT", "BR"=>"BRA", "IO"=>"IOT", "BN"=>"BRN", "BG"=>"BGR", + "BF"=>"BFA", "BI"=>"BDI", "CV"=>"CPV", "KH"=>"KHM", "CM"=>"CMR", + "CA"=>"CAN", "KY"=>"CYM", "CF"=>"CAF", "TD"=>"TCD", "CL"=>"CHL", + "CN"=>"CHN", "CX"=>"CXR", "CC"=>"CCK", "CO"=>"COL", "KM"=>"COM", + "CD"=>"COD", "CG"=>"COG", "CK"=>"COK", "CR"=>"CRI", "CI"=>"CIV", + "HR"=>"HRV", "CU"=>"CUB", "CW"=>"CUW", "CY"=>"CYP", "CZ"=>"CZE", + "DK"=>"DNK", "DJ"=>"DJI", "DM"=>"DMA", "DO"=>"DOM", "EC"=>"ECU", + "EG"=>"EGY", "SV"=>"SLV", "GQ"=>"GNQ", "ER"=>"ERI", "EE"=>"EST", + "ET"=>"ETH", "FK"=>"FLK", "FO"=>"FRO", "FJ"=>"FJI", "FI"=>"FIN", + "FR"=>"FRA", "GF"=>"GUF", "PF"=>"PYF", "TF"=>"ATF", "GA"=>"GAB", + "GM"=>"GMB", "GE"=>"GEO", "DE"=>"DEU", "GH"=>"GHA", "GI"=>"GIB", + "GR"=>"GRC", "GL"=>"GRL", "GD"=>"GRD", "GP"=>"GLP", "GU"=>"GUM", + "GT"=>"GTM", "GG"=>"GGY", "GN"=>"GIN", "GW"=>"GNB", "GY"=>"GUY", + "HT"=>"HTI", "HM"=>"HMD", "VA"=>"VAT", "HN"=>"HND", "HK"=>"HKG", + "HU"=>"HUN", "IS"=>"ISL", "IN"=>"IND", "ID"=>"IDN", "IR"=>"IRN", + "IQ"=>"IRQ", "IE"=>"IRL", "IM"=>"IMN", "IL"=>"ISR", "IT"=>"ITA", + "JM"=>"JAM", "JP"=>"JPN", "JE"=>"JEY", "JO"=>"JOR", "KZ"=>"KAZ", + "KE"=>"KEN", "KI"=>"KIR", "KP"=>"PRK", "KR"=>"KOR", "KW"=>"KWT", + "KG"=>"KGZ", "LA"=>"LAO", "LV"=>"LVA", "LB"=>"LBN", "LS"=>"LSO", + "LR"=>"LBR", "LY"=>"LBY", "LI"=>"LIE", "LT"=>"LTU", "LU"=>"LUX", + "MO"=>"MAC", "MK"=>"MKD", "MG"=>"MDG", "MW"=>"MWI", "MY"=>"MYS", + "MV"=>"MDV", "ML"=>"MLI", "MT"=>"MLT", "MH"=>"MHL", "MQ"=>"MTQ", + "MR"=>"MRT", "MU"=>"MUS", "YT"=>"MYT", "MX"=>"MEX", "FM"=>"FSM", + "MD"=>"MDA", "MC"=>"MCO", "MN"=>"MNG", "ME"=>"MNE", "MS"=>"MSR", + "MA"=>"MAR", "MZ"=>"MOZ", "MM"=>"MMR", "NA"=>"NAM", "NR"=>"NRU", + "NP"=>"NPL", "NL"=>"NLD", "NC"=>"NCL", "NZ"=>"NZL", "NI"=>"NIC", + "NE"=>"NER", "NG"=>"NGA", "NU"=>"NIU", "NF"=>"NFK", "MP"=>"MNP", + "NO"=>"NOR", "OM"=>"OMN", "PK"=>"PAK", "PW"=>"PLW", "PS"=>"PSE", + "PA"=>"PAN", "PG"=>"PNG", "PY"=>"PRY", "PE"=>"PER", "PH"=>"PHL", + "PN"=>"PCN", "PL"=>"POL", "PT"=>"PRT", "PR"=>"PRI", "QA"=>"QAT", + "RE"=>"REU", "RO"=>"ROU", "RU"=>"RUS", "RW"=>"RWA", "BL"=>"BLM", + "SH"=>"SHN", "KN"=>"KNA", "LC"=>"LCA", "MF"=>"MAF", "PM"=>"SPM", + "VC"=>"VCT", "WS"=>"WSM", "SM"=>"SMR", "ST"=>"STP", "SA"=>"SAU", + "SN"=>"SEN", "RS"=>"SRB", "SC"=>"SYC", "SL"=>"SLE", "SG"=>"SGP", + "SX"=>"SXM", "SK"=>"SVK", "SI"=>"SVN", "SB"=>"SLB", "SO"=>"SOM", + "ZA"=>"ZAF", "GS"=>"SGS", "SS"=>"SSD", "ES"=>"ESP", "LK"=>"LKA", + "SD"=>"SDN", "SR"=>"SUR", "SJ"=>"SJM", "SZ"=>"SWZ", "SE"=>"SWE", + "CH"=>"CHE", "SY"=>"SYR", "TW"=>"TWN", "TJ"=>"TJK", "TZ"=>"TZA", + "TH"=>"THA", "TL"=>"TLS", "TG"=>"TGO", "TK"=>"TKL", "TO"=>"TON", + "TT"=>"TTO", "TN"=>"TUN", "TR"=>"TUR", "TM"=>"TKM", "TC"=>"TCA", + "TV"=>"TUV", "UG"=>"UGA", "UA"=>"UKR", "AE"=>"ARE", "GB"=>"GBR", + "UM"=>"UMI", "US"=>"USA", "UY"=>"URY", "UZ"=>"UZB", "VU"=>"VUT", + "VE"=>"VEN", "VN"=>"VNM", "VG"=>"VGB", "VI"=>"VIR", "WF"=>"WLF", + "EH"=>"ESH", "YE"=>"YEM", "ZM"=>"ZMB", "ZW"=>"ZWE"} + end +end diff --git a/app/views/admin/settings/index.haml b/app/views/admin/settings/index.haml index e09e48396..863d197d0 100644 --- a/app/views/admin/settings/index.haml +++ b/app/views/admin/settings/index.haml @@ -51,6 +51,7 @@ = render 'setting_row', var: :transfer_wait_time = render 'setting_row', var: :ds_digest_type = render 'setting_row', var: :client_side_status_editing_enabled + = render 'setting_row', var: :days_to_keep_business_registry_cache = render 'setting_row', var: :api_ip_whitelist_enabled = render 'setting_row', var: :registrar_ip_whitelist_enabled = render 'setting_row', var: :request_confrimation_on_registrant_change_enabled diff --git a/app/views/registrant/contacts/partials/_address.haml b/app/views/registrant/contacts/partials/_address.haml new file mode 100644 index 000000000..9c0f548e3 --- /dev/null +++ b/app/views/registrant/contacts/partials/_address.haml @@ -0,0 +1,23 @@ +.panel.panel-default + .panel-heading + %h3.panel-title= t(:address) + .panel-body + %dl.dl-horizontal + - if @contact.org_name.present? + %dt= t(:org_name) + %dd= @contact.org_name + + %dt= t(:street) + %dd= @contact.street.to_s.gsub("\n", '
').html_safe + + %dt= t(:city) + %dd= @contact.city + + %dt= t(:zip) + %dd= @contact.zip + + %dt= t(:state) + %dd= @contact.state + + %dt= t(:country) + %dd= @contact.country diff --git a/app/views/registrant/contacts/partials/_domains.haml b/app/views/registrant/contacts/partials/_domains.haml new file mode 100644 index 000000000..d0180532d --- /dev/null +++ b/app/views/registrant/contacts/partials/_domains.haml @@ -0,0 +1,30 @@ +- domains = contact.all_domains(page: params[:domain_page], per: 20, params: params) +#contacts.panel.panel-default + .panel-heading + .pull-left + = t(:domains) + .pull-right + = form_tag request.path, method: :get do + = select_tag :domain_filter, options_for_select(%w(Registrant AdminDomainContact TechDomainContact), selected: params[:domain_filter]), + include_blank: true, class: 'form-control2 selectize2' + %button.btn.btn-primary + %span.glyphicon.glyphicon-search + .clearfix + + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-3'}=custom_sort_link t(:domain_name), :name + %th{class: 'col-xs-3'}=custom_sort_link t(:registrar), :registrar_name + %th{class: 'col-xs-3'}=custom_sort_link t(:valid_to), :valid_to + %th{class: 'col-xs-3'}= t(:roles) + %tbody + - domains.each do |x| + %tr + %td= link_to(x.name, [:registrant, x]) + %td= link_to(x.registrar, [:registrant, x.registrar]) + %td= l(x.valid_to, format: :short) + %td= x.roles.join(", ") + += paginate domains, param_name: :domain_page \ No newline at end of file diff --git a/app/views/registrant/contacts/partials/_general.haml b/app/views/registrant/contacts/partials/_general.haml new file mode 100644 index 000000000..36192cb2c --- /dev/null +++ b/app/views/registrant/contacts/partials/_general.haml @@ -0,0 +1,45 @@ +.panel.panel-default + .panel-heading + %h3.panel-title= t(:general) + .panel-body + %dl.dl-horizontal + %dt= t(:id) + %dd= @contact.code + + %dt= t(:password) + %dd + = text_field_tag :auth_info, @contact.auth_info, readonly: true, class: 'partially-hidden' + + %br + + %dt= t(:ident) + %dd= ident_for(@contact) + + %dt= t(:email) + %dd= @contact.email + + %dt= t(:phone) + %dd= @contact.phone + + - if @contact.fax + %dt= t(:fax) + %dd= @contact.fax + + %br + + %dt= t(:created) + %dd + = l(@contact.created_at, format: :short) + by + = creator_link(@contact) + + %dt= t(:updated) + %dd + = l(@contact.updated_at, format: :short) + by + = updator_link(@contact) + + %dt= t(:registrar) + %dd + - if @contact.registrar.present? + = link_to(@contact.registrar, registrant_registrar_path(@contact.registrar)) diff --git a/app/views/registrant/contacts/partials/_search.haml b/app/views/registrant/contacts/partials/_search.haml new file mode 100644 index 000000000..4a723bf6b --- /dev/null +++ b/app/views/registrant/contacts/partials/_search.haml @@ -0,0 +1,6 @@ += search_form_for [:registrant, @q] do |f| + = f.search_field :name_cont + = f.submit do + %span.glyphicon.glyphicon-search + + diff --git a/app/views/registrant/contacts/partials/_statuses.haml b/app/views/registrant/contacts/partials/_statuses.haml new file mode 100644 index 000000000..c39075754 --- /dev/null +++ b/app/views/registrant/contacts/partials/_statuses.haml @@ -0,0 +1,21 @@ +- panel_class = contact.errors.messages[:statuses] ? 'panel-danger' : 'panel-default' +#contact_statuses.panel{class: panel_class} + .panel-heading.clearfix + = t(:statuses) + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-6'}= t(:status) + %th{class: 'col-xs-6'}= t(:notes) + %tbody + - contact.statuses.each do |status| + %tr + %td= status + %td= contact.status_notes[status] + + - if contact.errors.messages[:statuses] + %tfoot + - @domain.errors.messages[:statuses].each do |s| + %tr + %td{colspan: 4}= s diff --git a/app/views/registrant/contacts/show.haml b/app/views/registrant/contacts/show.haml new file mode 100644 index 000000000..57915e9ff --- /dev/null +++ b/app/views/registrant/contacts/show.haml @@ -0,0 +1,12 @@ +- content_for :actions do + = render 'shared/title', name: @contact.name + +.row + .col-md-6= render 'registrant/contacts/partials/general' + .col-md-6= render 'registrant/contacts/partials/address' +.row + .col-md-12= render 'registrant/contacts/partials/statuses', contact: @contact +.row + .col-md-12= render 'registrant/contacts/partials/domains', contact: @contact + + diff --git a/app/views/registrant/domains/download_list.haml b/app/views/registrant/domains/download_list.haml new file mode 100644 index 000000000..40212812c --- /dev/null +++ b/app/views/registrant/domains/download_list.haml @@ -0,0 +1,28 @@ +!!! +%html + %head + %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"} + %title Contacts + %body + .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(:registrant) + %th{class: 'col-xs-2'} + =t(:valid_to) + %th{class: 'col-xs-2'} + =t(:registrar) + %tbody + - @domains.result.each do |x| + %tr + %td= x.name + %td= x.registrant + %td= l(x.valid_to, format: :short) + %td= x.registrar + .row + .col-md-6 diff --git a/app/views/registrant/domains/index.haml b/app/views/registrant/domains/index.haml index 8b71cefca..776b7878d 100644 --- a/app/views/registrant/domains/index.haml +++ b/app/views/registrant/domains/index.haml @@ -1,5 +1,52 @@ = render 'shared/title', name: t(:domains) +.row + .col-md-12 + = search_form_for [:registrant, @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(:registrant_ident) + = f.search_field :registrant_ident_eq, class: 'form-control', placeholder: t(:registrant_ident) + .row + .col-md-3 + .form-group + = f.label t(:valid_to_from) + = f.search_field :valid_to_gteq, value: params[:q][:valid_to_gteq], class: 'form-control datepicker', placeholder: t(:valid_to_from) + .col-md-3 + .form-group + = f.label t(:valid_to_until) + = f.search_field :valid_to_lteq, value: params[:q][:valid_to_lteq], class: 'form-control datepicker', placeholder: t(:valid_to_until) + .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_registrant_domains_path(q: params[:q], format: "pdf") + %li= link_to 'CSV', download_list_registrant_domains_path(q: params[:q], format: "csv") + .col-md-3 + .col-md-3 + .col-md-3 + + + %hr .row .col-md-12 @@ -8,20 +55,33 @@ %thead %tr %th{class: 'col-xs-2'} - = t(:name) + = sort_link(@q, 'name') %th{class: 'col-xs-2'} - = t(:registrant) + = sort_link(@q, 'registrant_name', t(:registrant)) %th{class: 'col-xs-2'} - = t(:valid_to) + = sort_link(@q, 'valid_to', t(:valid_to)) %th{class: 'col-xs-2'} - = t(:registrar) + = sort_link(@q, 'registrar_name', t(:registrar)) %tbody - -# - @domains.each do |x| - -# %tr - -# %td= link_to(x, admin_domain_path(x)) - -# %td - -# - if x.registrant - -# = link_to(x.registrant, [:admin, x.registrant]) + - @domains.each do |x| + %tr + %td= link_to(x, registrant_domain_path(x)) + %td + - if x.registrant + = link_to(x.registrant, [:registrant, x.registrant]) if x.registrant + + %td= l(x.valid_to, format: :short) + %td= link_to(x.registrar, registrant_registrar_path(x.registrar)) if x.registrar + + .row + .col-md-6 + = paginate @domains + .col-md-6.text-right + .pagination + = t(:result_count, count: @domains.total_count) + +:coffee + $(".js-reset-form").on "click", (e) -> + e.preventDefault(); + window.location = "#{registrant_domains_path}" - -# %td= l(x.valid_to, format: :short) - -# %td= link_to(x.registrar, admin_registrar_path(x.registrar)) if x.registrar diff --git a/app/views/registrant/domains/partials/_admin_contacts.haml b/app/views/registrant/domains/partials/_admin_contacts.haml new file mode 100644 index 000000000..5e49d3fbc --- /dev/null +++ b/app/views/registrant/domains/partials/_admin_contacts.haml @@ -0,0 +1,22 @@ +- panel_class = @domain.errors.messages[:admin_contacts] ? 'panel-danger' : 'panel-default' +.panel{class: panel_class} + .panel-heading.clearfix + = t(:admin_contacts) + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-4'}= t(:name) + %th{class: 'col-xs-4'}= t(:id) + %th{class: 'col-xs-4'}= t(:email) + %tbody + - @domain.admin_contacts.each do |ac| + %tr + %td= link_to(ac, registrant_contact_path(ac)) + %td= ac.code + %td= ac.email + - if @domain.errors.messages[:admin_contacts] + %tfoot + - @domain.errors.messages[:admin_contacts].each do |x| + %tr + %td{colspan: 4}= x diff --git a/app/views/registrant/domains/partials/_dnskeys.haml b/app/views/registrant/domains/partials/_dnskeys.haml new file mode 100644 index 000000000..6d5759e65 --- /dev/null +++ b/app/views/registrant/domains/partials/_dnskeys.haml @@ -0,0 +1,25 @@ +- panel_class = @domain.errors.messages[:dnskeys] ? 'panel-danger' : 'panel-default' +#dnskeys.panel{class: panel_class} + .panel-heading.clearfix + = t(:dnskeys) + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-1'}= t(:flag) + %th{class: 'col-xs-1'}= t(:protocol) + %th{class: 'col-xs-1'}= t(:algorithm) + %th{class: 'col-xs-9'}= t(:public_key) + %tbody + - @domain.dnskeys.each do |x| + %tr + %td= x.flags + %td= x.protocol + %td= x.alg + %td= x.public_key + - if @domain.errors.messages[:dnskeys] + %tfoot + - @domain.errors.messages[:dnskeys].each do |x| + %tr + %td{colspan: 4}= x + diff --git a/app/views/registrant/domains/partials/_general.haml b/app/views/registrant/domains/partials/_general.haml new file mode 100644 index 000000000..d80c1ce6a --- /dev/null +++ b/app/views/registrant/domains/partials/_general.haml @@ -0,0 +1,32 @@ +.panel.panel-default + .panel-heading + %h3.panel-title= t(:general) + .panel-body + %dl.dl-horizontal + %dt= t(:name) + %dd= @domain.name + + %dt= t(:registered_at) + %dd= l(@domain.registered_at) + + %dt= t(:registrar) + %dd= link_to(@domain.registrar, registrant_registrar_path(@domain.registrar)) + + %dt= t(:authinfo_pw) + %dd + = text_field_tag :password, @domain.auth_info, readonly: true, class: 'partially-hidden' + + %dt= t(:valid_from) + %dd= l(@domain.valid_from) + + %dt= t(:valid_to) + %dd= l(@domain.valid_to) + + %dt= t(:outzone_at) + %dd= l(@domain.outzone_at) + + %dt= t(:delete_at) + %dd= l(@domain.delete_at) + + %dt= t(:force_delete_at) + %dd= l(@domain.force_delete_at) diff --git a/app/views/registrant/domains/partials/_keyrelays.haml b/app/views/registrant/domains/partials/_keyrelays.haml new file mode 100644 index 000000000..d2d39f6ba --- /dev/null +++ b/app/views/registrant/domains/partials/_keyrelays.haml @@ -0,0 +1,20 @@ +.panel{class: 'panel-default'} + .panel-heading.clearfix + = t(:keyrelays) + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-4'}= t(:uploaded_at) + %th{class: 'col-xs-3'}= t(:expiry) + %th{class: 'col-xs-2'}= t(:requester) + %th{class: 'col-xs-2'}= t(:accepter) + %th{class: 'col-xs-1'}= t(:status) + %tbody + - @domain.keyrelays.includes([:requester, :accepter]).order(pa_date: :desc).each do |x| + %tr + %td= link_to(x.pa_date, [:registrar, x]) + %td= x.expiry + %td= link_to(x.requester, [:registrar, x.requester]) + %td= link_to(x.accepter, [:registrar, x.accepter]) + %td= x.status diff --git a/app/views/registrant/domains/partials/_legal_documents.haml b/app/views/registrant/domains/partials/_legal_documents.haml new file mode 100644 index 000000000..7d740977b --- /dev/null +++ b/app/views/registrant/domains/partials/_legal_documents.haml @@ -0,0 +1,14 @@ +.panel.panel-default + .panel-heading.clearfix + = t(:legal_documents) + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-8'}= t(:created_at) + %th{class: 'col-xs-4'}= t(:type) + %tbody + - legal_documents.each do |x| + %tr + %td= link_to(x.created_at, [:registrar, x]) + %td= x.document_type diff --git a/app/views/registrant/domains/partials/_nameservers.haml b/app/views/registrant/domains/partials/_nameservers.haml new file mode 100644 index 000000000..db3ca759a --- /dev/null +++ b/app/views/registrant/domains/partials/_nameservers.haml @@ -0,0 +1,23 @@ +- panel_class = @domain.errors.messages[:nameservers] ? 'panel-danger' : 'panel-default' +#nameservers.panel{class: panel_class} + .panel-heading.clearfix + = t(:nameservers) + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-4'}= t(:hostname) + %th{class: 'col-xs-4'}= t(:ipv4) + %th{class: 'col-xs-4'}= t(:ipv6) + %tbody + - @domain.nameservers.each do |x| + %tr + %td= x + %td= x.ipv4 + %td= x.ipv6 + - if @domain.errors.messages[:nameservers] + %tfoot + - @domain.errors.messages[:nameservers].each do |x| + %tr + %td{colspan: 3}= x + diff --git a/app/views/registrant/domains/partials/_owner.haml b/app/views/registrant/domains/partials/_owner.haml new file mode 100644 index 000000000..a7c678d56 --- /dev/null +++ b/app/views/registrant/domains/partials/_owner.haml @@ -0,0 +1,19 @@ +.panel.panel-default + .panel-heading + %h3.panel-title= t(:registrant) + .panel-body + %dl.dl-horizontal + %dt= t(:name) + %dd= link_to(@domain.registrant, [:registrar, @domain.registrant]) + + %dt= t(:id) + %dd= @domain.registrant_code + + %dt= t(:identity_code) + %dd= @domain.registrant_ident + + %dt= t(:email) + %dd= @domain.registrant_email + + %dt= t(:phone) + %dd= @domain.registrant_phone diff --git a/app/views/registrant/domains/partials/_statuses.haml b/app/views/registrant/domains/partials/_statuses.haml new file mode 100644 index 000000000..ab8e55e6c --- /dev/null +++ b/app/views/registrant/domains/partials/_statuses.haml @@ -0,0 +1,18 @@ +#domain_statuses.panel.panel-default + .panel-heading.clearfix + = t(:statuses) + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-6'}= t(:status) + %th{class: 'col-xs-6'}= t(:notes) + %tbody + - @domain.statuses.each do |status| + %tr + %td + - if @domain.pending_json.present? && [DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_DELETE].include?(status) + = link_to status, admin_domain_domain_versions_path(@domain.id) + - else + = status + %td= @domain.status_notes[status] diff --git a/app/views/registrant/domains/partials/_tech_contacts.haml b/app/views/registrant/domains/partials/_tech_contacts.haml new file mode 100644 index 000000000..12844a41e --- /dev/null +++ b/app/views/registrant/domains/partials/_tech_contacts.haml @@ -0,0 +1,22 @@ +- panel_class = @domain.errors.messages[:tech_contacts] ? 'panel-danger' : 'panel-default' +#tech_contacts.panel{class: panel_class} + .panel-heading.clearfix + = t(:tech_contacts) + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-4'}= t(:name) + %th{class: 'col-xs-4'}= t(:id) + %th{class: 'col-xs-4'}= t(:email) + %tbody + - @domain.tech_contacts.each do |tc| + %tr + %td= link_to(tc, registrant_contact_path(tc)) + %td= tc.code + %td= tc.email + - if @domain.errors.messages[:tech_contacts] + %tfoot + - @domain.errors.messages[:tech_contacts].each do |x| + %tr + %td{colspan: 4}= x diff --git a/app/views/registrant/domains/show.haml b/app/views/registrant/domains/show.haml new file mode 100644 index 000000000..0c1ceb48e --- /dev/null +++ b/app/views/registrant/domains/show.haml @@ -0,0 +1,17 @@ +- content_for :actions do + = render 'shared/title', name: @domain.name + +.row + .col-md-6= render 'registrant/domains/partials/general' +.row + .col-md-12= render 'registrant/domains/partials/tech_contacts' +.row + .col-md-12= render 'registrant/domains/partials/admin_contacts' +.row + .col-md-12= render 'registrant/domains/partials/statuses' +.row + .col-md-12= render 'registrant/domains/partials/nameservers' +.row + .col-md-12= render 'registrant/domains/partials/dnskeys' +.row + .col-md-12= render 'registrant/domains/partials/keyrelays' diff --git a/app/views/registrant/registrants/index.haml b/app/views/registrant/registrants/index.haml new file mode 100644 index 000000000..11838d1b2 --- /dev/null +++ b/app/views/registrant/registrants/index.haml @@ -0,0 +1,112 @@ += render 'shared/title', name: t(:contacts) + +.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) +%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)) + %tbody + - @contacts.each do |contact| + %tr + %td= link_to(contact, registrar_contact_path(contact)) + %td= contact.code + %td= ident_for(contact) + %td= l(contact.created_at, format: :short) + %td + - if contact.registrar + = link_to(contact.registrar, registrar_registrar_path(contact.registrar)) + +.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/app/views/registrant/registrants/show.haml b/app/views/registrant/registrants/show.haml new file mode 100644 index 000000000..5b2a527ca --- /dev/null +++ b/app/views/registrant/registrants/show.haml @@ -0,0 +1,75 @@ += render 'shared/title', name: @contact.name + +.row + .col-md-6 + .panel.panel-default + .panel-heading + %h3.panel-title= t(:general) + .panel-body + %dl.dl-horizontal + %dt= t(:id) + %dd= @contact.code + + %dt= t(:authinfo_pw) + %dd + = text_field_tag :auth_info, @contact.auth_info, readonly: true, class: 'partially-hidden' + + %br + + %dt= t(:ident) + %dd= ident_for(@contact) + + %dt= t(:email) + %dd= @contact.email + + %dt= t(:phone) + %dd= @contact.phone + + - if @contact.fax + %dt= t(:fax) + %dd= @contact.fax + + %br + + %dt= t(:created) + %dd + = l(@contact.created_at, format: :short) + by + = creator_link(@contact) + + %dt= t(:updated) + %dd + = l(@contact.updated_at, format: :short) + by + = updator_link(@contact) + + %dt= t(:registrar) + %dd + - if @contact.registrar.present? + = link_to(@contact.registrar, registrant_registrar_path(@contact.registrar)) if @contact.registrar + + .col-md-6 + .panel.panel-default + .panel-heading + %h3.panel-title= t(:contact) + .panel-body + %dl.dl-horizontal + %dl.dl-horizontal + - if @contact.org_name.present? + %dt= t(:org_name) + %dd= @contact.org_name + + %dt= t(:street) + %dd= @contact.street.to_s.gsub("\n", '
').html_safe + + %dt= t(:city) + %dd= @contact.city + + %dt= t(:zip) + %dd= @contact.zip + + %dt= t(:state) + %dd= @contact.state + + %dt= t(:country) + %dd= @contact.country \ No newline at end of file diff --git a/app/views/registrant/registrars/index.haml b/app/views/registrant/registrars/index.haml new file mode 100644 index 000000000..0489bcf52 --- /dev/null +++ b/app/views/registrant/registrars/index.haml @@ -0,0 +1,21 @@ +- content_for :actions do + = render 'shared/title', name: t(:registrars) + +.row + .col-md-12 + .table-responsive + %table.table.table-hover.table-bordered.table-condensed + %thead + %tr + %th{class: 'col-xs-6'} + = sort_link(@q, 'name') + %th{class: 'col-xs-6'} + = sort_link(@q, 'reg_no', t(:reg_no)) + %tbody + - @registrars.each do |x| + %tr + %td= link_to(x, [:registrar, x]) + %td= x.reg_no +.row + .col-md-12 + = paginate @registrars diff --git a/app/views/registrant/registrars/show.haml b/app/views/registrant/registrars/show.haml new file mode 100644 index 000000000..ed5c72b29 --- /dev/null +++ b/app/views/registrant/registrars/show.haml @@ -0,0 +1,53 @@ += render 'shared/title', name: @registrar.name + +- if @registrar.errors.any? + - @registrar.errors.each do |attr, err| + = err + %br +- if @registrar.errors.any? + %hr +.row + .col-md-6 + .panel.panel-default + .panel-heading + %h3.panel-title= t(:general) + .panel-body + %dl.dl-horizontal + %dt= t(:name) + %dd= @registrar.name + + %dt= t(:reg_no) + %dd= @registrar.reg_no + + %dt= t(:vat_no) + %dd= @registrar.vat_no + + %dt= t(:reference_no) + %dd= @registrar.reference_no + + %dt= t(:id) + %dd= @registrar.code + + .col-md-6 + .panel.panel-default + .panel-heading + %h3.panel-title= t(:contact) + .panel-body + %dl.dl-horizontal + %dt= t(:country) + %dd= @registrar.country + + %dt= t(:address) + %dd= @registrar.address + + %dt= t(:contact_phone) + %dd= @registrar.phone + + %dt= t(:contact_email) + %dd= @registrar.email + + %dt= t(:billing_address) + %dd= @registrar.billing_address + + %dt= t(:billing_email) + %dd= @registrar.billing_email diff --git a/app/views/registrant/whois/index.haml b/app/views/registrant/whois/index.haml index 3e390eaf3..3d95af638 100644 --- a/app/views/registrant/whois/index.haml +++ b/app/views/registrant/whois/index.haml @@ -17,5 +17,5 @@ %span.glyphicon.glyphicon-search   %hr - - if @results - = @results + - if @domain + %pre= @domain.body \ No newline at end of file diff --git a/config/application-example.yml b/config/application-example.yml index cf6e26357..4db92097f 100644 --- a/config/application-example.yml +++ b/config/application-example.yml @@ -88,6 +88,16 @@ repp_url: 'https://repp.gitlab.eu/repp/v1/' # restful_whois_url: 'https://restful-whois.example.com' +# +# Estonian Business Registry +# +# config/secrets.yml --- arireg: {username, password} +arireg_username: 'kasutaja' +arireg_password: 'parool' +# config/environments/production.rb --- Soap::Arireg.wsdl, Soap::Arireg.host +arireg_wsdl: 'lib/schemas/testariport.wsdl' # https://demo-ariregxml.rik.ee:447/testariport/?wsdl +#arireg_wsdl: 'lib/schemas/ariport.wsdl' # https://ariregxml.rik.ee/ariport/?wsdl +arireg_host: 'https://demo-ariregxml.rik.ee:447' # https://ariregxml.rik.ee/ # # REGISTRAR AND REGISTRANT diff --git a/config/application.rb b/config/application.rb index 7734cc6e9..2121039dc 100644 --- a/config/application.rb +++ b/config/application.rb @@ -7,6 +7,8 @@ require 'action_controller/railtie' require 'action_mailer/railtie' require 'action_view/railtie' require 'sprockets/railtie' +require 'csv' +require 'rails/all' # require "rails/test_unit/railtie" # Require the gems listed in Gemfile, including any gems diff --git a/config/initializers/initial_settings.rb b/config/initializers/initial_settings.rb index 1b25ddeb3..eb333943f 100644 --- a/config/initializers/initial_settings.rb +++ b/config/initializers/initial_settings.rb @@ -28,6 +28,8 @@ if con.present? && con.table_exists?('settings') Setting.save_default(:client_side_status_editing_enabled, false) + Setting.save_default(:days_to_keep_business_registry_cache, 2) + Setting.save_default(:invoice_number_min, 131050) Setting.save_default(:invoice_number_max, 149999) Setting.save_default(:days_to_keep_invoices_active, 30) diff --git a/config/locales/en.yml b/config/locales/en.yml index 08c70737f..db0ca37ce 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -537,7 +537,8 @@ en: switch_to: Switch to admin_menu: Admin domain_transfer_was_approved: 'Domain transfer was approved, associated contacts were: %{contacts} and registrant was %{registrant}' - + business_registry_service_not_available: "Business Registry service Ärireg is not available" + # DEPP activemodel: errors: diff --git a/config/routes.rb b/config/routes.rb index 86bdccaa9..e0a331256 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -103,6 +103,12 @@ Rails.application.routes.draw do namespace :registrant do root 'domains#index' + resources :domains do + collection do + get :download_list + end + end + # resources :invoices do # member do # get 'download_pdf' @@ -141,6 +147,17 @@ Rails.application.routes.draw do end end + resources :registrars do + resources :api_users + resources :white_ips + collection do + get :search + end + end + + resources :registrants + resources :contacts + resources :whois # resources :contacts do # member do diff --git a/db/migrate/20151209122816_create_business_registry_caches.rb b/db/migrate/20151209122816_create_business_registry_caches.rb new file mode 100644 index 000000000..3d7766a60 --- /dev/null +++ b/db/migrate/20151209122816_create_business_registry_caches.rb @@ -0,0 +1,13 @@ +class CreateBusinessRegistryCaches < ActiveRecord::Migration + def change + create_table :business_registry_caches do |t| + t.string :ident + t.string :ident_country_code + t.datetime :retrieved_on + t.string :associated_businesses, array: true + t.timestamps null: false + end + + add_index :business_registry_caches, :ident + end +end diff --git a/lib/schemas/ariport.wsdl b/lib/schemas/ariport.wsdl new file mode 100644 index 000000000..7525c9227 --- /dev/null +++ b/lib/schemas/ariport.wsdl @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Teenuste nimekiri + + + + + + + Adapteri test + + + + + + + Ettevõtjaga seotud dokumentide loetelu päring + + + + + + + Ettevõtja esmakannete päring + + + + + + + Ettevõtja muudatuste loetelu tasuline päring + + + + + + + Ettevotja rekvisiitide päring + + + + + + + Ettevotja rekvisiitide fail + + + + + + + Isikute otsing + + + + + + + Klassifikaatorite päring + + + + + + + Ettevõtja majandusaasta aruande päring + + + + + + + Ettevõtja majandusaasta aruande loetelu päring + + + + + + + Ettevõtja detailandmete päring v5 + + + + + + + E-notar: toimiku dokumendi sisu + + + + + + + Ettevõtja lihtandmete päring v5 + + + + + + + Ettevõtja lihtandmete päring tasuta + + + + + + + Esindusõiguste päring v3 + + + + + + + Esindusõiguste päring v4 + + + + + + + Visuaalse Äriregistri ettevõtete-isikute vaheliste seoste päring + + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + + + + + Äriregister_uus + + + + diff --git a/lib/schemas/testariport.wsdl b/lib/schemas/testariport.wsdl new file mode 100644 index 000000000..25e3818b2 --- /dev/null +++ b/lib/schemas/testariport.wsdl @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Teenuste nimekiri + + + + + + + Adapteri test + + + + + + + Ettevõtjaga seotud dokumentide loetelu päring + + + + + + + Ettevõtja esmakannete päring + + + + + + + Ettevõtja muudatuste loetelu tasuline päring + + + + + + + Ettevotja rekvisiitide päring + + + + + + + Ettevotja rekvisiitide fail + + + + + + + Isikute otsing + + + + + + + Klassifikaatorite päring + + + + + + + Ettevõtja majandusaasta aruande päring + + + + + + + Ettevõtja majandusaasta aruande loetelu päring + + + + + + + Ettevõtja detailandmete päring v5 + + + + + + + E-notar: toimiku dokumendi sisu + + + + + + + Ettevõtja lihtandmete päring v5 + + + + + + + Ettevõtja lihtandmete päring tasuta + + + + + + + Esindusõiguste päring v3 + + + + + + + Esindusõiguste päring v4 + + + + + + + Visuaalse Äriregistri ettevõtete-isikute vaheliste seoste päring + + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + v1 + + + + + + + + + + + + + + Äriregister_uus + + + +