diff --git a/.reek b/.reek
index d0f2aaba3..a511bdb43 100644
--- a/.reek
+++ b/.reek
@@ -191,7 +191,6 @@ DuplicateMethodCall:
- Registrant::SessionsController#mid_status
- Registrant::WhoisController#index
- Registrar::AccountActivitiesController#index
- - Registrar::BaseController#check_ip
- Registrar::ContactsController#download_list
- Registrar::ContactsController#index
- Registrar::ContactsController#normalize_search_parameters
@@ -666,7 +665,6 @@ TooManyStatements:
- Registrant::SessionsController#mid
- Registrant::SessionsController#mid_status
- Registrar::AccountActivitiesController#index
- - Registrar::BaseController#check_ip
- Registrar::ContactsController#download_list
- Registrar::ContactsController#index
- Registrar::ContactsController#normalize_search_parameters
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 472c5545d..66e29f9f7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+03.04.2018
+* BUG: Fixed bug with sometimes failing bank-link payments [#642](https://github.com/internetee/registry/issues/642)
+* EPP: Domain and associated objects are now validated on domain renew [#678](https://github.com/internetee/registry/issues/678)
+* Admin: drop uniqueness requirement from registrar's registry number field [#776](https://github.com/internetee/registry/issues/776)
+* Security: Loofah gem update to 2.2.2 [#783](https://github.com/internetee/registry/pull/783)
+* Disabled spellcheck for browsers to cleanup UI [#759](https://github.com/internetee/registry/issues/759)
+* Admin: refactored registrar management [#770](https://github.com/internetee/registry/pull/770)
+* Fix structure.sql [#796](https://github.com/internetee/registry/pull/796)
+
19.03.2018
* EPP transfer and REPP bulk transfer reuses contact objects [#746](https://github.com/internetee/registry/issues/746)
* Gems: Rack (1.6.9) and Rack-protection (1.5.5) update [#768](https://github.com/internetee/registry/issues/768)
diff --git a/Gemfile.lock b/Gemfile.lock
index ed559f465..6d9105baf 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -160,6 +160,7 @@ GEM
unicode_utils (~> 1.4)
crack (0.4.3)
safe_yaml (~> 1.0.0)
+ crass (1.0.3)
daemons (1.2.4)
daemons-rails (1.2.1)
daemons
@@ -247,7 +248,8 @@ GEM
activesupport (>= 3.0.0)
libxml-ruby (3.0.0)
liquid (3.0.6)
- loofah (2.0.3)
+ loofah (2.2.2)
+ crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.6.6)
mime-types (>= 1.16, < 4)
diff --git a/app/assets/javascripts/admin-manifest.coffee b/app/assets/javascripts/admin-manifest.coffee
index 909cd191c..dd99c1932 100644
--- a/app/assets/javascripts/admin-manifest.coffee
+++ b/app/assets/javascripts/admin-manifest.coffee
@@ -9,6 +9,7 @@
#= require select2
#= require jquery.doubleScroll
#= require datepicker
+#= require spell_check
#= require admin/application
#= require admin/app
#= require_tree ./admin
diff --git a/app/assets/javascripts/registrant-manifest.coffee b/app/assets/javascripts/registrant-manifest.coffee
index eb7577e02..84f95374a 100644
--- a/app/assets/javascripts/registrant-manifest.coffee
+++ b/app/assets/javascripts/registrant-manifest.coffee
@@ -4,4 +4,5 @@
#= require jquery-ui/datepicker
#= require select2
#= require datepicker
+#= require spell_check
#= require shared/general
diff --git a/app/assets/javascripts/registrar-manifest.coffee b/app/assets/javascripts/registrar-manifest.coffee
index 656b5cb18..5c4a58df6 100644
--- a/app/assets/javascripts/registrar-manifest.coffee
+++ b/app/assets/javascripts/registrar-manifest.coffee
@@ -6,6 +6,7 @@
#= require jquery-ui/datepicker
#= require select2
#= require datepicker
+#= require spell_check
#= require shared/general
#= require registrar/autocomplete
#= require registrar/application
diff --git a/app/assets/javascripts/spell_check.js b/app/assets/javascripts/spell_check.js
new file mode 100644
index 000000000..7c04ab071
--- /dev/null
+++ b/app/assets/javascripts/spell_check.js
@@ -0,0 +1,12 @@
+(function() {
+ function disableSpellCheck() {
+ let selector = 'input[type=text], textarea';
+ let textFields = document.querySelectorAll(selector);
+
+ for (let field of textFields) {
+ field.spellcheck = false;
+ }
+ }
+
+ disableSpellCheck();
+})();
diff --git a/app/controllers/admin/bank_statements_controller.rb b/app/controllers/admin/bank_statements_controller.rb
index d7b6edae2..a70387317 100644
--- a/app/controllers/admin/bank_statements_controller.rb
+++ b/app/controllers/admin/bank_statements_controller.rb
@@ -24,7 +24,7 @@ module Admin
@invoice = Invoice.find_by(id: params[:invoice_id])
@bank_transaction = @bank_statement.bank_transactions.build(
description: @invoice.to_s,
- sum: @invoice.sum,
+ sum: @invoice.total,
reference_no: @invoice.reference_no,
paid_at: Time.zone.now.to_date,
currency: 'EUR'
diff --git a/app/controllers/admin/registrars_controller.rb b/app/controllers/admin/registrars_controller.rb
index 8d020787b..e919bdb25 100644
--- a/app/controllers/admin/registrars_controller.rb
+++ b/app/controllers/admin/registrars_controller.rb
@@ -19,17 +19,15 @@ module Admin
def create
@registrar = Registrar.new(registrar_params)
- begin
+ if @registrar.valid?
@registrar.transaction do
@registrar.save!
@registrar.accounts.create!(account_type: Account::CASH, currency: 'EUR')
end
- flash[:notice] = t('.created')
- redirect_to [:admin, @registrar]
- rescue ActiveRecord::RecordInvalid
- flash.now[:alert] = t('.not_created')
- render 'new'
+ redirect_to [:admin, @registrar], notice: t('.created')
+ else
+ render :new
end
end
@@ -38,21 +36,19 @@ module Admin
def update
if @registrar.update(registrar_params)
- flash[:notice] = t('.updated')
- redirect_to [:admin, @registrar]
+ redirect_to [:admin, @registrar], notice: t('.updated')
else
- flash.now[:alert] = t('.not_updated')
- render 'edit'
+ render :edit
end
end
def destroy
if @registrar.destroy
- flash[:notice] = I18n.t('registrar_deleted')
- redirect_to admin_registrars_path
+ flash[:notice] = t('.deleted')
+ redirect_to admin_registrars_url
else
- flash.now[:alert] = I18n.t('failed_to_delete_registrar')
- render 'show'
+ flash[:alert] = @registrar.errors.full_messages.first
+ redirect_to admin_registrar_url(@registrar)
end
end
@@ -65,7 +61,6 @@ module Admin
def registrar_params
params.require(:registrar).permit(:name,
:reg_no,
- :vat_no,
:street,
:city,
:state,
@@ -74,10 +69,12 @@ module Admin
:email,
:phone,
:website,
- :billing_email,
:code,
:test_registrar,
+ :vat_no,
+ :vat_rate,
:accounting_customer_code,
+ :billing_email,
:language)
end
end
diff --git a/app/controllers/registrar/invoices_controller.rb b/app/controllers/registrar/invoices_controller.rb
index ac762e712..735df91a3 100644
--- a/app/controllers/registrar/invoices_controller.rb
+++ b/app/controllers/registrar/invoices_controller.rb
@@ -55,8 +55,8 @@ class Registrar
end
def normalize_search_parameters
- params[:q][:sum_cache_gteq].gsub!(',', '.') if params[:q][:sum_cache_gteq]
- params[:q][:sum_cache_lteq].gsub!(',', '.') if params[:q][:sum_cache_lteq]
+ params[:q][:total_gteq].gsub!(',', '.') if params[:q][:total_gteq]
+ params[:q][:total_lteq].gsub!(',', '.') if params[:q][:total_lteq]
ca_cache = params[:q][:due_date_lteq]
begin
diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb
index 696dbbc7e..18c892ea7 100644
--- a/app/controllers/registrar/payments_controller.rb
+++ b/app/controllers/registrar/payments_controller.rb
@@ -3,7 +3,7 @@ class Registrar
protect_from_forgery except: :back
skip_authorization_check # actually anyone can pay, no problems at all
- skip_before_action :authenticate_user!, :check_ip, only: [:back]
+ skip_before_action :authenticate_user!, :check_ip_restriction, only: [:back]
before_action :check_bank
# to handle existing model we should
diff --git a/app/models/bank_link.rb b/app/models/bank_link.rb
index 24c94a771..e388a0f8b 100644
--- a/app/models/bank_link.rb
+++ b/app/models/bank_link.rb
@@ -29,7 +29,7 @@ class BankLink
hash["VK_VERSION"] = "008"
hash["VK_SND_ID"] = ENV["payments_#{type}_seller_account"]
hash["VK_STAMP"] = invoice.number
- hash["VK_AMOUNT"] = number_with_precision(invoice.sum_cache, :precision => 2, :separator => ".")
+ hash["VK_AMOUNT"] = number_with_precision(invoice.total, :precision => 2, :separator => ".")
hash["VK_CURR"] = invoice.currency
hash["VK_REF"] = ""
hash["VK_MSG"] = invoice.order
@@ -140,7 +140,7 @@ class BankLink
def validate_amount
source = number_with_precision(BigDecimal.new(params["VK_AMOUNT"].to_s), precision: 2, separator: ".")
- target = number_with_precision(invoice.sum_cache, precision: 2, separator: ".")
+ target = number_with_precision(invoice.total, precision: 2, separator: ".")
source == target
end
diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb
index daf6abc29..3749f92b5 100644
--- a/app/models/bank_transaction.rb
+++ b/app/models/bank_transaction.rb
@@ -47,7 +47,7 @@ class BankTransaction < ActiveRecord::Base
return if invoice.binded?
return if invoice.cancelled?
- return if invoice.sum != sum
+ return if invoice.total != sum
create_activity(registrar, invoice)
end
# rubocop: enable Metrics/PerceivedComplexity
@@ -76,7 +76,7 @@ class BankTransaction < ActiveRecord::Base
return
end
- if invoice.sum != sum
+ if invoice.total != sum
errors.add(:base, I18n.t('invoice_and_transaction_sums_do_not_match'))
return
end
@@ -88,7 +88,7 @@ class BankTransaction < ActiveRecord::Base
create_account_activity(
account: registrar.cash_account,
invoice: invoice,
- sum: invoice.sum_without_vat,
+ sum: invoice.subtotal,
currency: currency,
description: description,
activity_type: AccountActivity::ADD_CREDIT
diff --git a/app/models/directo.rb b/app/models/directo.rb
index 62cf43804..9352c9356 100644
--- a/app/models/directo.rb
+++ b/app/models/directo.rb
@@ -3,7 +3,7 @@ class Directo < ActiveRecord::Base
belongs_to :item, polymorphic: true
def self.send_receipts
- new_trans = Invoice.where(invoice_type: "DEB", in_directo: false).where(cancelled_at: nil)
+ new_trans = Invoice.where(in_directo: false).where(cancelled_at: nil)
total = new_trans.count
counter = 0
Rails.logger.info("[DIRECTO] Will try to send #{total} invoices")
@@ -15,7 +15,7 @@ class Directo < ActiveRecord::Base
group.each do |invoice|
if invoice.account_activity.nil? || invoice.account_activity.bank_transaction.nil? ||
- invoice.account_activity.bank_transaction.sum.nil? || invoice.account_activity.bank_transaction.sum != invoice.sum_cache
+ invoice.account_activity.bank_transaction.sum.nil? || invoice.account_activity.bank_transaction.sum != invoice.total
Rails.logger.info("[DIRECTO] Invoice #{invoice.number} has been skipped")
next
end
@@ -29,12 +29,14 @@ class Directo < ActiveRecord::Base
"InvoiceDate" => invoice.created_at.strftime("%Y-%m-%dT%H:%M:%S"),
"PaymentTerm" => Setting.directo_receipt_payment_term,
"Currency" => invoice.currency,
- "CustomerCode"=> invoice.buyer.accounting_customer_code
+ "CustomerCode"=> invoice.buyer.accounting_customer_code,
+ 'TotalVAT' => ActionController::Base.helpers.number_with_precision(invoice.vat_amount, precision: 2, separator: '.')
){
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: "."),
+ "UnitPriceWoVAT" => ActionController::Base.helpers.number_with_precision(invoice.subtotal, precision: 2, separator: '.'),
+ 'VATCode' => invoice.buyer_vat_no,
"ProductName" => invoice.order
)
}
diff --git a/app/models/epp/domain.rb b/app/models/epp/domain.rb
index fb01fe38a..249f90a98 100644
--- a/app/models/epp/domain.rb
+++ b/app/models/epp/domain.rb
@@ -18,7 +18,7 @@ class Epp::Domain < Domain
after_validation :validate_contacts
def validate_contacts
- return true if is_renewal || is_transfer
+ return true if is_transfer
ok = true
active_admins = admin_domain_contacts.select { |x| !x.marked_for_destruction? }
diff --git a/app/models/invoice.rb b/app/models/invoice.rb
index ad478443d..a2e469ca0 100644
--- a/app/models/invoice.rb
+++ b/app/models/invoice.rb
@@ -27,12 +27,18 @@ class Invoice < ActiveRecord::Base
attr_accessor :billing_email
validates :billing_email, email_format: { message: :invalid }, allow_blank: true
- validates :invoice_type, :due_date, :currency, :seller_name,
- :seller_iban, :buyer_name, :invoice_items, :vat_prc, presence: true
+ validates :due_date, :currency, :seller_name,
+ :seller_iban, :buyer_name, :invoice_items, presence: true
+ validates :vat_rate, numericality: { greater_than_or_equal_to: 0, less_than: 100 },
+ allow_nil: true
- before_create :set_invoice_number, :check_vat
+ before_create :set_invoice_number
+ before_create :apply_default_vat_rate, unless: :vat_rate?
+ before_create :calculate_total, unless: :total?
+ before_create :apply_default_buyer_vat_no, unless: :buyer_vat_no?
- before_save :check_vat
+ attribute :vat_rate, ::Type::VATRate.new
+ attr_readonly :vat_rate
def set_invoice_number
last_no = Invoice.order(number: :desc).where('number IS NOT NULL').limit(1).pluck(:number).first
@@ -50,14 +56,6 @@ class Invoice < ActiveRecord::Base
false
end
- def check_vat
- if buyer.country_code != 'EE' && buyer.vat_no.present?
- self.vat_prc = 0
- end
- end
-
- before_save -> { self.sum_cache = sum }
-
class << self
def cancel_overdue_invoices
STDOUT << "#{Time.zone.now.utc} - Cancelling overdue invoices\n" unless Rails.env.test?
@@ -106,12 +104,12 @@ class Invoice < ActiveRecord::Base
def buyer_country
Country.new(buyer_country_code)
end
-
+
# order is used for directo/banklink description
def order
"Order nr. #{number}"
end
-
+
def pdf(html)
kit = PDFKit.new(html)
kit.to_pdf
@@ -152,15 +150,31 @@ class Invoice < ActiveRecord::Base
invoice_items
end
- def sum_without_vat
- (items.map(&:item_sum_without_vat).sum).round(2)
+ def subtotal
+ invoice_items.map(&:item_sum_without_vat).reduce(:+)
end
- def vat
- (sum_without_vat * vat_prc).round(2)
+ def vat_amount
+ return 0 unless vat_rate
+ subtotal * vat_rate / 100
end
- def sum
- (sum_without_vat + vat).round(2)
+ def total
+ calculate_total unless total?
+ read_attribute(:total)
+ end
+
+ private
+
+ def apply_default_vat_rate
+ self.vat_rate = buyer.effective_vat_rate
+ end
+
+ def apply_default_buyer_vat_no
+ self.buyer_vat_no = buyer.vat_no
+ end
+
+ def calculate_total
+ self.total = subtotal + vat_amount
end
end
diff --git a/app/models/registrar.rb b/app/models/registrar.rb
index 2aa9ea3e4..d539e01f2 100644
--- a/app/models/registrar.rb
+++ b/app/models/registrar.rb
@@ -6,7 +6,7 @@ class Registrar < ActiveRecord::Base
has_many :api_users, dependent: :restrict_with_error
has_many :messages
has_many :invoices, foreign_key: 'buyer_id'
- has_many :accounts
+ has_many :accounts, dependent: :destroy
has_many :nameservers, through: :domains
has_many :whois_records
has_many :white_ips, dependent: :destroy
@@ -17,37 +17,19 @@ class Registrar < ActiveRecord::Base
validates :name, :reference_no, :code, uniqueness: true
validates :accounting_customer_code, presence: true
validates :language, presence: true
- validate :forbidden_codes
+ validate :forbid_special_code
+ validates :vat_rate, presence: true, if: 'foreign_vat_payer? && vat_no.blank?'
+ validates :vat_rate, absence: true, if: :home_vat_payer?
+ validates :vat_rate, absence: true, if: 'foreign_vat_payer? && vat_no?'
+ validates :vat_rate, numericality: { greater_than_or_equal_to: 0, less_than: 100 },
+ allow_nil: true
+
+ validate :forbid_special_code
+
+ attribute :vat_rate, ::Type::VATRate.new
after_initialize :set_defaults
-
- def forbidden_codes
- return true unless ['CID'].include? code
- errors.add(:code, I18n.t(:forbidden_code))
- false
- end
-
before_validation :generate_iso_11649_reference_no
- def generate_iso_11649_reference_no
- return if reference_no.present?
-
- loop do
- base = nil
- loop do
- base = SecureRandom.random_number.to_s.last(8)
- break if base.to_i != 0 && base.length == 8
- end
-
- control_base = (base + '2715' + '00').to_i
- reminder = control_base % 97
- check_digits = 98 - reminder
-
- check_digits = check_digits < 10 ? "0#{check_digits}" : check_digits.to_s
-
- self.reference_no = "RF#{check_digits}#{base}"
- break unless self.class.exists?(reference_no: reference_no)
- end
- end
validates :email, :billing_email,
email_format: { message: :invalid },
@@ -76,12 +58,10 @@ class Registrar < ActiveRecord::Base
# rubocop:disable Metrics/AbcSize
def issue_prepayment_invoice(amount, description = nil)
invoices.create(
- invoice_type: 'DEB',
due_date: (Time.zone.now.to_date + Setting.days_to_keep_invoices_active.days).end_of_day,
payment_term: 'prepayment',
description: description,
currency: 'EUR',
- vat_prc: Setting.registry_vat_prc,
seller_name: Setting.registry_juridical_name,
seller_reg_no: Setting.registry_reg_no,
seller_iban: Setting.registry_iban,
@@ -97,7 +77,7 @@ class Registrar < ActiveRecord::Base
seller_url: Setting.registry_url,
seller_email: Setting.registry_email,
seller_contact_name: Setting.registry_invoice_contact,
- buyer_id: id,
+ buyer: self,
buyer_name: name,
buyer_reg_no: reg_no,
buyer_country_code: country_code,
@@ -132,11 +112,6 @@ class Registrar < ActiveRecord::Base
cash_account.account_activities.create!(args)
end
- def credit!(args)
- args[:currency] = 'EUR'
- cash_account.account_activities.create!(args)
- end
-
def address
[street, city, state, zip].reject(&:blank?).compact.join(', ')
end
@@ -172,9 +147,50 @@ class Registrar < ActiveRecord::Base
end
end
+ def effective_vat_rate
+ if home_vat_payer?
+ Registry.instance.vat_rate
+ else
+ vat_rate
+ end
+ end
+
private
def set_defaults
self.language = Setting.default_language unless language
end
+
+ def forbid_special_code
+ errors.add(:code, :forbidden) if code == 'CID'
+ end
+
+ def generate_iso_11649_reference_no
+ return if reference_no.present?
+
+ loop do
+ base = nil
+ loop do
+ base = SecureRandom.random_number.to_s.last(8)
+ break if base.to_i != 0 && base.length == 8
+ end
+
+ control_base = (base + '2715' + '00').to_i
+ reminder = control_base % 97
+ check_digits = 98 - reminder
+
+ check_digits = check_digits < 10 ? "0#{check_digits}" : check_digits.to_s
+
+ self.reference_no = "RF#{check_digits}#{base}"
+ break unless self.class.exists?(reference_no: reference_no)
+ end
+ end
+
+ def home_vat_payer?
+ country == Registry.instance.legal_address_country
+ end
+
+ def foreign_vat_payer?
+ !home_vat_payer?
+ end
end
diff --git a/app/models/registry.rb b/app/models/registry.rb
new file mode 100644
index 000000000..5e5c8cd93
--- /dev/null
+++ b/app/models/registry.rb
@@ -0,0 +1,11 @@
+class Registry
+ include Singleton
+
+ def vat_rate
+ Setting.registry_vat_prc.to_d * 100
+ end
+
+ def legal_address_country
+ Country.new(Setting.registry_country_code)
+ end
+end
diff --git a/app/models/type/vat_rate.rb b/app/models/type/vat_rate.rb
new file mode 100644
index 000000000..5ee993211
--- /dev/null
+++ b/app/models/type/vat_rate.rb
@@ -0,0 +1,11 @@
+module Type
+ class VATRate < ActiveRecord::Type::Decimal
+ def type_cast_from_database(value)
+ super * 100 if value
+ end
+
+ def type_cast_for_database(value)
+ super / 100.0 if value
+ end
+ end
+end
diff --git a/app/views/admin/bank_transactions/show.haml b/app/views/admin/bank_transactions/show.haml
index 4133386e5..60515200a 100644
--- a/app/views/admin/bank_transactions/show.haml
+++ b/app/views/admin/bank_transactions/show.haml
@@ -41,7 +41,7 @@
%dt= t(:currency)
%dd= @bank_transaction.currency
- %dt= t(:reference_no)
+ %dt= BankTransaction.human_attribute_name :reference_no
%dd= @bank_transaction.reference_no
%dt= t(:paid_at)
diff --git a/app/views/admin/mail_templates/_form.haml b/app/views/admin/mail_templates/_form.haml
index 739cce665..70873c22a 100644
--- a/app/views/admin/mail_templates/_form.haml
+++ b/app/views/admin/mail_templates/_form.haml
@@ -37,7 +37,7 @@
= f.email_field :bcc, class: 'form-control'
.form-group
.col-md-12
- = f.label :body, t(:html_body)
+ = f.label :body, t('admin.mail_templates.html_body')
= liquid_help
.col-md-12
= f.text_area(:body, class: 'form-control', size: '15x15')
@@ -48,7 +48,7 @@
.col-md-12
= f.text_area(:text_body, class: 'form-control', size: '15x15')
- %hr
+ %hr
.row
.col-md-12.text-right
= button_tag(t(:save), class: 'btn btn-primary')
diff --git a/app/views/admin/mail_templates/new.haml b/app/views/admin/mail_templates/new.haml
index e5889e2b3..ecf2ea1e8 100644
--- a/app/views/admin/mail_templates/new.haml
+++ b/app/views/admin/mail_templates/new.haml
@@ -1,3 +1,3 @@
-= render 'shared/title', name: t(:new_mail_template)
+= render 'shared/title', name: t('admin.mail_templates.new_mail_template')
= render 'form', mail_template: @mail_template
diff --git a/app/views/admin/registrars/_billing.html.erb b/app/views/admin/registrars/_billing.html.erb
new file mode 100644
index 000000000..7a7e49fea
--- /dev/null
+++ b/app/views/admin/registrars/_billing.html.erb
@@ -0,0 +1,20 @@
+
+
+ <%= t '.header' %>
+
+
+
+ - <%= Registrar.human_attribute_name :vat_no %>
+ - <%= registrar.vat_no %>
+
+ - <%= Registrar.human_attribute_name :vat_rate %>
+ - <%= number_to_percentage(registrar.vat_rate, precision: 1) %>
+
+ - <%= Registrar.human_attribute_name :accounting_customer_code %>
+ - <%= registrar.accounting_customer_code %>
+
+ - <%= Registrar.human_attribute_name :billing_email %>
+ - <%= registrar.billing_email %>
+
+
+
diff --git a/app/views/admin/registrars/_contacts.html.erb b/app/views/admin/registrars/_contacts.html.erb
new file mode 100644
index 000000000..190e48458
--- /dev/null
+++ b/app/views/admin/registrars/_contacts.html.erb
@@ -0,0 +1,24 @@
+
+
+ <%= t '.header' %>
+
+
+
+
+ - <%= t(:country) %>
+ - <%= @registrar.country %>
+
+ - <%= t(:address) %>
+ - <%= @registrar.address %>
+
+ - <%= t(:contact_phone) %>
+ - <%= @registrar.phone %>
+
+ - <%= t(:contact_email) %>
+ - <%= @registrar.email %>
+
+ - <%= Registrar.human_attribute_name :billing_email %>
+ - <%= @registrar.billing_email %>
+
+
+
diff --git a/app/views/admin/registrars/_details.html.erb b/app/views/admin/registrars/_details.html.erb
new file mode 100644
index 000000000..c640075ba
--- /dev/null
+++ b/app/views/admin/registrars/_details.html.erb
@@ -0,0 +1,27 @@
+
+
+ <%= t '.header' %>
+
+
+
+
+ - <%= Registrar.human_attribute_name :name %>
+ - <%= registrar.name %>
+
+ - <%= Registrar.human_attribute_name :reg_no %>
+ - <%= registrar.reg_no %>
+
+ - <%= Registrar.human_attribute_name :reference_no %>
+ - <%= registrar.reference_no %>
+
+ - <%= Registrar.human_attribute_name :code %>
+ - <%= registrar.code %>
+
+ - <%= Registrar.human_attribute_name :balance %>
+ - <%= registrar.balance %>
+
+ - <%= Registrar.human_attribute_name :website %>
+ - <%= registrar.website %>
+
+
+
diff --git a/app/views/admin/registrars/_form.html.erb b/app/views/admin/registrars/_form.html.erb
index 65a5351ad..71c4fb68f 100644
--- a/app/views/admin/registrars/_form.html.erb
+++ b/app/views/admin/registrars/_form.html.erb
@@ -1,5 +1,6 @@
<%= form_for([:admin, @registrar], html: { class: 'form-horizontal' }) do |f| %>
- <%= render 'shared/full_errors', object: @registrar %>
+ <%= render 'form_errors', target: @registrar %>
+
@@ -133,7 +134,9 @@
<%= f.label :code %>
- <%= f.text_field :code, required: f.object.new_record?, class: 'form-control', disabled: !f.object.new_record? %>
+ <%= f.text_field :code, required: f.object.new_record?,
+ disabled: f.object.persisted?,
+ class: 'form-control' %>
diff --git a/app/views/admin/registrars/show/_preferences.html.erb b/app/views/admin/registrars/_preferences.html.erb
similarity index 100%
rename from app/views/admin/registrars/show/_preferences.html.erb
rename to app/views/admin/registrars/_preferences.html.erb
diff --git a/app/views/admin/registrars/_users.html.erb b/app/views/admin/registrars/_users.html.erb
new file mode 100644
index 000000000..f182e4615
--- /dev/null
+++ b/app/views/admin/registrars/_users.html.erb
@@ -0,0 +1,28 @@
+
+
+ <%= t '.header' %>
+
+
+
+
+
+ <%= ApiUser.human_attribute_name :username %> |
+ <%= ApiUser.human_attribute_name :active %> |
+
+
+
+
+ <% registrar.api_users.each do |user| %>
+
+ <%= link_to(user, [:admin, user]) %> |
+ <%= user.active %> |
+
+ <% end %>
+
+
+
+
+
diff --git a/app/views/admin/registrars/_white_ips.html.erb b/app/views/admin/registrars/_white_ips.html.erb
new file mode 100644
index 000000000..c86c85eb9
--- /dev/null
+++ b/app/views/admin/registrars/_white_ips.html.erb
@@ -0,0 +1,38 @@
+
+
+ <%= t '.header' %>
+
+
+
+
+
+ <%= WhiteIp.human_attribute_name :ipv4 %> |
+ <%= WhiteIp.human_attribute_name :ipv6 %> |
+ <%= WhiteIp.human_attribute_name :interfaces %> |
+
+
+
+
+ <% registrar.white_ips.each do |white_ip| %>
+
+
+ <% if white_ip.ipv4.present? %>
+ <%= link_to(white_ip.ipv4, [:admin, registrar, white_ip]) %>
+ <% end %>
+ |
+
+ <% if white_ip.ipv6.present? %>
+ <%= link_to(white_ip.ipv6, [:admin, registrar, white_ip]) %>
+ <% end %>
+ |
+ <%= white_ip.interfaces.join(', ').upcase %> |
+
+ <% end %>
+
+
+
+
+
diff --git a/app/views/admin/registrars/edit.html.erb b/app/views/admin/registrars/edit.html.erb
index 71d6bd882..205ba6b28 100644
--- a/app/views/admin/registrars/edit.html.erb
+++ b/app/views/admin/registrars/edit.html.erb
@@ -1,5 +1,10 @@
-<% content_for :actions do %>
- <%= link_to(t(:back_to_registrar), [:admin, @registrar], class: 'btn btn-default') %>
-<% end %>
-<%= render 'shared/title', name: "#{t(:edit)}: #{@registrar.name}" %>
+
+ - <%= link_to t('admin.registrars.index.header'), admin_registrars_path %>
+ - <%= link_to @registrar.name, admin_registrar_path(@registrar) %>
+
+
+
+
<%= render 'form' %>
diff --git a/app/views/admin/registrars/form/_billing.html.erb b/app/views/admin/registrars/form/_billing.html.erb
index a3adf1312..c87da8b6c 100644
--- a/app/views/admin/registrars/form/_billing.html.erb
+++ b/app/views/admin/registrars/form/_billing.html.erb
@@ -17,6 +17,19 @@
+
+