diff --git a/Gemfile b/Gemfile index 8f4d88ac9..8405e0902 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,7 @@ source 'https://rubygems.org' # core gem 'rails', '4.2.5.2' # when update, all initializers eis_custom files needs check/update +gem 'rails-i18n', github: 'svenfuchs/rails-i18n', branch: 'rails-4-x' gem 'iso8601', '0.8.6' # for dates and times gem 'hashie-forbidden_attributes', '0.1.1' gem 'SyslogLogger', '2.0', require: 'syslog/logger' diff --git a/Gemfile.lock b/Gemfile.lock index b209fc763..b0143815b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -45,6 +45,15 @@ GIT bundler (~> 1.2) thor (~> 0.18) +GIT + remote: https://github.com/svenfuchs/rails-i18n.git + revision: 4913b54a5d7026066ceb12a4523476a1411e86bb + branch: rails-4-x + specs: + rails-i18n (4.0.8) + i18n (~> 0.7) + railties (~> 4.0) + GEM remote: https://rubygems.org/ specs: @@ -630,6 +639,7 @@ DEPENDENCIES que_mailer! railroady (= 1.3.0) rails (= 4.2.5.2) + rails-i18n! rails-settings-cached (= 0.4.1) rake ransack (= 1.5.1) diff --git a/app/controllers/admin/registrars_controller.rb b/app/controllers/admin/registrars_controller.rb index cf8c89505..eec50d064 100644 --- a/app/controllers/admin/registrars_controller.rb +++ b/app/controllers/admin/registrars_controller.rb @@ -57,7 +57,7 @@ class Admin::RegistrarsController < AdminController def registrar_params params.require(:registrar).permit( :name, :reg_no, :vat_no, :street, :city, :state, :zip, :billing_address, - :country_code, :email, :phone, :billing_email, :code + :country_code, :email, :phone, :billing_email, :code, :exclude_in_monthly_directo ) end end diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index 1a34965bf..daf6abc29 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -2,7 +2,6 @@ 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)') diff --git a/app/models/counter.rb b/app/models/counter.rb new file mode 100644 index 000000000..7d1c2b926 --- /dev/null +++ b/app/models/counter.rb @@ -0,0 +1,24 @@ +class Counter + def initialize value = 0 + @value = value + end + attr_accessor :value + def method_missing *args, &blk + @value.send(*args, &blk) + end + def to_s + @value.to_s + end + + def now + @value + end + + # pre-increment ".+" when x not present + def next(x = 1) + @value += x + end + def prev(x = 1) + @value -= x + end +end \ No newline at end of file diff --git a/app/models/directo.rb b/app/models/directo.rb index 66fada5d1..96d418ae0 100644 --- a/app/models/directo.rb +++ b/app/models/directo.rb @@ -1,4 +1,5 @@ class Directo < ActiveRecord::Base + DOMAIN_TO_PRODUCT = {"ee" => "01EE", "com.ee" => "02COM", "pri.ee" => "03PRI", "fie.ee"=>"04FIE", "med.ee" => "05MED"}.freeze belongs_to :item, polymorphic: true def self.send_receipts @@ -52,9 +53,119 @@ class Directo < ActiveRecord::Base 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.directo_records.create!(response: res.as_json.to_h, invoice_number: obj.number) 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 + + + def self.send_monthly_invoices + I18n.locale = :et + month = Time.now - 1.month + invoices_until = month.end_of_month + date_format = "%Y-%m-%d" + invoice_counter= Counter.new + + min_directo = Setting.invoice_number_min.presence.try(:to_i) + max_directo = Setting.directo_monthly_number_max.presence.try(:to_i) + last_directo = [Setting.directo_monthly_number_last.presence.try(:to_i), min_directo].compact.max || 0 + if max_directo && max_directo <= last_directo + raise "Directo counter is out of period" + end + + Registrar.where.not(exclude_in_monthly_directo: true).find_each do |registrar| + unless registrar.cash_account + Rails.logger.info("[DIRECTO] Monthly invoice for registrar #{registrar.id} has been skipped as it doesn't has cash_account") + next + end + counter = Counter.new(1) + items = {} + registrar_activities = AccountActivity.where(account_id: registrar.account_ids).where("created_at BETWEEN ? AND ?",month.beginning_of_month, month.end_of_month) + + # adding domains items + registrar_activities.where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]).each do |activity| + pricelist = load_activity_pricelist(activity) + unless pricelist + Rails.logger.error("[DIRECTO] Skipping activity #{activity.id} as pricelist not found") + next + end + + pricelist.years_amount.times do |i| + year = i+1 + hash = { + "ProductID" => DOMAIN_TO_PRODUCT[pricelist.category], + "Unit" => "tk", + "ProductName" => ".#{pricelist.category} registreerimine: #{pricelist.years_amount} aasta", + "UnitPriceWoVAT" => pricelist.price_decimal/pricelist.years_amount + } + hash["StartDate"] = (activity.created_at + year.year).strftime(date_format) if year > 1 + hash["EndDate"] = (activity.created_at + year.year + 1).strftime(date_format) if year > 1 + + if items.has_key?(hash) + items[hash]["Quantity"] += 1 + else + items[hash] = {"RN"=>counter.next, "RR" => counter.now - i, "Quantity"=> 1} + end + end + end + + #adding prepaiments + registrar_activities.where(activity_type: [AccountActivity::ADD_CREDIT]).each do |activity| + hash = {"ProductID" => Setting.directo_receipt_product_name, "Unit" => "tk", "ProductName" => "Domeenide ettemaks", "UnitPriceWoVAT"=>activity.sum} + items[hash] = {"RN"=>counter.next, "RR" => counter.now, "Quantity"=> -1} + end + + # generating XML + if items.any? + directo_next = last_directo + 1 + invoice_counter.next + + builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml| + xml.invoices{ + xml.invoice("Number" =>directo_next, + "InvoiceDate" =>invoices_until.strftime(date_format), + "PaymentTerm" =>"E", + "CustomerCode"=>registrar.directo_handle, + "Language" =>"", + "Currency" =>registrar_activities.first.currency, + "SalesAgent" =>Setting.directo_sales_agent){ + xml.line("RN" => 1, "RR"=>1, "ProductName"=> "Domeenide registreerimine - #{I18n.l(invoices_until, format: "%B %Y").titleize}") + items.each do |line, val| + xml.line(val.merge(line)) + 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 + Setting.directo_monthly_number_last = directo_next + Nokogiri::XML(response).css("Result").each do |res| + Directo.create!(response: res.as_json.to_h, invoice_number: directo_next) + Rails.logger.info("[DIRECTO] Invoice #{res.attributes["docid"].value} was pushed and return is #{res.as_json.to_h.inspect}") + end + else + Rails.logger.info("[DIRECTO] Registrar #{registrar.id} has nothing to be sent to Directo") + end + + end + STDOUT << "#{Time.zone.now.utc} - Directo invoices sending finished. #{invoice_counter.now} are sent\n" + end + + + def self.load_activity_pricelist activity + @pricelists ||= {} + return @pricelists[activity.log_pricelist_id] if @pricelists.has_key?(activity.log_pricelist_id) + + pricelist = Pricelist.find_by(id: activity.log_pricelist_id) || PricelistVersion.find_by(item_id: activity.log_pricelist_id).try(:reify) + unless pricelist + @pricelists[activity.log_pricelist_id] = nil + Rails.logger.info("[DIRECTO] AccountActivity #{activity.id} cannot be sent as pricelist wasn't found #{activity.log_pricelist_id}") + return + end + + @pricelists[activity.log_pricelist_id] = pricelist.version_at(activity.created_at) || pricelist + end end + diff --git a/app/models/domain.rb b/app/models/domain.rb index 9585cc27e..d52c04cd0 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -456,19 +456,14 @@ class Domain < ActiveRecord::Base period_i ||= period unit ||= period_unit + # TODO: test if name.scan(/\.(.+)\z/).first.first is faster zone = name.split('.').drop(1).join('.') p = period_i / 365 if unit == 'd' p = period_i / 12 if unit == 'm' p = period_i if unit == 'y' - if p > 1 - p = "#{p}years" - else - p = "#{p}year" - end - - Pricelist.pricelist_for(zone, operation, p) + Pricelist.pricelist_for(zone, operation, "#{p}year".pluralize(p)) end ### VALIDATIONS ### diff --git a/app/models/pricelist.rb b/app/models/pricelist.rb index 17420dfa1..d38e4290d 100644 --- a/app/models/pricelist.rb +++ b/app/models/pricelist.rb @@ -8,6 +8,8 @@ class Pricelist < ActiveRecord::Base ) } + scope :valid_at, ->(time){ where("valid_from IS NULL OR valid_from <= ?", time).where("valid_to IS NULL OR valid_to >= ?", time) } + monetize :price_cents validates :price_cents, :price_currency, :price, @@ -27,6 +29,14 @@ class Pricelist < ActiveRecord::Base "#{operation_category} #{category}" end + def years_amount + duration.to_i + end + + def price_decimal + price_cents / BigDecimal.new('100') + end + class << self def pricelist_for(zone, operation, period) lists = valid.where(category: zone, operation_category: operation, duration: period) diff --git a/app/views/admin/registrars/_form.haml b/app/views/admin/registrars/_form.haml index f00bf6a14..fbe2530d4 100644 --- a/app/views/admin/registrars/_form.haml +++ b/app/views/admin/registrars/_form.haml @@ -82,6 +82,11 @@ = f.label :code .col-md-7 = f.text_field(:code, class: 'form-control', disabled: !f.object.new_record?) + .form-group + .col-md-4.control-label + = f.label :exclude_in_monthly_directo + .col-md-7 + = f.check_box :exclude_in_monthly_directo, class: 'form-control' %hr .row diff --git a/app/views/admin/settings/index.haml b/app/views/admin/settings/index.haml index 863d197d0..6c7e3d74c 100644 --- a/app/views/admin/settings/index.haml +++ b/app/views/admin/settings/index.haml @@ -69,6 +69,9 @@ %tbody = render 'setting_row', var: :invoice_number_min = render 'setting_row', var: :invoice_number_max + = render 'setting_row', var: :directo_monthly_number_min + = render 'setting_row', var: :directo_monthly_number_max + = render 'setting_row', var: :directo_monthly_number_last = 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 diff --git a/config/initializers/initial_settings.rb b/config/initializers/initial_settings.rb index eb333943f..b6a60c5e8 100644 --- a/config/initializers/initial_settings.rb +++ b/config/initializers/initial_settings.rb @@ -32,6 +32,9 @@ if con.present? && con.table_exists?('settings') Setting.save_default(:invoice_number_min, 131050) Setting.save_default(:invoice_number_max, 149999) + Setting.save_default(:directo_monthly_number_min, 309901) + Setting.save_default(:directo_monthly_number_max, 309999) + Setting.save_default(:directo_monthly_number_last, 309901) Setting.save_default(:days_to_keep_invoices_active, 30) Setting.save_default(:days_to_keep_overdue_invoices_active, 30) Setting.save_default(:minimum_deposit, 0.0) diff --git a/db/migrate/20160304125933_add_invoice_number_to_directo.rb b/db/migrate/20160304125933_add_invoice_number_to_directo.rb new file mode 100644 index 000000000..e639e8910 --- /dev/null +++ b/db/migrate/20160304125933_add_invoice_number_to_directo.rb @@ -0,0 +1,6 @@ +class AddInvoiceNumberToDirecto < ActiveRecord::Migration + def change + add_column :directos, :invoice_number, :string + execute "UPDATE directos d SET invoice_number=i.number FROM invoices i WHERE d.item_type='Invoice' AND d.item_id=i.id" + end +end diff --git a/db/migrate/20160311085956_add_exclude_monthly_directo_to_registrar.rb b/db/migrate/20160311085956_add_exclude_monthly_directo_to_registrar.rb new file mode 100644 index 000000000..c6ae4d31b --- /dev/null +++ b/db/migrate/20160311085956_add_exclude_monthly_directo_to_registrar.rb @@ -0,0 +1,5 @@ +class AddExcludeMonthlyDirectoToRegistrar < ActiveRecord::Migration + def change + add_column :registrars, :exclude_in_monthly_directo, :boolean, default: false + end +end diff --git a/db/schema-read-only.rb b/db/schema-read-only.rb index 78722223a..2d410461c 100644 --- a/db/schema-read-only.rb +++ b/db/schema-read-only.rb @@ -11,11 +11,12 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160108135436) do +ActiveRecord::Schema.define(version: 20160304125933) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "hstore" + enable_extension "btree_gist" create_table "account_activities", force: :cascade do |t| t.integer "account_id" @@ -108,6 +109,7 @@ ActiveRecord::Schema.define(version: 20160108135436) do t.datetime "updated_at" t.string "creator_str" t.string "updator_str" + t.boolean "in_directo", default: false end create_table "banklink_transactions", force: :cascade do |t| @@ -144,6 +146,17 @@ ActiveRecord::Schema.define(version: 20160108135436) do add_index "blocked_domains", ["name"], name: "index_blocked_domains_on_name", using: :btree + create_table "business_registry_caches", force: :cascade do |t| + t.string "ident" + t.string "ident_country_code" + t.datetime "retrieved_on" + t.string "associated_businesses", array: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "business_registry_caches", ["ident"], name: "index_business_registry_caches_on_ident", using: :btree + create_table "cached_nameservers", id: false, force: :cascade do |t| t.string "hostname", limit: 255 t.string "ipv4", limit: 255 @@ -241,6 +254,17 @@ ActiveRecord::Schema.define(version: 20160108135436) do t.datetime "created_at" end + create_table "directos", force: :cascade do |t| + t.integer "item_id" + t.string "item_type" + t.json "response" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "invoice_number" + end + + add_index "directos", ["item_type", "item_id"], name: "index_directos_on_item_type_and_item_id", using: :btree + create_table "dnskeys", force: :cascade do |t| t.integer "domain_id" t.integer "flags" @@ -345,6 +369,7 @@ ActiveRecord::Schema.define(version: 20160108135436) do add_index "domains", ["registrant_verification_asked_at"], name: "index_domains_on_registrant_verification_asked_at", using: :btree add_index "domains", ["registrant_verification_token"], name: "index_domains_on_registrant_verification_token", using: :btree add_index "domains", ["registrar_id"], name: "index_domains_on_registrar_id", using: :btree + add_index "domains", ["statuses"], name: "index_domains_on_statuses", using: :gin create_table "epp_sessions", force: :cascade do |t| t.string "session_id" @@ -372,20 +397,20 @@ ActiveRecord::Schema.define(version: 20160108135436) do add_index "invoice_items", ["invoice_id"], name: "index_invoice_items_on_invoice_id", using: :btree create_table "invoices", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "invoice_type", null: false - t.datetime "due_date", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "invoice_type", null: false + t.datetime "due_date", null: false t.string "payment_term" - t.string "currency", null: false + t.string "currency", null: false t.string "description" t.string "reference_no" - t.decimal "vat_prc", precision: 10, scale: 2, null: false + t.decimal "vat_prc", precision: 10, scale: 2, null: false t.datetime "paid_at" t.integer "seller_id" - t.string "seller_name", null: false + t.string "seller_name", null: false t.string "seller_reg_no" - t.string "seller_iban", null: false + t.string "seller_iban", null: false t.string "seller_bank" t.string "seller_swift" t.string "seller_vat_no" @@ -399,7 +424,7 @@ ActiveRecord::Schema.define(version: 20160108135436) do t.string "seller_email" t.string "seller_contact_name" t.integer "buyer_id" - t.string "buyer_name", null: false + t.string "buyer_name", null: false t.string "buyer_reg_no" t.string "buyer_country_code" t.string "buyer_state" @@ -414,6 +439,7 @@ ActiveRecord::Schema.define(version: 20160108135436) do t.integer "number" t.datetime "cancelled_at" t.decimal "sum_cache", precision: 10, scale: 2 + t.boolean "in_directo", default: false end add_index "invoices", ["buyer_id"], name: "index_invoices_on_buyer_id", using: :btree @@ -592,7 +618,7 @@ ActiveRecord::Schema.define(version: 20160108135436) do t.integer "item_id", null: false t.string "event", null: false t.string "whodunnit" - t.json "object" + t.jsonb "object" t.json "object_changes" t.datetime "created_at" t.string "session" @@ -623,7 +649,7 @@ ActiveRecord::Schema.define(version: 20160108135436) do t.integer "item_id", null: false t.string "event", null: false t.string "whodunnit" - t.json "object" + t.jsonb "object" t.json "object_changes" t.datetime "created_at" t.string "session" @@ -683,7 +709,7 @@ ActiveRecord::Schema.define(version: 20160108135436) do t.integer "item_id", null: false t.string "event", null: false t.string "whodunnit" - t.json "object" + t.jsonb "object" t.json "object_changes" t.datetime "created_at" t.text "nameserver_ids", default: [], array: true @@ -761,7 +787,7 @@ ActiveRecord::Schema.define(version: 20160108135436) do t.integer "item_id", null: false t.string "event", null: false t.string "whodunnit" - t.json "object" + t.jsonb "object" t.json "object_changes" t.datetime "created_at" t.string "session" @@ -897,10 +923,10 @@ ActiveRecord::Schema.define(version: 20160108135436) do create_table "nameservers", force: :cascade do |t| t.string "hostname" - t.string "ipv4", default: [], array: true + t.string "ipv4", array: true t.datetime "created_at" t.datetime "updated_at" - t.string "ipv6", default: [], array: true + t.string "ipv6", array: true t.integer "domain_id" t.string "creator_str" t.string "updator_str" @@ -992,6 +1018,7 @@ ActiveRecord::Schema.define(version: 20160108135436) do end add_index "registrars", ["code"], name: "index_registrars_on_code", using: :btree + add_index "registrars", ["legacy_id"], name: "index_registrars_on_legacy_id", using: :btree create_table "reserved_domains", force: :cascade do |t| t.datetime "created_at" diff --git a/db/structure.sql b/db/structure.sql index cf413eff1..78228b693 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -23,6 +23,20 @@ CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; +-- +-- Name: btree_gist; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS btree_gist WITH SCHEMA public; + + +-- +-- Name: EXTENSION btree_gist; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION btree_gist IS 'support for indexing common datatypes in GiST'; + + -- -- Name: hstore; Type: EXTENSION; Schema: -; Owner: - -- @@ -39,140 +53,6 @@ COMMENT ON EXTENSION hstore IS 'data type for storing sets of (key, value) pairs SET search_path = public, pg_catalog; --- --- Name: change_ident_country(); Type: FUNCTION; Schema: public; Owner: - --- - -CREATE FUNCTION change_ident_country() RETURNS boolean - LANGUAGE plpgsql - AS $_$ -DECLARE - changed BOOLEAN; - multiplier INT []; - multiplier2 INT []; - multiplier3 INT []; - multiplier4 INT []; - r RECORD; - control TEXT; - total INT; - i INT; - mod INT; - counter INT; -BEGIN - - multiplier := ARRAY [1, 2, 3, 4, 5, 6, 7, 8, 9, 1]; - - multiplier2 := ARRAY [3, 4, 5, 6, 7, 8, 9, 1, 2, 3]; - - multiplier3 := ARRAY [1, 2, 3, 4, 5, 6, 7]; - - multiplier4 := ARRAY [3, 4, 5, 6, 7, 8, 9]; - - FOR r IN SELECT id, ident FROM contacts WHERE ident_type = 'priv' /*AND ident_country_code IS NULL*/ - LOOP - IF (length(r.ident) = 11 AND (r.ident ~ '^[0-9]+$') AND (substring(r.ident, 1, 1) = '3' OR substring(r.ident, 1, 1) = '4' OR substring(r.ident, 1, 1) = '5' OR substring(r.ident, 1, 1) = '6')) - THEN - total := 0; - counter := 1; - FOREACH i IN ARRAY multiplier - LOOP - total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); - counter := (counter + 1); - END LOOP; - mod := (total % 11); - counter := 1; - - IF (mod >= 10) - THEN - total = 0; - FOREACH i IN ARRAY multiplier2 - LOOP - total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); - counter := (counter + 1); - END LOOP; - mod := (total % 11); - END IF; - - IF (mod < 10 AND substring(r.ident, 11, 1) = to_char(mod, 'FM999MI')) - THEN - UPDATE contacts SET ident_country_code = 'EE' WHERE id = r.id; - END IF; - total = 0; - END IF; - END LOOP; - - FOR r IN SELECT id, ident FROM contacts WHERE ident_type = 'org' - LOOP - IF (length(r.ident) = 8 AND (r.ident ~ '^[0-9]+$') AND (substring(r.ident, 1, 1) = '1' OR substring(r.ident, 1, 1) = '8' OR substring(r.ident, 1, 1) = '9')) - THEN - total := 0; - counter := 1; - FOREACH i IN ARRAY multiplier3 - LOOP - total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); - counter := (counter + 1); - END LOOP; - mod := total % 11; - total = 0; - counter := 1; - - IF (mod >= 10) - THEN - total = 0; - FOREACH i IN ARRAY multiplier4 - LOOP - total := (total + (i * to_number(substring(r.ident, counter, 1), '9'))); - counter := (counter + 1); - END LOOP; - mod := (total % 11); - END IF; - - IF (mod < 10 AND (substring(r.ident, 8, 1) = to_char(mod, 'FM999MI'))) - THEN - UPDATE contacts SET ident_country_code = 'EE' WHERE id = r.id; - END IF; - END IF; - END LOOP; - - - - RETURN changed; -END; -$_$; - - --- --- Name: change_ident_country(integer, text); Type: FUNCTION; Schema: public; Owner: - --- - -CREATE FUNCTION change_ident_country(id integer, type text) RETURNS boolean - LANGUAGE plpgsql - AS $_$ -DECLARE - changed BOOLEAN; - multiplier int[]; - multiplier2 int[]; - code int; -BEGIN - - multiplier := ARRAY[1, 2, 3, 4, 5, 6, 7, 8, 9, 1]; - - multiplier2 := ARRAY[3, 4, 5, 6, 7, 8, 9, 1, 2, 3]; - - code := (SELECT code FROM contacts WHERE id = 208 AND ident_country_code = 'EE'); - - - - UPDATE contacts - SET ident = '' - WHERE id = $1 and ident_type = $2 AND ident_country_code = 'EE' - AND ident = ''; - - RETURN changed; -END; -$_$; - - -- -- Name: fill_ident_country(); Type: FUNCTION; Schema: public; Owner: - -- @@ -222,12 +102,10 @@ CREATE FUNCTION fill_ident_country() RETURNS boolean END LOOP; mod := (total % 11); END IF; - IF (mod = 10) THEN mod := 0; END IF; - IF (substring(r.ident, 11, 1) = to_char(mod, 'FM999MI')) THEN UPDATE contacts SET ident_country_code = 'EE' WHERE id = r.id; @@ -291,7 +169,7 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text ret text; BEGIN -- define filters - include_filter = '%' || i_origin; + include_filter = '%.' || i_origin; -- for %.%.% IF i_origin ~ '\.' THEN @@ -318,6 +196,10 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text ret = concat(tmp_var, chr(10), chr(10)); + -- origin ns records + SELECT ns_records FROM zonefile_settings zf WHERE i_origin = zf.origin INTO tmp_var; + ret := concat(ret, '; Zone NS Records', chr(10), tmp_var, chr(10)); + -- ns records SELECT array_to_string( array( @@ -325,26 +207,17 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text FROM domains d JOIN nameservers ns ON ns.domain_id = d.id WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND NOT ('{serverHold,clientHold}' && d.statuses) ORDER BY d.name ), chr(10) ) INTO tmp_var; - ret := concat(ret, '; Zone NS Records', chr(10), tmp_var, chr(10), chr(10)); + ret := concat(ret, tmp_var, chr(10), chr(10)); - -- a glue records for origin nameservers - SELECT array_to_string( - array( - SELECT concat(ns.hostname, '. IN A ', ns.ipv4) - FROM nameservers ns - JOIN domains d ON d.id = ns.domain_id - WHERE d.name = i_origin - AND ns.hostname LIKE '%.' || d.name - AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '' - ), chr(10) - ) INTO tmp_var; - - ret := concat(ret, '; Zone A Records', chr(10), tmp_var); + -- origin a glue records + SELECT a_records FROM zonefile_settings zf WHERE i_origin = zf.origin INTO tmp_var; + ret := concat(ret, '; Zone A Records', chr(10), tmp_var, chr(10)); -- a glue records for other nameservers SELECT array_to_string( @@ -355,44 +228,16 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter AND ns.hostname LIKE '%.' || d.name AND d.name <> i_origin - AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '' - AND NOT EXISTS ( -- filter out glue records that already appeared in origin glue recrods - SELECT 1 FROM nameservers nsi - JOIN domains di ON nsi.domain_id = di.id - WHERE di.name = i_origin - AND nsi.hostname = ns.hostname - ) + AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '{}' + AND NOT ('{serverHold,clientHold}' && d.statuses) ), chr(10) ) INTO tmp_var; - -- TODO This is a possible subtitition to the previous query, stress testing is needed to see which is faster + ret := concat(ret, tmp_var, chr(10), chr(10)); - -- SELECT ns.* - -- FROM nameservers ns - -- JOIN domains d ON d.id = ns.domain_id - -- WHERE d.name LIKE '%ee' AND d.name NOT LIKE '%pri.ee' - -- AND ns.hostname LIKE '%.' || d.name - -- AND d.name <> 'ee' - -- AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '' - -- AND ns.hostname NOT IN ( - -- SELECT ns.hostname FROM domains d JOIN nameservers ns ON d.id = ns.domain_id WHERE d.name = 'ee' - -- ) - - ret := concat(ret, chr(10), tmp_var, chr(10), chr(10)); - - -- aaaa glue records for origin nameservers - SELECT array_to_string( - array( - SELECT concat(ns.hostname, '. IN AAAA ', ns.ipv6) - FROM nameservers ns - JOIN domains d ON d.id = ns.domain_id - WHERE d.name = i_origin - AND ns.hostname LIKE '%.' || d.name - AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '' - ), chr(10) - ) INTO tmp_var; - - ret := concat(ret, '; Zone AAAA Records', chr(10), tmp_var); + -- origin aaaa glue records + SELECT a4_records FROM zonefile_settings zf WHERE i_origin = zf.origin INTO tmp_var; + ret := concat(ret, '; Zone AAAA Records', chr(10), tmp_var, chr(10)); -- aaaa glue records for other nameservers SELECT array_to_string( @@ -403,17 +248,12 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter AND ns.hostname LIKE '%.' || d.name AND d.name <> i_origin - AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '' - AND NOT EXISTS ( -- filter out glue records that already appeared in origin glue recrods - SELECT 1 FROM nameservers nsi - JOIN domains di ON nsi.domain_id = di.id - WHERE di.name = i_origin - AND nsi.hostname = ns.hostname - ) + AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '{}' + AND NOT ('{serverHold,clientHold}' && d.statuses) ), chr(10) ) INTO tmp_var; - ret := concat(ret, chr(10), tmp_var, chr(10), chr(10)); + ret := concat(ret, tmp_var, chr(10), chr(10)); -- ds records SELECT array_to_string( @@ -424,7 +264,8 @@ CREATE FUNCTION generate_zonefile(i_origin character varying) RETURNS text ) FROM domains d JOIN dnskeys dk ON dk.domain_id = d.id - WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter AND dk.flags = 257 + AND NOT ('{serverHold,clientHold}' && d.statuses) ), chr(10) ) INTO tmp_var; @@ -652,7 +493,8 @@ CREATE TABLE bank_transactions ( created_at timestamp without time zone, updated_at timestamp without time zone, creator_str character varying, - updator_str character varying + updator_str character varying, + in_directo boolean DEFAULT false ); @@ -757,6 +599,40 @@ CREATE SEQUENCE blocked_domains_id_seq ALTER SEQUENCE blocked_domains_id_seq OWNED BY blocked_domains.id; +-- +-- Name: business_registry_caches; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE business_registry_caches ( + id integer NOT NULL, + ident character varying, + ident_country_code character varying, + retrieved_on timestamp without time zone, + associated_businesses character varying[], + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: business_registry_caches_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE business_registry_caches_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: business_registry_caches_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE business_registry_caches_id_seq OWNED BY business_registry_caches.id; + + -- -- Name: cached_nameservers; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -1000,6 +876,40 @@ CREATE SEQUENCE depricated_versions_id_seq ALTER SEQUENCE depricated_versions_id_seq OWNED BY depricated_versions.id; +-- +-- Name: directos; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE directos ( + id integer NOT NULL, + item_id integer, + item_type character varying, + response json, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + invoice_number character varying +); + + +-- +-- Name: directos_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE directos_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: directos_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE directos_id_seq OWNED BY directos.id; + + -- -- Name: dnskeys; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -1328,7 +1238,8 @@ CREATE TABLE invoices ( updator_str character varying, number integer, cancelled_at timestamp without time zone, - sum_cache numeric(10,2) + sum_cache numeric(10,2), + in_directo boolean DEFAULT false ); @@ -1771,7 +1682,7 @@ CREATE TABLE log_contacts ( item_id integer NOT NULL, event character varying NOT NULL, whodunnit character varying, - object json, + object jsonb, object_changes json, created_at timestamp without time zone, session character varying, @@ -1846,7 +1757,7 @@ CREATE TABLE log_dnskeys ( item_id integer NOT NULL, event character varying NOT NULL, whodunnit character varying, - object json, + object jsonb, object_changes json, created_at timestamp without time zone, session character varying, @@ -1994,7 +1905,7 @@ CREATE TABLE log_domains ( item_id integer NOT NULL, event character varying NOT NULL, whodunnit character varying, - object json, + object jsonb, object_changes json, created_at timestamp without time zone, nameserver_ids text[] DEFAULT '{}'::text[], @@ -2182,7 +2093,7 @@ CREATE TABLE log_nameservers ( item_id integer NOT NULL, event character varying NOT NULL, whodunnit character varying, - object json, + object jsonb, object_changes json, created_at timestamp without time zone, session character varying, @@ -2548,10 +2459,10 @@ ALTER SEQUENCE messages_id_seq OWNED BY messages.id; CREATE TABLE nameservers ( id integer NOT NULL, hostname character varying, - ipv4 character varying[] DEFAULT '{}'::character varying[], + ipv4 character varying[], created_at timestamp without time zone, updated_at timestamp without time zone, - ipv6 character varying[] DEFAULT '{}'::character varying[], + ipv6 character varying[], domain_id integer, creator_str character varying, updator_str character varying, @@ -3118,6 +3029,13 @@ ALTER TABLE ONLY banklink_transactions ALTER COLUMN id SET DEFAULT nextval('bank ALTER TABLE ONLY blocked_domains ALTER COLUMN id SET DEFAULT nextval('blocked_domains_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY business_registry_caches ALTER COLUMN id SET DEFAULT nextval('business_registry_caches_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3160,6 +3078,13 @@ ALTER TABLE ONLY delegation_signers ALTER COLUMN id SET DEFAULT nextval('delegat ALTER TABLE ONLY depricated_versions ALTER COLUMN id SET DEFAULT nextval('depricated_versions_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY directos ALTER COLUMN id SET DEFAULT nextval('directos_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3595,6 +3520,14 @@ ALTER TABLE ONLY blocked_domains ADD CONSTRAINT blocked_domains_pkey PRIMARY KEY (id); +-- +-- Name: business_registry_caches_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY business_registry_caches + ADD CONSTRAINT business_registry_caches_pkey PRIMARY KEY (id); + + -- -- Name: certificates_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -3643,6 +3576,14 @@ ALTER TABLE ONLY depricated_versions ADD CONSTRAINT depricated_versions_pkey PRIMARY KEY (id); +-- +-- Name: directos_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY directos + ADD CONSTRAINT directos_pkey PRIMARY KEY (id); + + -- -- Name: dnskeys_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -4109,6 +4050,13 @@ CREATE INDEX index_api_users_on_registrar_id ON api_users USING btree (registrar CREATE INDEX index_blocked_domains_on_name ON blocked_domains USING btree (name); +-- +-- Name: index_business_registry_caches_on_ident; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_business_registry_caches_on_ident ON business_registry_caches USING btree (ident); + + -- -- Name: index_cached_nameservers_on_hostname_and_ipv4_and_ipv6; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -4158,6 +4106,13 @@ CREATE INDEX index_contacts_on_registrar_id_and_ident_type ON contacts USING btr CREATE INDEX index_delegation_signers_on_domain_id ON delegation_signers USING btree (domain_id); +-- +-- Name: index_directos_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_directos_on_item_type_and_item_id ON directos USING btree (item_type, item_id); + + -- -- Name: index_dnskeys_on_delegation_signer_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -4256,6 +4211,13 @@ CREATE INDEX index_domains_on_registrant_verification_token ON domains USING btr CREATE INDEX index_domains_on_registrar_id ON domains USING btree (registrar_id); +-- +-- Name: index_domains_on_statuses; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_domains_on_statuses ON domains USING gin (statuses); + + -- -- Name: index_epp_sessions_on_session_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -4732,6 +4694,13 @@ CREATE INDEX index_registrant_verifications_on_domain_id ON registrant_verificat CREATE INDEX index_registrars_on_code ON registrars USING btree (code); +-- +-- Name: index_registrars_on_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_registrars_on_legacy_id ON registrars USING btree (legacy_id); + + -- -- Name: index_reserved_domains_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -4774,6 +4743,41 @@ CREATE INDEX index_whois_records_on_domain_id ON whois_records USING btree (doma CREATE INDEX index_whois_records_on_registrar_id ON whois_records USING btree (registrar_id); +-- +-- Name: log_contacts_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX log_contacts_object_legacy_id ON log_contacts USING btree ((((object ->> 'legacy_id'::text))::integer)); + + +-- +-- Name: log_contacts_object_legacy_id1; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX log_contacts_object_legacy_id1 ON log_contacts USING btree ((((object ->> 'legacy_id'::text))::integer)); + + +-- +-- Name: log_dnskeys_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX log_dnskeys_object_legacy_id ON log_contacts USING btree ((((object ->> 'legacy_domain_id'::text))::integer)); + + +-- +-- Name: log_domains_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX log_domains_object_legacy_id ON log_contacts USING btree ((((object ->> 'legacy_id'::text))::integer)); + + +-- +-- Name: log_nameservers_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX log_nameservers_object_legacy_id ON log_contacts USING btree ((((object ->> 'legacy_domain_id'::text))::integer)); + + -- -- Name: unique_data_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace: -- @@ -5196,7 +5200,19 @@ INSERT INTO schema_migrations (version) VALUES ('20151130175654'); INSERT INTO schema_migrations (version) VALUES ('20151202123506'); -INSERT INTO schema_migrations (version) VALUES ('20160106092052'); +INSERT INTO schema_migrations (version) VALUES ('20151209122816'); + +INSERT INTO schema_migrations (version) VALUES ('20160106101725'); INSERT INTO schema_migrations (version) VALUES ('20160108135436'); +INSERT INTO schema_migrations (version) VALUES ('20160113143447'); + +INSERT INTO schema_migrations (version) VALUES ('20160118092453'); + +INSERT INTO schema_migrations (version) VALUES ('20160118092454'); + +INSERT INTO schema_migrations (version) VALUES ('20160218102355'); + +INSERT INTO schema_migrations (version) VALUES ('20160304125933'); +