diff --git a/Gemfile b/Gemfile
index 10c680786..d29fa223b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -12,6 +12,7 @@ gem 'rails', '4.2.4' # when update, all initializers eis_custom files nee
gem 'iso8601', '0.8.6' # for dates and times
gem 'hashie-forbidden_attributes', '0.1.1'
gem 'SyslogLogger', '2.0', require: 'syslog/logger'
+gem 'rest-client'
# load env
gem 'figaro', '1.1.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index b92d6dc1b..45eb09943 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -188,6 +188,8 @@ GEM
nokogiri (>= 1.4.0)
savon (>= 2.4.0)
docile (1.1.5)
+ domain_name (0.5.25)
+ unf (>= 0.0.5, < 1.0.0)
epp-xml (1.0.4)
activesupport (~> 4.1)
builder (~> 3.2)
@@ -261,6 +263,8 @@ GEM
nokogiri (~> 1.6.0)
ruby_parser (~> 3.5)
html5_validators (1.2.2)
+ http-cookie (1.0.2)
+ domain_name (~> 0.5)
httpclient (2.6.0.1)
httpi (2.4.1)
rack
@@ -320,6 +324,7 @@ GEM
multi_json (1.11.2)
multi_xml (0.5.5)
nenv (0.2.0)
+ netrc (0.11.0)
newrelic_rpm (3.12.0.288)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
@@ -412,6 +417,10 @@ GEM
request_store (1.1.0)
responders (2.1.0)
railties (>= 4.2.0, < 5)
+ rest-client (1.8.0)
+ http-cookie (>= 1.0.2, < 2.0)
+ mime-types (>= 1.16, < 3.0)
+ netrc (~> 0.7)
rspec (3.3.0)
rspec-core (~> 3.3.0)
rspec-expectations (~> 3.3.0)
@@ -515,6 +524,9 @@ GEM
uglifier (2.7.1)
execjs (>= 0.3.0)
json (>= 1.8.0)
+ unf (0.1.4)
+ unf_ext
+ unf_ext (0.0.7.1)
unicorn (4.9.0)
kgio (~> 2.6)
rack
@@ -617,6 +629,7 @@ DEPENDENCIES
rails-settings-cached (= 0.4.1)
rake
ransack (= 1.5.1)
+ rest-client
rspec-rails (= 3.3.2)
rubocop (= 0.32.1)
rubycritic (= 1.4.0)
diff --git a/app/controllers/admin/account_activities_controller.rb b/app/controllers/admin/account_activities_controller.rb
index 1c447d8a6..0f095734f 100644
--- a/app/controllers/admin/account_activities_controller.rb
+++ b/app/controllers/admin/account_activities_controller.rb
@@ -12,11 +12,27 @@ class Admin::AccountActivitiesController < AdminController
logger.warn('Invalid date')
end
+ balance_params = params[:q].deep_dup
+
+ if balance_params[:created_at_gteq]
+ balance_params.delete('created_at_gteq')
+ end
+
@q = AccountActivity.includes(:invoice, account: :registrar).search(params[:q])
+ @b = AccountActivity.search(balance_params)
@q.sorts = 'id desc' if @q.sorts.empty?
+ @account_activities = @q.result.page(params[:page]).per(params[:results_per_page])
+ sort = @account_activities.orders.map(&:to_sql).join(",")
+
+ if params[:page] && params[:page].to_i > 1
+ @sum = @q.result.reorder(sort).limit(@account_activities.offset_value) + @b.result.where.not(id: @q.result.map(&:id))
+ else
+ @sum = @b.result.where.not(id: @q.result.map(&:id))
+ end
+
respond_to do |format|
- format.html { @account_activities = @q.result.page(params[:page]) }
+ format.html
format.csv do
send_data @q.result.to_csv, filename: "account_activities_#{Time.zone.now.to_formatted_s(:number)}.csv"
end
diff --git a/app/controllers/admin/blocked_domains_controller.rb b/app/controllers/admin/blocked_domains_controller.rb
index 2df3f90d9..49cc65675 100644
--- a/app/controllers/admin/blocked_domains_controller.rb
+++ b/app/controllers/admin/blocked_domains_controller.rb
@@ -2,22 +2,54 @@ class Admin::BlockedDomainsController < AdminController
load_and_authorize_resource
def index
- bd = BlockedDomain.first_or_initialize
- @blocked_domains = bd.names.join("\n")
+
+ params[:q] ||= {}
+ domains = BlockedDomain.all.order(:name)
+ @q = domains.search(params[:q])
+ @domains = @q.result.page(params[:page])
+ @domains = @domains.per(params[:results_per_page]) if params[:results_per_page].to_i > 0
+
+ end
+
+ def new
+
+ @domain = BlockedDomain.new
+
end
def create
- names = params[:blocked_domains].split("\r\n").map(&:strip)
- bd = BlockedDomain.first_or_create
+ @domain = BlockedDomain.new(blocked_domain_params)
- if bd.update(names: names)
- flash[:notice] = I18n.t('record_updated')
- redirect_to :back
+ if @domain.save
+ flash[:notice] = I18n.t('domain_added')
+ redirect_to admin_blocked_domains_path
else
- @blocked_domains = params[:blocked_domains]
- flash.now[:alert] = I18n.t('failed_to_update_record')
- render :index
+ flash.now[:alert] = I18n.t('failed_to_add_domain')
+ render 'new'
+ end
+
+ end
+
+ def delete
+
+ if BlockedDomain.find(params[:id]).destroy
+ flash[:notice] = I18n.t('domain_deleted')
+ redirect_to admin_blocked_domains_path
+ else
+ flash.now[:alert] = I18n.t('failed_to_delete_domain')
+ redirect_to admin_blocked_domains_path
end
end
-end
+
+
+ def blocked_domain_params
+ params.require(:blocked_domain).permit(:name)
+ end
+
+ private
+
+ def set_domain
+ @domain = BlockedDomain.find(params[:id])
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/admin/contacts_controller.rb b/app/controllers/admin/contacts_controller.rb
index a1df165d2..960d74002 100644
--- a/app/controllers/admin/contacts_controller.rb
+++ b/app/controllers/admin/contacts_controller.rb
@@ -4,8 +4,14 @@ class Admin::ContactsController < AdminController
def index
params[:q] ||= {}
- @q = Contact.includes(:registrar).search(params[:q])
- @contacts = @q.result.page(params[:page])
+ search_params = params[:q].deep_dup
+
+ if search_params[:domain_contacts_type_in].is_a?(Array) && search_params[:domain_contacts_type_in].delete('registrant')
+ search_params[:registrant_domains_id_not_null] = 1
+ end
+
+ @q = Contact.includes(:registrar).search(search_params)
+ @contacts = @q.result(distinct: :true).page(params[:page])
if params[:statuses_contains]
contacts = Contact.includes(:registrar).where(
@@ -16,8 +22,8 @@ class Admin::ContactsController < AdminController
end
normalize_search_parameters do
- @q = contacts.search(params[:q])
- @contacts = @q.result.page(params[:page])
+ @q = contacts.search(search_params)
+ @contacts = @q.result(distinct: :true).page(params[:page])
end
@contacts = @contacts.per(params[:results_per_page]) if params[:results_per_page].to_i > 0
diff --git a/app/controllers/admin/invoices_controller.rb b/app/controllers/admin/invoices_controller.rb
index 5aa6d4438..709dc866a 100644
--- a/app/controllers/admin/invoices_controller.rb
+++ b/app/controllers/admin/invoices_controller.rb
@@ -23,7 +23,7 @@ class Admin::InvoicesController < AdminController
def index
@q = Invoice.includes(:account_activity).search(params[:q])
- @q.sorts = 'id desc' if @q.sorts.empty?
+ @q.sorts = 'number desc' if @q.sorts.empty?
@invoices = @q.result.page(params[:page])
end
diff --git a/app/controllers/admin/registrars_controller.rb b/app/controllers/admin/registrars_controller.rb
index c0d28908f..cf8c89505 100644
--- a/app/controllers/admin/registrars_controller.rb
+++ b/app/controllers/admin/registrars_controller.rb
@@ -6,7 +6,7 @@ class Admin::RegistrarsController < AdminController
end
def index
- @q = Registrar.ordered.search(params[:q])
+ @q = Registrar.joins(:accounts).ordered.search(params[:q])
@registrars = @q.result.page(params[:page])
end
diff --git a/app/controllers/admin/reserved_domains_controller.rb b/app/controllers/admin/reserved_domains_controller.rb
index 57e4b8ed3..7de8d9891 100644
--- a/app/controllers/admin/reserved_domains_controller.rb
+++ b/app/controllers/admin/reserved_domains_controller.rb
@@ -1,51 +1,68 @@
class Admin::ReservedDomainsController < AdminController
load_and_authorize_resource
+ before_action :set_domain, only: [:edit, :update]
def index
- names = ReservedDomain.pluck(:names).each_with_object({}){|e_h,h| h.merge!(e_h)}
- names.names = nil if names.blank?
- @reserved_domains = names.to_yaml.gsub(/---.?\n/, '').gsub(/\.\.\..?\n/, '')
+
+ params[:q] ||= {}
+ domains = ReservedDomain.all.order(:name)
+ @q = domains.search(params[:q])
+ @domains = @q.result.page(params[:page])
+ @domains = @domains.per(params[:results_per_page]) if params[:results_per_page].to_i > 0
+
+ end
+
+ def new
+ @domain = ReservedDomain.new
+ end
+
+ def edit
end
def create
- @reserved_domains = params[:reserved_domains]
- begin
- params[:reserved_domains] = "---\n" if params[:reserved_domains].blank?
- names = YAML.load(params[:reserved_domains])
- fail if names == false
- rescue
- flash.now[:alert] = I18n.t('invalid_yaml')
- logger.warn 'Invalid YAML'
- render :index and return
- end
+ @domain = ReservedDomain.new(reserved_domain_params)
- result = true
- ReservedDomain.transaction do
- # removing old ones
- existing = ReservedDomain.any_of_domains(names.keys).pluck(:id)
- ReservedDomain.where.not(id: existing).delete_all
-
- #updating and adding
- names.each do |name, psw|
- rec = ReservedDomain.by_domain(name).first
- rec ||= ReservedDomain.new
- rec.names = {name => psw}
-
- unless rec.save
- result = false
- raise ActiveRecord::Rollback
- end
- end
- end
-
-
- if result
- flash[:notice] = I18n.t('record_updated')
- redirect_to :back
+ if @domain.save
+ flash[:notice] = I18n.t('domain_added')
+ redirect_to admin_reserved_domains_path
else
- flash.now[:alert] = I18n.t('failed_to_update_record')
- render :index
+ flash.now[:alert] = I18n.t('failed_to_add_domain')
+ render 'new'
end
+
+ end
+
+ def update
+
+ if @domain.update(reserved_domain_params)
+ flash[:notice] = I18n.t('domain_updated')
+ else
+ flash.now[:alert] = I18n.t('failed_to_update_domain')
+ end
+ render 'edit'
+
+ end
+
+ def delete
+
+ if ReservedDomain.find(params[:id]).destroy
+ flash[:notice] = I18n.t('domain_deleted')
+ redirect_to admin_reserved_domains_path
+ else
+ flash.now[:alert] = I18n.t('failed_to_delete_domain')
+ redirect_to admin_reserved_domains_path
+ end
+
+ end
+
+ private
+
+ def reserved_domain_params
+ params.require(:reserved_domain).permit(:name, :password)
+ end
+
+ def set_domain
+ @domain = ReservedDomain.find(params[:id])
end
end
diff --git a/app/controllers/registrar/contacts_controller.rb b/app/controllers/registrar/contacts_controller.rb
index 878e29cd2..0581a3cfc 100644
--- a/app/controllers/registrar/contacts_controller.rb
+++ b/app/controllers/registrar/contacts_controller.rb
@@ -6,8 +6,15 @@ class Registrar::ContactsController < Registrar::DeppController # EPP controller
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])
+
+ search_params = params[:q].deep_dup
+
+ if search_params[:domain_contacts_type_in].is_a?(Array) && search_params[:domain_contacts_type_in].delete('registrant')
+ search_params[:registrant_domains_id_not_null] = 1
+ end
+
+ if search_params.length == 1 && search_params[:name_matches].present?
+ @contacts = Contact.find_by(name: search_params[:name_matches])
end
if params[:statuses_contains]
@@ -19,8 +26,8 @@ class Registrar::ContactsController < Registrar::DeppController # EPP controller
end
normalize_search_parameters do
- @q = contacts.search(params[:q])
- @contacts = @q.result.page(params[:page])
+ @q = contacts.search(search_params)
+ @contacts = @q.result(distinct: :true).page(params[:page])
end
@contacts = @contacts.per(params[:results_per_page]) if params[:results_per_page].to_i > 0
diff --git a/app/jobs/domain_update_confirm_job.rb b/app/jobs/domain_update_confirm_job.rb
index be0ada219..098b9853e 100644
--- a/app/jobs/domain_update_confirm_job.rb
+++ b/app/jobs/domain_update_confirm_job.rb
@@ -3,20 +3,16 @@ class DomainUpdateConfirmJob < Que::Job
# it's recommended to keep transaction against job table as short as possible.
ActiveRecord::Base.transaction do
domain = Epp::Domain.find(domain_id)
+ domain.is_admin = true
case action
when RegistrantVerification::CONFIRMED
domain.poll_message!(:poll_pending_update_confirmed_by_registrant)
- domain.apply_pending_update! do |e|
- e.instance_variable_set("@changed_attributes", e.changed_attributes.merge("statuses"=>[]))
- end
+ domain.apply_pending_update!
domain.clean_pendings!
- WhoisRecord.find_by(domain_id: domain.id).save
when RegistrantVerification::REJECTED
domain.send_mail :pending_update_rejected_notification_for_new_registrant
domain.poll_message!(:poll_pending_update_rejected_by_registrant)
- domain.clean_pendings!
- domain.instance_variable_set("@changed_attributes", domain.changed_attributes.merge("statuses"=>[]))
- domain.save
+ domain.clean_pendings_lowlevel
end
destroy # it's best to destroy the job in the same transaction
end
diff --git a/app/jobs/update_whois_record_job.rb b/app/jobs/update_whois_record_job.rb
new file mode 100644
index 000000000..b7edb1fdd
--- /dev/null
+++ b/app/jobs/update_whois_record_job.rb
@@ -0,0 +1,16 @@
+class UpdateWhoisRecordJob < Que::Job
+
+ def run(ids, type)
+ klass = case type
+ when 'reserved'then ReservedDomain
+ when 'blocked' then BlockedDomain
+ else Domain
+ end
+
+ ids.each do |id|
+ record = klass.find_by(id: id)
+ next unless record
+ record.update_whois_record
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/mailers/domain_mailer.rb b/app/mailers/domain_mailer.rb
index 66533e316..28e232a8c 100644
--- a/app/mailers/domain_mailer.rb
+++ b/app/mailers/domain_mailer.rb
@@ -97,8 +97,9 @@ class DomainMailer < ApplicationMailer
def expiration_reminder(domain_id)
@domain = Domain.find_by(id: domain_id)
- return unless @domain
+ return if @domain.nil? || !@domain.statuses.include?(DomainStatus::EXPIRED) || whitelist_blocked?(@domain.registrant.email)
return if whitelist_blocked?(@domain.registrant.email)
+
mail(to: format(@domain.registrant.email),
subject: "#{I18n.t(:expiration_remind_subject,
name: @domain.name)} [#{@domain.name}]")
diff --git a/app/models/bank_link.rb b/app/models/bank_link.rb
index 31be3e222..29857951f 100644
--- a/app/models/bank_link.rb
+++ b/app/models/bank_link.rb
@@ -32,7 +32,7 @@ class BankLink
hash["VK_AMOUNT"] = number_with_precision(invoice.sum_cache, :precision => 2, :separator => ".")
hash["VK_CURR"] = invoice.currency
hash["VK_REF"] = ""
- hash["VK_MSG"] = "Order nr. #{invoice.number}"
+ hash["VK_MSG"] = invoice.description
hash["VK_RETURN"] = controller.registrar_return_payment_with_url(type)
hash["VK_CANCEL"] = controller.registrar_return_payment_with_url(type)
hash["VK_DATETIME"] = Time.now.strftime("%Y-%m-%dT%H:%M:%S%z")
@@ -101,6 +101,7 @@ class BankLink
transaction.buyer_iban = params["VK_SND_ACC"]
transaction.buyer_name = params["VK_SND_NAME"]
transaction.paid_at = Time.parse(params["VK_T_DATETIME"])
+ transaction.save!
transaction.autobind_invoice
end
diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb
index 2e5b90a2e..1a34965bf 100644
--- a/app/models/bank_transaction.rb
+++ b/app/models/bank_transaction.rb
@@ -2,6 +2,7 @@ class BankTransaction < ActiveRecord::Base
include Versions
belongs_to :bank_statement
has_one :account_activity
+ has_many :directo_records, as: :item, class_name: 'Directo'# Deprecated
scope :unbinded, lambda {
where('id NOT IN (SELECT bank_transaction_id FROM account_activities where bank_transaction_id IS NOT NULL)')
@@ -16,21 +17,32 @@ class BankTransaction < ActiveRecord::Base
account_activity.invoice
end
+
+ def invoice_num
+ return @invoice_no if defined?(@invoice_no)
+
+ match = description.match(/^[^\d]*(\d+)/)
+ return unless match
+
+ @invoice_no = match[1].try(:to_i)
+ end
+
+ def invoice
+ @invoice ||= registrar.invoices.find_by(number: invoice_num) if registrar
+ end
+
+ def registrar
+ @registrar ||= Registrar.find_by(reference_no: reference_no)
+ end
+
+
# For successful binding, reference number, invoice id and sum must match with the invoice
# rubocop: disable Metrics/PerceivedComplexity
# rubocop: disable Metrics/CyclomaticComplexity
def autobind_invoice
return if binded?
- registrar = Registrar.find_by(reference_no: reference_no)
return unless registrar
-
- match = description.match(/^[^\d]*(\d+)/)
- return unless match
-
- invoice_no = match[1].to_i
- return unless invoice_no
-
- invoice = registrar.invoices.find_by(number: invoice_no)
+ return unless invoice_num
return unless invoice
return if invoice.binded?
diff --git a/app/models/blocked_domain.rb b/app/models/blocked_domain.rb
index 2a646a74f..252539e17 100644
--- a/app/models/blocked_domain.rb
+++ b/app/models/blocked_domain.rb
@@ -1,5 +1,56 @@
class BlockedDomain < ActiveRecord::Base
include Versions
+ before_save :generate_data
+ before_destroy :remove_data
+validates :name, domain_name: true, uniqueness: true
- after_initialize -> { self.names = [] if names.nil? }
+
+ class << self
+ def by_domain name
+ where(name: name)
+ end
+
+ def any_of_domains names
+ where(name: names)
+ end
+ end
+
+ def name= val
+ super SimpleIDN.to_unicode(val)
+ end
+
+ def generate_data
+ return if Domain.where(name: name).any?
+
+ @json = generate_json
+ @body = generate_body
+ update_whois_server
+ end
+
+ alias_method :update_whois_record, :generate_data
+
+ def update_whois_server
+ wr = Whois::Record.find_or_initialize_by(name: name)
+ wr.body = @body
+ wr.json = @json
+ wr.save
+ end
+
+ def generate_body
+ template = Rails.root.join("app/views/for_models/whois_other.erb".freeze)
+ ERB.new(template.read, nil, "-").result(binding)
+ end
+
+ def generate_json
+ h = HashWithIndifferentAccess.new
+ h[:name] = self.name
+ h[:status] = 'Blocked'
+ h
+ end
+
+ def remove_data
+ return if Domain.where(name: name).any?
+
+ Whois::Record.where(name: name).delete_all
+ end
end
diff --git a/app/models/contact.rb b/app/models/contact.rb
index 39672e2c4..3af8dcd0e 100644
--- a/app/models/contact.rb
+++ b/app/models/contact.rb
@@ -29,7 +29,7 @@ class Contact < ActiveRecord::Base
uniqueness: { message: :epp_id_taken },
format: { with: /\A[\w\-\:\.\_]*\z/i, message: :invalid },
length: { maximum: 100, message: :too_long_contact_code }
- validate :ident_valid_format?
+ validate :val_ident_valid_format?
validate :uniq_statuses?
validate :validate_html
@@ -235,16 +235,17 @@ class Contact < ActiveRecord::Base
name || '[no name]'
end
- def ident_valid_format?
+ def val_ident_valid_format?
case ident_country_code
when 'EE'.freeze
+ err_msg = "invalid_EE_identity_format#{"_update" if id}".to_sym
case ident_type
when 'priv'.freeze
- errors.add(:ident, :invalid_EE_identity_format) unless Isikukood.new(ident).valid?
+ errors.add(:ident, err_msg) unless Isikukood.new(ident).valid?
when 'org'.freeze
# !%w(1 7 8 9).freeze.include?(ident.first) ||
if ident.size != 8 || !(ident =~/\A[0-9]{8}\z/)
- errors.add(:ident, :invalid_EE_identity_format)
+ errors.add(:ident, err_msg)
end
end
end
diff --git a/app/models/directo.rb b/app/models/directo.rb
new file mode 100644
index 000000000..5a719d0a7
--- /dev/null
+++ b/app/models/directo.rb
@@ -0,0 +1,49 @@
+class Directo < ActiveRecord::Base
+ belongs_to :item, polymorphic: true
+
+ def self.send_receipts
+ new_trans = Invoice.where(invoice_type: "DEB", in_directo: false).where.not(cancelled_at: nil)
+ new_trans.find_in_batches(batch_size: 10).each do |group|
+ mappers = {} # need them as no direct connection between invoice
+ builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
+ xml.invoices {
+ group.each do |invoice|
+ next if invoice.account_activity.nil? || invoice.account_activity.bank_transaction.nil?
+ # next if invoice.account_activity.bank_transaction.sum.nil? || invoice.account_activity.bank_transaction.sum != invoice.sum_cache
+
+ num = invoice.number
+ mappers[num] = invoice
+ xml.invoice(
+ "SalesAgent" => Setting.directo_sales_agent,
+ "Number" => num,
+ "InvoiceDate" => invoice.created_at.strftime("%Y-%m-%dT%H:%M:%S"),
+ "PaymentTerm" => Setting.directo_receipt_payment_term,
+ "Currency" => invoice.currency,
+ "CustomerCode"=> invoice.buyer.try(:directo_handle)
+ ){
+ xml.line(
+ "ProductID" => Setting.directo_receipt_product_name,
+ "Quantity" => 1,
+ "UnitPriceWoVAT" => ActionController::Base.helpers.number_with_precision(invoice.sum_cache/(1+invoice.vat_prc), precision: 2, separator: "."),
+ "ProductName" => invoice.description
+ )
+ }
+ end
+ }
+ end
+
+ data = builder.to_xml.gsub("\n",'')
+ response = RestClient::Request.execute(url: ENV['directo_invoice_url'], method: :post, payload: {put: "1", what: "invoice", xmldata: data}, verify_ssl: false).to_s
+ dump_result_to_db(mappers, response)
+ end
+ end
+
+ def self.dump_result_to_db mappers, xml
+ Nokogiri::XML(xml).css("Result").each do |res|
+ obj = mappers[res.attributes["docid"].value.to_i]
+ obj.directo_records.create!(response: res.as_json.to_h)
+ obj.update_columns(in_directo: true)
+ Rails.logger.info("[DIRECTO] Invoice #{res.attributes["docid"].value} was pushed and return is #{res.as_json.to_h.inspect}")
+ end
+ end
+end
diff --git a/app/models/domain.rb b/app/models/domain.rb
index 05ffafc4d..9da57e27a 100644
--- a/app/models/domain.rb
+++ b/app/models/domain.rb
@@ -93,7 +93,7 @@ class Domain < ActiveRecord::Base
def update_reserved_domains
return unless in_reserved_list?
rd = ReservedDomain.by_domain(name).first
- rd.names[name] = SecureRandom.hex
+ rd.password = SecureRandom.hex
rd.save
end
@@ -244,7 +244,7 @@ class Domain < ActiveRecord::Base
if domain.pending_delete? || domain.pending_delete_confirmation?
DomainMailer.pending_delete_expired_notification(domain.id, true).deliver
end
- domain.clean_pendings!
+ domain.clean_pendings_lowlevel
unless Rails.env.test?
STDOUT << "#{Time.zone.now.utc} Domain.clean_expired_pendings: ##{domain.id} (#{domain.name})\n"
end
@@ -264,9 +264,9 @@ class Domain < ActiveRecord::Base
domains.each do |domain|
next unless domain.expirable?
domain.set_graceful_expired
- DomainMailer.expiration_reminder(domain.id).deliver
+ DomainMailer.expiration_reminder(domain.id).deliver_in(Setting.expiration_reminder_mail.to_i.days)
STDOUT << "#{Time.zone.now.utc} Domain.start_expire_period: ##{domain.id} (#{domain.name}) #{domain.changes}\n" unless Rails.env.test?
- domain.save
+ domain.save(validate: false)
end
STDOUT << "#{Time.zone.now.utc} - Successfully expired #{domains.count} domains\n" unless Rails.env.test?
@@ -280,7 +280,7 @@ class Domain < ActiveRecord::Base
next unless domain.server_holdable?
domain.statuses << DomainStatus::SERVER_HOLD
STDOUT << "#{Time.zone.now.utc} Domain.start_redemption_grace_period: ##{domain.id} (#{domain.name}) #{domain.changes}\n" unless Rails.env.test?
- domain.save
+ domain.save(validate: false)
end
STDOUT << "#{Time.zone.now.utc} - Successfully set server_hold to #{d.count} domains\n" unless Rails.env.test?
@@ -294,7 +294,7 @@ class Domain < ActiveRecord::Base
next unless domain.delete_candidateable?
domain.statuses << DomainStatus::DELETE_CANDIDATE
STDOUT << "#{Time.zone.now.utc} Domain.start_delete_period: ##{domain.id} (#{domain.name}) #{domain.changes}\n" unless Rails.env.test?
- domain.save
+ domain.save(validate: false)
end
return if Rails.env.test?
@@ -408,8 +408,7 @@ class Domain < ActiveRecord::Base
end
end
- return false if statuses.include_any?(DomainStatus::DELETE_CANDIDATE, DomainStatus::SERVER_RENEW_PROHIBITED,
- DomainStatus::CLIENT_RENEW_PROHIBITED, DomainStatus::PENDING_RENEW,
+ return false if statuses.include_any?(DomainStatus::DELETE_CANDIDATE, DomainStatus::PENDING_RENEW,
DomainStatus::PENDING_TRANSFER, DomainStatus::PENDING_DELETE,
DomainStatus::PENDING_UPDATE, DomainStatus::PENDING_DELETE_CONFIRMATION)
true
@@ -439,6 +438,25 @@ class Domain < ActiveRecord::Base
save
end
+
+ # state change shouln't be
+ def clean_pendings_lowlevel
+ statuses.delete(DomainStatus::PENDING_DELETE_CONFIRMATION)
+ statuses.delete(DomainStatus::PENDING_UPDATE)
+ statuses.delete(DomainStatus::PENDING_DELETE)
+
+ status_notes[DomainStatus::PENDING_UPDATE] = ''
+ status_notes[DomainStatus::PENDING_DELETE] = ''
+
+ update_columns(
+ registrant_verification_token: nil,
+ registrant_verification_asked_at: nil,
+ pending_json: {},
+ status_notes: status_notes,
+ statuses: statuses.presence || [DomainStatus::OK]
+ )
+ end
+
def pending_update!
return true if pending_update?
self.epp_pending_update = true # for epp
@@ -544,7 +562,7 @@ class Domain < ActiveRecord::Base
def validate_nameserver_ips
nameservers.to_a.reject(&:marked_for_destruction?).each do |ns|
- next unless ns.hostname.end_with?(name)
+ next unless ns.hostname.end_with?(".#{name}")
next if ns.ipv4.present?
errors.add(:nameservers, :invalid) if errors[:nameservers].blank?
ns.errors.add(:ipv4, :blank)
diff --git a/app/models/epp/contact.rb b/app/models/epp/contact.rb
index f4773f732..54806b88d 100644
--- a/app/models/epp/contact.rb
+++ b/app/models/epp/contact.rb
@@ -123,6 +123,7 @@ class Epp::Contact < Contact
[:email, :invalid],
[:ident, :invalid],
[:ident, :invalid_EE_identity_format],
+ [:ident, :invalid_EE_identity_format_update],
[:ident, :invalid_birthday_format],
[:ident, :invalid_country_code],
[:ident_type, :missing],
@@ -164,7 +165,7 @@ class Epp::Contact < Contact
org_priv = %w(org priv).freeze
if ident_country_code.blank? && org_priv.include?(ident_type) && org_priv.include?(ident_frame.attr('type'))
at.merge!(ident_country_code: ident_frame.attr('cc'), ident_type: ident_frame.attr('type'))
- elsif ident_type == "birthday" && ident !=~ /\d{4}-\d{2}-\d{2}/ && (Date.parse(ident) rescue false)
+ elsif ident_type == "birthday" && !ident[/\A\d{4}-\d{2}-\d{2}\z/] && (Date.parse(ident) rescue false)
at.merge!(ident: ident_frame.text)
at.merge!(ident_country_code: ident_frame.attr('cc')) if ident_frame.attr('cc').present?
elsif ident_type.blank? && ident_country_code.blank?
diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb
index d84de4ca6..3f32ce6d5 100644
--- a/app/models/epp/domain.rb
+++ b/app/models/epp/domain.rb
@@ -8,7 +8,7 @@ class Epp::Domain < Domain
before_validation :manage_permissions
def manage_permissions
return if is_admin # this bad hack for 109086524, refactor later
- return true if is_transfer
+ return true if is_transfer || is_renewal
return unless update_prohibited? || delete_prohibited?
add_epp_error('2304', nil, nil, I18n.t(:object_status_prohibits_operation))
false
@@ -507,18 +507,17 @@ class Epp::Domain < Domain
frame = Nokogiri::XML(pending_json['frame'])
self.deliver_emails = true # turn on email delivery
- send_mail :registrant_updated_notification_for_old_registrant
-
- statuses.delete(DomainStatus::PENDING_UPDATE)
- yield(self) if block_given? # need to skip statuses check here
- self.save
-
+ self.statuses.delete(DomainStatus::PENDING_UPDATE)
::PaperTrail.whodunnit = user.id_role_username # updator str should be the request originator not the approval user
+
+ send_mail :registrant_updated_notification_for_old_registrant
return unless update(frame, user, false)
clean_pendings!
send_mail :registrant_updated_notification_for_new_registrant
- update_whois_record
+ WhoisRecord.find_by(domain_id: id).save # need to reload model
+
+ save! # for notification if everything fails
true
end
@@ -591,6 +590,7 @@ class Epp::Domain < Domain
statuses.delete(DomainStatus::SERVER_HOLD)
statuses.delete(DomainStatus::EXPIRED)
+ statuses.delete(DomainStatus::SERVER_UPDATE_PROHIBITED)
save
end
diff --git a/app/models/invoice.rb b/app/models/invoice.rb
index 2f54e2287..425202a4c 100644
--- a/app/models/invoice.rb
+++ b/app/models/invoice.rb
@@ -2,14 +2,27 @@ class Invoice < ActiveRecord::Base
include Versions
belongs_to :seller, class_name: 'Registrar'
belongs_to :buyer, class_name: 'Registrar'
+ has_one :account_activity
has_many :invoice_items
- has_one :account_activity
+ has_many :directo_records, as: :item, class_name: 'Directo'
accepts_nested_attributes_for :invoice_items
scope :unbinded, lambda {
where('id NOT IN (SELECT invoice_id FROM account_activities where invoice_id IS NOT NULL)')
}
+ scope :all_columns, ->{select("invoices.*")}
+ scope :sort_due_date_column, ->{all_columns.select("CASE WHEN invoices.cancelled_at is not null THEN
+ (invoices.cancelled_at + interval '100 year') ELSE
+ invoices.due_date END AS sort_due_date")}
+ scope :sort_by_sort_due_date_asc, ->{sort_due_date_column.order("sort_due_date ASC")}
+ scope :sort_by_sort_due_date_desc, ->{sort_due_date_column.order("sort_due_date DESC")}
+ scope :sort_receipt_date_column, ->{all_columns.includes(:account_activity).references(:account_activity).select(%Q{
+ CASE WHEN account_activities.created_at is not null THEN account_activities.created_at
+ WHEN invoices.cancelled_at is not null THEN invoices.cancelled_at + interval '100 year'
+ ELSE NULL END AS sort_receipt_date })}
+ scope :sort_by_sort_receipt_date_asc, ->{sort_receipt_date_column.order("sort_receipt_date ASC")}
+ scope :sort_by_sort_receipt_date_desc, ->{sort_receipt_date_column.order("sort_receipt_date DESC")}
attr_accessor :billing_email
validates :billing_email, email_format: { message: :invalid }, allow_blank: true
@@ -19,6 +32,8 @@ class Invoice < ActiveRecord::Base
before_create :set_invoice_number, :check_vat
+ before_save :check_vat
+
def set_invoice_number
last_no = Invoice.order(number: :desc).where('number IS NOT NULL').limit(1).pluck(:number).first
@@ -97,6 +112,10 @@ class Invoice < ActiveRecord::Base
kit.to_pdf
end
+ def description
+ "Order nr. #{number}"
+ end
+
def pdf_name
"invoice-#{number}.pdf"
end
diff --git a/app/models/reserved_domain.rb b/app/models/reserved_domain.rb
index 09d72ec17..8b2cb49e6 100644
--- a/app/models/reserved_domain.rb
+++ b/app/models/reserved_domain.rb
@@ -1,25 +1,75 @@
class ReservedDomain < ActiveRecord::Base
include Versions # version/reserved_domain_version.rb
before_save :fill_empty_passwords
+ before_save :generate_data
+ before_destroy :remove_data
+ validates :name, domain_name: true, uniqueness: true
+
+
- def fill_empty_passwords
- return unless names
- names.each { |k, v| names[k] = SecureRandom.hex if v.blank? }
- end
class << self
def pw_for(domain_name)
- name_in_unicode = SimpleIDN.to_ascii(domain_name)
- by_domain(domain_name).select("names -> '#{domain_name}' AS pw").first.try(:pw) ||
- by_domain(name_in_unicode).select("names -> '#{name_in_unicode}' AS pw").first.try(:pw)
+ name_in_ascii = SimpleIDN.to_ascii(domain_name)
+ by_domain(domain_name).first.try(:password) || by_domain(name_in_ascii).first.try(:password)
end
def by_domain name
- where("names ? '#{name}'")
+ where(name: name)
end
def any_of_domains names
- where("names ?| ARRAY['#{names.join("','")}']")
+ where(name: names)
end
end
+
+
+ def fill_empty_passwords
+
+ if self.password.empty?
+
+ self.password = SecureRandom.hex
+
+ end
+ end
+
+ def name= val
+ super SimpleIDN.to_unicode(val)
+ end
+
+ def generate_data
+ return if Domain.where(name: name).any?
+
+ @json = generate_json
+ @body = generate_body
+ update_whois_server
+ end
+
+ alias_method :update_whois_record, :generate_data
+
+ def update_whois_server
+ wr = Whois::Record.find_or_initialize_by(name: name)
+ wr.body = @body
+ wr.json = @json
+ wr.save
+ end
+
+ def generate_body
+ template = Rails.root.join("app/views/for_models/whois_other.erb".freeze)
+ ERB.new(template.read, nil, "-").result(binding)
+ end
+
+ def generate_json
+ h = HashWithIndifferentAccess.new
+ h[:name] = self.name
+ h[:status] = 'Reserved'
+ h
+ end
+
+ def remove_data
+ return if Domain.where(name: name).any?
+
+ Whois::Record.where(name: name).delete_all
+ end
+
end
diff --git a/app/models/whois_record.rb b/app/models/whois_record.rb
index 08d1cdf14..c16e5ce73 100644
--- a/app/models/whois_record.rb
+++ b/app/models/whois_record.rb
@@ -106,7 +106,7 @@ class WhoisRecord < ActiveRecord::Base
self.json = generated_json
self.body = generated_body
self.name = json['name']
- self.registrar_id = domain.registrar_id # for faster registrar updates
+ self.registrar_id = domain.registrar_id if domain # for faster registrar updates
end
def update_whois_server
diff --git a/app/validators/domain_name_validator.rb b/app/validators/domain_name_validator.rb
index e39437f2b..be83f0835 100644
--- a/app/validators/domain_name_validator.rb
+++ b/app/validators/domain_name_validator.rb
@@ -38,7 +38,7 @@ class DomainNameValidator < ActiveModel::EachValidator
def validate_blocked(value)
return true unless value
- return false if BlockedDomain.where("names @> ?::varchar[]", "{#{value}}").count > 0
+ return false if BlockedDomain.where(name: value).count > 0
ZonefileSetting.where(origin: value).count == 0
end
end
diff --git a/app/views/admin/account_activities/index.haml b/app/views/admin/account_activities/index.haml
index 35e270dce..80ebba2f6 100644
--- a/app/views/admin/account_activities/index.haml
+++ b/app/views/admin/account_activities/index.haml
@@ -29,13 +29,24 @@
.form-group
= f.label t(:receipt_date_until)
= f.search_field :created_at_lteq, value: params[:q][:created_at_lteq], class: 'form-control datepicker', placeholder: t(:receipt_date_until), autocomplete: 'off'
- .col-md-6{style: 'padding-top: 25px;'}
+ .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-default.search
%span.glyphicon.glyphicon-search
%button.btn.btn-default.js-reset-form
= t(:clear_fields)
+.row
+ .col-md-3
+ .col-md-3
+ .col-md-2
+ .col-md-4{class: 'text-right'}
+ = t(:starting_balance) + " #{@sum.to_a.map(&:sum).sum.to_f} EUR"
+
%hr
.row
@@ -55,6 +66,7 @@
%th{class: 'col-xs-2'}
= sort_link(@q, 'sum')
%tbody
+ -total = @sum.to_a.map(&:sum).sum.to_f
- @account_activities.each do |x|
%tr
%td= link_to(x.account.registrar.try(:code), admin_registrar_path(x.account.registrar))
@@ -63,7 +75,15 @@
%td= l(x.created_at)
- c = x.sum > 0.0 ? 'text-success' : 'text-danger'
- s = x.sum > 0.0 ? "+#{x.sum} #{x.currency}" : "#{x.sum} #{x.currency}"
+ -total += x.sum
%td{class: c}= s
+ - if @account_activities.count > 0
+ %tr
+ %td
+ %td
+ %td
+ %td{class: 'text-right'}= t(:total)
+ %td{class: total > 0 ? 'text-success' : 'text-danger'}= total > 0 ? "+#{total} EUR" : "#{total} EUR"
.row
.col-md-12
= paginate @account_activities
diff --git a/app/views/admin/blocked_domains/_form.haml b/app/views/admin/blocked_domains/_form.haml
new file mode 100644
index 000000000..996d52843
--- /dev/null
+++ b/app/views/admin/blocked_domains/_form.haml
@@ -0,0 +1,17 @@
+= form_for([:admin, @domain], html: {class: 'form-horizontal'}) do |f|
+ = render 'shared/full_errors', object: @domain
+
+ .row
+ .col-md-8
+ .panel.panel-default
+ .panel-heading.clearfix
+ .pull-left= t(:general)
+ .panel-body
+ .form-group
+ .col-md-4.control-label
+ = f.label :name
+ .col-md-7
+ = f.text_field(:name, class: 'form-control')
+ .row
+ .col-md-8.text-right
+ = button_tag(t(:save), class: 'btn btn-primary')
diff --git a/app/views/admin/blocked_domains/edit.haml b/app/views/admin/blocked_domains/edit.haml
new file mode 100644
index 000000000..51d77f0cc
--- /dev/null
+++ b/app/views/admin/blocked_domains/edit.haml
@@ -0,0 +1,3 @@
+= render 'shared/title', name: t(:edit_pw)
+
+= render 'form'
diff --git a/app/views/admin/blocked_domains/index.haml b/app/views/admin/blocked_domains/index.haml
index bd5660193..5f6ac69d0 100644
--- a/app/views/admin/blocked_domains/index.haml
+++ b/app/views/admin/blocked_domains/index.haml
@@ -1,10 +1,68 @@
+- content_for :actions do
+ = link_to(t(:new), new_admin_blocked_domain_path, class: 'btn btn-primary')
= render 'shared/title', name: t(:blocked_domains)
-= form_tag([:admin, :blocked_domains]) do |f|
- .row
- .col-md-12
- = text_area_tag :blocked_domains, @blocked_domains, class: 'form-control', rows: 30
- %hr
- .row
- .col-md-12.text-right
- %button.btn.btn-warning=t(:save)
+.row
+ .col-md-12
+ = search_form_for [:admin, @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(: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)
+ .row
+ .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')
+ %th{class: 'col-xs-2'}
+ = sort_link(@q, 'created_at', t(:created_at))
+ %th{class: 'col-xs-2'}
+ = sort_link(@q, 'updated_at', t(:updated_at))
+ %th{class: 'col-xs-1'}
+ = t(:actions)
+ %tbody
+ - @domains.each do |x|
+ %tr
+ %td= x.name
+ %td= l(x.created_at, format: :short)
+ %td= l(x.updated_at, format: :short)
+ %td
+ %div{class: 'text-center'}
+ = link_to(t(:delete), delete_admin_blocked_domain_path(id: x.id),
+ data: { confirm: t(:are_you_sure) }, class: 'btn btn-danger btn-xs')
+.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 = "#{admin_blocked_domains_path}"
diff --git a/app/views/admin/blocked_domains/new.haml b/app/views/admin/blocked_domains/new.haml
new file mode 100644
index 000000000..4461eea40
--- /dev/null
+++ b/app/views/admin/blocked_domains/new.haml
@@ -0,0 +1,3 @@
+= render 'shared/title', name: t(:add_blocked_domain)
+
+= render 'form'
diff --git a/app/views/admin/contacts/index.haml b/app/views/admin/contacts/index.haml
index b8e7850e6..715b87eb6 100644
--- a/app/views/admin/contacts/index.haml
+++ b/app/views/admin/contacts/index.haml
@@ -29,15 +29,10 @@
.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
+ .col-md-6
.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' }
+ = select_tag '[q][domain_contacts_type_in]', options_for_select([['admin', 'AdminDomainContact'], ['tech', 'TechDomainContact'], ['registrant', 'registrant']], params[:q][:domain_contacts_type_in]), { multiple: true, placeholder: t(:choose), class: 'form-control js-combobox' }
.row
.col-md-3
.form-group
diff --git a/app/views/admin/domain_versions/_version.haml b/app/views/admin/domain_versions/_version.haml
index fd449b4b0..321e9abda 100644
--- a/app/views/admin/domain_versions/_version.haml
+++ b/app/views/admin/domain_versions/_version.haml
@@ -55,43 +55,47 @@
= "#{l(domain.valid_to, format: :date)}"
%td
- - registrant.each do |r|
- %p
- = r[:name]
- = r[:phone]
- = r[:email]
- %p
- = r[:code]
+ - if registrant
+ - registrant.each do |r|
+ %p
+ = r[:name]
+ = r[:phone]
+ = r[:email]
+ %p
+ = r[:code]
%td
- - admin_contacts.each do |ac|
- %p
- = ac[:name]
- = ac[:phone]
- = ac[:email]
- %p
- = ac[:code]
+ - if admin_contacts
+ - admin_contacts.each do |ac|
+ %p
+ = ac[:name]
+ = ac[:phone]
+ = ac[:email]
+ %p
+ = ac[:code]
%td
- - tech_contacts.each do |tc|
- %p
- = tc[:name]
- = tc[:phone]
- = tc[:email]
- %p
- = tc[:code]
+ - if tech_contacts
+ - tech_contacts.each do |tc|
+ %p
+ = tc[:name]
+ = tc[:phone]
+ = tc[:email]
+ %p
+ = tc[:code]
%td
%p
- - nameservers.each do |ns|
- = ns[:hostname]
- %br
- = ns[:ipv4]
- = ns[:ipv6]
+ - if nameservers
+ - nameservers.each do |ns|
+ = ns[:hostname]
+ %br
+ = ns[:ipv4]
+ = ns[:ipv6]
%td
%p
- = domain.registrar.name
+ = domain.registrar.name if domain.registrar
- if domain.pending_json.present?
%tr.js-pending{ style: 'display: none;' }
diff --git a/app/views/admin/invoices/index.haml b/app/views/admin/invoices/index.haml
index 75b6285a4..4b34dba94 100644
--- a/app/views/admin/invoices/index.haml
+++ b/app/views/admin/invoices/index.haml
@@ -8,13 +8,13 @@
%thead
%tr
%th{class: 'col-xs-3'}
- = sort_link(@q, 'invoice')
+ = sort_link(@q, :number)
%th{class: 'col-xs-3'}
- = sort_link(@q, 'buyer')
+ = sort_link(@q, :buyer_name, "Buyer")
%th{class: 'col-xs-3'}
- = sort_link(@q, 'due_date')
+ = sort_link(@q, :sort_due_date, "Due date")
%th{class: 'col-xs-3'}
- = sort_link(@q, 'receipt_date')
+ = sort_link(@q, :sort_receipt_date, "Receipt date")
%tbody
- @invoices.each do |x|
%tr
diff --git a/app/views/admin/registrars/index.haml b/app/views/admin/registrars/index.haml
index a2604dbec..8ba45d205 100644
--- a/app/views/admin/registrars/index.haml
+++ b/app/views/admin/registrars/index.haml
@@ -8,15 +8,18 @@
%table.table.table-hover.table-bordered.table-condensed
%thead
%tr
- %th{class: 'col-xs-6'}
+ %th{class: 'col-xs-4'}
= sort_link(@q, 'name')
- %th{class: 'col-xs-6'}
+ %th{class: 'col-xs-4'}
= sort_link(@q, 'reg_no', t(:reg_no))
+ %th{class: 'col-xs-4'}
+ = t(:credit_balance)
%tbody
- @registrars.each do |x|
%tr
%td= link_to(x, [:admin, x])
%td= x.reg_no
+ %td= "#{x.balance}"
.row
.col-md-12
= paginate @registrars
diff --git a/app/views/admin/registrars/show.haml b/app/views/admin/registrars/show.haml
index e3966583f..35938c0c6 100644
--- a/app/views/admin/registrars/show.haml
+++ b/app/views/admin/registrars/show.haml
@@ -32,6 +32,9 @@
%dt= t(:id)
%dd= @registrar.code
+ %dt= t(:credit_balance)
+ %dd= @registrar.balance
+
.col-md-6
.panel.panel-default
.panel-heading
diff --git a/app/views/admin/reserved_domains/_form.haml b/app/views/admin/reserved_domains/_form.haml
new file mode 100644
index 000000000..ec7492659
--- /dev/null
+++ b/app/views/admin/reserved_domains/_form.haml
@@ -0,0 +1,22 @@
+= form_for([:admin, @domain], html: {class: 'form-horizontal'}) do |f|
+ = render 'shared/full_errors', object: @domain
+
+ .row
+ .col-md-8
+ .panel.panel-default
+ .panel-heading.clearfix
+ .pull-left= t(:general)
+ .panel-body
+ .form-group
+ .col-md-4.control-label
+ = f.label :name
+ .col-md-7
+ = f.text_field(:name, class: 'form-control', disabled: !f.object.new_record?)
+ .form-group
+ .col-md-4.control-label
+ = f.label :password
+ .col-md-7
+ = f.text_field(:password, placeholder: t(:optional), class: 'form-control')
+ .row
+ .col-md-8.text-right
+ = button_tag(t(:save), class: 'btn btn-primary')
diff --git a/app/views/admin/reserved_domains/edit.haml b/app/views/admin/reserved_domains/edit.haml
new file mode 100644
index 000000000..51d77f0cc
--- /dev/null
+++ b/app/views/admin/reserved_domains/edit.haml
@@ -0,0 +1,3 @@
+= render 'shared/title', name: t(:edit_pw)
+
+= render 'form'
diff --git a/app/views/admin/reserved_domains/index.haml b/app/views/admin/reserved_domains/index.haml
index 15840ff93..06825b624 100644
--- a/app/views/admin/reserved_domains/index.haml
+++ b/app/views/admin/reserved_domains/index.haml
@@ -1,14 +1,72 @@
- content_for :actions do
- = link_to('#', class: 'btn btn-default', "data-container": "body", "data-title": t('list_format_is_in_yaml'), "data-content": "domain.ee: authinfopw
seconddomain.ee:
thirddomain.ee: authinfo3
#{t('if_auth_info_is_left_empty_it_will_be_auto_generated')}
#{t('each_domain_name_must_end_with_colon_sign')}", "data-placement": "left", "data-toggle": "popover", "data-html" => "true") do
- %span.glyphicon.glyphicon-info-sign{"aria-hidden" => "true"}
-
+ = link_to(t(:new), new_admin_reserved_domain_path, class: 'btn btn-primary')
= render 'shared/title', name: t(:reserved_domains)
-= form_tag([:admin, :reserved_domains]) do |f|
- .row
- .col-md-12
- = text_area_tag :reserved_domains, @reserved_domains, class: 'form-control', rows: 30
- %hr
- .row
- .col-md-12.text-right
- %button.btn.btn-warning=t(:save)
+.row
+ .col-md-12
+ = search_form_for [:admin, @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(: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)
+ .row
+ .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')
+ %th{class: 'col-xs-2'}
+ = sort_link(@q, 'password')
+ %th{class: 'col-xs-2'}
+ = sort_link(@q, 'created_at', t(:created_at))
+ %th{class: 'col-xs-2'}
+ = sort_link(@q, 'updated_at', t(:updated_at))
+ %th{class: 'col-xs-2'}
+ = t(:actions)
+ %tbody
+ - @domains.each do |x|
+ %tr
+ %td= x.name
+ %td= x.password
+ %td= l(x.created_at, format: :short)
+ %td= l(x.updated_at, format: :short)
+ %td
+ = link_to(t(:edit_pw), edit_admin_reserved_domain_path(id: x.id),
+ class: 'btn btn-primary btn-xs')
+ = link_to(t(:delete), delete_admin_reserved_domain_path(id: x.id),
+ data: { confirm: t(:are_you_sure) }, class: 'btn btn-danger btn-xs')
+.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 = "#{admin_reserved_domains_path}"
diff --git a/app/views/admin/reserved_domains/new.haml b/app/views/admin/reserved_domains/new.haml
new file mode 100644
index 000000000..cd6e189f9
--- /dev/null
+++ b/app/views/admin/reserved_domains/new.haml
@@ -0,0 +1,3 @@
+= render 'shared/title', name: t(:add_reserved_domain)
+
+= render 'form'
diff --git a/app/views/admin/settings/index.haml b/app/views/admin/settings/index.haml
index ede30e979..e09e48396 100644
--- a/app/views/admin/settings/index.haml
+++ b/app/views/admin/settings/index.haml
@@ -36,6 +36,7 @@
= render 'setting_row', var: :days_to_renew_domain_before_expire
= render 'setting_row', var: :expire_warning_period
= render 'setting_row', var: :redemption_grace_period
+ = render 'setting_row', var: :expiration_reminder_mail
.panel.panel-default
.panel-heading.clearfix
@@ -70,6 +71,9 @@
= render 'setting_row', var: :days_to_keep_invoices_active
= render 'setting_row', var: :days_to_keep_overdue_invoices_active
= render 'setting_row', var: :minimum_deposit
+ = render 'setting_row', var: :directo_receipt_payment_term
+ = render 'setting_row', var: :directo_receipt_product_name
+ = render 'setting_row', var: :directo_sales_agent
= render 'setting_row', var: :registry_billing_email
= render 'setting_row', var: :registry_invoice_contact
= render 'setting_row', var: :registry_vat_no
diff --git a/app/views/epp/contacts/info.xml.builder b/app/views/epp/contacts/info.xml.builder
index 39aa91b39..fe851a6d9 100644
--- a/app/views/epp/contacts/info.xml.builder
+++ b/app/views/epp/contacts/info.xml.builder
@@ -51,7 +51,7 @@ xml.epp_head do
xml.tag!('contact:crID', @contact.cr_id)
xml.tag!('contact:crDate', @contact.created_at.try(:iso8601))
- if @contact.updated_at != @contact.created_at
+ if @contact.updated_at > @contact.created_at
upID = @contact.updator.try(:registrar)
upID = upID.code if upID.present? # Did updator return a kind of User that has a registrar?
xml.tag!('contact:upID', upID) if upID.present? # optional upID
diff --git a/app/views/epp/domains/info.xml.builder b/app/views/epp/domains/info.xml.builder
index ec5947b13..ef283ab07 100644
--- a/app/views/epp/domains/info.xml.builder
+++ b/app/views/epp/domains/info.xml.builder
@@ -41,7 +41,7 @@ xml.epp_head do
xml.tag!('domain:crID', @domain.cr_id)
xml.tag!('domain:crDate', @domain.created_at.try(:iso8601))
- if @domain.updated_at != @domain.created_at
+ if @domain.updated_at > @domain.created_at
upID = @domain.updator.try(:registrar)
upID = upID.code if upID.present? # Did updator return a kind of User that has a registrar?
xml.tag!('domain:upID', upID) if upID.present? # optional upID
diff --git a/app/views/for_models/whois_other.erb b/app/views/for_models/whois_other.erb
new file mode 100644
index 000000000..33ee735e7
--- /dev/null
+++ b/app/views/for_models/whois_other.erb
@@ -0,0 +1,8 @@
+Estonia .ee Top Level Domain WHOIS server
+
+Domain:
+name: <%= @json['name'] %>
+status: <%= @json['status'] %>
+
+Estonia .ee Top Level Domain WHOIS server
+More information at http://internet.ee
diff --git a/app/views/mailers/domain_mailer/expiration_reminder.html.erb b/app/views/mailers/domain_mailer/expiration_reminder.html.erb
index 59f02c510..e29ca826e 100644
--- a/app/views/mailers/domain_mailer/expiration_reminder.html.erb
+++ b/app/views/mailers/domain_mailer/expiration_reminder.html.erb
@@ -1,7 +1,7 @@
Domeen <%= @domain.name %> on aegunud
Lugupeetud .ee domeeni kasutaja
-Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= l(@domain.outzone_at, format: :short) %> internetis kättesaadav. Alates <%= l(@domain.delete_at, format: :short) %> on domeen <%= @domain.name %> avatud registreerimiseks kõigile huvilistele.
+Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= l(@domain.outzone_at, format: :date) %> internetis kättesaadav. Alates <%= l(@domain.delete_at, format: :date) %> on domeen <%= @domain.name %> avatud registreerimiseks kõigile huvilistele.
Domeeni registreeringu pikendamiseks pöörduge palun oma registripidaja <%= @domain.registrar.name %> poole. Registripidajate kontaktid leiate aadressilt www.internet.ee/registripidajad.
@@ -27,7 +27,7 @@ Tel: +372 727 1000
The <%= @domain.name %> domain has expired
Dear user of .ee domain,
-The domain name <%= @domain.name %> has expired and will not be available on the Internet from <%= l(@domain.outzone_at, format: :short) %>. From <%= l(@domain.delete_at, format: :short) %>, the <%= @domain.name %> domain will be available for registration on a first come first served basis.
+The domain name <%= @domain.name %> has expired and will not be available on the Internet from <%= l(@domain.outzone_at, format: :date) %>. From <%= l(@domain.delete_at, format: :date) %>, the <%= @domain.name %> domain will be available for registration on a first come first served basis.
To renew the domain registration, please contact your registrar <%= @domain.registrar.name %>. You can find the registrar's contacts at http://www.internet.ee/en/registripidajad/.
@@ -53,7 +53,7 @@ Phone: +372 727 1000
Домен <%= @domain.name %> устарел
Уважаемый пользователь домена .ee
-Доменное имя <%= @domain.name %> устарело и с <%= l(@domain.outzone_at, format: :short) %> недоступно в Интернете. С <%= l(@domain.delete_at, format: :short) %> домен <%= @domain.name %> доступен для регистрации всем желающим по принципу "first come, first served".
+Доменное имя <%= @domain.name %> устарело и с <%= l(@domain.outzone_at, format: :date) %> недоступно в Интернете. С <%= l(@domain.delete_at, format: :date) %> домен <%= @domain.name %> доступен для регистрации всем желающим по принципу "first come, first served".
Для продления регистрации домена просим обратиться к своему регистратору <%= @domain.registrar.name %>. Контактные данные регистраторов можно найти по адресу http://www.internet.ee/ru/p/.
diff --git a/app/views/mailers/domain_mailer/expiration_reminder.text.erb b/app/views/mailers/domain_mailer/expiration_reminder.text.erb
index 988ae5e10..d16682ea5 100644
--- a/app/views/mailers/domain_mailer/expiration_reminder.text.erb
+++ b/app/views/mailers/domain_mailer/expiration_reminder.text.erb
@@ -1,7 +1,7 @@
Domeen <%= @domain.name %> on aegunud
Lugupeetud .ee domeeni kasutaja
-Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= l(@domain.outzone_at, format: :short) %> internetis kättesaadav. Alates <%= l(@domain.delete_at, format: :short) %> on domeen <%= @domain.name %> avatud registreerimiseks kõigile huvilistele.
+Domeeninimi <%= @domain.name %> on aegunud ja ei ole alates <%= l(@domain.outzone_at, format: :date) %> internetis kättesaadav. Alates <%= l(@domain.delete_at, format: :date) %> on domeen <%= @domain.name %> avatud registreerimiseks kõigile huvilistele.
Domeeni registreeringu pikendamiseks pöörduge palun oma registripidaja <%= @domain.registrar.name %> poole. Registripidajate kontaktid leiate aadressilt www.internet.ee/registripidajad.
@@ -27,7 +27,7 @@ Tel: +372 727 1000
The <%= @domain.name %> domain has expired
Dear user of .ee domain,
-The domain name <%= @domain.name %> has expired and will not be available on the Internet from <%= l(@domain.outzone_at, format: :short) %>. From <%= l(@domain.delete_at, format: :short) %>, the <%= @domain.name %> domain will be available for registration on a first come first served basis.
+The domain name <%= @domain.name %> has expired and will not be available on the Internet from <%= l(@domain.outzone_at, format: :date) %>. From <%= l(@domain.delete_at, format: :date) %>, the <%= @domain.name %> domain will be available for registration on a first come first served basis.
To renew the domain registration, please contact your registrar <%= @domain.registrar.name %>. You can find the registrar's contacts at http://www.internet.ee/en/registripidajad/.
@@ -53,7 +53,7 @@ Phone: +372 727 1000
Домен <%= @domain.name %> устарел
Уважаемый пользователь домена .ee
-Доменное имя <%= @domain.name %> устарело и с <%= l(@domain.outzone_at, format: :short) %> недоступно в Интернете. С <%= l(@domain.delete_at, format: :short) %> домен <%= @domain.name %> доступен для регистрации всем желающим по принципу "first come, first served".
+Доменное имя <%= @domain.name %> устарело и с <%= l(@domain.outzone_at, format: :date) %> недоступно в Интернете. С <%= l(@domain.delete_at, format: :date) %> домен <%= @domain.name %> доступен для регистрации всем желающим по принципу "first come, first served".
Для продления регистрации домена просим обратиться к своему регистратору <%= @domain.registrar.name %>. Контактные данные регистраторов можно найти по адресу http://www.internet.ee/ru/p/.
diff --git a/app/views/mailers/domain_mailer/force_delete.html.erb b/app/views/mailers/domain_mailer/force_delete.html.erb
index 82bdee156..6f4f4cb27 100644
--- a/app/views/mailers/domain_mailer/force_delete.html.erb
+++ b/app/views/mailers/domain_mailer/force_delete.html.erb
@@ -20,7 +20,7 @@ Registrikood: <%= @domain.registrant.try(:ident) %>
Domeenireeglite punktist 6.4 tulenevalt on domeeni suhtes õigust omaval registreerijal võimalus esitada domeeni <%= @domain.name %> registripidajale <%= @domain.registrar %> domeeni üleandmise taotlus Domeenireeglite p 5.3.6.2 kohaselt. Taotlusele tuleb lisada domeeni omandamist tõendavad dokumendid, mis asendavad Domeenireeglite punktis 5.3.6.3 sätestatud üleandva registreerija nõusolekut. Vastav dokumentatsioon tuleks esitada Registripidajale esimesel võimalusel.
-Kui üleandmine ei ole 30 päeva jooksul toimunud, kustub domeen <%= @domain.name %> 24 tunni jooksul <%= l(@domain.force_delete_at, format: :short) %> möödumisest juhuslikult valitud ajahetkel. Soovi korral on võimalik domeen pärast selle kustumist registrist “kes ees, see mees” põhimõttel uuesti registreerida.
+Kui üleandmine ei ole 30 päeva jooksul toimunud, kustub domeen <%= @domain.name %> 24 tunni jooksul <%= l(@domain.force_delete_at, format: :date) %> möödumisest juhuslikult valitud ajahetkel. Soovi korral on võimalik domeen pärast selle kustumist registrist “kes ees, see mees” põhimõttel uuesti registreerida.
Lisaküsimuste korral võtke palun ühendust oma registripidajaga <%= @domain.registrar %>, kelle kontaktandmed leiate lingilt http://www.internet.ee/registripidajad
According to paragraph 6.4 of the Domain Regulation, the registrant holding a right to the domain name <%= @domain.name %> can submit a domain name transfer application to the registrar <%= @domain.registrar %> in accordance with paragraph 5.3.6.2 of the Domain Regulation. The application must be submitted together with documents certifying the acquisition of the domain that will replace the consent of the surrendering registrant as laid down in paragraph 5.3.6.3 of the Domain Regulation. The relevant documents should be submitted to the registrar as soon as possible.
-If the transfer has not been made in 30 days, the domain <%= @domain.name %> will be deleted at a randomly chosen moment within 24 hours after <%= l(@domain.force_delete_at, format: :short) %>. After deletion it is possible to reregister the domain on a "first come, first served" basis.
+If the transfer has not been made in 30 days, the domain <%= @domain.name %> will be deleted at a randomly chosen moment within 24 hours after <%= l(@domain.force_delete_at, format: :date) %>. After deletion it is possible to reregister the domain on a "first come, first served" basis.
Should you have additional questions, please contact your registrar <%= @domain.registrar %>, whose contact information can be found at http://www.internet.ee/registrars/
Согласно пункту 6.4 Правил домена регистрант, имеющий право на домен, может подать регистратору <%= @domain.registrar %> домена <%= @domain.name %> ходатайство о передаче домена в соответствии с п. 5.3.6.2 Правил домена. К ходатайству следует приложить подтверждающие приобретение домена документы, заменяющие в соответствии с пунктом 5.3.6.3 Правил домена согласие передающего доменное имя регистранта. EIS предлагает представить соответствующую документацию Регистратору при первой возможности, начиная с инициирования процедуры удаления.
-Если в течение 30 дней передача не произошла, домен <%= @domain.name %> удаляется по истечении 24 часов <%= l(@domain.force_delete_at, format: :short) %> в случайный момент времени. По желанию после удаления из регистра домен можно снова зарегистрировать по принципу "кто успел, тот и съел".
+Если в течение 30 дней передача не произошла, домен <%= @domain.name %> удаляется по истечении 24 часов <%= l(@domain.force_delete_at, format: :date) %> в случайный момент времени. По желанию после удаления из регистра домен можно снова зарегистрировать по принципу "кто успел, тот и съел".
Просим обратиться к своему регистратору <%= @domain.registrar %>. Контактные данные регистраторов можно найти по адресу http://www.internet.ee/registratory/