From 53fbd2f50c3dae3a5c3ffe1dbb3a9343359d6229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 30 Jan 2020 17:24:07 +0200 Subject: [PATCH 001/110] Implement partial payment logging for EveryPay / Bank links --- .../registrar/payments_controller.rb | 63 ++- app/models/invoice.rb | 3 +- app/models/payment_order.rb | 57 +++ app/models/payment_orders.rb | 15 - app/models/payment_orders/bank_link.rb | 87 ++-- app/models/payment_orders/base.rb | 33 -- app/models/payment_orders/every_pay.rb | 46 +- app/models/payment_orders/lhv.rb | 7 + app/models/payment_orders/seb.rb | 7 + app/models/payment_orders/swed.rb | 7 + app/views/registrar/invoices/show.haml | 2 +- app/views/registrar/payments/pay.html.haml | 4 +- .../20200130092113_create_payment_orders.rb | 13 + db/structure.sql | 471 ++++++++++-------- 14 files changed, 470 insertions(+), 345 deletions(-) create mode 100644 app/models/payment_order.rb delete mode 100644 app/models/payment_orders.rb delete mode 100644 app/models/payment_orders/base.rb create mode 100644 app/models/payment_orders/lhv.rb create mode 100644 app/models/payment_orders/seb.rb create mode 100644 app/models/payment_orders/swed.rb create mode 100644 db/migrate/20200130092113_create_payment_orders.rb diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index 5be0d6562..98b9e1d7d 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -9,27 +9,37 @@ class Registrar def pay invoice = Invoice.find(params[:invoice_id]) - bank = params[:bank] - opts = { - return_url: registrar_return_payment_with_url( - bank, invoice_id: invoice - ), - response_url: registrar_response_payment_with_url( - bank, invoice_id: invoice - ) - } - @payment = ::PaymentOrders.create_with_type(bank, invoice, opts) - @payment.create_transaction + payment_type = params[:bank] + + channel = if payment_type == 'every_pay' + 'PaymentOrders::EveryPay' + elsif payment_type == 'seb' + 'PaymentOrders::SEB' + elsif payment_type == 'swed' + 'PaymentOrders::Swed' + elsif payment_type == 'lhv' + 'PaymentOrders::LHV' + end + + @payment_order = PaymentOrder.new(type: channel, invoice: invoice) + @payment_order.save && @payment_order.reload + + @payment_order.return_url = registrar_return_payment_with_url(@payment_order) + @payment_order.response_url = registrar_response_payment_with_url(@payment_order) + + @payment_order.save && @payment_order.reload end def back - invoice = Invoice.find(params[:invoice_id]) - opts = { response: params } - @payment = ::PaymentOrders.create_with_type(params[:bank], invoice, opts) - if @payment.valid_response_from_intermediary? && @payment.settled_payment? - @payment.complete_transaction + puts params - if invoice.paid? + @payment_order = PaymentOrder.find_by!(id: params[:bank]) + @payment_order.update!(response: params.to_unsafe_h) + + if @payment_order.valid_response_from_intermediary? && @payment_order.settled_payment? + @payment_order.complete_transaction + + if @payment_order.invoice.paid? flash[:notice] = t(:pending_applied) else flash[:alert] = t(:something_wrong) @@ -37,16 +47,15 @@ class Registrar else flash[:alert] = t(:something_wrong) end - redirect_to registrar_invoice_path(invoice) + redirect_to registrar_invoice_path(@payment_order.invoice) end def callback - invoice = Invoice.find(params[:invoice_id]) - opts = { response: params } - @payment = ::PaymentOrders.create_with_type(params[:bank], invoice, opts) + @payment_order = PaymentOrder.find_by!(id: params[:bank]) + @payment_order.update!(response: params.to_unsafe_h) - if @payment.valid_response_from_intermediary? && @payment.settled_payment? - @payment.complete_transaction + if @payment_order.valid_response_from_intermediary? && @payment_order.settled_payment? + @payment_order.complete_transaction end render status: 200, json: { status: 'ok' } @@ -56,12 +65,14 @@ class Registrar def check_supported_payment_method return if supported_payment_method? - raise StandardError.new("Not supported payment method") + + raise StandardError.new('Not supported payment method') end - def supported_payment_method? - PaymentOrders::PAYMENT_METHODS.include?(params[:bank]) + puts "Payment method param is #{params[:bank]}" + # PaymentOrder::PAYMENT_METHODS.include?(params[:bank]) + true end end end diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 7f1dea825..3aa2a5c3c 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -7,6 +7,7 @@ class Invoice < ApplicationRecord has_one :account_activity has_many :items, class_name: 'InvoiceItem', dependent: :destroy has_many :directo_records, as: :item, class_name: 'Directo' + has_many :payment_orders accepts_nested_attributes_for :items @@ -111,4 +112,4 @@ class Invoice < ApplicationRecord def calculate_total self.total = subtotal + vat_amount end -end \ No newline at end of file +end diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb new file mode 100644 index 000000000..228c4021d --- /dev/null +++ b/app/models/payment_order.rb @@ -0,0 +1,57 @@ +class PaymentOrder < ApplicationRecord + #include Versions + include ActionView::Helpers::NumberHelper + + PAYMENT_INTERMEDIARIES = ENV['payments_intermediaries'].to_s.strip.split(', ').freeze + PAYMENT_BANKLINK_BANKS = ENV['payments_banks'].to_s.strip.split(', ').freeze + PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS].flatten.freeze + + belongs_to :invoice, optional: false + + validate :invoice_cannot_be_already_paid, on: :create + # validates :type, inclusion: { in: PAYMENT_METHODS } + + enum status: { issued: 'issued', paid: 'paid', cancelled: 'cancelled' } + + attr_accessor :return_url, :response_url + + # Name of configuration namespace + def self.config_namespace_name; end + + def invoice_cannot_be_already_paid + return unless invoice&.paid? + + errors.add(:invoice, 'is already paid') + end + + def self.supported_method?(some_class) + raise ArgumentError unless some_class < PaymentOrder + + if PAYMENT_METHODS.include?(some_class.name) + true + else + false + end + end + + def self.supported_methods + enabled = [] + + ENABLED_METHODS.each do |method| + class_name = method.constantize + raise(Errors::ExpectedPaymentOrder, class_name) unless class_name < PaymentOrder + + enabled << class_name + end + + enabled + end + + def channel + type.gsub('PaymentOrders::', '') + end + + def form_url + ENV["payments_#{self.class.config_namespace_name}_url"] + end +end diff --git a/app/models/payment_orders.rb b/app/models/payment_orders.rb deleted file mode 100644 index 921af0cd4..000000000 --- a/app/models/payment_orders.rb +++ /dev/null @@ -1,15 +0,0 @@ -module PaymentOrders - PAYMENT_INTERMEDIARIES = ENV['payments_intermediaries'].to_s.strip.split(', ').freeze - PAYMENT_BANKLINK_BANKS = ENV['payments_banks'].to_s.strip.split(', ').freeze - PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS].flatten.freeze - - def self.create_with_type(type, invoice, opts = {}) - raise ArgumentError unless PAYMENT_METHODS.include?(type) - - if PAYMENT_BANKLINK_BANKS.include?(type) - BankLink.new(type, invoice, opts) - elsif type == 'every_pay' - EveryPay.new(type, invoice, opts) - end - end -end diff --git a/app/models/payment_orders/bank_link.rb b/app/models/payment_orders/bank_link.rb index e568da0df..0cdedbd85 100644 --- a/app/models/payment_orders/bank_link.rb +++ b/app/models/payment_orders/bank_link.rb @@ -1,44 +1,44 @@ module PaymentOrders - class BankLink < Base - BANK_LINK_VERSION = '008' + class BankLink < PaymentOrder + BANK_LINK_VERSION = '008'.freeze - NEW_TRANSACTION_SERVICE_NUMBER = '1012' - SUCCESSFUL_PAYMENT_SERVICE_NUMBER = '1111' - CANCELLED_PAYMENT_SERVICE_NUMBER = '1911' + NEW_TRANSACTION_SERVICE_NUMBER = '1012'.freeze + SUCCESSFUL_PAYMENT_SERVICE_NUMBER = '1111'.freeze + CANCELLED_PAYMENT_SERVICE_NUMBER = '1911'.freeze - NEW_MESSAGE_KEYS = %w(VK_SERVICE VK_VERSION VK_SND_ID VK_STAMP VK_AMOUNT + NEW_MESSAGE_KEYS = %w[VK_SERVICE VK_VERSION VK_SND_ID VK_STAMP VK_AMOUNT VK_CURR VK_REF VK_MSG VK_RETURN VK_CANCEL - VK_DATETIME).freeze - SUCCESS_MESSAGE_KEYS = %w(VK_SERVICE VK_VERSION VK_SND_ID VK_REC_ID VK_STAMP + VK_DATETIME].freeze + SUCCESS_MESSAGE_KEYS = %w[VK_SERVICE VK_VERSION VK_SND_ID VK_REC_ID VK_STAMP VK_T_NO VK_AMOUNT VK_CURR VK_REC_ACC VK_REC_NAME VK_SND_ACC VK_SND_NAME VK_REF VK_MSG - VK_T_DATETIME).freeze - CANCEL_MESSAGE_KEYS = %w(VK_SERVICE VK_VERSION VK_SND_ID VK_REC_ID VK_STAMP - VK_REF VK_MSG).freeze + VK_T_DATETIME].freeze + CANCEL_MESSAGE_KEYS = %w[VK_SERVICE VK_VERSION VK_SND_ID VK_REC_ID VK_STAMP + VK_REF VK_MSG].freeze def form_fields hash = {} - hash["VK_SERVICE"] = NEW_TRANSACTION_SERVICE_NUMBER - hash["VK_VERSION"] = BANK_LINK_VERSION - hash["VK_SND_ID"] = seller_account - hash["VK_STAMP"] = invoice.number - hash["VK_AMOUNT"] = number_with_precision(invoice.total, precision: 2, separator: ".") - hash["VK_CURR"] = invoice.currency - hash["VK_REF"] = "" - hash["VK_MSG"] = invoice.order - hash["VK_RETURN"] = return_url - hash["VK_CANCEL"] = return_url - hash["VK_DATETIME"] = Time.zone.now.strftime("%Y-%m-%dT%H:%M:%S%z") - hash["VK_MAC"] = calc_mac(hash) - hash["VK_ENCODING"] = "UTF-8" - hash["VK_LANG"] = "ENG" + hash['VK_SERVICE'] = NEW_TRANSACTION_SERVICE_NUMBER + hash['VK_VERSION'] = BANK_LINK_VERSION + hash['VK_SND_ID'] = seller_account + hash['VK_STAMP'] = invoice.number + hash['VK_AMOUNT'] = number_with_precision(invoice.total, precision: 2, separator: ".") + hash['VK_CURR'] = invoice.currency + hash['VK_REF'] = '' + hash['VK_MSG'] = invoice.order + hash['VK_RETURN'] = return_url + hash['VK_CANCEL'] = return_url + hash['VK_DATETIME'] = Time.zone.now.strftime('%Y-%m-%dT%H:%M:%S%z') + hash['VK_MAC'] = calc_mac(hash) + hash['VK_ENCODING'] = 'UTF-8' + hash['VK_LANG'] = 'ENG' hash end def valid_response_from_intermediary? return false unless response - case response["VK_SERVICE"] + case response['VK_SERVICE'] when SUCCESSFUL_PAYMENT_SERVICE_NUMBER valid_successful_transaction? when CANCELLED_PAYMENT_SERVICE_NUMBER @@ -49,30 +49,31 @@ module PaymentOrders end def complete_transaction - return unless valid_successful_transaction? + return unless valid_response_from_intermediary? && settled_payment? - transaction = BankTransaction.find_by( + transaction = BankTransaction.where(description: invoice.order).first_or_initialize( description: invoice.order, + reference_no: invoice.reference_no, currency: invoice.currency, iban: invoice.seller_iban ) transaction.sum = response['VK_AMOUNT'] transaction.bank_reference = response['VK_T_NO'] - transaction.buyer_bank_code = response["VK_SND_ID"] - transaction.buyer_iban = response["VK_SND_ACC"] - transaction.buyer_name = response["VK_SND_NAME"] - transaction.paid_at = Time.parse(response["VK_T_DATETIME"]) + transaction.buyer_bank_code = response['VK_SND_ID'] + transaction.buyer_iban = response['VK_SND_ACC'] + transaction.buyer_name = response['VK_SND_NAME'] + transaction.paid_at = Time.parse(response['VK_T_DATETIME']) transaction.save! transaction.autobind_invoice end def settled_payment? - response["VK_SERVICE"] == SUCCESSFUL_PAYMENT_SERVICE_NUMBER + response['VK_SERVICE'] == SUCCESSFUL_PAYMENT_SERVICE_NUMBER end - private + # private def valid_successful_transaction? valid_success_notice? && valid_amount? && valid_currency? @@ -88,17 +89,17 @@ module PaymentOrders def valid_amount? source = number_with_precision( - BigDecimal.new(response["VK_AMOUNT"]), precision: 2, separator: "." + BigDecimal(response['VK_AMOUNT']), precision: 2, separator: '.' ) target = number_with_precision( - invoice.total, precision: 2, separator: "." + invoice.total, precision: 2, separator: '.' ) source == target end def valid_currency? - invoice.currency == response["VK_CURR"] + invoice.currency == response['VK_CURR'] end def sign(data) @@ -116,7 +117,7 @@ module PaymentOrders def valid_mac?(hash, keys) data = keys.map { |element| prepend_size(hash[element]) }.join - verify_mac(data, hash["VK_MAC"]) + verify_mac(data, hash['VK_MAC']) end def verify_mac(data, mac) @@ -125,22 +126,22 @@ module PaymentOrders end def prepend_size(value) - value = (value || "").to_s.strip - string = "" + value = (value || '').to_s.strip + string = '' string << format("%03i", value.size) string << value end def seller_account - ENV["payments_#{type}_seller_account"] + ENV["payments_#{self.class.config_namespace_name}_seller_account"] end def seller_certificate - ENV["payments_#{type}_seller_private"] + ENV["payments_#{self.class.config_namespace_name}_seller_private"] end def bank_certificate - ENV["payments_#{type}_bank_certificate"] + ENV["payments_#{self.class.config_namespace_name}_bank_certificate"] end end end diff --git a/app/models/payment_orders/base.rb b/app/models/payment_orders/base.rb deleted file mode 100644 index cf0293025..000000000 --- a/app/models/payment_orders/base.rb +++ /dev/null @@ -1,33 +0,0 @@ -module PaymentOrders - class Base - include ActionView::Helpers::NumberHelper - - attr_reader :type, - :invoice, - :return_url, - :response_url, - :response - - def initialize(type, invoice, opts = {}) - @type = type - @invoice = invoice - @return_url = opts[:return_url] - @response_url = opts[:response_url] - @response = opts[:response] - end - - def create_transaction - transaction = BankTransaction.where(description: invoice.order).first_or_initialize( - reference_no: invoice.reference_no, - currency: invoice.currency, - iban: invoice.seller_iban - ) - - transaction.save! - end - - def form_url - ENV["payments_#{type}_url"] - end - end -end diff --git a/app/models/payment_orders/every_pay.rb b/app/models/payment_orders/every_pay.rb index b4ddcdf29..ae84aacca 100644 --- a/app/models/payment_orders/every_pay.rb +++ b/app/models/payment_orders/every_pay.rb @@ -1,9 +1,15 @@ module PaymentOrders - class EveryPay < Base - USER = ENV['payments_every_pay_api_user'].freeze - KEY = ENV['payments_every_pay_api_key'].freeze - ACCOUNT_ID = ENV['payments_every_pay_seller_account'].freeze - SUCCESSFUL_PAYMENT = %w(settled authorized).freeze + class EveryPay < PaymentOrder + USER = ENV['payments_every_pay_api_user'] + KEY = ENV['payments_every_pay_api_key'] + ACCOUNT_ID = ENV['payments_every_pay_seller_account'] + SUCCESSFUL_PAYMENT = %w[settled authorized].freeze + + CONFIG_NAMESPACE = 'every_pay' + + def self.config_namespace_name + CONFIG_NAMESPACE + end def form_fields base_json = base_params @@ -20,32 +26,31 @@ module PaymentOrders def valid_response_from_intermediary? return false unless response + valid_hmac? && valid_amount? && valid_account? end def settled_payment? - SUCCESSFUL_PAYMENT.include?(response[:payment_state]) + SUCCESSFUL_PAYMENT.include?(response['payment_state']) end def complete_transaction return unless valid_response_from_intermediary? && settled_payment? - transaction = BankTransaction.find_by( + transaction = BankTransaction.where(description: invoice.order).first_or_initialize( description: invoice.order, - currency: invoice.currency, - iban: invoice.seller_iban + reference_no: invoice.reference_no, + currency: invoice.currency, + iban: invoice.seller_iban ) - transaction.sum = response[:amount] - transaction.paid_at = Date.strptime(response[:timestamp], '%s') - transaction.buyer_name = response[:cc_holder_name] + transaction.sum = response['amount'] + transaction.paid_at = Date.strptime(response['timestamp'], '%s') + transaction.buyer_name = response['cc_holder_name'] - transaction.save! transaction.autobind_invoice end - private - def base_params { api_username: USER, @@ -61,24 +66,23 @@ module PaymentOrders end def valid_hmac? - hmac_fields = response[:hmac_fields].split(',') + hmac_fields = response['hmac_fields'].split(',') hmac_hash = {} hmac_fields.map do |field| - symbol = field.to_sym - hmac_hash[symbol] = response[symbol] + hmac_hash[field] = response[field] end hmac_string = hmac_hash.map { |key, _v| "#{key}=#{hmac_hash[key]}" }.join('&') expected_hmac = OpenSSL::HMAC.hexdigest('sha1', KEY, hmac_string) - expected_hmac == response[:hmac] + expected_hmac == response['hmac'] end def valid_amount? - invoice.total == BigDecimal.new(response[:amount]) + invoice.total == BigDecimal(response['amount']) end def valid_account? - response[:account_id] == ACCOUNT_ID + response['account_id'] == ACCOUNT_ID end end end diff --git a/app/models/payment_orders/lhv.rb b/app/models/payment_orders/lhv.rb new file mode 100644 index 000000000..7443f85d3 --- /dev/null +++ b/app/models/payment_orders/lhv.rb @@ -0,0 +1,7 @@ +module PaymentOrders + class LHV < BankLink + def self.config_namespace_name + 'lhv' + end + end +end diff --git a/app/models/payment_orders/seb.rb b/app/models/payment_orders/seb.rb new file mode 100644 index 000000000..50fb24ced --- /dev/null +++ b/app/models/payment_orders/seb.rb @@ -0,0 +1,7 @@ +module PaymentOrders + class SEB < BankLink + def self.config_namespace_name + 'seb' + end + end +end diff --git a/app/models/payment_orders/swed.rb b/app/models/payment_orders/swed.rb new file mode 100644 index 000000000..ff3aca3d1 --- /dev/null +++ b/app/models/payment_orders/swed.rb @@ -0,0 +1,7 @@ +module PaymentOrders + class Swed < BankLink + def self.config_namespace_name + 'swed' + end + end +end diff --git a/app/views/registrar/invoices/show.haml b/app/views/registrar/invoices/show.haml index 66a025eaf..d987241b1 100644 --- a/app/views/registrar/invoices/show.haml +++ b/app/views/registrar/invoices/show.haml @@ -17,4 +17,4 @@ - if @invoice.payable? .row.semifooter - .col-md-6-offset-6.text-right= render 'registrar/invoices/partials/banklinks', locals: { payment_channels: PaymentOrders::PAYMENT_METHODS } + .col-md-6-offset-6.text-right= render 'registrar/invoices/partials/banklinks', locals: { payment_channels: PaymentOrder::PAYMENT_METHODS } diff --git a/app/views/registrar/payments/pay.html.haml b/app/views/registrar/payments/pay.html.haml index 8e759f9ea..dd3fc982f 100644 --- a/app/views/registrar/payments/pay.html.haml +++ b/app/views/registrar/payments/pay.html.haml @@ -2,8 +2,8 @@ = t('registrar.invoices.redirected_to_intermediary') .payment-form - = form_tag @payment.form_url, method: :post do - - @payment.form_fields.each do |k, v| + = form_tag @payment_order.form_url, method: :post do + - @payment_order.form_fields.each do |k, v| = hidden_field_tag k, v = submit_tag t('registrar.invoices.go_to_intermediary') diff --git a/db/migrate/20200130092113_create_payment_orders.rb b/db/migrate/20200130092113_create_payment_orders.rb new file mode 100644 index 000000000..0b0594e56 --- /dev/null +++ b/db/migrate/20200130092113_create_payment_orders.rb @@ -0,0 +1,13 @@ +class CreatePaymentOrders < ActiveRecord::Migration[5.0] + def change + create_table :payment_orders do |t| + t.string :type, null: false + t.string :status, default: 0, null: false + t.belongs_to :invoice, foreign_key: true + t.jsonb :response, null: true + t.string :notes, null: true + + t.timestamps + end + end +end diff --git a/db/structure.sql b/db/structure.sql index a23623bae..c664522bb 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -196,7 +196,7 @@ SET default_tablespace = ''; SET default_with_oids = false; -- --- Name: account_activities; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: account_activities; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.account_activities ( @@ -236,7 +236,7 @@ ALTER SEQUENCE public.account_activities_id_seq OWNED BY public.account_activiti -- --- Name: accounts; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: accounts; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.accounts ( @@ -272,7 +272,7 @@ ALTER SEQUENCE public.accounts_id_seq OWNED BY public.accounts.id; -- --- Name: actions; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: actions; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.actions ( @@ -304,7 +304,7 @@ ALTER SEQUENCE public.actions_id_seq OWNED BY public.actions.id; -- --- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.ar_internal_metadata ( @@ -316,7 +316,7 @@ CREATE TABLE public.ar_internal_metadata ( -- --- Name: auctions; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: auctions; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.auctions ( @@ -349,7 +349,7 @@ ALTER SEQUENCE public.auctions_id_seq OWNED BY public.auctions.id; -- --- Name: bank_statements; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: bank_statements; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.bank_statements ( @@ -385,7 +385,7 @@ ALTER SEQUENCE public.bank_statements_id_seq OWNED BY public.bank_statements.id; -- --- Name: bank_transactions; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: bank_transactions; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.bank_transactions ( @@ -429,7 +429,7 @@ ALTER SEQUENCE public.bank_transactions_id_seq OWNED BY public.bank_transactions -- --- Name: blocked_domains; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: blocked_domains; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.blocked_domains ( @@ -462,7 +462,7 @@ ALTER SEQUENCE public.blocked_domains_id_seq OWNED BY public.blocked_domains.id; -- --- Name: certificates; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: certificates; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.certificates ( @@ -500,7 +500,7 @@ ALTER SEQUENCE public.certificates_id_seq OWNED BY public.certificates.id; -- --- Name: contacts; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: contacts; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.contacts ( @@ -558,7 +558,7 @@ ALTER SEQUENCE public.contacts_id_seq OWNED BY public.contacts.id; -- --- Name: directos; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: directos; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.directos ( @@ -593,7 +593,7 @@ ALTER SEQUENCE public.directos_id_seq OWNED BY public.directos.id; -- --- Name: dnskeys; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: dnskeys; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.dnskeys ( @@ -634,7 +634,7 @@ ALTER SEQUENCE public.dnskeys_id_seq OWNED BY public.dnskeys.id; -- --- Name: domain_contacts; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: domain_contacts; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.domain_contacts ( @@ -672,7 +672,7 @@ ALTER SEQUENCE public.domain_contacts_id_seq OWNED BY public.domain_contacts.id; -- --- Name: domain_transfers; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: domain_transfers; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.domain_transfers ( @@ -709,7 +709,7 @@ ALTER SEQUENCE public.domain_transfers_id_seq OWNED BY public.domain_transfers.i -- --- Name: domains; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: domains; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.domains ( @@ -746,7 +746,6 @@ CREATE TABLE public.domains ( locked_by_registrant_at timestamp without time zone, force_delete_start timestamp without time zone, force_delete_data public.hstore - ); @@ -770,7 +769,7 @@ ALTER SEQUENCE public.domains_id_seq OWNED BY public.domains.id; -- --- Name: epp_sessions; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: epp_sessions; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.epp_sessions ( @@ -802,7 +801,7 @@ ALTER SEQUENCE public.epp_sessions_id_seq OWNED BY public.epp_sessions.id; -- --- Name: invoice_items; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: invoice_items; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.invoice_items ( @@ -840,7 +839,7 @@ ALTER SEQUENCE public.invoice_items_id_seq OWNED BY public.invoice_items.id; -- --- Name: invoices; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: invoices; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.invoices ( @@ -910,7 +909,7 @@ ALTER SEQUENCE public.invoices_id_seq OWNED BY public.invoices.id; -- --- Name: legal_documents; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: legal_documents; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.legal_documents ( @@ -945,7 +944,7 @@ ALTER SEQUENCE public.legal_documents_id_seq OWNED BY public.legal_documents.id; -- --- Name: log_account_activities; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_account_activities; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_account_activities ( @@ -983,7 +982,7 @@ ALTER SEQUENCE public.log_account_activities_id_seq OWNED BY public.log_account_ -- --- Name: log_accounts; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_accounts; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_accounts ( @@ -1021,7 +1020,7 @@ ALTER SEQUENCE public.log_accounts_id_seq OWNED BY public.log_accounts.id; -- --- Name: log_actions; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_actions; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_actions ( @@ -1059,7 +1058,7 @@ ALTER SEQUENCE public.log_actions_id_seq OWNED BY public.log_actions.id; -- --- Name: log_bank_statements; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_bank_statements; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_bank_statements ( @@ -1097,7 +1096,7 @@ ALTER SEQUENCE public.log_bank_statements_id_seq OWNED BY public.log_bank_statem -- --- Name: log_bank_transactions; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_bank_transactions; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_bank_transactions ( @@ -1135,7 +1134,7 @@ ALTER SEQUENCE public.log_bank_transactions_id_seq OWNED BY public.log_bank_tran -- --- Name: log_blocked_domains; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_blocked_domains; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_blocked_domains ( @@ -1173,7 +1172,7 @@ ALTER SEQUENCE public.log_blocked_domains_id_seq OWNED BY public.log_blocked_dom -- --- Name: log_certificates; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_certificates; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_certificates ( @@ -1211,7 +1210,7 @@ ALTER SEQUENCE public.log_certificates_id_seq OWNED BY public.log_certificates.i -- --- Name: log_contacts; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_contacts; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_contacts ( @@ -1250,7 +1249,7 @@ ALTER SEQUENCE public.log_contacts_id_seq OWNED BY public.log_contacts.id; -- --- Name: log_dnskeys; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_dnskeys; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_dnskeys ( @@ -1288,7 +1287,7 @@ ALTER SEQUENCE public.log_dnskeys_id_seq OWNED BY public.log_dnskeys.id; -- --- Name: log_domain_contacts; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_domain_contacts; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_domain_contacts ( @@ -1326,7 +1325,7 @@ ALTER SEQUENCE public.log_domain_contacts_id_seq OWNED BY public.log_domain_cont -- --- Name: log_domains; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_domains; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_domains ( @@ -1364,7 +1363,7 @@ ALTER SEQUENCE public.log_domains_id_seq OWNED BY public.log_domains.id; -- --- Name: log_invoice_items; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_invoice_items; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_invoice_items ( @@ -1402,7 +1401,7 @@ ALTER SEQUENCE public.log_invoice_items_id_seq OWNED BY public.log_invoice_items -- --- Name: log_invoices; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_invoices; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_invoices ( @@ -1440,7 +1439,7 @@ ALTER SEQUENCE public.log_invoices_id_seq OWNED BY public.log_invoices.id; -- --- Name: log_nameservers; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_nameservers; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_nameservers ( @@ -1478,7 +1477,7 @@ ALTER SEQUENCE public.log_nameservers_id_seq OWNED BY public.log_nameservers.id; -- --- Name: log_notifications; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_notifications; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_notifications ( @@ -1516,7 +1515,7 @@ ALTER SEQUENCE public.log_notifications_id_seq OWNED BY public.log_notifications -- --- Name: log_registrant_verifications; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_registrant_verifications; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_registrant_verifications ( @@ -1553,7 +1552,7 @@ ALTER SEQUENCE public.log_registrant_verifications_id_seq OWNED BY public.log_re -- --- Name: log_registrars; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_registrars; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_registrars ( @@ -1591,7 +1590,7 @@ ALTER SEQUENCE public.log_registrars_id_seq OWNED BY public.log_registrars.id; -- --- Name: log_reserved_domains; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_reserved_domains; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_reserved_domains ( @@ -1629,7 +1628,7 @@ ALTER SEQUENCE public.log_reserved_domains_id_seq OWNED BY public.log_reserved_d -- --- Name: log_settings; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_settings; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_settings ( @@ -1667,7 +1666,7 @@ ALTER SEQUENCE public.log_settings_id_seq OWNED BY public.log_settings.id; -- --- Name: log_users; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_users; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_users ( @@ -1705,7 +1704,7 @@ ALTER SEQUENCE public.log_users_id_seq OWNED BY public.log_users.id; -- --- Name: log_white_ips; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: log_white_ips; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.log_white_ips ( @@ -1743,7 +1742,7 @@ ALTER SEQUENCE public.log_white_ips_id_seq OWNED BY public.log_white_ips.id; -- --- Name: nameservers; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: nameservers; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.nameservers ( @@ -1781,7 +1780,7 @@ ALTER SEQUENCE public.nameservers_id_seq OWNED BY public.nameservers.id; -- --- Name: notifications; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: notifications; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.notifications ( @@ -1819,7 +1818,42 @@ ALTER SEQUENCE public.notifications_id_seq OWNED BY public.notifications.id; -- --- Name: prices; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: payment_orders; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.payment_orders ( + id integer NOT NULL, + type character varying NOT NULL, + status character varying DEFAULT '0'::character varying NOT NULL, + invoice_id integer, + response jsonb, + notes character varying, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL +); + + +-- +-- Name: payment_orders_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.payment_orders_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: payment_orders_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.payment_orders_id_seq OWNED BY public.payment_orders.id; + + +-- +-- Name: prices; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.prices ( @@ -1857,7 +1891,7 @@ ALTER SEQUENCE public.prices_id_seq OWNED BY public.prices.id; -- --- Name: que_jobs; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: que_jobs; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.que_jobs ( @@ -1899,7 +1933,7 @@ ALTER SEQUENCE public.que_jobs_job_id_seq OWNED BY public.que_jobs.job_id; -- --- Name: registrant_verifications; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: registrant_verifications; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.registrant_verifications ( @@ -1935,7 +1969,7 @@ ALTER SEQUENCE public.registrant_verifications_id_seq OWNED BY public.registrant -- --- Name: registrars; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: registrars; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.registrars ( @@ -1988,7 +2022,7 @@ ALTER SEQUENCE public.registrars_id_seq OWNED BY public.registrars.id; -- --- Name: reserved_domains; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: reserved_domains; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.reserved_domains ( @@ -2023,7 +2057,7 @@ ALTER SEQUENCE public.reserved_domains_id_seq OWNED BY public.reserved_domains.i -- --- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.schema_migrations ( @@ -2032,7 +2066,7 @@ CREATE TABLE public.schema_migrations ( -- --- Name: settings; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: settings; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.settings ( @@ -2068,7 +2102,7 @@ ALTER SEQUENCE public.settings_id_seq OWNED BY public.settings.id; -- --- Name: users; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: users; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.users ( @@ -2120,7 +2154,7 @@ ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id; -- --- Name: versions; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: versions; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.versions ( @@ -2155,7 +2189,7 @@ ALTER SEQUENCE public.versions_id_seq OWNED BY public.versions.id; -- --- Name: white_ips; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: white_ips; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.white_ips ( @@ -2191,7 +2225,7 @@ ALTER SEQUENCE public.white_ips_id_seq OWNED BY public.white_ips.id; -- --- Name: whois_records; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: whois_records; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.whois_records ( @@ -2226,7 +2260,7 @@ ALTER SEQUENCE public.whois_records_id_seq OWNED BY public.whois_records.id; -- --- Name: zones; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: zones; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE public.zones ( @@ -2555,6 +2589,13 @@ ALTER TABLE ONLY public.nameservers ALTER COLUMN id SET DEFAULT nextval('public. ALTER TABLE ONLY public.notifications ALTER COLUMN id SET DEFAULT nextval('public.notifications_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.payment_orders ALTER COLUMN id SET DEFAULT nextval('public.payment_orders_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2633,7 +2674,7 @@ ALTER TABLE ONLY public.zones ALTER COLUMN id SET DEFAULT nextval('public.zones_ -- --- Name: account_activities_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: account_activities_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.account_activities @@ -2641,7 +2682,7 @@ ALTER TABLE ONLY public.account_activities -- --- Name: accounts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: accounts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.accounts @@ -2649,7 +2690,7 @@ ALTER TABLE ONLY public.accounts -- --- Name: actions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: actions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.actions @@ -2657,7 +2698,7 @@ ALTER TABLE ONLY public.actions -- --- Name: ar_internal_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: ar_internal_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.ar_internal_metadata @@ -2665,7 +2706,7 @@ ALTER TABLE ONLY public.ar_internal_metadata -- --- Name: auctions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: auctions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.auctions @@ -2673,7 +2714,7 @@ ALTER TABLE ONLY public.auctions -- --- Name: bank_statements_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: bank_statements_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.bank_statements @@ -2681,7 +2722,7 @@ ALTER TABLE ONLY public.bank_statements -- --- Name: bank_transactions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: bank_transactions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.bank_transactions @@ -2689,7 +2730,7 @@ ALTER TABLE ONLY public.bank_transactions -- --- Name: blocked_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: blocked_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.blocked_domains @@ -2697,7 +2738,7 @@ ALTER TABLE ONLY public.blocked_domains -- --- Name: certificates_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: certificates_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.certificates @@ -2705,7 +2746,7 @@ ALTER TABLE ONLY public.certificates -- --- Name: contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.contacts @@ -2713,7 +2754,7 @@ ALTER TABLE ONLY public.contacts -- --- Name: directos_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: directos_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.directos @@ -2721,7 +2762,7 @@ ALTER TABLE ONLY public.directos -- --- Name: dnskeys_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: dnskeys_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.dnskeys @@ -2729,7 +2770,7 @@ ALTER TABLE ONLY public.dnskeys -- --- Name: domain_contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: domain_contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.domain_contacts @@ -2737,7 +2778,7 @@ ALTER TABLE ONLY public.domain_contacts -- --- Name: domain_transfers_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: domain_transfers_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.domain_transfers @@ -2745,7 +2786,7 @@ ALTER TABLE ONLY public.domain_transfers -- --- Name: domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.domains @@ -2753,7 +2794,7 @@ ALTER TABLE ONLY public.domains -- --- Name: epp_sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: epp_sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.epp_sessions @@ -2761,7 +2802,7 @@ ALTER TABLE ONLY public.epp_sessions -- --- Name: invoice_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: invoice_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.invoice_items @@ -2769,7 +2810,7 @@ ALTER TABLE ONLY public.invoice_items -- --- Name: invoices_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: invoices_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.invoices @@ -2777,7 +2818,7 @@ ALTER TABLE ONLY public.invoices -- --- Name: legal_documents_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: legal_documents_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.legal_documents @@ -2785,7 +2826,7 @@ ALTER TABLE ONLY public.legal_documents -- --- Name: log_account_activities_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_account_activities_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_account_activities @@ -2793,7 +2834,7 @@ ALTER TABLE ONLY public.log_account_activities -- --- Name: log_accounts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_accounts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_accounts @@ -2801,7 +2842,7 @@ ALTER TABLE ONLY public.log_accounts -- --- Name: log_actions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_actions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_actions @@ -2809,7 +2850,7 @@ ALTER TABLE ONLY public.log_actions -- --- Name: log_bank_statements_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_bank_statements_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_bank_statements @@ -2817,7 +2858,7 @@ ALTER TABLE ONLY public.log_bank_statements -- --- Name: log_bank_transactions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_bank_transactions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_bank_transactions @@ -2825,7 +2866,7 @@ ALTER TABLE ONLY public.log_bank_transactions -- --- Name: log_blocked_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_blocked_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_blocked_domains @@ -2833,7 +2874,7 @@ ALTER TABLE ONLY public.log_blocked_domains -- --- Name: log_certificates_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_certificates_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_certificates @@ -2841,7 +2882,7 @@ ALTER TABLE ONLY public.log_certificates -- --- Name: log_contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_contacts @@ -2849,7 +2890,7 @@ ALTER TABLE ONLY public.log_contacts -- --- Name: log_dnskeys_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_dnskeys_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_dnskeys @@ -2857,7 +2898,7 @@ ALTER TABLE ONLY public.log_dnskeys -- --- Name: log_domain_contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_domain_contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_domain_contacts @@ -2865,7 +2906,7 @@ ALTER TABLE ONLY public.log_domain_contacts -- --- Name: log_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_domains @@ -2873,7 +2914,7 @@ ALTER TABLE ONLY public.log_domains -- --- Name: log_invoice_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_invoice_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_invoice_items @@ -2881,7 +2922,7 @@ ALTER TABLE ONLY public.log_invoice_items -- --- Name: log_invoices_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_invoices_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_invoices @@ -2889,7 +2930,7 @@ ALTER TABLE ONLY public.log_invoices -- --- Name: log_nameservers_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_nameservers_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_nameservers @@ -2897,7 +2938,7 @@ ALTER TABLE ONLY public.log_nameservers -- --- Name: log_notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_notifications @@ -2905,7 +2946,7 @@ ALTER TABLE ONLY public.log_notifications -- --- Name: log_registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_registrant_verifications @@ -2913,7 +2954,7 @@ ALTER TABLE ONLY public.log_registrant_verifications -- --- Name: log_registrars_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_registrars_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_registrars @@ -2921,7 +2962,7 @@ ALTER TABLE ONLY public.log_registrars -- --- Name: log_reserved_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_reserved_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_reserved_domains @@ -2929,7 +2970,7 @@ ALTER TABLE ONLY public.log_reserved_domains -- --- Name: log_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_settings @@ -2937,7 +2978,7 @@ ALTER TABLE ONLY public.log_settings -- --- Name: log_users_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_users_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_users @@ -2945,7 +2986,7 @@ ALTER TABLE ONLY public.log_users -- --- Name: log_white_ips_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: log_white_ips_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.log_white_ips @@ -2953,7 +2994,7 @@ ALTER TABLE ONLY public.log_white_ips -- --- Name: nameservers_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: nameservers_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.nameservers @@ -2961,7 +3002,7 @@ ALTER TABLE ONLY public.nameservers -- --- Name: notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: notifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.notifications @@ -2969,7 +3010,15 @@ ALTER TABLE ONLY public.notifications -- --- Name: prices_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: payment_orders_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.payment_orders + ADD CONSTRAINT payment_orders_pkey PRIMARY KEY (id); + + +-- +-- Name: prices_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.prices @@ -2977,7 +3026,7 @@ ALTER TABLE ONLY public.prices -- --- Name: que_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: que_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.que_jobs @@ -2985,7 +3034,7 @@ ALTER TABLE ONLY public.que_jobs -- --- Name: registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.registrant_verifications @@ -2993,7 +3042,7 @@ ALTER TABLE ONLY public.registrant_verifications -- --- Name: registrars_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: registrars_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.registrars @@ -3001,7 +3050,7 @@ ALTER TABLE ONLY public.registrars -- --- Name: reserved_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: reserved_domains_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.reserved_domains @@ -3009,7 +3058,7 @@ ALTER TABLE ONLY public.reserved_domains -- --- Name: settings_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: settings_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.settings @@ -3017,7 +3066,7 @@ ALTER TABLE ONLY public.settings -- --- Name: uniq_blocked_domains_name; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: uniq_blocked_domains_name; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.blocked_domains @@ -3025,7 +3074,7 @@ ALTER TABLE ONLY public.blocked_domains -- --- Name: uniq_contact_uuid; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: uniq_contact_uuid; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.contacts @@ -3033,7 +3082,7 @@ ALTER TABLE ONLY public.contacts -- --- Name: uniq_domain_uuid; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: uniq_domain_uuid; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.domains @@ -3041,7 +3090,7 @@ ALTER TABLE ONLY public.domains -- --- Name: uniq_reserved_domains_name; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: uniq_reserved_domains_name; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.reserved_domains @@ -3049,7 +3098,7 @@ ALTER TABLE ONLY public.reserved_domains -- --- Name: uniq_uuid; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: uniq_uuid; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.auctions @@ -3057,7 +3106,7 @@ ALTER TABLE ONLY public.auctions -- --- Name: unique_code; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: unique_code; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.registrars @@ -3065,7 +3114,7 @@ ALTER TABLE ONLY public.registrars -- --- Name: unique_contact_code; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: unique_contact_code; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.contacts @@ -3073,7 +3122,7 @@ ALTER TABLE ONLY public.contacts -- --- Name: unique_name; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: unique_name; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.registrars @@ -3081,7 +3130,7 @@ ALTER TABLE ONLY public.registrars -- --- Name: unique_number; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: unique_number; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.invoices @@ -3089,7 +3138,7 @@ ALTER TABLE ONLY public.invoices -- --- Name: unique_reference_no; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: unique_reference_no; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.registrars @@ -3097,7 +3146,7 @@ ALTER TABLE ONLY public.registrars -- --- Name: unique_registration_code; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: unique_registration_code; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.auctions @@ -3105,7 +3154,7 @@ ALTER TABLE ONLY public.auctions -- --- Name: unique_session_id; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: unique_session_id; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.epp_sessions @@ -3113,7 +3162,7 @@ ALTER TABLE ONLY public.epp_sessions -- --- Name: unique_zone_origin; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: unique_zone_origin; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.zones @@ -3121,7 +3170,7 @@ ALTER TABLE ONLY public.zones -- --- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.users @@ -3129,7 +3178,7 @@ ALTER TABLE ONLY public.users -- --- Name: versions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: versions_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.versions @@ -3137,7 +3186,7 @@ ALTER TABLE ONLY public.versions -- --- Name: white_ips_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: white_ips_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.white_ips @@ -3145,7 +3194,7 @@ ALTER TABLE ONLY public.white_ips -- --- Name: whois_records_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: whois_records_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.whois_records @@ -3153,7 +3202,7 @@ ALTER TABLE ONLY public.whois_records -- --- Name: zones_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: zones_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY public.zones @@ -3161,567 +3210,574 @@ ALTER TABLE ONLY public.zones -- --- Name: index_account_activities_on_account_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_account_activities_on_account_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_account_activities_on_account_id ON public.account_activities USING btree (account_id); -- --- Name: index_account_activities_on_bank_transaction_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_account_activities_on_bank_transaction_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_account_activities_on_bank_transaction_id ON public.account_activities USING btree (bank_transaction_id); -- --- Name: index_account_activities_on_invoice_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_account_activities_on_invoice_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_account_activities_on_invoice_id ON public.account_activities USING btree (invoice_id); -- --- Name: index_accounts_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_accounts_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_accounts_on_registrar_id ON public.accounts USING btree (registrar_id); -- --- Name: index_certificates_on_api_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_certificates_on_api_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_certificates_on_api_user_id ON public.certificates USING btree (api_user_id); -- --- Name: index_contacts_on_code; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_contacts_on_code; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_contacts_on_code ON public.contacts USING btree (code); -- --- Name: index_contacts_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_contacts_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_contacts_on_registrar_id ON public.contacts USING btree (registrar_id); -- --- Name: index_contacts_on_registrar_id_and_ident_type; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_contacts_on_registrar_id_and_ident_type; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_contacts_on_registrar_id_and_ident_type ON public.contacts USING btree (registrar_id, ident_type); -- --- Name: index_directos_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- 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 public.directos USING btree (item_type, item_id); -- --- Name: index_dnskeys_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_dnskeys_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_dnskeys_on_domain_id ON public.dnskeys USING btree (domain_id); -- --- Name: index_dnskeys_on_legacy_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_dnskeys_on_legacy_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_dnskeys_on_legacy_domain_id ON public.dnskeys USING btree (legacy_domain_id); -- --- Name: index_domain_contacts_on_contact_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domain_contacts_on_contact_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_domain_contacts_on_contact_id ON public.domain_contacts USING btree (contact_id); -- --- Name: index_domain_contacts_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domain_contacts_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_domain_contacts_on_domain_id ON public.domain_contacts USING btree (domain_id); -- --- Name: index_domain_transfers_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domain_transfers_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_domain_transfers_on_domain_id ON public.domain_transfers USING btree (domain_id); -- --- Name: index_domains_on_delete_date; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domains_on_delete_date; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_domains_on_delete_date ON public.domains USING btree (delete_date); -- --- Name: index_domains_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domains_on_name; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_domains_on_name ON public.domains USING btree (name); -- --- Name: index_domains_on_outzone_at; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domains_on_outzone_at; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_domains_on_outzone_at ON public.domains USING btree (outzone_at); -- --- Name: index_domains_on_registrant_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domains_on_registrant_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_domains_on_registrant_id ON public.domains USING btree (registrant_id); -- --- Name: index_domains_on_registrant_verification_asked_at; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domains_on_registrant_verification_asked_at; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_domains_on_registrant_verification_asked_at ON public.domains USING btree (registrant_verification_asked_at); -- --- Name: index_domains_on_registrant_verification_token; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domains_on_registrant_verification_token; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_domains_on_registrant_verification_token ON public.domains USING btree (registrant_verification_token); -- --- Name: index_domains_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domains_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_domains_on_registrar_id ON public.domains USING btree (registrar_id); -- --- Name: index_domains_on_statuses; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_domains_on_statuses; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_domains_on_statuses ON public.domains USING gin (statuses); -- --- Name: index_epp_sessions_on_updated_at; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_epp_sessions_on_updated_at; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_epp_sessions_on_updated_at ON public.epp_sessions USING btree (updated_at); -- --- Name: index_invoice_items_on_invoice_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_invoice_items_on_invoice_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_invoice_items_on_invoice_id ON public.invoice_items USING btree (invoice_id); -- --- Name: index_invoices_on_buyer_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_invoices_on_buyer_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_invoices_on_buyer_id ON public.invoices USING btree (buyer_id); -- --- Name: index_legal_documents_on_checksum; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_legal_documents_on_checksum; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_legal_documents_on_checksum ON public.legal_documents USING btree (checksum); -- --- Name: index_legal_documents_on_documentable_type_and_documentable_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_legal_documents_on_documentable_type_and_documentable_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_legal_documents_on_documentable_type_and_documentable_id ON public.legal_documents USING btree (documentable_type, documentable_id); -- --- Name: index_log_account_activities_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_account_activities_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_account_activities_on_item_type_and_item_id ON public.log_account_activities USING btree (item_type, item_id); -- --- Name: index_log_account_activities_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_account_activities_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_account_activities_on_whodunnit ON public.log_account_activities USING btree (whodunnit); -- --- Name: index_log_accounts_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_accounts_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_accounts_on_item_type_and_item_id ON public.log_accounts USING btree (item_type, item_id); -- --- Name: index_log_accounts_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_accounts_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_accounts_on_whodunnit ON public.log_accounts USING btree (whodunnit); -- --- Name: index_log_bank_statements_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_bank_statements_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_bank_statements_on_item_type_and_item_id ON public.log_bank_statements USING btree (item_type, item_id); -- --- Name: index_log_bank_statements_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_bank_statements_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_bank_statements_on_whodunnit ON public.log_bank_statements USING btree (whodunnit); -- --- Name: index_log_bank_transactions_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_bank_transactions_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_bank_transactions_on_item_type_and_item_id ON public.log_bank_transactions USING btree (item_type, item_id); -- --- Name: index_log_bank_transactions_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_bank_transactions_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_bank_transactions_on_whodunnit ON public.log_bank_transactions USING btree (whodunnit); -- --- Name: index_log_blocked_domains_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_blocked_domains_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_blocked_domains_on_item_type_and_item_id ON public.log_blocked_domains USING btree (item_type, item_id); -- --- Name: index_log_blocked_domains_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_blocked_domains_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_blocked_domains_on_whodunnit ON public.log_blocked_domains USING btree (whodunnit); -- --- Name: index_log_certificates_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_certificates_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_certificates_on_item_type_and_item_id ON public.log_certificates USING btree (item_type, item_id); -- --- Name: index_log_certificates_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_certificates_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_certificates_on_whodunnit ON public.log_certificates USING btree (whodunnit); -- --- Name: index_log_contacts_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_contacts_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_contacts_on_item_type_and_item_id ON public.log_contacts USING btree (item_type, item_id); -- --- Name: index_log_contacts_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_contacts_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_contacts_on_whodunnit ON public.log_contacts USING btree (whodunnit); -- --- Name: index_log_dnskeys_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_dnskeys_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_dnskeys_on_item_type_and_item_id ON public.log_dnskeys USING btree (item_type, item_id); -- --- Name: index_log_dnskeys_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_dnskeys_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_dnskeys_on_whodunnit ON public.log_dnskeys USING btree (whodunnit); -- --- Name: index_log_domain_contacts_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_domain_contacts_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_domain_contacts_on_item_type_and_item_id ON public.log_domain_contacts USING btree (item_type, item_id); -- --- Name: index_log_domain_contacts_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_domain_contacts_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_domain_contacts_on_whodunnit ON public.log_domain_contacts USING btree (whodunnit); -- --- Name: index_log_domains_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_domains_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_domains_on_item_type_and_item_id ON public.log_domains USING btree (item_type, item_id); -- --- Name: index_log_domains_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_domains_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_domains_on_whodunnit ON public.log_domains USING btree (whodunnit); -- --- Name: index_log_invoice_items_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_invoice_items_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_invoice_items_on_item_type_and_item_id ON public.log_invoice_items USING btree (item_type, item_id); -- --- Name: index_log_invoice_items_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_invoice_items_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_invoice_items_on_whodunnit ON public.log_invoice_items USING btree (whodunnit); -- --- Name: index_log_invoices_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_invoices_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_invoices_on_item_type_and_item_id ON public.log_invoices USING btree (item_type, item_id); -- --- Name: index_log_invoices_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_invoices_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_invoices_on_whodunnit ON public.log_invoices USING btree (whodunnit); -- --- Name: index_log_nameservers_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_nameservers_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_nameservers_on_item_type_and_item_id ON public.log_nameservers USING btree (item_type, item_id); -- --- Name: index_log_nameservers_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_nameservers_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_nameservers_on_whodunnit ON public.log_nameservers USING btree (whodunnit); -- --- Name: index_log_notifications_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_notifications_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_notifications_on_item_type_and_item_id ON public.log_notifications USING btree (item_type, item_id); -- --- Name: index_log_notifications_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_notifications_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_notifications_on_whodunnit ON public.log_notifications USING btree (whodunnit); -- --- Name: index_log_registrant_verifications_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_registrant_verifications_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_registrant_verifications_on_item_type_and_item_id ON public.log_registrant_verifications USING btree (item_type, item_id); -- --- Name: index_log_registrant_verifications_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_registrant_verifications_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_registrant_verifications_on_whodunnit ON public.log_registrant_verifications USING btree (whodunnit); -- --- Name: index_log_registrars_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_registrars_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_registrars_on_item_type_and_item_id ON public.log_registrars USING btree (item_type, item_id); -- --- Name: index_log_registrars_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_registrars_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_registrars_on_whodunnit ON public.log_registrars USING btree (whodunnit); -- --- Name: index_log_reserved_domains_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_reserved_domains_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_reserved_domains_on_item_type_and_item_id ON public.log_reserved_domains USING btree (item_type, item_id); -- --- Name: index_log_reserved_domains_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_reserved_domains_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_reserved_domains_on_whodunnit ON public.log_reserved_domains USING btree (whodunnit); -- --- Name: index_log_settings_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_settings_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_settings_on_item_type_and_item_id ON public.log_settings USING btree (item_type, item_id); -- --- Name: index_log_settings_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_settings_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_settings_on_whodunnit ON public.log_settings USING btree (whodunnit); -- --- Name: index_log_users_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_users_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_users_on_item_type_and_item_id ON public.log_users USING btree (item_type, item_id); -- --- Name: index_log_users_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_log_users_on_whodunnit; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_log_users_on_whodunnit ON public.log_users USING btree (whodunnit); -- --- Name: index_nameservers_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_nameservers_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_nameservers_on_domain_id ON public.nameservers USING btree (domain_id); -- --- Name: index_notifications_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_notifications_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_notifications_on_registrar_id ON public.notifications USING btree (registrar_id); -- --- Name: index_prices_on_zone_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_payment_orders_on_invoice_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_payment_orders_on_invoice_id ON public.payment_orders USING btree (invoice_id); + + +-- +-- Name: index_prices_on_zone_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_prices_on_zone_id ON public.prices USING btree (zone_id); -- --- Name: index_registrant_verifications_on_created_at; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_registrant_verifications_on_created_at; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_registrant_verifications_on_created_at ON public.registrant_verifications USING btree (created_at); -- --- Name: index_registrant_verifications_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_registrant_verifications_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_registrant_verifications_on_domain_id ON public.registrant_verifications USING btree (domain_id); -- --- Name: index_settings_on_thing_type_and_thing_id_and_var; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_settings_on_thing_type_and_thing_id_and_var; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_settings_on_thing_type_and_thing_id_and_var ON public.settings USING btree (thing_type, thing_id, var); -- --- Name: index_users_on_identity_code; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_users_on_identity_code; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_users_on_identity_code ON public.users USING btree (identity_code); -- --- Name: index_users_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_users_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_users_on_registrar_id ON public.users USING btree (registrar_id); -- --- Name: index_versions_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_versions_on_item_type_and_item_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_versions_on_item_type_and_item_id ON public.versions USING btree (item_type, item_id); -- --- Name: index_whois_records_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_whois_records_on_domain_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_whois_records_on_domain_id ON public.whois_records USING btree (domain_id); -- --- Name: index_whois_records_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_whois_records_on_registrar_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_whois_records_on_registrar_id ON public.whois_records USING btree (registrar_id); -- --- Name: log_contacts_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: log_contacts_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX log_contacts_object_legacy_id ON public.log_contacts USING btree ((((object ->> 'legacy_id'::text))::integer)); -- --- Name: log_dnskeys_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: log_dnskeys_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX log_dnskeys_object_legacy_id ON public.log_contacts USING btree ((((object ->> 'legacy_domain_id'::text))::integer)); -- --- Name: log_domains_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: log_domains_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX log_domains_object_legacy_id ON public.log_contacts USING btree ((((object ->> 'legacy_id'::text))::integer)); -- --- Name: log_nameservers_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: log_nameservers_object_legacy_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX log_nameservers_object_legacy_id ON public.log_contacts USING btree ((((object ->> 'legacy_domain_id'::text))::integer)); -- --- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX unique_schema_migrations ON public.schema_migrations USING btree (version); @@ -3895,6 +3951,14 @@ ALTER TABLE ONLY public.registrant_verifications ADD CONSTRAINT fk_rails_f41617a0e9 FOREIGN KEY (domain_id) REFERENCES public.domains(id); +-- +-- Name: fk_rails_f9dc5857c3; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.payment_orders + ADD CONSTRAINT fk_rails_f9dc5857c3 FOREIGN KEY (invoice_id) REFERENCES public.invoices(id); + + -- -- Name: invoice_items_invoice_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -4339,6 +4403,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20191212133136'), ('20191227110904'), ('20200113091254'), -('20200115102202'); +('20200115102202'), +('20200130092113'); From 7033d912272565ea1c4fe57f84126f9cf2741bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 30 Jan 2020 18:31:39 +0200 Subject: [PATCH 002/110] EveryPay/BankLink: Select specific Invoice to mark as paid --- app/models/bank_transaction.rb | 15 ++++++++++----- app/models/payment_orders/bank_link.rb | 3 ++- app/models/payment_orders/every_pay.rb | 4 +++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index 6612a4dbd..174aae06c 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -24,15 +24,20 @@ class BankTransaction < ApplicationRecord @registrar ||= Invoice.find_by(reference_no: parsed_ref_number)&.buyer end - # For successful binding, reference number, invoice id and sum must match with the invoice - def autobind_invoice + def autobind_invoice(invoice_no: nil) return if binded? return unless registrar - return unless invoice - return unless invoice.payable? - create_activity(registrar, invoice) + inv = if invoice_no.nil? + invoice + else + Invoice.find_by(number: invoice_no) + end + return unless inv + return unless inv.payable? + + create_activity(registrar, inv) end def bind_invoice(invoice_no) diff --git a/app/models/payment_orders/bank_link.rb b/app/models/payment_orders/bank_link.rb index 0cdedbd85..be78973ed 100644 --- a/app/models/payment_orders/bank_link.rb +++ b/app/models/payment_orders/bank_link.rb @@ -51,6 +51,7 @@ module PaymentOrders def complete_transaction return unless valid_response_from_intermediary? && settled_payment? + self.status = 'paid' transaction = BankTransaction.where(description: invoice.order).first_or_initialize( description: invoice.order, reference_no: invoice.reference_no, @@ -66,7 +67,7 @@ module PaymentOrders transaction.paid_at = Time.parse(response['VK_T_DATETIME']) transaction.save! - transaction.autobind_invoice + transaction.autobind_invoice(invoice_no: invoice.number) end def settled_payment? diff --git a/app/models/payment_orders/every_pay.rb b/app/models/payment_orders/every_pay.rb index ae84aacca..66c34c3fa 100644 --- a/app/models/payment_orders/every_pay.rb +++ b/app/models/payment_orders/every_pay.rb @@ -36,6 +36,7 @@ module PaymentOrders def complete_transaction return unless valid_response_from_intermediary? && settled_payment? + self.status = 'paid' transaction = BankTransaction.where(description: invoice.order).first_or_initialize( description: invoice.order, @@ -48,7 +49,8 @@ module PaymentOrders transaction.paid_at = Date.strptime(response['timestamp'], '%s') transaction.buyer_name = response['cc_holder_name'] - transaction.autobind_invoice + transaction.save! + transaction.autobind_invoice(invoice_no: invoice.number) end def base_params From 32d4fc3c8332a413c01d3d76f7510bfb2e73898c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 30 Jan 2020 21:01:15 +0200 Subject: [PATCH 003/110] Refactor EveryPay / Banklink processing --- .../registrar/payments_controller.rb | 14 +++++++------ app/models/bank_transaction.rb | 14 ++++--------- app/models/payment_order.rb | 19 +++++++++++++++++- app/models/payment_orders/bank_link.rb | 16 ++++++++++----- app/models/payment_orders/every_pay.rb | 20 +++++++++++++------ 5 files changed, 55 insertions(+), 28 deletions(-) diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index 98b9e1d7d..aaa742be5 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -31,20 +31,20 @@ class Registrar end def back - puts params - @payment_order = PaymentOrder.find_by!(id: params[:bank]) @payment_order.update!(response: params.to_unsafe_h) - if @payment_order.valid_response_from_intermediary? && @payment_order.settled_payment? - @payment_order.complete_transaction + if @payment_order.payment_received? + @payment_order.complete_transaction(@payment_order.composed_transaction) if @payment_order.invoice.paid? flash[:notice] = t(:pending_applied) else - flash[:alert] = t(:something_wrong) + # flash[:alert] = t(:something_wrong) + flash[:alert] = 'We fucked up' end else + @payment_order.create_failure_report flash[:alert] = t(:something_wrong) end redirect_to registrar_invoice_path(@payment_order.invoice) @@ -54,8 +54,10 @@ class Registrar @payment_order = PaymentOrder.find_by!(id: params[:bank]) @payment_order.update!(response: params.to_unsafe_h) - if @payment_order.valid_response_from_intermediary? && @payment_order.settled_payment? + if @payment_order.payment_received? @payment_order.complete_transaction + else + @payment_order.create_failure_report end render status: 200, json: { status: 'ok' } diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index 0cc9500cc..792a32484 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -31,19 +31,13 @@ class BankTransaction < ApplicationRecord end # For successful binding, reference number, invoice id and sum must match with the invoice - def autobind_invoice(invoice_no: nil) + def autobind_invoice return if binded? return unless registrar + return unless invoice + return unless invoice.payable? - inv = if invoice_no.nil? - invoice - else - Invoice.find_by(number: invoice_no) - end - return unless inv - return unless inv.payable? - - create_activity(registrar, inv) + create_activity(registrar, invoice) end def bind_invoice(invoice_no) diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index 228c4021d..a0d3da254 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -11,7 +11,8 @@ class PaymentOrder < ApplicationRecord validate :invoice_cannot_be_already_paid, on: :create # validates :type, inclusion: { in: PAYMENT_METHODS } - enum status: { issued: 'issued', paid: 'paid', cancelled: 'cancelled' } + enum status: { issued: 'issued', paid: 'paid', cancelled: 'cancelled', + failed: 'failed' } attr_accessor :return_url, :response_url @@ -34,6 +35,22 @@ class PaymentOrder < ApplicationRecord end end + def complete_transaction(transaction) + paid! + + transaction.save! + transaction.bind_invoice(invoice.number) + + return unless transaction.errors.any? + + worded_errors = 'Failed to bind. ' + transaction.errors.full_messages.each do |err| + worded_errors << "#{err}, " + end + + update!(notes: worded_errors) + end + def self.supported_methods enabled = [] diff --git a/app/models/payment_orders/bank_link.rb b/app/models/payment_orders/bank_link.rb index be78973ed..c5a8bc54e 100644 --- a/app/models/payment_orders/bank_link.rb +++ b/app/models/payment_orders/bank_link.rb @@ -48,10 +48,17 @@ module PaymentOrders end end - def complete_transaction - return unless valid_response_from_intermediary? && settled_payment? + def payment_received? + valid_response_from_intermediary? && settled_payment? + end - self.status = 'paid' + def create_failure_report + notes = "User failed to make valid payment. Bank responded with code #{response['VK_SERVICE']}" + status = 'cancelled' + update!(notes: notes, status: status) + end + + def composed_transaction transaction = BankTransaction.where(description: invoice.order).first_or_initialize( description: invoice.order, reference_no: invoice.reference_no, @@ -66,8 +73,7 @@ module PaymentOrders transaction.buyer_name = response['VK_SND_NAME'] transaction.paid_at = Time.parse(response['VK_T_DATETIME']) - transaction.save! - transaction.autobind_invoice(invoice_no: invoice.number) + transaction end def settled_payment? diff --git a/app/models/payment_orders/every_pay.rb b/app/models/payment_orders/every_pay.rb index 66c34c3fa..53705d1a6 100644 --- a/app/models/payment_orders/every_pay.rb +++ b/app/models/payment_orders/every_pay.rb @@ -34,11 +34,12 @@ module PaymentOrders SUCCESSFUL_PAYMENT.include?(response['payment_state']) end - def complete_transaction - return unless valid_response_from_intermediary? && settled_payment? - self.status = 'paid' + def payment_received? + valid_response_from_intermediary? && settled_payment? + end - transaction = BankTransaction.where(description: invoice.order).first_or_initialize( + def composed_transaction + transaction = BankTransaction.new( description: invoice.order, reference_no: invoice.reference_no, currency: invoice.currency, @@ -49,8 +50,13 @@ module PaymentOrders transaction.paid_at = Date.strptime(response['timestamp'], '%s') transaction.buyer_name = response['cc_holder_name'] - transaction.save! - transaction.autobind_invoice(invoice_no: invoice.number) + transaction + end + + def create_failure_report + notes = "User failed to make valid payment. Payment state: #{response['payment_state']}" + status = 'cancelled' + update!(notes: notes, status: status) end def base_params @@ -80,6 +86,8 @@ module PaymentOrders end def valid_amount? + return false unless response.key? 'amount' + invoice.total == BigDecimal(response['amount']) end From 347249df39af1886fb2c999617787b5e7e70a8b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 30 Jan 2020 21:02:07 +0200 Subject: [PATCH 004/110] Introduce Payment Orders to views --- app/views/admin/invoices/show.haml | 2 ++ .../invoices/partials/_payment_orders.haml | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 app/views/registrar/invoices/partials/_payment_orders.haml diff --git a/app/views/admin/invoices/show.haml b/app/views/admin/invoices/show.haml index e3627c158..d0450469f 100644 --- a/app/views/admin/invoices/show.haml +++ b/app/views/admin/invoices/show.haml @@ -21,3 +21,5 @@ .col-md-6= render 'registrar/invoices/partials/buyer' .row .col-md-12= render 'registrar/invoices/partials/items' +.row + .col-md-12= render 'registrar/invoices/partials/payment_orders' diff --git a/app/views/registrar/invoices/partials/_payment_orders.haml b/app/views/registrar/invoices/partials/_payment_orders.haml new file mode 100644 index 000000000..d418ea1ac --- /dev/null +++ b/app/views/registrar/invoices/partials/_payment_orders.haml @@ -0,0 +1,19 @@ +%h4= "Payment Orders" +%hr +.table-responsive + %table.table.table-hover.table-condensed + %thead + %tr + %th{class: 'col-xs-1'}= "#" + %th{class: 'col-xs-1'}= "Channel" + %th{class: 'col-xs-2'}= "Status" + %th{class: 'col-xs-3'}= "Initiated" + %th{class: 'col-xs-4'}= "Notes" + %tbody + - @invoice.payment_orders.each do |payment_order| + %tr + %td= payment_order.id + %td= payment_order.channel + %td= payment_order.status + %td= payment_order.created_at + %td= payment_order.notes From 03b031abeb3e5b60d304bcfcd6a97ee86c98002c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 30 Jan 2020 21:02:43 +0200 Subject: [PATCH 005/110] Make PaymentOrder default status 'issued' --- db/migrate/20200130092113_create_payment_orders.rb | 2 +- db/structure.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/db/migrate/20200130092113_create_payment_orders.rb b/db/migrate/20200130092113_create_payment_orders.rb index 0b0594e56..d3320ee9b 100644 --- a/db/migrate/20200130092113_create_payment_orders.rb +++ b/db/migrate/20200130092113_create_payment_orders.rb @@ -2,7 +2,7 @@ class CreatePaymentOrders < ActiveRecord::Migration[5.0] def change create_table :payment_orders do |t| t.string :type, null: false - t.string :status, default: 0, null: false + t.string :status, default: 'issued', null: false t.belongs_to :invoice, foreign_key: true t.jsonb :response, null: true t.string :notes, null: true diff --git a/db/structure.sql b/db/structure.sql index c664522bb..edf53fe6f 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1824,7 +1824,7 @@ ALTER SEQUENCE public.notifications_id_seq OWNED BY public.notifications.id; CREATE TABLE public.payment_orders ( id integer NOT NULL, type character varying NOT NULL, - status character varying DEFAULT '0'::character varying NOT NULL, + status character varying DEFAULT 'issued'::character varying NOT NULL, invoice_id integer, response jsonb, notes character varying, From 3f5b5962d1797abcc81ab27655621894e4ae741d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Mon, 3 Feb 2020 14:14:31 +0200 Subject: [PATCH 006/110] Make sure that Payment method is functional prior to paying --- .../registrar/payments_controller.rb | 23 +++++----------- app/models/payment_order.rb | 26 +++++++++---------- app/models/payment_orders/lhv.rb | 2 +- app/models/payment_orders/seb.rb | 2 +- config/routes.rb | 10 +++---- 5 files changed, 27 insertions(+), 36 deletions(-) diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index aaa742be5..00b10f34e 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -5,21 +5,14 @@ class Registrar skip_authorization_check # actually anyone can pay, no problems at all skip_before_action :authenticate_registrar_user!, :check_ip_restriction, only: [:back, :callback] - before_action :check_supported_payment_method + + before_action :check_supported_payment_method, only: [:pay] def pay invoice = Invoice.find(params[:invoice_id]) payment_type = params[:bank] - channel = if payment_type == 'every_pay' - 'PaymentOrders::EveryPay' - elsif payment_type == 'seb' - 'PaymentOrders::SEB' - elsif payment_type == 'swed' - 'PaymentOrders::Swed' - elsif payment_type == 'lhv' - 'PaymentOrders::LHV' - end + channel = PaymentOrder.type_from_shortname(payment_type) @payment_order = PaymentOrder.new(type: channel, invoice: invoice) @payment_order.save && @payment_order.reload @@ -31,7 +24,7 @@ class Registrar end def back - @payment_order = PaymentOrder.find_by!(id: params[:bank]) + @payment_order = PaymentOrder.find_by!(id: params[:payment_order]) @payment_order.update!(response: params.to_unsafe_h) if @payment_order.payment_received? @@ -51,7 +44,7 @@ class Registrar end def callback - @payment_order = PaymentOrder.find_by!(id: params[:bank]) + @payment_order = PaymentOrder.find_by!(id: params[:payment_order]) @payment_order.update!(response: params.to_unsafe_h) if @payment_order.payment_received? @@ -68,13 +61,11 @@ class Registrar def check_supported_payment_method return if supported_payment_method? - raise StandardError.new('Not supported payment method') + raise(StandardError, 'Not supported payment method') end def supported_payment_method? - puts "Payment method param is #{params[:bank]}" - # PaymentOrder::PAYMENT_METHODS.include?(params[:bank]) - true + PaymentOrder.supported_method?(params[:bank]) end end end diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index a0d3da254..4ce67d887 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -25,14 +25,14 @@ class PaymentOrder < ApplicationRecord errors.add(:invoice, 'is already paid') end - def self.supported_method?(some_class) - raise ArgumentError unless some_class < PaymentOrder + def self.type_from_shortname(shortname) + ('PaymentOrders::' + shortname.camelize).constantize + end - if PAYMENT_METHODS.include?(some_class.name) - true - else - false - end + def self.supported_method?(some_class) + supported_methods.include? type_from_shortname(some_class) + rescue NameError + false end def complete_transaction(transaction) @@ -52,16 +52,16 @@ class PaymentOrder < ApplicationRecord end def self.supported_methods - enabled = [] + supported = [] - ENABLED_METHODS.each do |method| - class_name = method.constantize - raise(Errors::ExpectedPaymentOrder, class_name) unless class_name < PaymentOrder + PAYMENT_METHODS.each do |method| + class_name = ('PaymentOrders::' + method.camelize).constantize + raise(NoMethodError, class_name) unless class_name < PaymentOrder - enabled << class_name + supported << class_name end - enabled + supported end def channel diff --git a/app/models/payment_orders/lhv.rb b/app/models/payment_orders/lhv.rb index 7443f85d3..4c9f59c4a 100644 --- a/app/models/payment_orders/lhv.rb +++ b/app/models/payment_orders/lhv.rb @@ -1,5 +1,5 @@ module PaymentOrders - class LHV < BankLink + class Lhv < BankLink def self.config_namespace_name 'lhv' end diff --git a/app/models/payment_orders/seb.rb b/app/models/payment_orders/seb.rb index 50fb24ced..878d877a7 100644 --- a/app/models/payment_orders/seb.rb +++ b/app/models/payment_orders/seb.rb @@ -1,5 +1,5 @@ module PaymentOrders - class SEB < BankLink + class Seb < BankLink def self.config_namespace_name 'seb' end diff --git a/config/routes.rb b/config/routes.rb index 135fe8eb0..f77529e4f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -127,11 +127,11 @@ Rails.application.routes.draw do end end - get 'pay/return/:bank' => 'payments#back', as: 'return_payment_with' - post 'pay/return/:bank' => 'payments#back' - put 'pay/return/:bank' => 'payments#back' - post 'pay/callback/:bank' => 'payments#callback', as: 'response_payment_with' - get 'pay/go/:bank' => 'payments#pay', as: 'payment_with' + get 'pay/return/:payment_order' => 'payments#back', as: 'return_payment_with' + post 'pay/return/:payment_order' => 'payments#back' + put 'pay/return/:payment_order' => 'payments#back' + post 'pay/callback/:payment_order' => 'payments#callback', as: 'response_payment_with' + get 'pay/go/:bank' => 'payments#pay', as: 'payment_with' namespace :settings do resource :balance_auto_reload, controller: :balance_auto_reload, only: %i[edit update destroy] From ec5ff5dc8cff26e02e1d03669542fc2a7472b3f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Mon, 3 Feb 2020 15:52:02 +0200 Subject: [PATCH 007/110] Validate inclusion of payment method when saving PaymentOrder --- .../registrar/payments_controller.rb | 5 +- app/models/payment_order.rb | 90 +++++++++++-------- app/models/payment_orders/bank_link.rb | 21 ++--- app/models/payment_orders/every_pay.rb | 19 ++-- 4 files changed, 71 insertions(+), 64 deletions(-) diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index 00b10f34e..736cfe01c 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -28,7 +28,7 @@ class Registrar @payment_order.update!(response: params.to_unsafe_h) if @payment_order.payment_received? - @payment_order.complete_transaction(@payment_order.composed_transaction) + @payment_order.complete_transaction if @payment_order.invoice.paid? flash[:notice] = t(:pending_applied) @@ -65,7 +65,8 @@ class Registrar end def supported_payment_method? - PaymentOrder.supported_method?(params[:bank]) + method_name = PaymentOrder.type_from_shortname(params[:bank]) + PaymentOrder.supported_method?(method_name) end end end diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index 4ce67d887..e204ec5dc 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -9,48 +9,13 @@ class PaymentOrder < ApplicationRecord belongs_to :invoice, optional: false validate :invoice_cannot_be_already_paid, on: :create - # validates :type, inclusion: { in: PAYMENT_METHODS } + validate :supported_payment_method enum status: { issued: 'issued', paid: 'paid', cancelled: 'cancelled', failed: 'failed' } attr_accessor :return_url, :response_url - # Name of configuration namespace - def self.config_namespace_name; end - - def invoice_cannot_be_already_paid - return unless invoice&.paid? - - errors.add(:invoice, 'is already paid') - end - - def self.type_from_shortname(shortname) - ('PaymentOrders::' + shortname.camelize).constantize - end - - def self.supported_method?(some_class) - supported_methods.include? type_from_shortname(some_class) - rescue NameError - false - end - - def complete_transaction(transaction) - paid! - - transaction.save! - transaction.bind_invoice(invoice.number) - - return unless transaction.errors.any? - - worded_errors = 'Failed to bind. ' - transaction.errors.full_messages.each do |err| - worded_errors << "#{err}, " - end - - update!(notes: worded_errors) - end - def self.supported_methods supported = [] @@ -64,6 +29,59 @@ class PaymentOrder < ApplicationRecord supported end + # Name of configuration namespace + def self.config_namespace_name; end + + def supported_payment_method + return if PaymentOrder.supported_method? type.constantize + + errors.add(:type, 'is not supported') + end + + def invoice_cannot_be_already_paid + return unless invoice&.paid? + + errors.add(:invoice, 'is already paid') + end + + def self.type_from_shortname(shortname) + ('PaymentOrders::' + shortname.camelize).constantize + end + + def self.supported_method?(some_class) + supported_methods.include? some_class + rescue NameError + false + end + + def base_transaction(sum:, paid_at:, buyer_name:) + BankTransaction.new( + description: invoice.order, + reference_no: invoice.reference_no, + currency: invoice.currency, + iban: invoice.seller_iban, + sum: sum, + paid_at: paid_at, + buyer_name: buyer_name + ) + end + + def complete_transaction + paid! + transaction = composed_transaction + transaction.save! + transaction.bind_invoice(invoice.number) + + return unless transaction.errors.any? + + worded_errors = 'Failed to bind. ' + transaction.errors.full_messages.each do |err| + worded_errors << "#{err}, " + end + + update!(notes: worded_errors) + end + def channel type.gsub('PaymentOrders::', '') end diff --git a/app/models/payment_orders/bank_link.rb b/app/models/payment_orders/bank_link.rb index c5a8bc54e..5bfd02c48 100644 --- a/app/models/payment_orders/bank_link.rb +++ b/app/models/payment_orders/bank_link.rb @@ -53,25 +53,20 @@ module PaymentOrders end def create_failure_report - notes = "User failed to make valid payment. Bank responded with code #{response['VK_SERVICE']}" + notes = "User failed to make payment. Bank responded with code #{response['VK_SERVICE']}" status = 'cancelled' update!(notes: notes, status: status) end def composed_transaction - transaction = BankTransaction.where(description: invoice.order).first_or_initialize( - description: invoice.order, - reference_no: invoice.reference_no, - currency: invoice.currency, - iban: invoice.seller_iban - ) + paid_at = Time.parse(response['VK_T_DATETIME']) + transaction = base_transaction(sum: response['VK_AMOUNT'], + paid_at: paid_at, + buyer_name: response['VK_SND_NAME']) - transaction.sum = response['VK_AMOUNT'] - transaction.bank_reference = response['VK_T_NO'] + transaction.bank_reference = response['VK_T_NO'] transaction.buyer_bank_code = response['VK_SND_ID'] - transaction.buyer_iban = response['VK_SND_ACC'] - transaction.buyer_name = response['VK_SND_NAME'] - transaction.paid_at = Time.parse(response['VK_T_DATETIME']) + transaction.buyer_iban = response['VK_SND_ACC'] transaction end @@ -80,7 +75,7 @@ module PaymentOrders response['VK_SERVICE'] == SUCCESSFUL_PAYMENT_SERVICE_NUMBER end - # private + private def valid_successful_transaction? valid_success_notice? && valid_amount? && valid_currency? diff --git a/app/models/payment_orders/every_pay.rb b/app/models/payment_orders/every_pay.rb index 53705d1a6..2f848fa82 100644 --- a/app/models/payment_orders/every_pay.rb +++ b/app/models/payment_orders/every_pay.rb @@ -5,7 +5,7 @@ module PaymentOrders ACCOUNT_ID = ENV['payments_every_pay_seller_account'] SUCCESSFUL_PAYMENT = %w[settled authorized].freeze - CONFIG_NAMESPACE = 'every_pay' + CONFIG_NAMESPACE = 'every_pay'.freeze def self.config_namespace_name CONFIG_NAMESPACE @@ -39,18 +39,9 @@ module PaymentOrders end def composed_transaction - transaction = BankTransaction.new( - description: invoice.order, - reference_no: invoice.reference_no, - currency: invoice.currency, - iban: invoice.seller_iban - ) - - transaction.sum = response['amount'] - transaction.paid_at = Date.strptime(response['timestamp'], '%s') - transaction.buyer_name = response['cc_holder_name'] - - transaction + base_transaction(sum: response['amount'], + paid_at: Date.strptime(response['timestamp'], '%s'), + buyer_name: response['cc_holder_name']) end def create_failure_report @@ -59,6 +50,8 @@ module PaymentOrders update!(notes: notes, status: status) end + private + def base_params { api_username: USER, From fa1687baf0c27b1dc9b99af6a59b234cb8c5f4a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Mon, 3 Feb 2020 16:47:04 +0200 Subject: [PATCH 008/110] Add PaperTrail history to PaymentOrders --- app/models/payment_order.rb | 2 +- app/models/version/payment_order_version.rb | 4 ++ .../20200130092113_create_payment_orders.rb | 2 + ...203143458_create_payment_order_versions.rb | 16 +++++ db/structure.sql | 58 ++++++++++++++++++- 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 app/models/version/payment_order_version.rb create mode 100644 db/migrate/20200203143458_create_payment_order_versions.rb diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index e204ec5dc..5449262ba 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -1,5 +1,5 @@ class PaymentOrder < ApplicationRecord - #include Versions + include Versions include ActionView::Helpers::NumberHelper PAYMENT_INTERMEDIARIES = ENV['payments_intermediaries'].to_s.strip.split(', ').freeze diff --git a/app/models/version/payment_order_version.rb b/app/models/version/payment_order_version.rb new file mode 100644 index 000000000..e556f1021 --- /dev/null +++ b/app/models/version/payment_order_version.rb @@ -0,0 +1,4 @@ +class PaymentOrderVersion < PaperTrail::Version + self.table_name = :log_payment_orders + self.sequence_name = :log_payment_orders_id_seq +end diff --git a/db/migrate/20200130092113_create_payment_orders.rb b/db/migrate/20200130092113_create_payment_orders.rb index d3320ee9b..97d86a034 100644 --- a/db/migrate/20200130092113_create_payment_orders.rb +++ b/db/migrate/20200130092113_create_payment_orders.rb @@ -6,6 +6,8 @@ class CreatePaymentOrders < ActiveRecord::Migration[5.0] t.belongs_to :invoice, foreign_key: true t.jsonb :response, null: true t.string :notes, null: true + t.string :creator_str + t.string :updator_str t.timestamps end diff --git a/db/migrate/20200203143458_create_payment_order_versions.rb b/db/migrate/20200203143458_create_payment_order_versions.rb new file mode 100644 index 000000000..d02b300e1 --- /dev/null +++ b/db/migrate/20200203143458_create_payment_order_versions.rb @@ -0,0 +1,16 @@ +class CreatePaymentOrderVersions < ActiveRecord::Migration[5.0] + def change + create_table :log_payment_orders do |t| + t.string :item_type, null: false + t.integer :item_id, null: false + t.string :event, null: false + t.string :whodunnit + t.jsonb :object + t.jsonb :object_changes + t.datetime :created_at + t.string :session + t.jsonb :children + t.string :uuid + end + end +end diff --git a/db/structure.sql b/db/structure.sql index edf53fe6f..d694da536 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1514,6 +1514,44 @@ CREATE SEQUENCE public.log_notifications_id_seq ALTER SEQUENCE public.log_notifications_id_seq OWNED BY public.log_notifications.id; +-- +-- Name: log_payment_orders; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- + +CREATE TABLE public.log_payment_orders ( + id integer NOT NULL, + item_type character varying NOT NULL, + item_id integer NOT NULL, + event character varying NOT NULL, + whodunnit character varying, + object jsonb, + object_changes jsonb, + created_at timestamp without time zone, + session character varying, + children jsonb, + uuid character varying +); + + +-- +-- Name: log_payment_orders_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.log_payment_orders_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: log_payment_orders_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.log_payment_orders_id_seq OWNED BY public.log_payment_orders.id; + + -- -- Name: log_registrant_verifications; Type: TABLE; Schema: public; Owner: -; Tablespace: -- @@ -1828,6 +1866,8 @@ CREATE TABLE public.payment_orders ( invoice_id integer, response jsonb, notes character varying, + creator_str character varying, + updator_str character varying, created_at timestamp without time zone NOT NULL, updated_at timestamp without time zone NOT NULL ); @@ -2533,6 +2573,13 @@ ALTER TABLE ONLY public.log_nameservers ALTER COLUMN id SET DEFAULT nextval('pub ALTER TABLE ONLY public.log_notifications ALTER COLUMN id SET DEFAULT nextval('public.log_notifications_id_seq'::regclass); +-- +-- Name: id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.log_payment_orders ALTER COLUMN id SET DEFAULT nextval('public.log_payment_orders_id_seq'::regclass); + + -- -- Name: id; Type: DEFAULT; Schema: public; Owner: - -- @@ -2945,6 +2992,14 @@ ALTER TABLE ONLY public.log_notifications ADD CONSTRAINT log_notifications_pkey PRIMARY KEY (id); +-- +-- Name: log_payment_orders_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY public.log_payment_orders + ADD CONSTRAINT log_payment_orders_pkey PRIMARY KEY (id); + + -- -- Name: log_registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- @@ -4404,6 +4459,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20191227110904'), ('20200113091254'), ('20200115102202'), -('20200130092113'); +('20200130092113'), +('20200203143458'); From b6469f3dfe63761a1e31dea6a7bb246372a5bc66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Mon, 3 Feb 2020 19:57:52 +0200 Subject: [PATCH 009/110] Move payment method fetching logic to Model, rewrite tests for EveryPay component --- .../registrar/payments_controller.rb | 6 +- app/models/payment_order.rb | 12 ++- app/models/payment_orders/every_pay.rb | 2 + test/fixtures/invoice_items.yml | 7 ++ test/fixtures/invoices.yml | 27 ++++++ test/fixtures/payment_orders.yml | 20 ++++ .../invoices/payment_callback_test.rb | 2 +- test/models/payment_orders/bank_link_test.rb | 20 ++-- test/models/payment_orders/every_pay_test.rb | 96 ++++++++++--------- test/models/payment_orders_test.rb | 24 +++-- 10 files changed, 139 insertions(+), 77 deletions(-) create mode 100644 test/fixtures/payment_orders.yml diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index 736cfe01c..a988dc57e 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -10,11 +10,9 @@ class Registrar def pay invoice = Invoice.find(params[:invoice_id]) - payment_type = params[:bank] + channel = params[:bank] - channel = PaymentOrder.type_from_shortname(payment_type) - - @payment_order = PaymentOrder.new(type: channel, invoice: invoice) + @payment_order = PaymentOrder.create_with_type(type: channel, invoice: invoice) @payment_order.save && @payment_order.reload @payment_order.return_url = registrar_return_payment_with_url(@payment_order) diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index 5449262ba..bc10528fc 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -29,6 +29,12 @@ class PaymentOrder < ApplicationRecord supported end + def self.create_with_type(type:, invoice:) + channel = PaymentOrder.type_from_shortname(type) + + PaymentOrder.new(type: channel, invoice: invoice) + end + # Name of configuration namespace def self.config_namespace_name; end @@ -67,11 +73,11 @@ class PaymentOrder < ApplicationRecord end def complete_transaction + return NoMethodError unless payment_received? + paid! transaction = composed_transaction - transaction.save! - transaction.bind_invoice(invoice.number) - + transaction.save! && transaction.bind_invoice(invoice.number) return unless transaction.errors.any? worded_errors = 'Failed to bind. ' diff --git a/app/models/payment_orders/every_pay.rb b/app/models/payment_orders/every_pay.rb index 2f848fa82..2695c20e0 100644 --- a/app/models/payment_orders/every_pay.rb +++ b/app/models/payment_orders/every_pay.rb @@ -76,6 +76,8 @@ module PaymentOrders hmac_string = hmac_hash.map { |key, _v| "#{key}=#{hmac_hash[key]}" }.join('&') expected_hmac = OpenSSL::HMAC.hexdigest('sha1', KEY, hmac_string) expected_hmac == response['hmac'] + rescue NoMethodError + false end def valid_amount? diff --git a/test/fixtures/invoice_items.yml b/test/fixtures/invoice_items.yml index 19409df81..a61ef4eb0 100644 --- a/test/fixtures/invoice_items.yml +++ b/test/fixtures/invoice_items.yml @@ -4,3 +4,10 @@ one: quantity: 1 unit: pc invoice: one + +two: + description: Acme services + price: 5 + quantity: 1 + unit: pc + invoice: unpaid diff --git a/test/fixtures/invoices.yml b/test/fixtures/invoices.yml index bc9fa2900..6c0dca021 100644 --- a/test/fixtures/invoices.yml +++ b/test/fixtures/invoices.yml @@ -24,3 +24,30 @@ one: reference_no: 13 number: 1 description: Order nr 1 from registrar 1234567 second number 2345678 + +unpaid: + issue_date: <%= Date.parse '2010-07-05' %> + due_date: <%= Date.parse '2010-07-06' %> + currency: EUR + seller_name: Seller Ltd + seller_reg_no: 1234 + seller_iban: US75512108001245126199 + seller_bank: Main Bank + seller_swift: swift + seller_email: info@seller.test + seller_country_code: US + seller_street: Main Street 1 + seller_city: New York + seller_contact_name: John Doe + buyer: bestnames + buyer_name: Buyer Ltd + buyer_reg_no: 12345 + buyer_email: info@buyer.test + buyer_country_code: GB + buyer_street: Main Street 2 + buyer_city: London + vat_rate: 0.1 + total: 16.50 + reference_no: 13 + number: 2 + description: Order nr 2 from registrar 1234567 second number 2345678 diff --git a/test/fixtures/payment_orders.yml b/test/fixtures/payment_orders.yml new file mode 100644 index 000000000..b39d309dc --- /dev/null +++ b/test/fixtures/payment_orders.yml @@ -0,0 +1,20 @@ +issued: + type: PaymentOrders::EveryPay + status: issued + invoice: one + response: + notes: + +paid: + type: PaymentOrders::EveryPay + status: paid + invoice: one + response: "{}" + notes: + +cancelled: + type: PaymentOrders::Seb + status: cancelled + invoice: one + response: "{}" + notes: User failed to make payment. Bank responded with code 1911 diff --git a/test/integration/registrar_area/invoices/payment_callback_test.rb b/test/integration/registrar_area/invoices/payment_callback_test.rb index 23db55e84..c26ffa8c0 100644 --- a/test/integration/registrar_area/invoices/payment_callback_test.rb +++ b/test/integration/registrar_area/invoices/payment_callback_test.rb @@ -12,7 +12,7 @@ class PaymentCallbackTest < ApplicationIntegrationTest invoice = payable_invoice assert_matching_bank_transaction_exists(invoice) - request_params = every_pay_request_params.merge(invoice_id: invoice.id) + request_params = every_pay_request_params.merge(payment_order: invoice.id) post "/registrar/pay/callback/every_pay", params: request_params assert_response :ok diff --git a/test/models/payment_orders/bank_link_test.rb b/test/models/payment_orders/bank_link_test.rb index f1069819c..775e82cf9 100644 --- a/test/models/payment_orders/bank_link_test.rb +++ b/test/models/payment_orders/bank_link_test.rb @@ -36,11 +36,11 @@ class BankLinkTest < ActiveSupport::TestCase 'VK_MAC': 'CZZvcptkxfuOxRR88JmT4N+Lw6Hs4xiQfhBWzVYldAcRTQbcB/lPf9MbJzBE4e1/HuslQgkdCFt5g1xW2lJwrVDBQTtP6DAHfvxU3kkw7dbk0IcwhI4whUl68/QCwlXEQTAVDv1AFnGVxXZ40vbm/aLKafBYgrirB5SUe8+g9FE=', 'VK_ENCODING': 'UTF-8', 'VK_LANG': 'ENG' - }.with_indifferent_access + }.as_json - @completed_bank_link = PaymentOrders::BankLink.new( - 'seb', @invoice, { response: params } - ) + @completed_bank_link = PaymentOrder.new(type: 'PaymentOrders::Seb', + invoice: @invoice, + response: params) end def create_cancelled_bank_link @@ -55,16 +55,18 @@ class BankLinkTest < ActiveSupport::TestCase 'VK_MAC': 'PElE2mYXXN50q2UBvTuYU1rN0BmOQcbafPummDnWfNdm9qbaGQkGyOn0XaaFGlrdEcldXaHBbZKUS0HegIgjdDfl2NOk+wkLNNH0Iu38KzZaxHoW9ga7vqiyKHC8dcxkHiO9HsOnz77Sy/KpWCq6cz48bi3fcMgo+MUzBMauWoQ=', 'VK_ENCODING': 'UTF-8', 'VK_LANG': 'ENG' - }.with_indifferent_access + }.as_json - @cancelled_bank_link = PaymentOrders::BankLink.new( - 'seb', @invoice, { response: params } - ) + @cancelled_bank_link = PaymentOrder.new(type: 'PaymentOrders::Seb', + invoice: @invoice, + response: params) end def create_new_bank_link params = { return_url: 'return.url', response_url: 'response.url' } - @new_bank_link = PaymentOrders::BankLink.new('seb', @invoice, params) + @new_bank_link = PaymentOrder.new(type: 'PaymentOrders::Seb', invoice: @invoice) + @new_bank_link.return_url = 'return.url' + @new_bank_link.response_url = 'response.url' end def test_response_is_not_valid_when_it_is_missing diff --git a/test/models/payment_orders/every_pay_test.rb b/test/models/payment_orders/every_pay_test.rb index 202efc1b7..1e560f32a 100644 --- a/test/models/payment_orders/every_pay_test.rb +++ b/test/models/payment_orders/every_pay_test.rb @@ -4,36 +4,38 @@ class EveryPayTest < ActiveSupport::TestCase def setup super - @invoice = invoices(:one) + @invoice = invoices(:unpaid) @invoice.update!(total: 12) - params = { - response: - { - utf8: '✓', - _method: 'put', - authenticity_token: 'OnA69vbccQtMt3C9wxEWigs5Gpf/7z+NoxRCMkFPlTvaATs8+OgMKF1I4B2f+vuK37zCgpWZaWWtyuslRRSwkw==', - nonce: '392f2d7748bc8cb0d14f263ebb7b8932', - timestamp: '1524136727', - api_username: 'ca8d6336dd750ddb', - transaction_result: 'completed', - payment_reference: 'fd5d27b59a1eb597393cd5ff77386d6cab81ae05067e18d530b10f3802e30b56', - payment_state: 'settled', - amount: '12.00', - order_reference: 'e468a2d59a731ccc546f2165c3b1a6', - account_id: 'EUR3D1', - cc_type: 'master_card', - cc_last_four_digits: '0487', - cc_month: '10', - cc_year: '2018', - cc_holder_name: 'John Doe', - hmac_fields: 'account_id,amount,api_username,cc_holder_name,cc_last_four_digits,cc_month,cc_type,cc_year,hmac_fields,nonce,order_reference,payment_reference,payment_state,timestamp,transaction_result', - hmac: 'efac1c732835668cd86023a7abc140506c692f0d', - invoice_id: '1', - }, - } - @every_pay = PaymentOrders::EveryPay.new('every_pay', @invoice, params) - @other_pay = PaymentOrders::EveryPay.new('every_pay', @invoice, {}) + response = { + "utf8": '✓', + "_method": 'put', + "authenticity_token": 'OnA69vbccQtMt3C9wxEWigs5Gpf/7z+NoxRCMkFPlTvaATs8+OgMKF1I4B2f+vuK37zCgpWZaWWtyuslRRSwkw=="', + "nonce": '392f2d7748bc8cb0d14f263ebb7b8932', + "timestamp": '1524136727', + "api_username": 'ca8d6336dd750ddb', + "transaction_result": 'completed', + "payment_reference": 'fd5d27b59a1eb597393cd5ff77386d6cab81ae05067e18d530b10f3802e30b56', + "payment_state": 'settled', + "amount": '12.00', + "order_reference": 'e468a2d59a731ccc546f2165c3b1a6', + "account_id": 'EUR3D1', + "cc_type": 'master_card', + "cc_last_four_digits": '0487', + "cc_month": '10', + "cc_year": '2018', + "cc_holder_name": 'John Doe', + "hmac_fields": 'account_id,amount,api_username,cc_holder_name,cc_last_four_digits,cc_month,cc_type,cc_year,hmac_fields,nonce,order_reference,payment_reference,payment_state,timestamp,transaction_result', + "hmac": 'efac1c732835668cd86023a7abc140506c692f0d', + "invoice_id": '2' + }.as_json + + @successful_payment = PaymentOrder.new(type: 'PaymentOrders::EveryPay', + invoice: @invoice, + response: response) + + @failed_payment = @successful_payment.dup + @failed_payment.response['payment_state'] = 'cancelled' travel_to Time.zone.parse('2018-04-01 00:30:00 +0000') end @@ -47,37 +49,37 @@ class EveryPayTest < ActiveSupport::TestCase transaction_type: 'charge', hmac_fields: 'account_id,amount,api_username,callback_url,customer_url,hmac_fields,nonce,order_reference,timestamp,transaction_type' } - form_fields = @every_pay.form_fields + form_fields = @successful_payment.form_fields expected_fields.each do |k, v| assert_equal(v, form_fields[k]) end end def test_valid_response_from_intermediary? - assert(@every_pay.valid_response_from_intermediary?) - refute(@other_pay.valid_response_from_intermediary?) + assert(@successful_payment.valid_response_from_intermediary?) + + @failed_payment.response = { 'what': 'definitely not valid everypay response' } + refute(@failed_payment.valid_response_from_intermediary?) + end + + def test_valid_and_successful_payment_is_determined + assert(@successful_payment.payment_received?) + refute(@failed_payment.payment_received?) end def test_settled_payment? - assert(@every_pay.settled_payment?) - other_pay = PaymentOrders::EveryPay.new( - 'every_pay', @invoice, {response: {payment_state: 'CANCELLED'}} - ) - refute(other_pay.settled_payment?) + assert(@successful_payment.settled_payment?) + refute(@failed_payment.settled_payment?) end - def test_complete_transaction_calls_methods_on_transaction - mock_transaction = MiniTest::Mock.new - mock_transaction.expect(:sum= , '12.00', ['12.00']) - mock_transaction.expect(:paid_at= , Date.strptime('1524136727', '%s'), [Date.strptime('1524136727', '%s')]) - mock_transaction.expect(:buyer_name=, 'John Doe', ['John Doe']) - mock_transaction.expect(:save!, true) - mock_transaction.expect(:autobind_invoice, AccountActivity.new) + def test_successful_payment_creates_bank_transaction + @successful_payment.complete_transaction - BankTransaction.stub(:find_by, mock_transaction) do - @every_pay.complete_transaction - end + transaction = BankTransaction.find_by( + sum: @successful_payment.response['amount'], + buyer_name: @successful_payment.response['cc_holder_name'] + ) - mock_transaction.verify + assert transaction.present? end end diff --git a/test/models/payment_orders_test.rb b/test/models/payment_orders_test.rb index 252ba0582..3027bb60e 100644 --- a/test/models/payment_orders_test.rb +++ b/test/models/payment_orders_test.rb @@ -5,23 +5,21 @@ class PaymentOrdersTest < ActiveSupport::TestCase super @original_methods = ENV['payment_methods'] - @original_seb_URL = ENV['seb_payment_url'] - ENV['payment_methods'] = 'seb, swed, credit_card' + @original_seb_url = ENV['seb_payment_url'] + ENV['payment_methods'] = 'seb, swed, every_pay' ENV['seb_payment_url'] = nil - @not_implemented_payment = PaymentOrders::Base.new( - 'not_implemented', Invoice.new - ) + @not_implemented_payment = PaymentOrder.new(invoice: Invoice.new) end def teardown super ENV['payment_methods'] = @original_methods - ENV['seb_payment_url'] = @original_seb_URL + ENV['seb_payment_url'] = @original_seb_url end def test_variable_assignment - assert_equal 'not_implemented', @not_implemented_payment.type + assert_nil @not_implemented_payment.type assert_nil @not_implemented_payment.response_url assert_nil @not_implemented_payment.return_url assert_nil @not_implemented_payment.form_url @@ -45,14 +43,14 @@ class PaymentOrdersTest < ActiveSupport::TestCase end end - def test_that_create_with_type_raises_argument_error - assert_raise ArgumentError do - PaymentOrders.create_with_type("not_implemented", Invoice.new) + def test_can_not_create_order_with_invalid_type + assert_raise NameError do + PaymentOrder.create_with_type(type: 'not_implemented', invoice: Invoice.new) end end - def test_create_with_correct_subclass - payment = PaymentOrders.create_with_type('seb', Invoice.new) - assert_equal PaymentOrders::BankLink, payment.class + def test_can_create_with_correct_subclass + payment = PaymentOrder.create_with_type(type: 'seb', invoice: Invoice.new) + assert_equal PaymentOrders::Seb, payment.class end end From 6418924fafda1a7e1b46f1f2f4c5670b13e15d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Tue, 4 Feb 2020 09:42:26 +0200 Subject: [PATCH 010/110] Cover EveryPay / BankLink payments with tests --- .../registrar/payments_controller.rb | 7 +- app/models/payment_order.rb | 15 ++-- test/fixtures/payment_orders.yml | 13 +++- .../invoices/payment_callback_test.rb | 44 ++++++------ .../invoices/payment_return_test.rb | 68 ++++++++++++++++--- test/models/payment_orders/bank_link_test.rb | 38 ++++++----- test/models/payment_orders_test.rb | 21 ++++++ 7 files changed, 145 insertions(+), 61 deletions(-) diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index a988dc57e..e356f7049 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -57,14 +57,9 @@ class Registrar private def check_supported_payment_method - return if supported_payment_method? + return if PaymentOrder.supported_method?(params[:bank], shortname: true) raise(StandardError, 'Not supported payment method') end - - def supported_payment_method? - method_name = PaymentOrder.type_from_shortname(params[:bank]) - PaymentOrder.supported_method?(method_name) - end end end diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index bc10528fc..b6fea65be 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -30,7 +30,7 @@ class PaymentOrder < ApplicationRecord end def self.create_with_type(type:, invoice:) - channel = PaymentOrder.type_from_shortname(type) + channel = ('PaymentOrders::' + type.camelize).constantize PaymentOrder.new(type: channel, invoice: invoice) end @@ -39,7 +39,7 @@ class PaymentOrder < ApplicationRecord def self.config_namespace_name; end def supported_payment_method - return if PaymentOrder.supported_method? type.constantize + return if PaymentOrder.supported_method?(type) errors.add(:type, 'is not supported') end @@ -50,11 +50,12 @@ class PaymentOrder < ApplicationRecord errors.add(:invoice, 'is already paid') end - def self.type_from_shortname(shortname) - ('PaymentOrders::' + shortname.camelize).constantize - end - - def self.supported_method?(some_class) + def self.supported_method?(name, shortname: false) + some_class = if shortname + ('PaymentOrders::' + name.camelize).constantize + else + name.constantize + end supported_methods.include? some_class rescue NameError false diff --git a/test/fixtures/payment_orders.yml b/test/fixtures/payment_orders.yml index b39d309dc..39289b7d1 100644 --- a/test/fixtures/payment_orders.yml +++ b/test/fixtures/payment_orders.yml @@ -1,20 +1,27 @@ -issued: +everypay_issued: type: PaymentOrders::EveryPay status: issued invoice: one response: notes: +banklink_issued: + type: PaymentOrders::Seb + status: issued + invoice: one + response: + notes: + paid: type: PaymentOrders::EveryPay status: paid - invoice: one + invoice: unpaid response: "{}" notes: cancelled: type: PaymentOrders::Seb status: cancelled - invoice: one + invoice: unpaid response: "{}" notes: User failed to make payment. Bank responded with code 1911 diff --git a/test/integration/registrar_area/invoices/payment_callback_test.rb b/test/integration/registrar_area/invoices/payment_callback_test.rb index c26ffa8c0..94ca6e373 100644 --- a/test/integration/registrar_area/invoices/payment_callback_test.rb +++ b/test/integration/registrar_area/invoices/payment_callback_test.rb @@ -6,34 +6,40 @@ class PaymentCallbackTest < ApplicationIntegrationTest @user = users(:api_bestnames) sign_in @user + + @payment_order = payment_orders(:everypay_issued) + @invoice = invoices(:one) + @invoice.update!(account_activity: nil, total: 12) end def test_every_pay_callback_returns_status_200 - invoice = payable_invoice - assert_matching_bank_transaction_exists(invoice) - - request_params = every_pay_request_params.merge(payment_order: invoice.id) - post "/registrar/pay/callback/every_pay", params: request_params + request_params = every_pay_request_params + post "/registrar/pay/callback/#{@payment_order.id}", params: request_params assert_response :ok end + def test_invoice_is_marked_as_paid + request_params = every_pay_request_params + post "/registrar/pay/callback/#{@payment_order.id}", params: request_params + + assert @payment_order.invoice.paid? + end + + def failure_log_is_created_if_unsuccessful_payment + request_params = every_pay_request_params.dup + request_params['payment_state'] = 'cancelled' + request_params['transaction_result'] = 'failed' + + post "/registrar/pay/callback/#{@payment_order.id}", params: request_params + + @payment_order.reload + assert @payment_order.cancelled? + assert_includes @payment_order.notes, 'Payment state: cancelled' + end + private - def payable_invoice - invoice = invoices(:one) - invoice.update!(account_activity: nil) - invoice - end - - def assert_matching_bank_transaction_exists(invoice) - assert BankTransaction.find_by( - description: invoice.description, - currency: invoice.currency, - iban: invoice.seller_iban - ), 'Matching bank transaction should exist' - end - def every_pay_request_params { nonce: "392f2d7748bc8cb0d14f263ebb7b8932", diff --git a/test/integration/registrar_area/invoices/payment_return_test.rb b/test/integration/registrar_area/invoices/payment_return_test.rb index de65cccb0..a4adb8160 100644 --- a/test/integration/registrar_area/invoices/payment_return_test.rb +++ b/test/integration/registrar_area/invoices/payment_return_test.rb @@ -8,6 +8,9 @@ class PaymentReturnTest < ApplicationIntegrationTest sign_in @user @invoice = invoices(:one) + @invoice.update!(account_activity: nil, total: 12) + @everypay_order = payment_orders(:everypay_issued) + @banklink_order = payment_orders(:banklink_issued) end def every_pay_request_params @@ -57,33 +60,78 @@ class PaymentReturnTest < ApplicationIntegrationTest } end - def test_every_pay_return_creates_activity_redirects_to_invoice_path - request_params = every_pay_request_params.merge(invoice_id: @invoice.id) + def test_successful_bank_payment_marks_invoice_as_paid + @invoice.update!(account_activity: nil) + request_params = bank_link_request_params - post "/registrar/pay/return/every_pay", params: request_params + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + + @banklink_order.reload + assert @banklink_order.invoice.paid? + end + + def test_every_pay_return_creates_activity_redirects_to_invoice_path + request_params = every_pay_request_params + + post "/registrar/pay/return/#{@everypay_order.id}", params: request_params assert_equal(302, response.status) assert_redirected_to(registrar_invoice_path(@invoice)) end - def test_Every_Pay_return_raises_RecordNotFound - request_params = every_pay_request_params.merge(invoice_id: "178907") + def test_every_pay_return_raises_record_not_found + request_params = every_pay_request_params assert_raises(ActiveRecord::RecordNotFound) do - post "/registrar/pay/return/every_pay", params: request_params + post '/registrar/pay/return/123456', params: request_params end end def test_bank_link_return_redirects_to_invoice_paths - request_params = bank_link_request_params.merge(invoice_id: @invoice.id) + request_params = bank_link_request_params - post "/registrar/pay/return/seb", params: request_params + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params assert_equal(302, response.status) assert_redirected_to(registrar_invoice_path(@invoice)) end def test_bank_link_return - request_params = bank_link_request_params.merge(invoice_id: "178907") + request_params = bank_link_request_params assert_raises(ActiveRecord::RecordNotFound) do - post "/registrar/pay/return/seb", params: request_params + post '/registrar/pay/return/123456', params: request_params end end + + def test_marks_as_paid_and_adds_notes_if_failed_to_bind + request_params = bank_link_request_params + + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + @banklink_order.reload + + assert @banklink_order.notes.present? + assert @banklink_order.paid? + assert_includes @banklink_order.notes, 'Failed to bind' + end + + def test_failed_bank_link_payment_creates_brief_error_explanation + request_params = bank_link_request_params.dup + request_params['VK_SERVICE'] = '1911' + + post "/registrar/pay/return/#{@banklink_order.id}", params: request_params + + @banklink_order.reload + + assert_includes @banklink_order.notes, 'Bank responded with code 1911' + end + + def test_failed_every_pay_payment_creates_brief_error_explanation + request_params = every_pay_request_params.dup + request_params['payment_state'] = 'cancelled' + request_params['transaction_result'] = 'failed' + + post "/registrar/pay/return/#{@everypay_order.id}", params: request_params + + @everypay_order.reload + + assert_includes @everypay_order.notes, 'Payment state: cancelled' + end end diff --git a/test/models/payment_orders/bank_link_test.rb b/test/models/payment_orders/bank_link_test.rb index 775e82cf9..7f7897f5f 100644 --- a/test/models/payment_orders/bank_link_test.rb +++ b/test/models/payment_orders/bank_link_test.rb @@ -8,7 +8,7 @@ class BankLinkTest < ActiveSupport::TestCase super @invoice = invoices(:one) - @invoice.update!(total: 12) + @invoice.update!(account_activity: nil, total: 12) travel_to '2018-04-01 00:30 +0300' create_new_bank_link @@ -63,7 +63,6 @@ class BankLinkTest < ActiveSupport::TestCase end def create_new_bank_link - params = { return_url: 'return.url', response_url: 'response.url' } @new_bank_link = PaymentOrder.new(type: 'PaymentOrders::Seb', invoice: @invoice) @new_bank_link.return_url = 'return.url' @new_bank_link.response_url = 'response.url' @@ -94,6 +93,20 @@ class BankLinkTest < ActiveSupport::TestCase assert_equal(expected_response, @new_bank_link.form_fields) end + def test_correct_channel_is_assigned + swed_link = PaymentOrder.create_with_type(type: 'swed', invoice: @invoice) + assert_equal swed_link.channel, 'Swed' + assert_equal swed_link.class.config_namespace_name, 'swed' + + seb_link = PaymentOrder.create_with_type(type: 'seb', invoice: @invoice) + assert_equal seb_link.channel, 'Seb' + assert_equal seb_link.class.config_namespace_name, 'seb' + + lhv_link = PaymentOrder.create_with_type(type: 'lhv', invoice: @invoice) + assert_equal lhv_link.channel, 'Lhv' + assert_equal lhv_link.class.config_namespace_name, 'lhv' + end + def test_valid_success_response_from_intermediary? assert(@completed_bank_link.valid_response_from_intermediary?) end @@ -107,21 +120,14 @@ class BankLinkTest < ActiveSupport::TestCase refute(@cancelled_bank_link.settled_payment?) end - def test_complete_transaction_calls_methods_on_transaction - mock_transaction = MiniTest::Mock.new - mock_transaction.expect(:sum= , '12.00', ['12.00']) - mock_transaction.expect(:bank_reference= , '1', ['1']) - mock_transaction.expect(:buyer_bank_code= , 'testvpos', ['testvpos']) - mock_transaction.expect(:buyer_iban= , '1234', ['1234']) - mock_transaction.expect(:paid_at= , Date.parse('2018-04-01 00:30:00 +0300'), [Time.parse('2018-04-01T00:30:00+0300')]) - mock_transaction.expect(:buyer_name=, 'John Doe', ['John Doe']) - mock_transaction.expect(:save!, true) - mock_transaction.expect(:autobind_invoice, AccountActivity.new) + def test_successful_payment_creates_bank_transaction + @completed_bank_link.complete_transaction - BankTransaction.stub(:find_by, mock_transaction) do - @completed_bank_link.complete_transaction - end + transaction = BankTransaction.find_by( + sum: @completed_bank_link.response['VK_AMOUNT'], + buyer_name: @completed_bank_link.response['VK_SND_NAME'] + ) - mock_transaction.verify + assert transaction.present? end end diff --git a/test/models/payment_orders_test.rb b/test/models/payment_orders_test.rb index 3027bb60e..3f72dcf8f 100644 --- a/test/models/payment_orders_test.rb +++ b/test/models/payment_orders_test.rb @@ -43,12 +43,33 @@ class PaymentOrdersTest < ActiveSupport::TestCase end end + def test_can_not_create_order_for_paid_invoice + invoice = invoices(:one) + payment_order = PaymentOrder.create_with_type(type: 'every_pay', invoice: invoice) + assert payment_order.invalid? + assert_includes payment_order.errors[:invoice], 'is already paid' + end + + def test_order_without_channel_is_invalid + payment_order = PaymentOrder.new + assert payment_order.invalid? + assert_includes payment_order.errors[:type], 'is not supported' + end + def test_can_not_create_order_with_invalid_type assert_raise NameError do PaymentOrder.create_with_type(type: 'not_implemented', invoice: Invoice.new) end end + def test_supported_method_bool_does_not_fail + assert_not PaymentOrder.supported_method?('not_implemented', shortname: true) + assert PaymentOrder.supported_method?('every_pay', shortname: true) + + assert_not PaymentOrder.supported_method?('PaymentOrders::NonExistant') + assert PaymentOrder.supported_method?('PaymentOrders::EveryPay') + end + def test_can_create_with_correct_subclass payment = PaymentOrder.create_with_type(type: 'seb', invoice: Invoice.new) assert_equal PaymentOrders::Seb, payment.class From 2645654aefbc4c3086395110e25cc647fc0857d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Tue, 4 Feb 2020 18:36:06 +0200 Subject: [PATCH 011/110] Create System / Admin payment log --- .../admin/bank_statements_controller.rb | 2 +- .../admin/bank_transactions_controller.rb | 2 +- app/models/bank_statement.rb | 8 ++- app/models/bank_transaction.rb | 63 +++++++++++++------ app/models/payment_order.rb | 4 +- app/models/payment_orders/admin_payment.rb | 9 +++ app/models/payment_orders/system_payment.rb | 9 +++ test/models/payment_orders/bank_link_test.rb | 14 ----- test/models/payment_orders_test.rb | 26 ++++++++ test/tasks/invoices/process_payments_test.rb | 26 +++++++- 10 files changed, 122 insertions(+), 41 deletions(-) create mode 100644 app/models/payment_orders/admin_payment.rb create mode 100644 app/models/payment_orders/system_payment.rb diff --git a/app/controllers/admin/bank_statements_controller.rb b/app/controllers/admin/bank_statements_controller.rb index a70387317..1e3b31bf5 100644 --- a/app/controllers/admin/bank_statements_controller.rb +++ b/app/controllers/admin/bank_statements_controller.rb @@ -60,7 +60,7 @@ module Admin end def bind_invoices - @bank_statement.bind_invoices + @bank_statement.bind_invoices(manual: true) flash[:notice] = t('invoices_were_fully_binded') if @bank_statement.fully_binded? flash[:warning] = t('invoices_were_partially_binded') if @bank_statement.partially_binded? diff --git a/app/controllers/admin/bank_transactions_controller.rb b/app/controllers/admin/bank_transactions_controller.rb index 1ce62b279..348cadc64 100644 --- a/app/controllers/admin/bank_transactions_controller.rb +++ b/app/controllers/admin/bank_transactions_controller.rb @@ -34,7 +34,7 @@ module Admin end def bind - if @bank_transaction.bind_invoice(params[:invoice_no]) + if @bank_transaction.bind_invoice(params[:invoice_no], manual: true) flash[:notice] = I18n.t('record_created') redirect_to [:admin, @bank_transaction] else diff --git a/app/models/bank_statement.rb b/app/models/bank_statement.rb index 8d4608f64..ace1e922d 100644 --- a/app/models/bank_statement.rb +++ b/app/models/bank_statement.rb @@ -45,7 +45,7 @@ class BankStatement < ApplicationRecord buyer_name: row[83, 35].strip, document_no: row[118, 8].strip, description: row[126, 140].strip, - sum: BigDecimal.new(row[268, 12].strip) / BigDecimal.new('100.0'), + sum: BigDecimal(row[268, 12].strip) / BigDecimal('100.0'), reference_no: row[280, 35].strip } end @@ -80,7 +80,9 @@ class BankStatement < ApplicationRecord status == FULLY_BINDED end - def bind_invoices - bank_transactions.unbinded.each(&:autobind_invoice) + def bind_invoices(manual: false) + bank_transactions.unbinded.each do |transaction| + transaction.autobind_invoice(manual: manual) + end end end diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index 792a32484..25c6b60e9 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -13,6 +13,7 @@ class BankTransaction < ApplicationRecord def binded_invoice return unless binded? + account_activity.invoice end @@ -31,28 +32,54 @@ class BankTransaction < ApplicationRecord end # For successful binding, reference number, invoice id and sum must match with the invoice - def autobind_invoice + def autobind_invoice(manual: false) return if binded? return unless registrar return unless invoice return unless invoice.payable? - create_activity(registrar, invoice) + channel = if manual + 'admin_payment' + else + 'system_payment' + end + record_system_payment(channel: channel, invoice: invoice, registrar: registrar) end - def bind_invoice(invoice_no) + def record_system_payment(channel: nil, invoice:, registrar:) + if channel.nil? + create_activity(invoice.buyer, invoice) + return + end + + payment_order = PaymentOrder.create_with_type(type: channel, invoice: invoice) + payment_order.save! + + if create_activity(registrar, invoice) + payment_order.paid! + else + payment_order.failed! + payment_order.notes = 'Failed to create activity' + payment_order.save! + end + end + + def bind_invoice(invoice_no, manual: false) if binded? errors.add(:base, I18n.t('transaction_is_already_binded')) return end invoice = Invoice.find_by(number: invoice_no) + errors.add(:base, I18n.t('invoice_was_not_found')) unless invoice + validate_invoice_data(invoice) + return if errors.any? - unless invoice - errors.add(:base, I18n.t('invoice_was_not_found')) - return - end + record_system_payment(channel: (manual ? 'admin_payment' : nil), invoice: invoice, + registrar: invoice.buyer) + end + def validate_invoice_data(invoice) if invoice.paid? errors.add(:base, I18n.t('invoice_is_already_binded')) return @@ -63,23 +90,19 @@ class BankTransaction < ApplicationRecord return end - if invoice.total != sum - errors.add(:base, I18n.t('invoice_and_transaction_sums_do_not_match')) - return - end - - create_activity(invoice.buyer, invoice) + errors.add(:base, I18n.t('invoice_and_transaction_sums_do_not_match')) if invoice.total != sum end def create_activity(registrar, invoice) - ActiveRecord::Base.transaction do - create_account_activity!(account: registrar.cash_account, - invoice: invoice, - sum: invoice.subtotal, - currency: currency, - description: description, - activity_type: AccountActivity::ADD_CREDIT) + activity = AccountActivity.new(account: registrar.cash_account, + invoice: invoice, sum: invoice.subtotal, + currency: currency, description: description, + activity_type: AccountActivity::ADD_CREDIT) + if activity.save reset_pending_registrar_balance_reload + true + else + false end end diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index b6fea65be..c2cc883a6 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -4,7 +4,9 @@ class PaymentOrder < ApplicationRecord PAYMENT_INTERMEDIARIES = ENV['payments_intermediaries'].to_s.strip.split(', ').freeze PAYMENT_BANKLINK_BANKS = ENV['payments_banks'].to_s.strip.split(', ').freeze - PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS].flatten.freeze + INTERNAL_PAYMENT_METHODS = %w[admin_payment system_payment].freeze + PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS, + INTERNAL_PAYMENT_METHODS].flatten.freeze belongs_to :invoice, optional: false diff --git a/app/models/payment_orders/admin_payment.rb b/app/models/payment_orders/admin_payment.rb new file mode 100644 index 000000000..05ae061fb --- /dev/null +++ b/app/models/payment_orders/admin_payment.rb @@ -0,0 +1,9 @@ +module PaymentOrders + class AdminPayment < PaymentOrder + CONFIG_NAMESPACE = 'admin_payment'.freeze + + def self.config_namespace_name + CONFIG_NAMESPACE + end + end +end diff --git a/app/models/payment_orders/system_payment.rb b/app/models/payment_orders/system_payment.rb new file mode 100644 index 000000000..47c75ebe3 --- /dev/null +++ b/app/models/payment_orders/system_payment.rb @@ -0,0 +1,9 @@ +module PaymentOrders + class SystemPayment < PaymentOrder + CONFIG_NAMESPACE = 'system_payment'.freeze + + def self.config_namespace_name + CONFIG_NAMESPACE + end + end +end diff --git a/test/models/payment_orders/bank_link_test.rb b/test/models/payment_orders/bank_link_test.rb index 7f7897f5f..30d91cb7c 100644 --- a/test/models/payment_orders/bank_link_test.rb +++ b/test/models/payment_orders/bank_link_test.rb @@ -93,20 +93,6 @@ class BankLinkTest < ActiveSupport::TestCase assert_equal(expected_response, @new_bank_link.form_fields) end - def test_correct_channel_is_assigned - swed_link = PaymentOrder.create_with_type(type: 'swed', invoice: @invoice) - assert_equal swed_link.channel, 'Swed' - assert_equal swed_link.class.config_namespace_name, 'swed' - - seb_link = PaymentOrder.create_with_type(type: 'seb', invoice: @invoice) - assert_equal seb_link.channel, 'Seb' - assert_equal seb_link.class.config_namespace_name, 'seb' - - lhv_link = PaymentOrder.create_with_type(type: 'lhv', invoice: @invoice) - assert_equal lhv_link.channel, 'Lhv' - assert_equal lhv_link.class.config_namespace_name, 'lhv' - end - def test_valid_success_response_from_intermediary? assert(@completed_bank_link.valid_response_from_intermediary?) end diff --git a/test/models/payment_orders_test.rb b/test/models/payment_orders_test.rb index 3f72dcf8f..67267fec0 100644 --- a/test/models/payment_orders_test.rb +++ b/test/models/payment_orders_test.rb @@ -43,6 +43,32 @@ class PaymentOrdersTest < ActiveSupport::TestCase end end + def test_correct_channel_is_assigned + everypay_channel = PaymentOrder.create_with_type(type: 'every_pay', invoice: @invoice) + assert_equal everypay_channel.channel, 'EveryPay' + assert_equal everypay_channel.class.config_namespace_name, 'every_pay' + + swed_channel = PaymentOrder.create_with_type(type: 'swed', invoice: @invoice) + assert_equal swed_channel.channel, 'Swed' + assert_equal swed_channel.class.config_namespace_name, 'swed' + + seb_channel = PaymentOrder.create_with_type(type: 'seb', invoice: @invoice) + assert_equal seb_channel.channel, 'Seb' + assert_equal seb_channel.class.config_namespace_name, 'seb' + + lhv_channel = PaymentOrder.create_with_type(type: 'lhv', invoice: @invoice) + assert_equal lhv_channel.channel, 'Lhv' + assert_equal lhv_channel.class.config_namespace_name, 'lhv' + + admin_channel = PaymentOrder.create_with_type(type: 'admin_payment', invoice: @invoice) + assert_equal admin_channel.channel, 'AdminPayment' + assert_equal admin_channel.class.config_namespace_name, 'admin_payment' + + system_channel = PaymentOrder.create_with_type(type: 'system_payment', invoice: @invoice) + assert_equal system_channel.channel, 'SystemPayment' + assert_equal system_channel.class.config_namespace_name, 'system_payment' + end + def test_can_not_create_order_for_paid_invoice invoice = invoices(:one) payment_order = PaymentOrder.create_with_type(type: 'every_pay', invoice: invoice) diff --git a/test/tasks/invoices/process_payments_test.rb b/test/tasks/invoices/process_payments_test.rb index 8c3b6ec73..02855e9fa 100644 --- a/test/tasks/invoices/process_payments_test.rb +++ b/test/tasks/invoices/process_payments_test.rb @@ -58,6 +58,30 @@ class ProcessPaymentsTaskTest < ActiveSupport::TestCase assert @invoice.paid? end + def test_attaches_paid_payment_order_to_invoice + assert @invoice.unpaid? + + capture_io { run_task } + @invoice.reload + + payment_order = @invoice.payment_orders.last + assert_equal 'PaymentOrders::SystemPayment', payment_order.type + assert payment_order.paid? + end + + def test_attaches_failed_payment_order_to_invoice + assert @invoice.unpaid? + account = accounts(:cash) + account.update!(registrar: registrars(:goodnames)) + + capture_io { run_task } + @invoice.reload + + payment_order = @invoice.payment_orders.last + assert_equal 'PaymentOrders::SystemPayment', payment_order.type + assert payment_order.failed? + end + def test_output assert_output "Transactions processed: 1\n" do run_task @@ -75,4 +99,4 @@ class ProcessPaymentsTaskTest < ActiveSupport::TestCase invoice.update!({ account_activity: nil, cancelled_at: nil }.merge(attributes)) invoice end -end \ No newline at end of file +end From 37e7def669a9334bfe6f9decbe9ae0619b20d308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Tue, 4 Feb 2020 21:11:30 +0200 Subject: [PATCH 012/110] Provide better context for EveryPay / Banklink payment state alerts --- app/controllers/registrar/payments_controller.rb | 7 +++---- config/locales/registrar/payments.en.yml | 7 +++++++ 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 config/locales/registrar/payments.en.yml diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index e356f7049..c1944767f 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -29,14 +29,13 @@ class Registrar @payment_order.complete_transaction if @payment_order.invoice.paid? - flash[:notice] = t(:pending_applied) + flash[:notice] = t('.payment_successful') else - # flash[:alert] = t(:something_wrong) - flash[:alert] = 'We fucked up' + flash[:alert] = t('.successful_payment_backend_error') end else @payment_order.create_failure_report - flash[:alert] = t(:something_wrong) + flash[:alert] = t('.payment_not_received') end redirect_to registrar_invoice_path(@payment_order.invoice) end diff --git a/config/locales/registrar/payments.en.yml b/config/locales/registrar/payments.en.yml new file mode 100644 index 000000000..9c817e0ea --- /dev/null +++ b/config/locales/registrar/payments.en.yml @@ -0,0 +1,7 @@ +en: + registrar: + payments: + back: + payment_successful: 'Thank you! Payment received successfully.' + successful_payment_backend_error: 'We received your payment, but something went wrong on our side. Please contact us via email or phone.' + payment_not_received: 'Payment was unsuccessful. Please make sure you have enough funds on your account and try again.' From 5393130e34bc869bd42fc4c461059041c88f161a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 5 Feb 2020 09:15:56 +0200 Subject: [PATCH 013/110] Rename create_payment_method to create_internal_payment_record --- app/models/bank_transaction.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index 25c6b60e9..105f7d14f 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -43,10 +43,11 @@ class BankTransaction < ApplicationRecord else 'system_payment' end - record_system_payment(channel: channel, invoice: invoice, registrar: registrar) + create_internal_payment_record(channel: channel, invoice: invoice, + registrar: registrar) end - def record_system_payment(channel: nil, invoice:, registrar:) + def create_internal_payment_record(channel: nil, invoice:, registrar:) if channel.nil? create_activity(invoice.buyer, invoice) return @@ -75,8 +76,8 @@ class BankTransaction < ApplicationRecord validate_invoice_data(invoice) return if errors.any? - record_system_payment(channel: (manual ? 'admin_payment' : nil), invoice: invoice, - registrar: invoice.buyer) + create_internal_payment_record(channel: (manual ? 'admin_payment' : nil), invoice: invoice, + registrar: invoice.buyer) end def validate_invoice_data(invoice) From fe8d1d1f0b0b7ffba5a779a6faaef115ced16cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 5 Feb 2020 09:16:24 +0200 Subject: [PATCH 014/110] Show user only allowed customer-scoped payment methods --- app/models/payment_order.rb | 1 + app/views/registrar/invoices/show.haml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index c2cc883a6..3d788913b 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -7,6 +7,7 @@ class PaymentOrder < ApplicationRecord INTERNAL_PAYMENT_METHODS = %w[admin_payment system_payment].freeze PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS, INTERNAL_PAYMENT_METHODS].flatten.freeze + CUSTOMER_PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS].flatten.freeze belongs_to :invoice, optional: false diff --git a/app/views/registrar/invoices/show.haml b/app/views/registrar/invoices/show.haml index d987241b1..5e6104091 100644 --- a/app/views/registrar/invoices/show.haml +++ b/app/views/registrar/invoices/show.haml @@ -17,4 +17,4 @@ - if @invoice.payable? .row.semifooter - .col-md-6-offset-6.text-right= render 'registrar/invoices/partials/banklinks', locals: { payment_channels: PaymentOrder::PAYMENT_METHODS } + .col-md-6-offset-6.text-right= render 'registrar/invoices/partials/banklinks', locals: { payment_channels: PaymentOrder::CUSTOMER_PAYMENT_METHODS } From 1a594877243bea76a3dc42c907ea8837d56a19c7 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 29 Jan 2020 13:40:19 +0500 Subject: [PATCH 015/110] Raise ruby version to 2.5.7, raise some gem versions --- .ruby-version | 2 +- Gemfile.lock | 151 ++++++++++++++++++----------------- config/initializers/money.rb | 4 +- 3 files changed, 83 insertions(+), 74 deletions(-) diff --git a/.ruby-version b/.ruby-version index e30309f73..35d16fb1a 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.4.7 +2.5.7 diff --git a/Gemfile.lock b/Gemfile.lock index 23aa90a51..6c374892f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -27,7 +27,7 @@ GIT GIT remote: https://github.com/internetee/epp.git - revision: 76f9fd487d0ca3865b6f706c5a72703951c03996 + revision: af7cefda37ac81d14b1d12641cde410776082d59 branch: master specs: epp (1.5.0) @@ -97,9 +97,9 @@ GEM tzinfo (~> 1.1) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) - airbrake (9.4.5) - airbrake-ruby (~> 4.7) - airbrake-ruby (4.7.1) + airbrake (10.0.1) + airbrake-ruby (~> 4.13) + airbrake-ruby (4.13.0) rbtree3 (~> 0.5) akami (1.3.1) gyoku (>= 0.4.0) @@ -109,19 +109,15 @@ GEM actionpack activesupport (>= 3.0.0) rspec - autoprefixer-rails (9.6.5) + autoprefixer-rails (9.7.4) execjs - axiom-types (0.1.1) - descendants_tracker (~> 0.0.4) - ice_nine (~> 0.11.0) - thread_safe (~> 0.3, >= 0.3.1) bcrypt (3.1.13) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) sassc (>= 2.0.0) - builder (3.2.3) - cancancan (3.0.1) - capybara (3.29.0) + builder (3.2.4) + cancancan (3.0.2) + capybara (3.31.0) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) @@ -132,8 +128,6 @@ GEM childprocess (3.0.0) chronic (0.10.2) coderay (1.1.0) - coercible (1.0.0) - descendants_tracker (~> 0.0.1) coffee-rails (4.2.2) coffee-script (>= 2.2.0) railties (>= 4.0.0) @@ -148,16 +142,14 @@ GEM unicode_utils (~> 1.4) crack (0.4.3) safe_yaml (~> 1.0.0) - crass (1.0.5) + crass (1.0.6) daemons (1.3.1) daemons-rails (1.2.1) daemons multi_json (~> 1.0) - data_migrate (6.0.5) + data_migrate (6.2.0) rails (>= 5.0) - database_cleaner (1.7.0) - descendants_tracker (0.0.4) - thread_safe (~> 0.3, >= 0.3.1) + database_cleaner (1.8.2) devise (4.7.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) @@ -168,21 +160,41 @@ GEM docile (1.3.2) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - equalizer (0.0.11) + dry-configurable (0.9.0) + concurrent-ruby (~> 1.0) + dry-core (~> 0.4, >= 0.4.7) + dry-container (0.7.2) + concurrent-ruby (~> 1.0) + dry-configurable (~> 0.1, >= 0.1.3) + dry-core (0.4.9) + concurrent-ruby (~> 1.0) + dry-equalizer (0.3.0) + dry-inflector (0.2.0) + dry-logic (1.0.5) + concurrent-ruby (~> 1.0) + dry-core (~> 0.2) + dry-equalizer (~> 0.2) + dry-types (1.2.2) + concurrent-ruby (~> 1.0) + dry-container (~> 0.3) + dry-core (~> 0.4, >= 0.4.4) + dry-equalizer (~> 0.3) + dry-inflector (~> 0.1, >= 0.1.2) + dry-logic (~> 1.0, >= 1.0.2) erubis (2.7.0) execjs (2.7.0) - ffi (1.11.1) + ffi (1.12.2) figaro (1.1.1) thor (~> 0.14) globalid (0.4.2) activesupport (>= 4.2.0) - grape (1.2.4) + grape (1.3.0) activesupport builder + dry-types (>= 1.1) mustermann-grape (~> 1.0.0) rack (>= 1.3.0) rack-accept - virtus (>= 1.0.0) gyoku (1.3.1) builder (>= 2.1.2) haml (5.1.2) @@ -197,10 +209,9 @@ GEM httpi (2.4.4) rack socksify - i18n (1.7.0) + i18n (1.8.2) concurrent-ruby (~> 1.0) i18n_data (0.8.0) - ice_nine (0.11.2) isikukood (0.1.2) iso8601 (0.8.6) jquery-rails (4.3.5) @@ -210,27 +221,27 @@ GEM jquery-ui-rails (5.0.5) railties (>= 3.2.16) json (1.8.6) - kaminari (1.1.1) + kaminari (1.2.0) activesupport (>= 4.1.0) - kaminari-actionview (= 1.1.1) - kaminari-activerecord (= 1.1.1) - kaminari-core (= 1.1.1) - kaminari-actionview (1.1.1) + kaminari-actionview (= 1.2.0) + kaminari-activerecord (= 1.2.0) + kaminari-core (= 1.2.0) + kaminari-actionview (1.2.0) actionview - kaminari-core (= 1.1.1) - kaminari-activerecord (1.1.1) + kaminari-core (= 1.2.0) + kaminari-activerecord (1.2.0) activerecord - kaminari-core (= 1.1.1) - kaminari-core (1.1.1) + kaminari-core (= 1.2.0) + kaminari-core (1.2.0) keystores (0.4.0) libxml-ruby (3.1.0) - loofah (2.3.1) + loofah (2.4.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) method_source (0.8.2) - mime-types (3.3) + mime-types (3.3.1) mime-types-data (~> 3.2015) mime-types-data (3.2019.1009) mina (0.3.1) @@ -239,22 +250,23 @@ GEM mini_mime (1.0.2) mini_portile2 (2.4.0) minitest (5.10.3) - monetize (1.9.2) + monetize (1.9.4) money (~> 6.12) - money (6.13.4) + money (6.13.7) i18n (>= 0.6.4, <= 2) - money-rails (1.13.2) + money-rails (1.13.3) activesupport (>= 3.0) monetize (~> 1.9.0) money (~> 6.13.2) railties (>= 3.0) multi_json (1.14.1) - mustermann (1.0.3) - mustermann-grape (1.0.0) - mustermann (~> 1.0.0) + mustermann (1.1.1) + ruby2_keywords (~> 0.0.1) + mustermann-grape (1.0.1) + mustermann (>= 1.0.0) netrc (0.11.0) nio4r (2.5.2) - nokogiri (1.10.4) + nokogiri (1.10.7) mini_portile2 (~> 2.4.0) nori (2.6.0) open4 (1.3.4) @@ -269,7 +281,7 @@ GEM coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) - public_suffix (4.0.1) + public_suffix (4.0.3) puma (4.3.1) nio4r (~> 2.0) que (0.14.3) @@ -277,10 +289,10 @@ GEM erubis que (~> 0.8) sinatra - rack (2.0.8) + rack (2.1.2) rack-accept (0.4.5) rack (>= 0.4) - rack-protection (2.0.7) + rack-protection (2.0.8.1) rack rack-test (0.6.3) rack (>= 1.0) @@ -310,19 +322,19 @@ GEM method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rake (13.0.0) + rake (13.0.1) ransack (1.8.10) actionpack (>= 3.0, < 5.2) activerecord (>= 3.0, < 5.2) activesupport (>= 3.0, < 5.2) i18n rb-fsevent (0.10.3) - rb-inotify (0.10.0) + rb-inotify (0.10.1) ffi (~> 1.0) - rbtree3 (0.5.0) + rbtree3 (0.6.0) rdoc (4.3.0) regexp_parser (1.6.0) - request_store (1.4.1) + request_store (1.5.0) rack (>= 1.4) responders (3.0.0) actionpack (>= 5.0) @@ -336,16 +348,17 @@ GEM rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) rspec-mocks (~> 3.9.0) - rspec-core (3.9.0) - rspec-support (~> 3.9.0) + rspec-core (3.9.1) + rspec-support (~> 3.9.1) rspec-expectations (3.9.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) - rspec-mocks (3.9.0) + rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) - rspec-support (3.9.0) - rubyzip (2.0.0) + rspec-support (3.9.2) + ruby2_keywords (0.0.2) + rubyzip (2.2.0) safe_yaml (1.0.5) sass (3.7.4) sass-listen (~> 4.0.0) @@ -374,19 +387,18 @@ GEM select2-rails (3.5.9.3) thor (~> 0.14) selectize-rails (0.12.1) - selenium-webdriver (3.142.6) + selenium-webdriver (3.142.7) childprocess (>= 0.5, < 4.0) rubyzip (>= 1.2.2) - simplecov (0.17.1) + simplecov (0.18.1) docile (~> 1.1) - json (>= 1.8, < 3) - simplecov-html (~> 0.10.0) - simplecov-html (0.10.2) + simplecov-html (~> 0.11.0) + simplecov-html (0.11.0) simpleidn (0.0.9) - sinatra (2.0.7) + sinatra (2.0.8.1) mustermann (~> 1.0) rack (~> 2.0) - rack-protection (= 2.0.7) + rack-protection (= 2.0.8.1) tilt (~> 2.0) sixarm_ruby_unaccent (1.2.0) slop (3.6.0) @@ -402,7 +414,7 @@ GEM thor (0.20.3) thread_safe (0.3.6) tilt (2.0.10) - tzinfo (1.2.5) + tzinfo (1.2.6) thread_safe (~> 0.1) uglifier (4.2.0) execjs (>= 0.3.0, < 3) @@ -412,21 +424,16 @@ GEM unicode_utils (1.4.0) validates_email_format_of (1.6.3) i18n - virtus (1.0.5) - axiom-types (~> 0.1) - coercible (~> 1.0) - descendants_tracker (~> 0.0, >= 0.0.3) - equalizer (~> 0.0, >= 0.0.9) warden (1.2.8) rack (>= 2.0.6) wasabi (3.5.0) httpi (~> 2.0) nokogiri (>= 1.4.2) - webdrivers (4.1.3) + webdrivers (4.2.0) nokogiri (~> 1.6) rubyzip (>= 1.3.0) selenium-webdriver (>= 3.0, < 4.0) - webmock (3.7.6) + webmock (3.8.0) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -435,7 +442,7 @@ GEM websocket-extensions (0.1.4) whenever (0.9.4) chronic (>= 0.6.3) - wkhtmltopdf-binary (0.12.4) + wkhtmltopdf-binary (0.12.5.1) xpath (3.2.0) nokogiri (~> 1.8) @@ -500,4 +507,4 @@ DEPENDENCIES wkhtmltopdf-binary BUNDLED WITH - 2.0.2 + 2.1.4 diff --git a/config/initializers/money.rb b/config/initializers/money.rb index cb476b589..a52ff280d 100644 --- a/config/initializers/money.rb +++ b/config/initializers/money.rb @@ -1,4 +1,6 @@ MoneyRails.configure do |config| # Wrapper for Money#default_currency with additional functionality config.default_currency = :eur -end \ No newline at end of file + config.rounding_mode = BigDecimal::ROUND_HALF_EVEN + config.locale_backend = :i18n +end From af57711dc0433f03bae59340bea50b14e0a2a1a3 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 29 Jan 2020 14:51:00 +0500 Subject: [PATCH 016/110] Pump rails version, fix tests --- Gemfile | 2 +- Gemfile.lock | 81 ++++++++++--------- bin/setup | 25 +++--- bin/update | 0 bin/yarn | 11 +++ config/application.rb | 1 + config/cable.yml | 1 + config/environments/production.rb | 2 +- config/initializers/assets.rb | 3 +- .../new_framework_defaults_5_1.rb | 14 ++++ config/puma.rb | 23 ++++-- config/spring.rb | 6 ++ test/models/dns/domain_name_test.rb | 2 + 13 files changed, 110 insertions(+), 61 deletions(-) mode change 100644 => 100755 bin/update create mode 100755 bin/yarn create mode 100644 config/initializers/new_framework_defaults_5_1.rb create mode 100644 config/spring.rb diff --git a/Gemfile b/Gemfile index b3882e792..57e78ed84 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' # core gem 'iso8601', '0.8.6' # for dates and times -gem 'rails', '~> 5.0.7' +gem 'rails', '~> 5.1.7' gem 'rest-client' gem 'uglifier' diff --git a/Gemfile.lock b/Gemfile.lock index 6c374892f..381645baa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -58,39 +58,39 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (5.0.7.2) - actionpack (= 5.0.7.2) - nio4r (>= 1.2, < 3.0) + actioncable (5.1.7) + actionpack (= 5.1.7) + nio4r (~> 2.0) websocket-driver (~> 0.6.1) - actionmailer (5.0.7.2) - actionpack (= 5.0.7.2) - actionview (= 5.0.7.2) - activejob (= 5.0.7.2) + actionmailer (5.1.7) + actionpack (= 5.1.7) + actionview (= 5.1.7) + activejob (= 5.1.7) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.0.7.2) - actionview (= 5.0.7.2) - activesupport (= 5.0.7.2) + actionpack (5.1.7) + actionview (= 5.1.7) + activesupport (= 5.1.7) rack (~> 2.0) - rack-test (~> 0.6.3) + rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.0.7.2) - activesupport (= 5.0.7.2) + actionview (5.1.7) + activesupport (= 5.1.7) builder (~> 3.1) - erubis (~> 2.7.0) + erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.0.7.2) - activesupport (= 5.0.7.2) + activejob (5.1.7) + activesupport (= 5.1.7) globalid (>= 0.3.6) - activemodel (5.0.7.2) - activesupport (= 5.0.7.2) - activerecord (5.0.7.2) - activemodel (= 5.0.7.2) - activesupport (= 5.0.7.2) - arel (~> 7.0) - activesupport (5.0.7.2) + activemodel (5.1.7) + activesupport (= 5.1.7) + activerecord (5.1.7) + activemodel (= 5.1.7) + activesupport (= 5.1.7) + arel (~> 8.0) + activesupport (5.1.7) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -104,7 +104,7 @@ GEM akami (1.3.1) gyoku (>= 0.4.0) nokogiri - arel (7.1.4) + arel (8.0.0) autodoc (0.7.3) actionpack activesupport (>= 3.0.0) @@ -181,6 +181,7 @@ GEM dry-equalizer (~> 0.3) dry-inflector (~> 0.1, >= 0.1.2) dry-logic (~> 1.0, >= 1.0.2) + erubi (1.9.0) erubis (2.7.0) execjs (2.7.0) ffi (1.12.2) @@ -294,20 +295,20 @@ GEM rack (>= 0.4) rack-protection (2.0.8.1) rack - rack-test (0.6.3) - rack (>= 1.0) + rack-test (1.1.0) + rack (>= 1.0, < 3) railroady (1.3.0) - rails (5.0.7.2) - actioncable (= 5.0.7.2) - actionmailer (= 5.0.7.2) - actionpack (= 5.0.7.2) - actionview (= 5.0.7.2) - activejob (= 5.0.7.2) - activemodel (= 5.0.7.2) - activerecord (= 5.0.7.2) - activesupport (= 5.0.7.2) + rails (5.1.7) + actioncable (= 5.1.7) + actionmailer (= 5.1.7) + actionpack (= 5.1.7) + actionview (= 5.1.7) + activejob (= 5.1.7) + activemodel (= 5.1.7) + activerecord (= 5.1.7) + activesupport (= 5.1.7) bundler (>= 1.3.0) - railties (= 5.0.7.2) + railties (= 5.1.7) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) @@ -316,9 +317,9 @@ GEM loofah (~> 2.3) rails-settings-cached (0.7.2) rails (>= 4.2.0) - railties (5.0.7.2) - actionpack (= 5.0.7.2) - activesupport (= 5.0.7.2) + railties (5.1.7) + actionpack (= 5.1.7) + activesupport (= 5.1.7) method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) @@ -489,7 +490,7 @@ DEPENDENCIES que que-web railroady (= 1.3.0) - rails (~> 5.0.7) + rails (~> 5.1.7) rails-settings-cached (= 0.7.2) ransack (~> 1.8) rest-client diff --git a/bin/setup b/bin/setup index b3067cf22..b5ca43ac5 100755 --- a/bin/setup +++ b/bin/setup @@ -1,33 +1,36 @@ #!/usr/bin/env ruby require 'pathname' -require 'fileutils' +include FileUtils # path to your application root. APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) - def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") end -Dir.chdir APP_ROOT do +chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file. - puts '== Installing dependencies with bundler ==' + puts '== Installing dependencies ==' system! 'gem install bundler --conservative' system('bundle check') || system!('bundle install') - puts "\n== Copying sample development database config files ==" - unless File.exist?('config/database.yml') - system! 'cp config/database-example-development.yml config/database.yml' - end + # Install JavaScript dependencies if using Yarn + # system('bin/yarn') + + puts "\n== Copying sample files ==" + unless File.exist?('config/database.yml') + system! 'cp config/database.yml.sample config/database.yml' + end puts "\n== Preparing database ==" system! 'bin/rails db:setup' puts "\n== Removing old logs and tempfiles ==" - system! 'bin/rake log:clear tmp:clear' + system! 'bin/rails log:clear tmp:clear' puts "\n== Restarting application server ==" - system! 'touch tmp/restart.txt' - + system! 'bin/rails restart' end diff --git a/bin/update b/bin/update old mode 100644 new mode 100755 diff --git a/bin/yarn b/bin/yarn new file mode 100755 index 000000000..c2bacef83 --- /dev/null +++ b/bin/yarn @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby +VENDOR_PATH = File.expand_path('..', __dir__) +Dir.chdir(VENDOR_PATH) do + begin + exec "yarnpkg #{ARGV.join(" ")}" + rescue Errno::ENOENT + $stderr.puts "Yarn executable was not detected in the system." + $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" + exit 1 + end +end diff --git a/config/application.rb b/config/application.rb index c70ab2111..57a3878a9 100644 --- a/config/application.rb +++ b/config/application.rb @@ -16,6 +16,7 @@ end module DomainNameRegistry class Application < Rails::Application + #config.load_defaults 5.1 # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. diff --git a/config/cable.yml b/config/cable.yml index 0bbde6f74..858bb1f14 100644 --- a/config/cable.yml +++ b/config/cable.yml @@ -7,3 +7,4 @@ test: production: adapter: redis url: redis://localhost:6379/1 + channel_prefix: domain_name_registry_production diff --git a/config/environments/production.rb b/config/environments/production.rb index c2262235d..6e13ea1f7 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -66,7 +66,7 @@ Rails.application.configure do # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation cannot be found). - config.i18n.fallbacks = [I18n.default_locale] + config.i18n.fallbacks = true # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index d3b8408d5..ba78ea325 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -5,7 +5,7 @@ Rails.application.configure do config.assets.version = '1.0' # Add additional assets to the asset load path - config.assets.paths << Rails.root.join('vendor', 'assets', 'fonts') + config.assets.paths << Rails.root.join('vendor', 'assets', 'fonts', 'node_modules') # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. @@ -14,4 +14,5 @@ Rails.application.configure do config.assets.precompile += %w(admin-manifest.css admin-manifest.js) config.assets.precompile += %w(registrar-manifest.css registrar-manifest.js) config.assets.precompile += %w(registrant-manifest.css registrant-manifest.js) + config.assets.precompile += %w( admin.js admin.css ) end diff --git a/config/initializers/new_framework_defaults_5_1.rb b/config/initializers/new_framework_defaults_5_1.rb new file mode 100644 index 000000000..9010abd5c --- /dev/null +++ b/config/initializers/new_framework_defaults_5_1.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 5.1 upgrade. +# +# Once upgraded flip defaults one by one to migrate to the new default. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. + +# Make `form_with` generate non-remote forms. +Rails.application.config.action_view.form_with_generates_remote_forms = false + +# Unknown asset fallback will return the path passed in when the given +# asset is not present in the asset pipeline. +# Rails.application.config.assets.unknown_asset_fallback = false diff --git a/config/puma.rb b/config/puma.rb index c7f311f81..1e19380dc 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,13 +1,13 @@ # Puma can serve each request in a thread from an internal thread pool. -# The `threads` method setting takes two numbers a minimum and maximum. +# The `threads` method setting takes two numbers: a minimum and maximum. # Any libraries that use thread pools should be configured to match # the maximum value specified for Puma. Default is set to 5 threads for minimum -# and maximum, this matches the default thread size of Active Record. +# and maximum; this matches the default thread size of Active Record. # -threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i +threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } threads threads_count, threads_count -# Specifies the `port` that Puma will listen on to receive requests, default is 3000. +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. # port ENV.fetch("PORT") { 3000 } @@ -32,16 +32,25 @@ environment ENV.fetch("RAILS_ENV") { "development" } # # preload_app! +# If you are preloading your application and using Active Record, it's +# recommended that you close any connections to the database before workers +# are forked to prevent connection leakage. +# +# before_fork do +# ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord) +# end + # The code in the `on_worker_boot` will be called if you are using # clustered mode by specifying a number of `workers`. After each worker -# process is booted this block will be run, if you are using `preload_app!` -# option you will want to use this block to reconnect to any threads -# or connections that may have been created at application boot, Ruby +# process is booted, this block will be run. If you are using the `preload_app!` +# option, you will want to use this block to reconnect to any threads +# or connections that may have been created at application boot, as Ruby # cannot share connections between processes. # # on_worker_boot do # ActiveRecord::Base.establish_connection if defined?(ActiveRecord) # end +# # Allow puma to be restarted by `rails restart` command. plugin :tmp_restart diff --git a/config/spring.rb b/config/spring.rb new file mode 100644 index 000000000..c9119b40c --- /dev/null +++ b/config/spring.rb @@ -0,0 +1,6 @@ +%w( + .ruby-version + .rbenv-vars + tmp/restart.txt + tmp/caching-dev.txt +).each { |path| Spring.watch(path) } diff --git a/test/models/dns/domain_name_test.rb b/test/models/dns/domain_name_test.rb index bd83076bc..4f8922d32 100644 --- a/test/models/dns/domain_name_test.rb +++ b/test/models/dns/domain_name_test.rb @@ -13,6 +13,8 @@ class AuctionDoubleTest < ActiveSupport::TestCase end class DNS::DomainNameTest < ActiveSupport::TestCase + fixtures 'whois/records' + def test_available_when_not_at_auction domain_name = DNS::DomainName.new('auction.test') auctions(:one).update!(domain: 'auction.test', status: Auction.statuses[:domain_registered]) From 95ad3086b0fd2f7ba6362191e36218df2a12b6f8 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 29 Jan 2020 15:13:48 +0500 Subject: [PATCH 017/110] Change deprecated usage of strings in if blocks --- app/controllers/epp/base_controller.rb | 2 +- app/models/contact.rb | 4 ++-- app/models/registrar.rb | 4 ++-- config/application.rb | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/epp/base_controller.rb b/app/controllers/epp/base_controller.rb index 6e3f39e46..fb48c285a 100644 --- a/app/controllers/epp/base_controller.rb +++ b/app/controllers/epp/base_controller.rb @@ -10,7 +10,7 @@ module Epp before_action :latin_only before_action :validate_against_schema before_action :validate_request - before_action :update_epp_session, if: 'signed_in?' + before_action :update_epp_session, if: -> { signed_in? } around_action :wrap_exceptions diff --git a/app/models/contact.rb b/app/models/contact.rb index 558292dbd..31ef7241e 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -23,7 +23,7 @@ class Contact < ApplicationRecord accepts_nested_attributes_for :legal_documents validates :name, :email, presence: true - validates :street, :city, :zip, :country_code, presence: true, if: 'self.class.address_processing?' + validates :street, :city, :zip, :country_code, presence: true, if: -> { self.class.address_processing? } validates :phone, presence: true, e164: true, phone: true @@ -37,7 +37,7 @@ class Contact < ApplicationRecord validates_associated :identifier validate :validate_html - validate :validate_country_code, if: 'self.class.address_processing?' + validate :validate_country_code, if: -> { self.class.address_processing? } after_initialize do self.status_notes = {} if status_notes.nil? diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 8f41d62ca..3ebddf8ae 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -21,9 +21,9 @@ class Registrar < ApplicationRecord validates :reference_no, format: Billing::ReferenceNo::REGEXP validate :forbid_special_code - validates :vat_rate, presence: true, if: 'vat_liable_in_foreign_country? && vat_no.blank?' + validates :vat_rate, presence: true, if: -> { vat_liable_in_foreign_country? && vat_no.blank? } validates :vat_rate, absence: true, if: :vat_liable_locally? - validates :vat_rate, absence: true, if: 'vat_liable_in_foreign_country? && vat_no?' + validates :vat_rate, absence: true, if: -> { vat_liable_in_foreign_country? && vat_no? } validates :vat_rate, numericality: { greater_than_or_equal_to: 0, less_than: 100 }, allow_nil: true diff --git a/config/application.rb b/config/application.rb index 57a3878a9..72b592a3b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -16,7 +16,7 @@ end module DomainNameRegistry class Application < Rails::Application - #config.load_defaults 5.1 + config.load_defaults 5.1 # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. From 01114386b31a9a04a73dd9a5e30edc769c6ec5c4 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 29 Jan 2020 15:41:03 +0500 Subject: [PATCH 018/110] Change deprecated changed? methods to new in callbacks --- app/models/admin_user.rb | 2 +- app/models/api_user.rb | 2 +- app/models/contact.rb | 2 +- app/models/dnskey.rb | 9 +++++++-- app/models/domain.rb | 4 ++-- app/models/epp/contact.rb | 2 +- app/models/registrar.rb | 2 +- 7 files changed, 14 insertions(+), 9 deletions(-) diff --git a/app/models/admin_user.rb b/app/models/admin_user.rb index 07686e921..159578ab0 100644 --- a/app/models/admin_user.rb +++ b/app/models/admin_user.rb @@ -4,7 +4,7 @@ class AdminUser < User validates :identity_code, presence: true, if: -> { country_code == 'EE' } validates :email, presence: true validates :password, :password_confirmation, presence: true, if: :new_record? - validates :password_confirmation, presence: true, if: :encrypted_password_changed? + validates :password_confirmation, presence: true, if: :will_save_change_to_encrypted_password? validate :validate_identity_code, if: -> { country_code == 'EE' } ROLES = %w(user customer_service admin) # should not match to api_users roles diff --git a/app/models/api_user.rb b/app/models/api_user.rb index e11dbf90f..3dc240727 100644 --- a/app/models/api_user.rb +++ b/app/models/api_user.rb @@ -43,7 +43,7 @@ class ApiUser < User after_initialize :set_defaults def set_defaults return unless new_record? - self.active = true unless active_changed? + self.active = true unless saved_change_to_active? end class << self diff --git a/app/models/contact.rb b/app/models/contact.rb index 31ef7241e..e4ed542a6 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -28,7 +28,7 @@ class Contact < ApplicationRecord validates :phone, presence: true, e164: true, phone: true validates :email, format: /@/ - validates :email, email_format: { message: :invalid }, if: proc { |c| c.email_changed? } + validates :email, email_format: { message: :invalid }, if: proc { |c| c.will_save_change_to_email? } validates :code, uniqueness: { message: :epp_id_taken }, diff --git a/app/models/dnskey.rb b/app/models/dnskey.rb index 922844874..08a5b03d8 100644 --- a/app/models/dnskey.rb +++ b/app/models/dnskey.rb @@ -9,10 +9,15 @@ class Dnskey < ApplicationRecord validate :validate_protocol validate :validate_flags - before_save -> { generate_digest if public_key_changed? && !ds_digest_changed? } + before_save -> { generate_digest if will_save_change_to_public_key? && + !will_save_change_to_ds_digest? } before_save lambda { - if (public_key_changed? || flags_changed? || alg_changed? || protocol_changed?) && !ds_key_tag_changed? + if (will_save_change_to_public_key? || + will_save_change_to_flags? || + will_save_change_to_alg? || + will_save_change_to_protocol?) && + !will_save_change_to_ds_key_tag? generate_ds_key_tag end } diff --git a/app/models/domain.rb b/app/models/domain.rb index d6545284d..3ad3b09f2 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -73,7 +73,7 @@ class Domain < ApplicationRecord before_update :manage_statuses def manage_statuses - return unless registrant_id_changed? # rollback has not yet happened + return unless will_save_change_to_registrant_id? # rollback has not yet happened pending_update! if registrant_verification_asked? true end @@ -547,7 +547,7 @@ class Domain < ApplicationRecord activate if nameservers.reject(&:marked_for_destruction?).size >= Setting.ns_min_count end - cancel_force_delete if force_delete_scheduled? && registrant_id_changed? + cancel_force_delete if force_delete_scheduled? && will_save_change_to_registrant_id? if statuses.empty? && valid? statuses << DomainStatus::OK diff --git a/app/models/epp/contact.rb b/app/models/epp/contact.rb index 742f0339f..fa488d9e1 100644 --- a/app/models/epp/contact.rb +++ b/app/models/epp/contact.rb @@ -182,7 +182,7 @@ class Epp::Contact < Contact self.attributes = at - email_changed = email_changed? + email_changed = will_save_change_to_email? old_email = email_was updated = save diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 3ebddf8ae..88aa1c629 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -33,7 +33,7 @@ class Registrar < ApplicationRecord after_initialize :set_defaults validates :email, email_format: { message: :invalid }, - allow_blank: true, if: proc { |c| c.email_changed? } + allow_blank: true, if: proc { |c| c.will_save_change_to_email? } validates :billing_email, email_format: { message: :invalid }, allow_blank: true alias_attribute :contact_email, :email From c7593338e2be685715b957b86d8d0fb30253ea07 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 29 Jan 2020 15:50:09 +0500 Subject: [PATCH 019/110] Pump pg gem version up to 1.2.2 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 57e78ed84..68e0b4aa2 100644 --- a/Gemfile +++ b/Gemfile @@ -10,7 +10,7 @@ gem 'uglifier' gem 'figaro', '1.1.1' # model related -gem 'pg', '0.19.0' +gem 'pg', '1.2.2' # 1.8 is for Rails < 5.0 gem 'ransack', '~> 1.8' gem 'validates_email_format_of', '1.6.3' # validates email against RFC 2822 and RFC 3696 diff --git a/Gemfile.lock b/Gemfile.lock index 381645baa..ed210f681 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -277,7 +277,7 @@ GEM activesupport (>= 3.0, < 6.0) request_store (~> 1.1) pdfkit (0.8.4.1) - pg (0.19.0) + pg (1.2.2) pry (0.10.1) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -484,7 +484,7 @@ DEPENDENCIES nokogiri paper_trail (~> 4.0) pdfkit - pg (= 0.19.0) + pg (= 1.2.2) pry (= 0.10.1) puma que From 4e1bec3613886afa183d4df17c9874e5c5c62560 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 30 Jan 2020 13:55:08 +0500 Subject: [PATCH 020/110] Pump minitest version --- Gemfile | 2 +- Gemfile.lock | 4 +- app/models/contact.rb | 4 +- app/models/dnskey.rb | 7 ++- app/models/domain.rb | 3 +- test/support/rails5_assertions.rb | 96 ------------------------------- test/test_helper.rb | 1 - 7 files changed, 12 insertions(+), 105 deletions(-) delete mode 100644 test/support/rails5_assertions.rb diff --git a/Gemfile b/Gemfile index 68e0b4aa2..ce9565beb 100644 --- a/Gemfile +++ b/Gemfile @@ -84,8 +84,8 @@ end group :test do gem 'capybara' gem 'database_cleaner' + gem 'minitest', '~> 5.14' gem 'simplecov', require: false gem 'webdrivers' gem 'webmock' - gem 'minitest', '~> 5.10.0' end diff --git a/Gemfile.lock b/Gemfile.lock index ed210f681..75317c030 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -250,7 +250,7 @@ GEM rake mini_mime (1.0.2) mini_portile2 (2.4.0) - minitest (5.10.3) + minitest (5.14.0) monetize (1.9.4) money (~> 6.12) money (6.13.7) @@ -479,7 +479,7 @@ DEPENDENCIES kaminari lhv! mina (= 0.3.1) - minitest (~> 5.10.0) + minitest (~> 5.14) money-rails nokogiri paper_trail (~> 4.0) diff --git a/app/models/contact.rb b/app/models/contact.rb index e4ed542a6..9cb954462 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -23,7 +23,9 @@ class Contact < ApplicationRecord accepts_nested_attributes_for :legal_documents validates :name, :email, presence: true - validates :street, :city, :zip, :country_code, presence: true, if: -> { self.class.address_processing? } + validates :street, :city, :zip, :country_code, presence: true, if: lambda { + self.class.address_processing? + } validates :phone, presence: true, e164: true, phone: true diff --git a/app/models/dnskey.rb b/app/models/dnskey.rb index 08a5b03d8..c0f3f7491 100644 --- a/app/models/dnskey.rb +++ b/app/models/dnskey.rb @@ -9,15 +9,16 @@ class Dnskey < ApplicationRecord validate :validate_protocol validate :validate_flags - before_save -> { generate_digest if will_save_change_to_public_key? && - !will_save_change_to_ds_digest? } + before_save lambda { + generate_digest if will_save_change_to_public_key? && !will_save_change_to_ds_digest? + } before_save lambda { if (will_save_change_to_public_key? || will_save_change_to_flags? || will_save_change_to_alg? || will_save_change_to_protocol?) && - !will_save_change_to_ds_key_tag? + !will_save_change_to_ds_key_tag? generate_ds_key_tag end } diff --git a/app/models/domain.rb b/app/models/domain.rb index 3ad3b09f2..b37d31ea0 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -74,11 +74,12 @@ class Domain < ApplicationRecord before_update :manage_statuses def manage_statuses return unless will_save_change_to_registrant_id? # rollback has not yet happened + pending_update! if registrant_verification_asked? true end - after_commit :update_whois_record, unless: 'domain_name.at_auction?' + after_commit :update_whois_record, unless: -> { domain_name.at_auction? } after_create :update_reserved_domains def update_reserved_domains diff --git a/test/support/rails5_assertions.rb b/test/support/rails5_assertions.rb deleted file mode 100644 index a11bb3ef1..000000000 --- a/test/support/rails5_assertions.rb +++ /dev/null @@ -1,96 +0,0 @@ -# Built-in since Rails 5.1 - -module ActiveSupport - module Testing - module Assertions - UNTRACKED = Object.new # :nodoc: - - # Assertion that the result of evaluating an expression is changed before - # and after invoking the passed in block. - # - # assert_changes 'Status.all_good?' do - # post :create, params: { status: { ok: false } } - # end - # - # You can pass the block as a string to be evaluated in the context of - # the block. A lambda can be passed for the block as well. - # - # assert_changes -> { Status.all_good? } do - # post :create, params: { status: { ok: false } } - # end - # - # The assertion is useful to test side effects. The passed block can be - # anything that can be converted to string with #to_s. - # - # assert_changes :@object do - # @object = 42 - # end - # - # The keyword arguments :from and :to can be given to specify the - # expected initial value and the expected value after the block was - # executed. - # - # assert_changes :@object, from: nil, to: :foo do - # @object = :foo - # end - # - # An error message can be specified. - # - # assert_changes -> { Status.all_good? }, 'Expected the status to be bad' do - # post :create, params: { status: { incident: true } } - # end - def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block) - exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) } - - before = exp.call - retval = yield - - unless from == UNTRACKED - error = "#{expression.inspect} isn't #{from.inspect}" - error = "#{message}.\n#{error}" if message - assert from === before, error - end - - after = exp.call - - if to == UNTRACKED - error = "#{expression.inspect} didn't changed" - error = "#{message}.\n#{error}" if message - assert_not_equal before, after, error - else - error = "#{expression.inspect} didn't change to #{to}" - error = "#{message}.\n#{error}" if message - assert to === after, error - end - - retval - end - - # Assertion that the result of evaluating an expression is changed before - # and after invoking the passed in block. - # - # assert_no_changes 'Status.all_good?' do - # post :create, params: { status: { ok: true } } - # end - # - # An error message can be specified. - # - # assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do - # post :create, params: { status: { ok: false } } - # end - def assert_no_changes(expression, message = nil, &block) - exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) } - - before = exp.call - retval = yield - after = exp.call - - error = "#{expression.inspect} did change to #{after}" - error = "#{message}.\n#{error}" if message - assert_equal before, after, error - - retval - end - end - end -end diff --git a/test/test_helper.rb b/test/test_helper.rb index 4cd632ea2..efdbc288f 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -16,7 +16,6 @@ require 'minitest/mock' require 'capybara/rails' require 'capybara/minitest' require 'webmock/minitest' -require 'support/rails5_assertions' # Remove once upgraded to Rails 5.1 require 'support/assertions/epp_assertions' From ad46e08f32215ef99e7762d32c753b728235ab81 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 30 Jan 2020 16:18:04 +0500 Subject: [PATCH 021/110] Pump iso8601 gem version --- Gemfile | 2 +- Gemfile.lock | 4 ++-- app/models/concerns/contact/transferable.rb | 2 +- config/initializers/new_framework_defaults.rb | 7 +++++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index ce9565beb..6a5c89321 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' # core -gem 'iso8601', '0.8.6' # for dates and times +gem 'iso8601', '0.12.1' # for dates and times gem 'rails', '~> 5.1.7' gem 'rest-client' gem 'uglifier' diff --git a/Gemfile.lock b/Gemfile.lock index 75317c030..b76bfefd0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -214,7 +214,7 @@ GEM concurrent-ruby (~> 1.0) i18n_data (0.8.0) isikukood (0.1.2) - iso8601 (0.8.6) + iso8601 (0.12.1) jquery-rails (4.3.5) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) @@ -473,7 +473,7 @@ DEPENDENCIES grape haml (~> 5.0) isikukood - iso8601 (= 0.8.6) + iso8601 (= 0.12.1) jquery-rails jquery-ui-rails (= 5.0.5) kaminari diff --git a/app/models/concerns/contact/transferable.rb b/app/models/concerns/contact/transferable.rb index 3f151251a..987933a8d 100644 --- a/app/models/concerns/contact/transferable.rb +++ b/app/models/concerns/contact/transferable.rb @@ -3,7 +3,7 @@ module Concerns::Contact::Transferable included do validates :auth_info, presence: true - after_initialize :generate_auth_info, if: 'new_record? && auth_info.blank?' + after_initialize :generate_auth_info, if: -> { new_record? && auth_info.blank? } end def transfer(new_registrar) diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb index 99b2db3b0..2f9c3c5cb 100644 --- a/config/initializers/new_framework_defaults.rb +++ b/config/initializers/new_framework_defaults.rb @@ -6,7 +6,8 @@ # # Read the Guide for Upgrading Ruby on Rails for more info on each option. -Rails.application.config.action_controller.raise_on_unfiltered_parameters = true +# DEPRECATION WARNING: raise_on_unfiltered_parameters is deprecated and has no effect in Rails 5.1. +#Rails.application.config.action_controller.raise_on_unfiltered_parameters = true # Enable per-form CSRF tokens. Previous versions had false. Rails.application.config.action_controller.per_form_csrf_tokens = true @@ -19,7 +20,9 @@ Rails.application.config.action_controller.forgery_protection_origin_check = tru ActiveSupport.to_time_preserves_timezone = true # Do not halt callback chains when a callback returns false. Previous versions had true. -ActiveSupport.halt_callback_chains_on_return_false = false +# DEPRECATION WARNING: ActiveSupport.halt_callback_chains_on_return_false= is deprecated and +# will be removed in Rails 5.2. +#ActiveSupport.halt_callback_chains_on_return_false = false # Configure SSL options to enable HSTS with subdomains. Previous versions had false. Rails.application.config.ssl_options = { hsts: { subdomains: true } } From a18f7b160537edf6b91adf8e541401305ac39069 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 30 Jan 2020 17:07:53 +0500 Subject: [PATCH 022/110] Pump papertrail version to 6.0.2 --- Gemfile | 2 +- Gemfile.lock | 7 +++---- app/controllers/application_controller.rb | 3 ++- app/controllers/epp/domains_controller.rb | 1 + app/controllers/epp/sessions_controller.rb | 1 + app/models/concerns/versions.rb | 2 +- config/initializers/paper_trail.rb | 1 + .../api/registrant/registrant_api_registry_locks_test.rb | 2 +- test/integration/contact/audit_log_test.rb | 4 ++-- test/integration/domain/audit_log_test.rb | 4 ++-- test/learning/paper_trail_test.rb | 4 ++-- test/models/domain/domain_version_test.rb | 4 ++-- 12 files changed, 19 insertions(+), 16 deletions(-) create mode 100644 config/initializers/paper_trail.rb diff --git a/Gemfile b/Gemfile index 6a5c89321..89472674b 100644 --- a/Gemfile +++ b/Gemfile @@ -14,7 +14,7 @@ gem 'pg', '1.2.2' # 1.8 is for Rails < 5.0 gem 'ransack', '~> 1.8' gem 'validates_email_format_of', '1.6.3' # validates email against RFC 2822 and RFC 3696 -gem 'paper_trail', '~> 4.0' +gem 'paper_trail', '~> 6.0' # 0.7.3 is the latest for Rails 4.2, however, it is absent on Rubygems server # https://github.com/huacnlee/rails-settings-cached/issues/165 diff --git a/Gemfile.lock b/Gemfile.lock index b76bfefd0..097ab7c97 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -272,9 +272,8 @@ GEM nori (2.6.0) open4 (1.3.4) orm_adapter (0.5.0) - paper_trail (4.2.0) - activerecord (>= 3.0, < 6.0) - activesupport (>= 3.0, < 6.0) + paper_trail (6.0.2) + activerecord (>= 4.0, < 5.2) request_store (~> 1.1) pdfkit (0.8.4.1) pg (1.2.2) @@ -482,7 +481,7 @@ DEPENDENCIES minitest (~> 5.14) money-rails nokogiri - paper_trail (~> 4.0) + paper_trail (~> 6.0) pdfkit pg (= 1.2.2) pry (= 0.10.1) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1a57b5573..5a6b45668 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,5 +1,6 @@ class ApplicationController < ActionController::Base check_authorization unless: :devise_controller? + before_action :set_paper_trail_whodunnit # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. @@ -32,4 +33,4 @@ class ApplicationController < ActionController::Base def available_languages { en: 'English', et: 'Estonian' }.invert end -end \ No newline at end of file +end diff --git a/app/controllers/epp/domains_controller.rb b/app/controllers/epp/domains_controller.rb index 1295f558e..9e4f6123a 100644 --- a/app/controllers/epp/domains_controller.rb +++ b/app/controllers/epp/domains_controller.rb @@ -2,6 +2,7 @@ module Epp class DomainsController < BaseController before_action :find_domain, only: %i[info renew update transfer delete] before_action :find_password, only: %i[info update transfer delete] + before_action :set_paper_trail_whodunnit def info authorize! :info, @domain diff --git a/app/controllers/epp/sessions_controller.rb b/app/controllers/epp/sessions_controller.rb index 2175f7281..ef8f125ee 100644 --- a/app/controllers/epp/sessions_controller.rb +++ b/app/controllers/epp/sessions_controller.rb @@ -1,6 +1,7 @@ module Epp class SessionsController < BaseController skip_authorization_check only: [:hello, :login, :logout] + before_action :set_paper_trail_whodunnit def hello render_epp_response('greeting') diff --git a/app/models/concerns/versions.rb b/app/models/concerns/versions.rb index b0a82376f..df464f10c 100644 --- a/app/models/concerns/versions.rb +++ b/app/models/concerns/versions.rb @@ -55,7 +55,7 @@ module Versions module ClassMethods def all_versions_for(ids, time) - ver_klass = paper_trail_version_class + ver_klass = paper_trail.version_class from_history = ver_klass.where(item_id: ids.to_a). order(:item_id). preceding(time + 1, true). diff --git a/config/initializers/paper_trail.rb b/config/initializers/paper_trail.rb new file mode 100644 index 000000000..39a667917 --- /dev/null +++ b/config/initializers/paper_trail.rb @@ -0,0 +1 @@ +PaperTrail.config.track_associations = false diff --git a/test/integration/api/registrant/registrant_api_registry_locks_test.rb b/test/integration/api/registrant/registrant_api_registry_locks_test.rb index 4babdf428..e4f551072 100644 --- a/test/integration/api/registrant/registrant_api_registry_locks_test.rb +++ b/test/integration/api/registrant/registrant_api_registry_locks_test.rb @@ -25,7 +25,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest end def test_locking_a_domain_creates_a_version_record - assert_difference '@domain.versions.count', 1 do + assert_difference '@domain.versions.count', 2 do post '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock', headers: @auth_headers end diff --git a/test/integration/contact/audit_log_test.rb b/test/integration/contact/audit_log_test.rb index f0f6a4bf2..41eb74cdd 100644 --- a/test/integration/contact/audit_log_test.rb +++ b/test/integration/contact/audit_log_test.rb @@ -5,7 +5,7 @@ class ContactAuditLogTest < ActionDispatch::IntegrationTest contact = contacts(:john) contact.legal_document_id = 1 - assert_difference 'contact.versions.count' do + assert_difference 'contact.versions.count', 2 do contact.save! end @@ -13,4 +13,4 @@ class ContactAuditLogTest < ActionDispatch::IntegrationTest assert_equal ({ legal_documents: [1] }).with_indifferent_access, contact_version.children.with_indifferent_access end -end \ No newline at end of file +end diff --git a/test/integration/domain/audit_log_test.rb b/test/integration/domain/audit_log_test.rb index 292994ca3..244e55ff7 100644 --- a/test/integration/domain/audit_log_test.rb +++ b/test/integration/domain/audit_log_test.rb @@ -14,7 +14,7 @@ class DomainAuditLogTest < ActionDispatch::IntegrationTest assert_equal registrant_id, domain.registrant_id domain.legal_document_id = legal_document_id - assert_difference 'domain.versions.count' do + assert_difference 'domain.versions.count', 2 do domain.save! end @@ -26,4 +26,4 @@ class DomainAuditLogTest < ActionDispatch::IntegrationTest assert_equal [legal_document_id], domain_version.children['legal_documents'] assert_equal [registrant_id], domain_version.children['registrant'] end -end \ No newline at end of file +end diff --git a/test/learning/paper_trail_test.rb b/test/learning/paper_trail_test.rb index 9396496b7..1a46022e4 100644 --- a/test/learning/paper_trail_test.rb +++ b/test/learning/paper_trail_test.rb @@ -40,7 +40,7 @@ class PaperTrailLearningTest < ActiveSupport::TestCase @record = Post.create!(title: 'any') assert_difference -> { @record.versions.size } do - @record.touch_with_version + @record.paper_trail.touch_with_version end end -end \ No newline at end of file +end diff --git a/test/models/domain/domain_version_test.rb b/test/models/domain/domain_version_test.rb index 74844f3af..305f353fa 100644 --- a/test/models/domain/domain_version_test.rb +++ b/test/models/domain/domain_version_test.rb @@ -17,7 +17,7 @@ class DomainVersionTest < ActiveSupport::TestCase duplicate_domain = prepare_duplicate_domain PaperTrail.whodunnit = @user.id_role_username - assert_difference 'duplicate_domain.versions.count', 1 do + assert_difference 'duplicate_domain.versions.count', 2 do duplicate_domain.save! end @@ -30,7 +30,7 @@ class DomainVersionTest < ActiveSupport::TestCase def test_assigns_updator_to_paper_trail_whodunnit PaperTrail.whodunnit = @user.id_role_username - assert_difference '@domain.versions.count', 1 do + assert_difference '@domain.versions.count', 2 do @domain.apply_registry_lock end From 8240b37910246234cfa2f34a5902af2438b8f982 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 30 Jan 2020 17:19:03 +0500 Subject: [PATCH 023/110] Pump papertrail gem to 8.1 --- Gemfile | 2 +- Gemfile.lock | 6 +++--- app/models/concerns/versions.rb | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 89472674b..82f07ed9e 100644 --- a/Gemfile +++ b/Gemfile @@ -10,11 +10,11 @@ gem 'uglifier' gem 'figaro', '1.1.1' # model related +gem 'paper_trail', '~> 8.1' gem 'pg', '1.2.2' # 1.8 is for Rails < 5.0 gem 'ransack', '~> 1.8' gem 'validates_email_format_of', '1.6.3' # validates email against RFC 2822 and RFC 3696 -gem 'paper_trail', '~> 6.0' # 0.7.3 is the latest for Rails 4.2, however, it is absent on Rubygems server # https://github.com/huacnlee/rails-settings-cached/issues/165 diff --git a/Gemfile.lock b/Gemfile.lock index 097ab7c97..c922a04dd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -272,8 +272,8 @@ GEM nori (2.6.0) open4 (1.3.4) orm_adapter (0.5.0) - paper_trail (6.0.2) - activerecord (>= 4.0, < 5.2) + paper_trail (8.1.2) + activerecord (>= 4.2, < 5.2) request_store (~> 1.1) pdfkit (0.8.4.1) pg (1.2.2) @@ -481,7 +481,7 @@ DEPENDENCIES minitest (~> 5.14) money-rails nokogiri - paper_trail (~> 6.0) + paper_trail (~> 8.1) pdfkit pg (= 1.2.2) pry (= 0.10.1) diff --git a/app/models/concerns/versions.rb b/app/models/concerns/versions.rb index df464f10c..bd6580adf 100644 --- a/app/models/concerns/versions.rb +++ b/app/models/concerns/versions.rb @@ -45,11 +45,11 @@ module Versions # callbacks def touch_domain_version - domain.try(:touch_with_version) + domain.paper_trail.try(:touch_with_version) end def touch_domains_version - domains.each(&:touch_with_version) + domains.each { |domain| domain.paper_trail.touch_with_version } end end From 6c7a63f25e20b2c8b8302741861fc1c8602199c0 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 30 Jan 2020 17:37:45 +0500 Subject: [PATCH 024/110] Pump ruby version to 2.6 --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 35d16fb1a..ec1cf33c3 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.5.7 +2.6.3 From 725ff30bb302ff53a594c6e01f3c8927e816297d Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 4 Feb 2020 14:29:05 +0500 Subject: [PATCH 025/110] Pump ruby version in dockerfile --- Dockerfile | 2 +- app/jobs/send_e_invoice_job.rb | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 app/jobs/send_e_invoice_job.rb diff --git a/Dockerfile b/Dockerfile index 7e3b11d80..5d241eeef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM internetee/ruby:2.4 +FROM internetee/ruby:2.6-buster RUN mkdir -p /opt/webapps/app/tmp/pids WORKDIR /opt/webapps/app diff --git a/app/jobs/send_e_invoice_job.rb b/app/jobs/send_e_invoice_job.rb new file mode 100644 index 000000000..e69de29bb From 62fef98eeb9b7811fede2bbd870156ce3c44fcc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 5 Feb 2020 13:48:28 +0200 Subject: [PATCH 026/110] Update CHANGELOG.md [ci skip] --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0670abc8..9bd0e3602 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +05.02.2020 +* Ruby version upgrade to 2.6.3 [#846](https://github.com/internetee/registry/issues/846) + 04.02.2020 * Fixed bug that allowed bypassing blocked domain validation using punycode [#1142](https://github.com/internetee/registry/issues/1142) * SimpleIDN gem update to 0.0.9 [#1508](https://github.com/internetee/registry/pull/1508) From faeb50cad5b7fc2dc92b1c307786b8e87bca1986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 5 Feb 2020 15:42:57 +0200 Subject: [PATCH 027/110] DirectoInvoiceForwardJob, send prepayments via Directo gem --- Gemfile | 2 + app/jobs/directo_invoice_forward_job_job.rb | 100 ++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 app/jobs/directo_invoice_forward_job_job.rb diff --git a/Gemfile b/Gemfile index b3882e792..f91077714 100644 --- a/Gemfile +++ b/Gemfile @@ -68,6 +68,8 @@ gem 'domain_name' gem 'haml', '~> 5.0' gem 'wkhtmltopdf-binary' +gem 'directo', github: 'internetee/directo', branch: 'directo-api' + group :development do # deploy gem 'mina', '0.3.1' # for fast deployment diff --git a/app/jobs/directo_invoice_forward_job_job.rb b/app/jobs/directo_invoice_forward_job_job.rb new file mode 100644 index 000000000..4c95bb366 --- /dev/null +++ b/app/jobs/directo_invoice_forward_job_job.rb @@ -0,0 +1,100 @@ +class DirectoInvoiceForwardJobJob < ApplicationJob + queue_as :default + + def perform(monthly: false, dry: false) + api_url = ENV['directo_invoice_url'] + sales_agent = Setting.directo_sales_agent + payment_term = Setting.directo_receipt_payment_term + @prepayment_product_id = Setting.directo_receipt_product_name + + @client = DirectoApi::Client.new(api_url, sales_agent, payment_term) + monthly ? send_monthly_invoices(dry: dry) : send_receipts(dry: dry) + end + + def send_receipts + unsent_invoices = Invoice.where(in_directo: false).non_cancelled + + Rails.logger.info("[DIRECTO] Trying to send #{unsent_invoices.count} prepayment invoices") + unsent_invoices.each do |invoice| + unless valid_invoice_conditions?(invoice) + Rails.logger.info("[DIRECTO] Invoice #{invoice.number} has been skipped") && next + end + + @client.invoices.add(generate_directo_invoice(invoice: invoice, client: @client, + product_id: @prepayment_product_id)) + end + sync_with_directo + end + + def send_monthly_invoices; end + + def valid_invoice_conditions?(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.total + false + end + true + end + + def generate_directo_invoice(invoice:, client:, product_id:) + inv = client.invoices.new + inv = create_invoice_meta(directo_invoice: inv, invoice: invoice) + inv = create_invoice_line(invoice: invoice, directo_invoice: inv, product_id: product_id) + + inv + end + + def create_invoice_meta(directo_invoice:, invoice:) + directo_invoice.customer = create_invoice_customer(invoice: invoice) + directo_invoice.date = invoice.issue_date.strftime('%Y-%m-%d') # Mapped + directo_invoice.transaction_date = + invoice.account_activity.bank_transaction&.paid_at&.strftime('%Y-%m-%d') # Mapped + directo_invoice.number = invoice.number # Mapped + directo_invoice.currency = invoice.currency # Mapped + directo_invoice.language = 'ENG' # Hardcoded + + directo_invoice + end + + def create_invoice_line(invoice:, directo_invoice:, product_id:) + line = directo_invoice.lines.new + line.code = product_id # MAPPED + line.description = invoice.result.auction.domain_name # MAPPED + line.quantity = 1 # MAPPED + line.price = ActionController::Base.helpers. + number_with_precision(invoice.subtotal, precision: 2, separator: ".") # MAPPED + directo_invoice.lines.add(line) + + directo_invoice + end + + def create_invoice_customer(invoice:) + customer = Directo::Customer.new + customer.code = invoice.buyer.accounting_customer_code # MAPPED + + customer + end + + def sync_with_directo + res = @client.invoices.deliver(ssl_verify: false) + Rails.logger.info("[Directo] Directo responded with code: #{res.code}, body: #{res.body}") + update_invoice_directo_state(res.body) if res.code == '200' + rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, + EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError + Rails.logger.info("[Directo] Failed. Responded with code: #{res.code}, body: #{res.body}") + end + + def update_invoice_directo_state(xml) + Nokogiri::XML(xml).css('Result').each do |res| + inv = Invoice.find_by(number: res.attributes['docid'].value.to_i) + mark_invoice_as_sent(invoice: inv, data: res) + end + end + + def mark_invoice_as_sent(invoice:, data:) + invoice.directo_records.create!(response: data.as_json.to_h, invoice_number: invoice.number) + invoice.update_columns(in_directo: true) + Rails.logger.info("[DIRECTO] Invoice #{invoice.number} was pushed and return is #{data.as_json.to_h.inspect}") + end +end From 3439c5f77afe9a431b7309fa89bbf6b7d20a8ddf Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 5 Feb 2020 19:39:01 +0500 Subject: [PATCH 028/110] Pump up lhv gem version --- Gemfile | 2 +- Gemfile.lock | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 82f07ed9e..cab5e0dd6 100644 --- a/Gemfile +++ b/Gemfile @@ -63,7 +63,7 @@ gem 'airbrake' gem 'company_register', github: 'internetee/company_register', branch: :master gem 'e_invoice', github: 'internetee/e_invoice', branch: :master -gem 'lhv', github: 'internetee/lhv', tag: 'v0.1.0' +gem 'lhv', github: 'internetee/lhv', branch: :master gem 'domain_name' gem 'haml', '~> 5.0' gem 'wkhtmltopdf-binary' diff --git a/Gemfile.lock b/Gemfile.lock index c922a04dd..fad531c26 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,11 +36,12 @@ GIT GIT remote: https://github.com/internetee/lhv.git - revision: e211516bc5fff2139584d4da41c17511863c229d - tag: v0.1.0 + revision: 145f66e21d65a4a7543f6b28a4124440d36fec98 + branch: master specs: lhv (0.1.0) keystores + logger nokogiri GIT @@ -236,6 +237,7 @@ GEM kaminari-core (1.2.0) keystores (0.4.0) libxml-ruby (3.1.0) + logger (1.4.2) loofah (2.4.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) From 5d8e78f3c657056b7c8c50855ce7b1cb3dc3229d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 5 Feb 2020 16:28:01 +0200 Subject: [PATCH 029/110] Rename #create_with_type to #new_with_type --- .../registrar/payments_controller.rb | 8 +++++--- app/models/bank_transaction.rb | 2 +- app/models/payment_order.rb | 2 +- test/models/payment_orders_test.rb | 18 +++++++++--------- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index c1944767f..598d13446 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -12,13 +12,15 @@ class Registrar invoice = Invoice.find(params[:invoice_id]) channel = params[:bank] - @payment_order = PaymentOrder.create_with_type(type: channel, invoice: invoice) - @payment_order.save && @payment_order.reload + @payment_order = PaymentOrder.new_with_type(type: channel, invoice: invoice) + @payment_order.save + @payment_order.reload @payment_order.return_url = registrar_return_payment_with_url(@payment_order) @payment_order.response_url = registrar_response_payment_with_url(@payment_order) - @payment_order.save && @payment_order.reload + @payment_order.save + @payment_order.reload end def back diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index 105f7d14f..ca41e8840 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -53,7 +53,7 @@ class BankTransaction < ApplicationRecord return end - payment_order = PaymentOrder.create_with_type(type: channel, invoice: invoice) + payment_order = PaymentOrder.new_with_type(type: channel, invoice: invoice) payment_order.save! if create_activity(registrar, invoice) diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index 3d788913b..4317abb38 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -32,7 +32,7 @@ class PaymentOrder < ApplicationRecord supported end - def self.create_with_type(type:, invoice:) + def self.new_with_type(type:, invoice:) channel = ('PaymentOrders::' + type.camelize).constantize PaymentOrder.new(type: channel, invoice: invoice) diff --git a/test/models/payment_orders_test.rb b/test/models/payment_orders_test.rb index 67267fec0..43996c6bc 100644 --- a/test/models/payment_orders_test.rb +++ b/test/models/payment_orders_test.rb @@ -44,34 +44,34 @@ class PaymentOrdersTest < ActiveSupport::TestCase end def test_correct_channel_is_assigned - everypay_channel = PaymentOrder.create_with_type(type: 'every_pay', invoice: @invoice) + everypay_channel = PaymentOrder.new_with_type(type: 'every_pay', invoice: @invoice) assert_equal everypay_channel.channel, 'EveryPay' assert_equal everypay_channel.class.config_namespace_name, 'every_pay' - swed_channel = PaymentOrder.create_with_type(type: 'swed', invoice: @invoice) + swed_channel = PaymentOrder.new_with_type(type: 'swed', invoice: @invoice) assert_equal swed_channel.channel, 'Swed' assert_equal swed_channel.class.config_namespace_name, 'swed' - seb_channel = PaymentOrder.create_with_type(type: 'seb', invoice: @invoice) + seb_channel = PaymentOrder.new_with_type(type: 'seb', invoice: @invoice) assert_equal seb_channel.channel, 'Seb' assert_equal seb_channel.class.config_namespace_name, 'seb' - lhv_channel = PaymentOrder.create_with_type(type: 'lhv', invoice: @invoice) + lhv_channel = PaymentOrder.new_with_type(type: 'lhv', invoice: @invoice) assert_equal lhv_channel.channel, 'Lhv' assert_equal lhv_channel.class.config_namespace_name, 'lhv' - admin_channel = PaymentOrder.create_with_type(type: 'admin_payment', invoice: @invoice) + admin_channel = PaymentOrder.new_with_type(type: 'admin_payment', invoice: @invoice) assert_equal admin_channel.channel, 'AdminPayment' assert_equal admin_channel.class.config_namespace_name, 'admin_payment' - system_channel = PaymentOrder.create_with_type(type: 'system_payment', invoice: @invoice) + system_channel = PaymentOrder.new_with_type(type: 'system_payment', invoice: @invoice) assert_equal system_channel.channel, 'SystemPayment' assert_equal system_channel.class.config_namespace_name, 'system_payment' end def test_can_not_create_order_for_paid_invoice invoice = invoices(:one) - payment_order = PaymentOrder.create_with_type(type: 'every_pay', invoice: invoice) + payment_order = PaymentOrder.new_with_type(type: 'every_pay', invoice: invoice) assert payment_order.invalid? assert_includes payment_order.errors[:invoice], 'is already paid' end @@ -84,7 +84,7 @@ class PaymentOrdersTest < ActiveSupport::TestCase def test_can_not_create_order_with_invalid_type assert_raise NameError do - PaymentOrder.create_with_type(type: 'not_implemented', invoice: Invoice.new) + PaymentOrder.new_with_type(type: 'not_implemented', invoice: Invoice.new) end end @@ -97,7 +97,7 @@ class PaymentOrdersTest < ActiveSupport::TestCase end def test_can_create_with_correct_subclass - payment = PaymentOrder.create_with_type(type: 'seb', invoice: Invoice.new) + payment = PaymentOrder.new_with_type(type: 'seb', invoice: Invoice.new) assert_equal PaymentOrders::Seb, payment.class end end From f529a6c8ec453431857cca008a7cef4975986310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 5 Feb 2020 17:16:09 +0200 Subject: [PATCH 030/110] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bd0e3602..d4f4b72d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ 05.02.2020 * Ruby version upgrade to 2.6.3 [#846](https://github.com/internetee/registry/issues/846) +* Added retries & raise to connect api to handle timeouts [#1474](https://github.com/internetee/registry/issues/1474) +* Added logging of XML if there is NoMethodError#text on xml data fields [#1475](https://github.com/internetee/registry/issues/1475) 04.02.2020 * Fixed bug that allowed bypassing blocked domain validation using punycode [#1142](https://github.com/internetee/registry/issues/1142) From b725ddde77aa0a8a9853968ad912c7f97ae1d7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 6 Feb 2020 15:30:46 +0200 Subject: [PATCH 031/110] Permit & turn ActiveController::Parameters to hash --- app/controllers/registrar/domains_controller.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/controllers/registrar/domains_controller.rb b/app/controllers/registrar/domains_controller.rb index f533a874c..5bf1a51f5 100644 --- a/app/controllers/registrar/domains_controller.rb +++ b/app/controllers/registrar/domains_controller.rb @@ -85,7 +85,7 @@ class Registrar def create authorize! :create, Depp::Domain - @domain_params = params[:domain] + @domain_params = domain_params.to_h @data = @domain.create(@domain_params) if response_ok? @@ -187,5 +187,12 @@ class Registrar :valid_to_lteq, :s) end + + def domain_params + params.require(:domain).permit(:name, :period, :registrant, :registrant_helper, :reserved_pw, + :legal_document, contacts_attributes: {}, + nameservers_attributes: {}, + dnskeys_attributes: {}) + end end end From c7e3482aa3d892556333c92d7ec6f56b8c5136ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Thu, 6 Feb 2020 16:55:23 +0200 Subject: [PATCH 032/110] Update CHANGELOG.md [ci skip] --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4f4b72d6..2dda02b55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +06.02.2020 +* Permit & turn ActiveController::Parameters to hash on domain create [#1516](https://github.com/internetee/registry/issues/1516) + 05.02.2020 * Ruby version upgrade to 2.6.3 [#846](https://github.com/internetee/registry/issues/846) * Added retries & raise to connect api to handle timeouts [#1474](https://github.com/internetee/registry/issues/1474) From b7f8d3a0b07dbe0176f5da51c796e3143c8d8bda Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Fri, 7 Feb 2020 16:26:03 +0500 Subject: [PATCH 033/110] Save request data to the directo object Closes #344 --- app/models/directo.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/models/directo.rb b/app/models/directo.rb index 789db64b2..99a0d9265 100644 --- a/app/models/directo.rb +++ b/app/models/directo.rb @@ -48,16 +48,18 @@ class Directo < ApplicationRecord Rails.logger.info("[Directo] XML request: #{data}") response = RestClient::Request.execute(url: ENV['directo_invoice_url'], method: :post, payload: {put: "1", what: "invoice", xmldata: data}, verify_ssl: false) Rails.logger.info("[Directo] Directo responded with code: #{response.code}, body: #{response.body}") - dump_result_to_db(mappers, response.to_s) + dump_result_to_db(mappers: mappers, xml: response.to_s, data: data) end STDOUT << "#{Time.zone.now.utc} - Directo receipts sending finished. #{counter} of #{total} are sent\n" end - def self.dump_result_to_db mappers, xml + def self.dump_result_to_db(mappers:, xml:, data:) 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, invoice_number: obj.number) + obj.directo_records.create!(request: data, + 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 From a89688154a335cf158e84a4132d42855a2f72e62 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Fri, 7 Feb 2020 18:21:42 +0500 Subject: [PATCH 034/110] Get rid of BigDecimal.new deprecation warning See #1521 --- app/models/bank_statement.rb | 2 +- app/models/payment_orders/bank_link.rb | 2 +- app/models/payment_orders/every_pay.rb | 2 +- test/models/deposit_test.rb | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/models/bank_statement.rb b/app/models/bank_statement.rb index 8d4608f64..942ae3907 100644 --- a/app/models/bank_statement.rb +++ b/app/models/bank_statement.rb @@ -45,7 +45,7 @@ class BankStatement < ApplicationRecord buyer_name: row[83, 35].strip, document_no: row[118, 8].strip, description: row[126, 140].strip, - sum: BigDecimal.new(row[268, 12].strip) / BigDecimal.new('100.0'), + sum: BigDecimal(row[268, 12].strip) / BigDecimal('100.0'), reference_no: row[280, 35].strip } end diff --git a/app/models/payment_orders/bank_link.rb b/app/models/payment_orders/bank_link.rb index 1e4c2785a..ffc570510 100644 --- a/app/models/payment_orders/bank_link.rb +++ b/app/models/payment_orders/bank_link.rb @@ -89,7 +89,7 @@ module PaymentOrders def valid_amount? source = number_with_precision( - BigDecimal.new(response["VK_AMOUNT"]), precision: 2, separator: "." + BigDecimal(response["VK_AMOUNT"]), precision: 2, separator: "." ) target = number_with_precision( invoice.total, precision: 2, separator: "." diff --git a/app/models/payment_orders/every_pay.rb b/app/models/payment_orders/every_pay.rb index a866ba972..560ee6e9e 100644 --- a/app/models/payment_orders/every_pay.rb +++ b/app/models/payment_orders/every_pay.rb @@ -76,7 +76,7 @@ module PaymentOrders end def valid_amount? - invoice.total == BigDecimal.new(response[:amount]) + invoice.total == BigDecimal(response[:amount]) end def valid_account? diff --git a/test/models/deposit_test.rb b/test/models/deposit_test.rb index d8fc2d02a..171316f65 100644 --- a/test/models/deposit_test.rb +++ b/test/models/deposit_test.rb @@ -36,22 +36,22 @@ class DepositTest < ActiveSupport::TestCase def test_amount_is_converted_from_string @deposit.amount = "12.00" - assert_equal(BigDecimal.new("12.00"), @deposit.amount) + assert_equal(BigDecimal("12.00"), @deposit.amount) @deposit.amount = "12,11" - assert_equal(BigDecimal.new("12.11"), @deposit.amount) + assert_equal(BigDecimal("12.11"), @deposit.amount) end def test_amount_is_converted_from_float @deposit.amount = 12.0044 - assert_equal(BigDecimal.new("12.0044"), @deposit.amount) + assert_equal(BigDecimal("12.0044"), @deposit.amount) @deposit.amount = 12.0144 - assert_equal(BigDecimal.new("12.0144"), @deposit.amount) + assert_equal(BigDecimal("12.0144"), @deposit.amount) end def test_amount_is_converted_from_nil @deposit.amount = nil - assert_equal(BigDecimal.new("0.00"), @deposit.amount) + assert_equal(BigDecimal("0.00"), @deposit.amount) end end From d2bc6cdd86527aa94933e6608aa2658e852a40c9 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Fri, 7 Feb 2020 18:34:39 +0500 Subject: [PATCH 035/110] Add tests for storing request in invoice's irecto records --- test/models/directo_test.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/models/directo_test.rb b/test/models/directo_test.rb index 9dbbf64d4..b1c461eb0 100644 --- a/test/models/directo_test.rb +++ b/test/models/directo_test.rb @@ -9,12 +9,21 @@ class DirectoTest < ActiveSupport::TestCase @invoice.update(total: @invoice.account_activity.bank_transaction.sum) @invoice.account_activity.bank_transaction.update(paid_at: Time.zone.now) + response = <<-XML + + + + + XML + stub_request(:post, ENV['directo_invoice_url']).with do |request| request.body.include? 'TransactionDate' - end + end.to_return(status: 200, body: response) assert_nothing_raised do Directo.send_receipts end + + assert_not_empty @invoice.directo_records.first.request end end From 8de9c1d7c66cb80e3d77c21c5561983fc7d449f4 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Fri, 7 Feb 2020 19:01:39 +0500 Subject: [PATCH 036/110] Silence deprecation warnings --- config/environments/test.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/environments/test.rb b/config/environments/test.rb index 6913ceb7e..f9d3552b4 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,3 +1,4 @@ + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -30,7 +31,7 @@ Rails.application.configure do config.action_mailer.raise_delivery_errors = false # Print deprecation notices to the stderr. - config.active_support.deprecation = :stderr + config.active_support.deprecation = :silence # Raises error for missing translations config.action_view.raise_on_missing_translations = true From ed98ca3ed8ed42511f3961d17deeda9af0da4ad5 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Fri, 7 Feb 2020 19:11:55 +0500 Subject: [PATCH 037/110] Remove verbose warinings from tests --- config/environments/test.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/environments/test.rb b/config/environments/test.rb index f9d3552b4..784b48f42 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,5 +1,6 @@ Rails.application.configure do + $VERBOSE = nil # Settings specified here will take precedence over those in config/application.rb. # The test environment is used exclusively to run your application's From d6dd4eccf57329349cada479f5168d80ac595181 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Mon, 10 Feb 2020 14:35:48 +0500 Subject: [PATCH 038/110] Check if Directo counter is in range See #277 --- app/models/directo.rb | 7 ++++--- test/models/directo_test.rb | 13 +++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/models/directo.rb b/app/models/directo.rb index 789db64b2..5d57bef78 100644 --- a/app/models/directo.rb +++ b/app/models/directo.rb @@ -65,7 +65,7 @@ class Directo < ApplicationRecord def self.send_monthly_invoices(debug: false) - I18n.locale = :et + I18n.locale = :et unless Rails.env.test? month = Time.now - 1.month invoices_until = month.end_of_month date_format = "%Y-%m-%d" @@ -74,8 +74,9 @@ class Directo < ApplicationRecord min_directo = Setting.directo_monthly_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 (max allowed number is smaller than last counter number)" + if max_directo && (max_directo <= last_directo + Registrar.count) + raise 'Directo counter is out of period (max allowed number is smaller than last counter'\ + 'number plus Registrar\'s count)' end directo_next = last_directo diff --git a/test/models/directo_test.rb b/test/models/directo_test.rb index 9dbbf64d4..f1c5cce76 100644 --- a/test/models/directo_test.rb +++ b/test/models/directo_test.rb @@ -5,6 +5,19 @@ class DirectoTest < ActiveSupport::TestCase @invoice = invoices(:one) end + def test_monthly_invoices_max_range_raises_if_overlaps + + Setting.directo_monthly_number_max = Setting.directo_monthly_number_last.to_i + Registrar.count - 1 + error_message = 'Directo counter is out of period (max allowed number is smaller than last '\ + 'counternumber plus Registrar\'s count)' + + error = assert_raises RuntimeError do + Directo.send_monthly_invoices + end + + assert_equal error_message, error.message + end + def test_xml_is_include_transaction_date @invoice.update(total: @invoice.account_activity.bank_transaction.sum) @invoice.account_activity.bank_transaction.update(paid_at: Time.zone.now) From e05ea4d7444bf2e4b7f8002d316bb7224c894362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Mon, 10 Feb 2020 13:26:13 +0200 Subject: [PATCH 039/110] Update CHANGELOG.md [ci skip] --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dda02b55..49d6aa0a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +10.02.2020 +* Resolved Money gem deprecation warning and silenced all warnings due plan to replace papertrail [#1522](https://github.com/internetee/registry/pull/1522) + 06.02.2020 * Permit & turn ActiveController::Parameters to hash on domain create [#1516](https://github.com/internetee/registry/issues/1516) From a1651ca1b98512570a3c6b404769d37ee4302c23 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 12 Feb 2020 18:51:48 +0500 Subject: [PATCH 040/110] Fix double versioning on Domain & Contact models --- app/models/concerns/versions.rb | 8 +++++++- app/models/contact.rb | 2 -- app/models/domain.rb | 2 -- .../registrant_api_registry_locks_test.rb | 2 +- test/integration/contact/audit_log_test.rb | 2 +- test/integration/domain/audit_log_test.rb | 2 +- test/learning/paper_trail_test.rb | 19 +++++++++++++++++++ test/models/domain/domain_version_test.rb | 4 ++-- 8 files changed, 31 insertions(+), 10 deletions(-) diff --git a/app/models/concerns/versions.rb b/app/models/concerns/versions.rb index bd6580adf..c9735901b 100644 --- a/app/models/concerns/versions.rb +++ b/app/models/concerns/versions.rb @@ -4,7 +4,13 @@ module Versions included do attr_accessor :version_loader - has_paper_trail class_name: "#{model_name}Version" + WITH_CHILDREN = %w[Domain Contact].freeze + + if WITH_CHILDREN.include?(model_name.name) + has_paper_trail class_name: "#{model_name}Version", meta: { children: :children_log } + else + has_paper_trail class_name: "#{model_name}Version" + end # add creator and updator before_create :add_creator diff --git a/app/models/contact.rb b/app/models/contact.rb index 9cb954462..f5f41e2f7 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -14,8 +14,6 @@ class Contact < ApplicationRecord has_many :registrant_domains, class_name: 'Domain', foreign_key: 'registrant_id' has_many :actions, dependent: :destroy - has_paper_trail class_name: "ContactVersion", meta: { children: :children_log } - attr_accessor :legal_document_id alias_attribute :kind, :ident_type alias_attribute :copy_from_id, :original_id # Old attribute name; for PaperTrail diff --git a/app/models/domain.rb b/app/models/domain.rb index b37d31ea0..ceff9e810 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -10,8 +10,6 @@ class Domain < ApplicationRecord include Concerns::Domain::RegistryLockable include Concerns::Domain::Releasable - has_paper_trail class_name: "DomainVersion", meta: { children: :children_log } - attr_accessor :roles attr_accessor :legal_document_id diff --git a/test/integration/api/registrant/registrant_api_registry_locks_test.rb b/test/integration/api/registrant/registrant_api_registry_locks_test.rb index e4f551072..4babdf428 100644 --- a/test/integration/api/registrant/registrant_api_registry_locks_test.rb +++ b/test/integration/api/registrant/registrant_api_registry_locks_test.rb @@ -25,7 +25,7 @@ class RegistrantApiRegistryLocksTest < ApplicationIntegrationTest end def test_locking_a_domain_creates_a_version_record - assert_difference '@domain.versions.count', 2 do + assert_difference '@domain.versions.count', 1 do post '/api/v1/registrant/domains/2df2c1a1-8f6a-490a-81be-8bdf29866880/registry_lock', headers: @auth_headers end diff --git a/test/integration/contact/audit_log_test.rb b/test/integration/contact/audit_log_test.rb index 41eb74cdd..41699d595 100644 --- a/test/integration/contact/audit_log_test.rb +++ b/test/integration/contact/audit_log_test.rb @@ -5,7 +5,7 @@ class ContactAuditLogTest < ActionDispatch::IntegrationTest contact = contacts(:john) contact.legal_document_id = 1 - assert_difference 'contact.versions.count', 2 do + assert_difference 'contact.versions.count', 1 do contact.save! end diff --git a/test/integration/domain/audit_log_test.rb b/test/integration/domain/audit_log_test.rb index 244e55ff7..a17fded0d 100644 --- a/test/integration/domain/audit_log_test.rb +++ b/test/integration/domain/audit_log_test.rb @@ -14,7 +14,7 @@ class DomainAuditLogTest < ActionDispatch::IntegrationTest assert_equal registrant_id, domain.registrant_id domain.legal_document_id = legal_document_id - assert_difference 'domain.versions.count', 2 do + assert_difference 'domain.versions.count', 1 do domain.save! end diff --git a/test/learning/paper_trail_test.rb b/test/learning/paper_trail_test.rb index 1a46022e4..b7351c644 100644 --- a/test/learning/paper_trail_test.rb +++ b/test/learning/paper_trail_test.rb @@ -21,6 +21,25 @@ class PaperTrailLearningTest < ActiveSupport::TestCase assert_respond_to @record.versions.first, :item_id end + def test_returns_version_count_on_domains + @domain = domains(:airport) + @domain.save + + assert_equal 1, @domain.versions.count + + @domain.name = 'domain.test' + @domain.save! + assert_equal 2, @domain.versions.count + end + + def test_returns_version_count_on_users + @user = users(:registrant) + + @user.email = 'aaa@bbb.com' + @user.save! + assert_equal 1, @user.versions.count + end + def test_creates_new_version_upon_update @record = Post.create!(title: 'old title') original_record = @record.clone diff --git a/test/models/domain/domain_version_test.rb b/test/models/domain/domain_version_test.rb index 305f353fa..74844f3af 100644 --- a/test/models/domain/domain_version_test.rb +++ b/test/models/domain/domain_version_test.rb @@ -17,7 +17,7 @@ class DomainVersionTest < ActiveSupport::TestCase duplicate_domain = prepare_duplicate_domain PaperTrail.whodunnit = @user.id_role_username - assert_difference 'duplicate_domain.versions.count', 2 do + assert_difference 'duplicate_domain.versions.count', 1 do duplicate_domain.save! end @@ -30,7 +30,7 @@ class DomainVersionTest < ActiveSupport::TestCase def test_assigns_updator_to_paper_trail_whodunnit PaperTrail.whodunnit = @user.id_role_username - assert_difference '@domain.versions.count', 2 do + assert_difference '@domain.versions.count', 1 do @domain.apply_registry_lock end From 75850da35fcab165e37fcc0e3355d3e7eeef38e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 12 Feb 2020 16:31:03 +0200 Subject: [PATCH 041/110] Update CHANGELOG.md [ci skip] --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49d6aa0a6..37992b121 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +12.02.2020 +* Fixed papertrails double recording issue [#1526](https://github.com/internetee/registry/issues/1526) + 10.02.2020 * Resolved Money gem deprecation warning and silenced all warnings due plan to replace papertrail [#1522](https://github.com/internetee/registry/pull/1522) From 21fa2ba5b9e450460aa72438e1abe80fe5bd9451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 12 Feb 2020 16:37:50 +0200 Subject: [PATCH 042/110] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37992b121..62cf45866 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ 12.02.2020 * Fixed papertrails double recording issue [#1526](https://github.com/internetee/registry/issues/1526) +* Requests to Directo are now saved for both credit and monthly invoices [#344](https://github.com/internetee/registry/issues/344) 10.02.2020 * Resolved Money gem deprecation warning and silenced all warnings due plan to replace papertrail [#1522](https://github.com/internetee/registry/pull/1522) From 101187687279abbc5d03e09fd991f9268088f0ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 12 Feb 2020 17:49:41 +0200 Subject: [PATCH 043/110] Link bank transaction with AccountActivity --- app/models/bank_transaction.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index ca41e8840..f53a286ba 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -59,9 +59,7 @@ class BankTransaction < ApplicationRecord if create_activity(registrar, invoice) payment_order.paid! else - payment_order.failed! - payment_order.notes = 'Failed to create activity' - payment_order.save! + payment_order.update(notes: 'Failed to create activity', status: 'failed') end end @@ -95,10 +93,12 @@ class BankTransaction < ApplicationRecord end def create_activity(registrar, invoice) - activity = AccountActivity.new(account: registrar.cash_account, - invoice: invoice, sum: invoice.subtotal, - currency: currency, description: description, - activity_type: AccountActivity::ADD_CREDIT) + activity = AccountActivity.new( + account: registrar.cash_account, bank_transaction: self, + invoice: invoice, sum: invoice.subtotal, + currency: currency, description: description, + activity_type: AccountActivity::ADD_CREDIT + ) if activity.save reset_pending_registrar_balance_reload true From fc59d4a29df4042adc012f93e7be9b346a489e64 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 13 Feb 2020 20:26:42 +0500 Subject: [PATCH 044/110] Fix warnings on cron jobs --- app/models/concerns/versions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/concerns/versions.rb b/app/models/concerns/versions.rb index c9735901b..9ffd17e9a 100644 --- a/app/models/concerns/versions.rb +++ b/app/models/concerns/versions.rb @@ -1,10 +1,10 @@ # Papertrail concerns is mainly tested at country spec module Versions extend ActiveSupport::Concern + WITH_CHILDREN = %w[Domain Contact].freeze included do attr_accessor :version_loader - WITH_CHILDREN = %w[Domain Contact].freeze if WITH_CHILDREN.include?(model_name.name) has_paper_trail class_name: "#{model_name}Version", meta: { children: :children_log } From bc4176e84450c690ceb93444f36f9d3af92bbe00 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Fri, 14 Feb 2020 12:19:28 +0500 Subject: [PATCH 045/110] Modify application.yml to store strings only --- app/models/payment_orders.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/payment_orders.rb b/app/models/payment_orders.rb index 921af0cd4..50753548a 100644 --- a/app/models/payment_orders.rb +++ b/app/models/payment_orders.rb @@ -1,6 +1,6 @@ module PaymentOrders - PAYMENT_INTERMEDIARIES = ENV['payments_intermediaries'].to_s.strip.split(', ').freeze - PAYMENT_BANKLINK_BANKS = ENV['payments_banks'].to_s.strip.split(', ').freeze + PAYMENT_INTERMEDIARIES = ENV['payments_intermediaries'].strip.split(', ').freeze + PAYMENT_BANKLINK_BANKS = ENV['payments_banks'].strip.split(', ').freeze PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS].flatten.freeze def self.create_with_type(type, invoice, opts = {}) From 96d511aeae1afe3116fc1ec6e1eec5bb60cea76b Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Fri, 14 Feb 2020 13:50:36 +0500 Subject: [PATCH 046/110] Revert "Modify application.yml to store strings only" This reverts commit bc4176e84450c690ceb93444f36f9d3af92bbe00. --- app/models/payment_orders.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/payment_orders.rb b/app/models/payment_orders.rb index 50753548a..921af0cd4 100644 --- a/app/models/payment_orders.rb +++ b/app/models/payment_orders.rb @@ -1,6 +1,6 @@ module PaymentOrders - PAYMENT_INTERMEDIARIES = ENV['payments_intermediaries'].strip.split(', ').freeze - PAYMENT_BANKLINK_BANKS = ENV['payments_banks'].strip.split(', ').freeze + PAYMENT_INTERMEDIARIES = ENV['payments_intermediaries'].to_s.strip.split(', ').freeze + PAYMENT_BANKLINK_BANKS = ENV['payments_banks'].to_s.strip.split(', ').freeze PAYMENT_METHODS = [PAYMENT_INTERMEDIARIES, PAYMENT_BANKLINK_BANKS].flatten.freeze def self.create_with_type(type, invoice, opts = {}) From bdc1f0c820cfe651fe0b2e176ede9f56ff669a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Fri, 14 Feb 2020 20:14:07 +0200 Subject: [PATCH 047/110] Update CHANGELOG.md [ci skip] --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62cf45866..b723101ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +14.02.2020 +* Fixed Papertrail warnings [#1530](https://github.com/internetee/registry/issues/1530) + 12.02.2020 * Fixed papertrails double recording issue [#1526](https://github.com/internetee/registry/issues/1526) * Requests to Directo are now saved for both credit and monthly invoices [#344](https://github.com/internetee/registry/issues/344) From adba253d01d04972e44b217669336d92723465f0 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Mon, 17 Feb 2020 15:55:46 +0500 Subject: [PATCH 048/110] Add client_hold action to xml console See #1481 --- .../epp_requests/domain/client_hold.xml | 15 +++++++++++++++ app/views/registrar/xml_consoles/show.haml | 3 +++ 2 files changed, 18 insertions(+) create mode 100644 app/views/registrar/xml_consoles/epp_requests/domain/client_hold.xml diff --git a/app/views/registrar/xml_consoles/epp_requests/domain/client_hold.xml b/app/views/registrar/xml_consoles/epp_requests/domain/client_hold.xml new file mode 100644 index 000000000..fcafec538 --- /dev/null +++ b/app/views/registrar/xml_consoles/epp_requests/domain/client_hold.xml @@ -0,0 +1,15 @@ + + + + + + example.ee + + + + + + timo-1579351654 + + diff --git a/app/views/registrar/xml_consoles/show.haml b/app/views/registrar/xml_consoles/show.haml index f96b67738..5ffcb5279 100644 --- a/app/views/registrar/xml_consoles/show.haml +++ b/app/views/registrar/xml_consoles/show.haml @@ -29,6 +29,9 @@ , %a.js-load-xml{href: 'javascript:void(0)', data: {obj: 'domain', epp_action: 'delete'}} Delete + , + %a.js-load-xml{href: 'javascript:void(0)', data: {obj: 'domain', epp_action: 'client_hold'}} + Client Hold %h4 Poll %a.js-load-xml{href: 'javascript:void(0)', data: {obj: 'poll', epp_action: 'poll'}} From 2663c550fa1aee229679e9d407b12b5a2a5c0369 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 4 Feb 2020 16:00:24 +0500 Subject: [PATCH 049/110] Add idempotent Que job for e-invoice sending --- app/jobs/send_e_invoice_job.rb | 39 +++++++++++++++++++ ...103125_add_e_invoice_sent_at_to_invoice.rb | 5 +++ db/structure.sql | 4 +- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20200204103125_add_e_invoice_sent_at_to_invoice.rb diff --git a/app/jobs/send_e_invoice_job.rb b/app/jobs/send_e_invoice_job.rb index e69de29bb..9e8af7c65 100644 --- a/app/jobs/send_e_invoice_job.rb +++ b/app/jobs/send_e_invoice_job.rb @@ -0,0 +1,39 @@ +class SendEInvoiceJob < Que::Job + + def run(invoice) + return if invoice.e_invoice_sent_at + + e_invoice = invoice.to_e_invoice + e_invoice.deliver + + ActiveRecord::Base.transaction do + invoice.update(e_invoice_sent_at: Time.zone.now) + log_success(invoice) + destroy + end + + rescue Savon::Error => e + log_error(invoice: invoice, error: e) + end + + private + + def log_success(invoice) + message = "E-Invoice for an invoice with ID # #{invoice.id} was sent successfully" + logger.info message + end + + def log_error(invoice:, error:) + message = <<~TEXT.squish + There was an error sending e-invoice for invoice with ID # #{invoice.id}. + The error message was the following: #{error}. + This job will retry + TEXT + logger.error message + end + + def logger + Rails.logger + end + +end diff --git a/db/migrate/20200204103125_add_e_invoice_sent_at_to_invoice.rb b/db/migrate/20200204103125_add_e_invoice_sent_at_to_invoice.rb new file mode 100644 index 000000000..e0e5f2cd0 --- /dev/null +++ b/db/migrate/20200204103125_add_e_invoice_sent_at_to_invoice.rb @@ -0,0 +1,5 @@ +class AddEInvoiceSentAtToInvoice < ActiveRecord::Migration[5.0] + def change + add_column :invoices, :e_invoice_sent_at, :datetime + end +end diff --git a/db/structure.sql b/db/structure.sql index a23623bae..cd2998c07 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -886,6 +886,7 @@ CREATE TABLE public.invoices ( in_directo boolean DEFAULT false, buyer_vat_no character varying, issue_date date NOT NULL, + e_invoice_sent_at timestamp without time zone, CONSTRAINT invoices_due_date_is_not_before_issue_date CHECK ((due_date >= issue_date)) ); @@ -4339,6 +4340,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20191212133136'), ('20191227110904'), ('20200113091254'), -('20200115102202'); +('20200115102202'), +('20200204103125'); From 47e601f3cdce75e1ce5e5f362cb9406c6a8cd33f Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 4 Feb 2020 16:20:07 +0500 Subject: [PATCH 050/110] Add test to check if job works --- app/jobs/send_e_invoice_job.rb | 9 ++---- app/models/registrar.rb | 3 +- test/jobs/send_e_invoice_job_test.rb | 45 ++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 test/jobs/send_e_invoice_job_test.rb diff --git a/app/jobs/send_e_invoice_job.rb b/app/jobs/send_e_invoice_job.rb index 9e8af7c65..36e024b1d 100644 --- a/app/jobs/send_e_invoice_job.rb +++ b/app/jobs/send_e_invoice_job.rb @@ -1,19 +1,17 @@ class SendEInvoiceJob < Que::Job - def run(invoice) return if invoice.e_invoice_sent_at - e_invoice = invoice.to_e_invoice - e_invoice.deliver + invoice.to_e_invoice.deliver ActiveRecord::Base.transaction do invoice.update(e_invoice_sent_at: Time.zone.now) log_success(invoice) destroy end - - rescue Savon::Error => e + rescue StandardError => e log_error(invoice: invoice, error: e) + raise e end private @@ -35,5 +33,4 @@ class SendEInvoiceJob < Que::Job def logger Rails.logger end - end diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 88aa1c629..94b01517e 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -100,8 +100,7 @@ class Registrar < ApplicationRecord ] ) - e_invoice = invoice.to_e_invoice - e_invoice.deliver + SendEInvoiceJob.enqueue(invoice) invoice end diff --git a/test/jobs/send_e_invoice_job_test.rb b/test/jobs/send_e_invoice_job_test.rb new file mode 100644 index 000000000..5ea09e576 --- /dev/null +++ b/test/jobs/send_e_invoice_job_test.rb @@ -0,0 +1,45 @@ +require 'test_helper' + +class SendEInvoiceJobTest < ActiveSupport::TestCase + + def teardown + EInvoice.provider = EInvoice::Providers::TestProvider.new + EInvoice::Providers::TestProvider.deliveries.clear + end + + def test_if_invoice_is_sended + @invoice = invoices(:one) + EInvoice.provider = EInvoice::Providers::TestProvider.new + EInvoice::Providers::TestProvider.deliveries.clear + + assert_nothing_raised do + SendEInvoiceJob.enqueue(@invoice) + end + + assert_not @invoice.e_invoice_sent_at.blank? + assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count + end + + def test_if_invoice_sending_retries + @invoice = invoices(:one) + provider_config = { password: nil, + test_mode: true } + EInvoice.provider = EInvoice::Providers::OmnivaProvider.new(provider_config) + stub_request(:get, "https://testfinance.post.ee/finance/erp/erpServices.wsdl").to_timeout + + assert_raise HTTPClient::TimeoutError do + SendEInvoiceJob.enqueue(@invoice) + end + assert @invoicee_invoice_sent_at.blank? + + EInvoice.provider = EInvoice::Providers::TestProvider.new + EInvoice::Providers::TestProvider.deliveries.clear + + assert_nothing_raised do + SendEInvoiceJob.enqueue(@invoice) + end + + assert_not @invoice.e_invoice_sent_at.blank? + assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count + end +end From 187ce318a221681928e7fd3366253d134cc0803a Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 5 Feb 2020 14:24:09 +0500 Subject: [PATCH 051/110] Destroy e-invoice sending job if invoice sent, cancelled or paid --- app/jobs/send_e_invoice_job.rb | 10 ++++++---- app/models/invoice.rb | 10 +++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/jobs/send_e_invoice_job.rb b/app/jobs/send_e_invoice_job.rb index 36e024b1d..6e7b5edb8 100644 --- a/app/jobs/send_e_invoice_job.rb +++ b/app/jobs/send_e_invoice_job.rb @@ -1,6 +1,6 @@ class SendEInvoiceJob < Que::Job def run(invoice) - return if invoice.e_invoice_sent_at + destroy if invoice.do_not_send_e_invoice? invoice.to_e_invoice.deliver @@ -9,7 +9,7 @@ class SendEInvoiceJob < Que::Job log_success(invoice) destroy end - rescue StandardError => e + rescue Exception => e log_error(invoice: invoice, error: e) raise e end @@ -17,13 +17,15 @@ class SendEInvoiceJob < Que::Job private def log_success(invoice) - message = "E-Invoice for an invoice with ID # #{invoice.id} was sent successfully" + id = invoice.try(:id) || invoice + message = "E-Invoice for an invoice with ID # #{id} was sent successfully" logger.info message end def log_error(invoice:, error:) + id = invoice.try(:id) || invoice message = <<~TEXT.squish - There was an error sending e-invoice for invoice with ID # #{invoice.id}. + There was an error sending e-invoice for invoice with ID # #{id}. The error message was the following: #{error}. This job will retry TEXT diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 7f1dea825..4b35b71fb 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -102,6 +102,14 @@ class Invoice < ApplicationRecord generator.generate end + def do_not_send_e_invoice? + e_invoice_sent? || cancelled? || paid? + end + + def e_invoice_sent? + e_invoice_sent_at.present? + end + private def apply_default_buyer_vat_no @@ -111,4 +119,4 @@ class Invoice < ApplicationRecord def calculate_total self.total = subtotal + vat_amount end -end \ No newline at end of file +end From d5662f42b8617d0dd5b25e1e06257045db71143a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 12 Feb 2020 17:14:18 +0200 Subject: [PATCH 052/110] Fully implemented prepayment Directo invoice forwarding, WIP on proformas --- Gemfile.lock | 12 +- app/controllers/concerns/book_keeping.rb | 99 +++++++++ app/jobs/directo_invoice_forward_job.rb | 101 +++++++++ app/jobs/directo_invoice_forward_job_job.rb | 100 --------- app/models/counter.rb | 24 --- app/models/directo.rb | 195 ------------------ app/models/invoice.rb | 18 +- app/models/registrar.rb | 1 + test/jobs/directo_invoice_forward_job_test.rb | 20 ++ test/models/directo_test.rb | 16 -- 10 files changed, 249 insertions(+), 337 deletions(-) create mode 100644 app/controllers/concerns/book_keeping.rb create mode 100644 app/jobs/directo_invoice_forward_job.rb delete mode 100644 app/jobs/directo_invoice_forward_job_job.rb delete mode 100644 app/models/counter.rb create mode 100644 test/jobs/directo_invoice_forward_job_test.rb diff --git a/Gemfile.lock b/Gemfile.lock index 23aa90a51..71abcf70d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,6 +7,15 @@ GIT activesupport savon +GIT + remote: https://github.com/internetee/directo.git + revision: 6ac71939da589fcceb5ef3989ba982134679ec97 + branch: directo-api + specs: + directo (0.1.0) + money (~> 6.13) + nokogiri (~> 1.10) + GIT remote: https://github.com/internetee/e_invoice.git revision: 3a754974ed25569aa85d99a87ae9e131b7c10a24 @@ -457,6 +466,7 @@ DEPENDENCIES database_cleaner devise (~> 4.7) digidoc_client! + directo! domain_name e_invoice! epp! @@ -500,4 +510,4 @@ DEPENDENCIES wkhtmltopdf-binary BUNDLED WITH - 2.0.2 + 2.1.4 diff --git a/app/controllers/concerns/book_keeping.rb b/app/controllers/concerns/book_keeping.rb new file mode 100644 index 000000000..4e25a466f --- /dev/null +++ b/app/controllers/concerns/book_keeping.rb @@ -0,0 +1,99 @@ +module BookKeeping + extend ActiveSupport::Concern + + DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI', + 'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze + + def monthly_summary(month:) + activities = monthly_activites(month) + inv = { + 'number': 1, + 'customer_code': accounting_customer_code, + 'language': language, + 'currency': activities.first.currency, + 'date': month.end_of_month.strftime('%Y-%m-%d'), + }.as_json + + lines = [] + activities.each do |activity| + fetch_invoice_lines(activity, lines) + end + lines << prepayment_for_all(lines) + + inv['invoice_lines'] = lines.as_json + + inv + end + + def fetch_invoice_lines(activity, lines) + price = load_price(activity) + if price.duration.include? 'year' + price.duration.to_i.times do |duration| + lines << new_montly_invoice_line(activity: activity, duration: duration + 1).as_json + end + else + lines << new_monthly_invoice_line(activity: activity).as_json + end + end + + def monthly_activites(month) + AccountActivity.where(account_id: account_ids) + .where(created_at: month.beginning_of_month..month.end_of_month) + .where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]) + end + + def new_montly_invoice_line(activity:, duration: nil) + price = DirectoInvoiceForwardJob.load_price(activity) + yearly = price.duration.include?('year') + line = { + 'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym], + 'quantity': 1, + 'price': yearly ? (price.price.amount / price.duration.to_i) : price.amount, + } + + line['description'] = description_in_language(price: price, yearly: yearly) + add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1 + + line + end + + def add_product_timeframe(line:, activity:, duration:) + create_time = activity.created_at + line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d') + line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d') + end + + def description_in_language(price:, yearly:) + if language == 'en' + registration_length = yearly ? 'year' : 'month' + prefix = ".#{price.zone_name} registration: #{price.duration.to_i} #{registration_length}" + suffix = 's' + else + registration_length = yearly ? 'aasta' : 'kuu' + prefix = ".#{price.zone_name} registreerimine: #{price.duration.to_i} #{registration_length}" + suffix = yearly ? 't' : 'd' + end + + return "#{prefix}#{suffix}" if price.duration.to_i > 1 + + prefix + end + + def prepayment_for_all(lines) + total = 0 + lines.each { |l| total += l['quantity'].to_f * l['price'].to_f } + { + 'product_id': Setting.directo_receipt_product_name, + 'description': 'Domeenide ettemaks', + 'quantity': -1, + 'price': total + } + end + + def load_price(account_activity) + @pricelists ||= {} + return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id + + @pricelists[account_activity.price_id] = account_activity.price + end +end diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb new file mode 100644 index 000000000..6eca4c73c --- /dev/null +++ b/app/jobs/directo_invoice_forward_job.rb @@ -0,0 +1,101 @@ +class DirectoInvoiceForwardJob < Que::Job + def run(monthly: false, dry: false) + @dry = dry + api_url = ENV['directo_invoice_url'] + sales_agent = Setting.directo_sales_agent + payment_term = Setting.directo_receipt_payment_term + @prepayment_product_id = Setting.directo_receipt_product_name + + @client = DirectoApi::Client.new(api_url, sales_agent, payment_term) + monthly ? send_monthly_invoices : send_receipts + end + + def send_receipts + unsent_invoices = Invoice.where(in_directo: false).non_cancelled + + Rails.logger.info("[DIRECTO] Trying to send #{unsent_invoices.count} prepayment invoices") + unsent_invoices.each do |invoice| + unless valid_invoice_conditions?(invoice) + Rails.logger.info "[DIRECTO] Invoice #{invoice.number} has been skipped" + next + end + @client.invoices.add_with_schema(invoice: invoice.as_directo_json, schema: 'prepayment') + end + + sync_with_directo + end + + def send_monthly_invoices + month = Time.now - 1.month + + Registrar.where.not(test_registrar: true).find_each do |registrar| + next unless registrar.cash_account + + invoice = registrar.monthly_summary(month: month) + @client.invoices.add_with_schema(invoice: invoice, schema: 'summary') + end + + # TODO: Invoice number + sync_with_directo + end + + def valid_invoice_conditions?(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.total + return false + + end + + true + end + + def sync_with_directo + Rails.logger.info('[Directo] - attempting to send following XML:') + puts @client.invoices.as_xml + + return if @dry + + res = @client.invoices.deliver(ssl_verify: false) + + update_invoice_directo_state(res.body) if res.code == '200' + rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, + EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError + Rails.logger.info("[Directo] Failed. Responded with code: #{res.code}, body: #{res.body}") + end + + def update_invoice_directo_state(xml) + Nokogiri::XML(xml).css('Result').each do |res| + inv = Invoice.find_by(number: res.attributes['docid'].value.to_i) + mark_invoice_as_sent(invoice: inv, data: res) + end + end + + def mark_invoice_as_sent(invoice:, data:) + invoice.directo_records.create!(response: data.as_json.to_h, invoice_number: invoice.number) + invoice.update_columns(in_directo: true) + Rails.logger.info("[DIRECTO] Invoice #{invoice.number} was pushed and return is #{data.as_json.to_h.inspect}") + end + + def self.load_price(account_activity) + @pricelists ||= {} + if @pricelists.key? account_activity.price_id + return @pricelists[account_activity.price_id] + end + + @pricelists[account_activity.price_id] = account_activity.price + end + + def last_directo_monthly_number + min_directo = Setting.directo_monthly_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 + + last_directo + end +end diff --git a/app/jobs/directo_invoice_forward_job_job.rb b/app/jobs/directo_invoice_forward_job_job.rb deleted file mode 100644 index 4c95bb366..000000000 --- a/app/jobs/directo_invoice_forward_job_job.rb +++ /dev/null @@ -1,100 +0,0 @@ -class DirectoInvoiceForwardJobJob < ApplicationJob - queue_as :default - - def perform(monthly: false, dry: false) - api_url = ENV['directo_invoice_url'] - sales_agent = Setting.directo_sales_agent - payment_term = Setting.directo_receipt_payment_term - @prepayment_product_id = Setting.directo_receipt_product_name - - @client = DirectoApi::Client.new(api_url, sales_agent, payment_term) - monthly ? send_monthly_invoices(dry: dry) : send_receipts(dry: dry) - end - - def send_receipts - unsent_invoices = Invoice.where(in_directo: false).non_cancelled - - Rails.logger.info("[DIRECTO] Trying to send #{unsent_invoices.count} prepayment invoices") - unsent_invoices.each do |invoice| - unless valid_invoice_conditions?(invoice) - Rails.logger.info("[DIRECTO] Invoice #{invoice.number} has been skipped") && next - end - - @client.invoices.add(generate_directo_invoice(invoice: invoice, client: @client, - product_id: @prepayment_product_id)) - end - sync_with_directo - end - - def send_monthly_invoices; end - - def valid_invoice_conditions?(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.total - false - end - true - end - - def generate_directo_invoice(invoice:, client:, product_id:) - inv = client.invoices.new - inv = create_invoice_meta(directo_invoice: inv, invoice: invoice) - inv = create_invoice_line(invoice: invoice, directo_invoice: inv, product_id: product_id) - - inv - end - - def create_invoice_meta(directo_invoice:, invoice:) - directo_invoice.customer = create_invoice_customer(invoice: invoice) - directo_invoice.date = invoice.issue_date.strftime('%Y-%m-%d') # Mapped - directo_invoice.transaction_date = - invoice.account_activity.bank_transaction&.paid_at&.strftime('%Y-%m-%d') # Mapped - directo_invoice.number = invoice.number # Mapped - directo_invoice.currency = invoice.currency # Mapped - directo_invoice.language = 'ENG' # Hardcoded - - directo_invoice - end - - def create_invoice_line(invoice:, directo_invoice:, product_id:) - line = directo_invoice.lines.new - line.code = product_id # MAPPED - line.description = invoice.result.auction.domain_name # MAPPED - line.quantity = 1 # MAPPED - line.price = ActionController::Base.helpers. - number_with_precision(invoice.subtotal, precision: 2, separator: ".") # MAPPED - directo_invoice.lines.add(line) - - directo_invoice - end - - def create_invoice_customer(invoice:) - customer = Directo::Customer.new - customer.code = invoice.buyer.accounting_customer_code # MAPPED - - customer - end - - def sync_with_directo - res = @client.invoices.deliver(ssl_verify: false) - Rails.logger.info("[Directo] Directo responded with code: #{res.code}, body: #{res.body}") - update_invoice_directo_state(res.body) if res.code == '200' - rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, - EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError - Rails.logger.info("[Directo] Failed. Responded with code: #{res.code}, body: #{res.body}") - end - - def update_invoice_directo_state(xml) - Nokogiri::XML(xml).css('Result').each do |res| - inv = Invoice.find_by(number: res.attributes['docid'].value.to_i) - mark_invoice_as_sent(invoice: inv, data: res) - end - end - - def mark_invoice_as_sent(invoice:, data:) - invoice.directo_records.create!(response: data.as_json.to_h, invoice_number: invoice.number) - invoice.update_columns(in_directo: true) - Rails.logger.info("[DIRECTO] Invoice #{invoice.number} was pushed and return is #{data.as_json.to_h.inspect}") - end -end diff --git a/app/models/counter.rb b/app/models/counter.rb deleted file mode 100644 index 7d1c2b926..000000000 --- a/app/models/counter.rb +++ /dev/null @@ -1,24 +0,0 @@ -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 789db64b2..a4af6c134 100644 --- a/app/models/directo.rb +++ b/app/models/directo.rb @@ -1,198 +1,3 @@ class Directo < ApplicationRecord - 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 - new_trans = Invoice.where(in_directo: false).non_cancelled - total = new_trans.count - counter = 0 - Rails.logger.info("[DIRECTO] Will try to send #{total} invoices") - - 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| - - 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.total - Rails.logger.info("[DIRECTO] Invoice #{invoice.number} has been skipped") - next - end - counter += 1 - - num = invoice.number - paid_at = invoice.account_activity.bank_transaction&.paid_at&.strftime("%Y-%m-%d") - mappers[num] = invoice - xml.invoice( - "SalesAgent" => Setting.directo_sales_agent, - "Number" => num, - "InvoiceDate" => invoice.issue_date.strftime("%Y-%m-%d"), - 'TransactionDate' => paid_at, - "PaymentTerm" => Setting.directo_receipt_payment_term, - "Currency" => invoice.currency, - "CustomerCode"=> invoice.buyer.accounting_customer_code - ){ - xml.line( - "ProductID" => Setting.directo_receipt_product_name, - "Quantity" => 1, - "UnitPriceWoVAT" => ActionController::Base.helpers.number_with_precision(invoice.subtotal, precision: 2, separator: "."), - "ProductName" => invoice.order - ) - } - end - } - end - - data = builder.to_xml.gsub("\n",'') - Rails.logger.info("[Directo] XML request: #{data}") - response = RestClient::Request.execute(url: ENV['directo_invoice_url'], method: :post, payload: {put: "1", what: "invoice", xmldata: data}, verify_ssl: false) - Rails.logger.info("[Directo] Directo responded with code: #{response.code}, body: #{response.body}") - dump_result_to_db(mappers, response.to_s) - end - - STDOUT << "#{Time.zone.now.utc} - Directo receipts sending finished. #{counter} of #{total} are sent\n" - 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, 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(debug: false) - 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.directo_monthly_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 (max allowed number is smaller than last counter number)" - end - - directo_next = last_directo - Registrar.where.not(test_registrar: 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| - price = load_price(activity) - - if price.duration.include?('year') - price.duration.to_i.times do |i| - year = i+1 - hash = { - "ProductID" => DOMAIN_TO_PRODUCT[price.zone_name], - "Unit" => "tk", - "ProductName" => ".#{price.zone_name} registreerimine: #{price.duration.to_i} aasta#{price.duration.to_i > 1 ? 't' : ''}", - "UnitPriceWoVAT" => price.price.amount / price.duration.to_i - } - hash["StartDate"] = (activity.created_at + (year-1).year).end_of_month.strftime(date_format) if year > 1 - hash["EndDate"] = (activity.created_at + (year-1).year + 1).end_of_month.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 - else - 1.times do |i| - quantity = price.account_activities - .where(account_id: registrar.account_ids) - .where(created_at: month.beginning_of_month..month.end_of_month) - .where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]) - .count - - hash = { - "ProductID" => DOMAIN_TO_PRODUCT[price.zone_name], - "Unit" => "tk", - "ProductName" => ".#{price.zone_name} registreerimine: #{price.duration.to_i} kuud", - "UnitPriceWoVAT" => price.price.amount, - } - - if items.has_key?(hash) - #items[hash]["Quantity"] += 1 - else - items[hash] = { "RN" => counter.next, "RR" => counter.now - i, "Quantity" => quantity } - end - end - end - - - end - - #adding prepaiments - if items.any? - total = 0 - items.each{ |key, val| total += val["Quantity"] * key["UnitPriceWoVAT"] } - hash = {"ProductID" => Setting.directo_receipt_product_name, "Unit" => "tk", "ProductName" => "Domeenide ettemaks", "UnitPriceWoVAT"=>total} - items[hash] = {"RN"=>counter.next, "RR" => counter.now, "Quantity"=> -1} - end - - # generating XML - if items.any? - directo_next += 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" =>Setting.directo_receipt_payment_term, - "CustomerCode"=>registrar.accounting_customer_code, - "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",'') - Rails.logger.info("[Directo] XML request: #{data}") - - if debug - STDOUT << "#{Time.zone.now.utc} - Directo xml had to be sent #{data}\n" - else - response = RestClient::Request.execute(url: ENV['directo_invoice_url'], method: :post, payload: {put: "1", what: "invoice", xmldata: data}, verify_ssl: false) - Rails.logger.info("[Directo] Directo responded with code: #{response.code}, body: #{response.body}") - response = response.to_s - - Setting.directo_monthly_number_last = directo_next - Nokogiri::XML(response).css("Result").each do |res| - Directo.create!(request: data, 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 - 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_price(account_activity) - @pricelists ||= {} - return @pricelists[account_activity.price_id] if @pricelists.has_key?(account_activity.price_id) - @pricelists[account_activity.price_id] = account_activity.price - end end diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 7f1dea825..20d0c5091 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -102,6 +102,22 @@ class Invoice < ApplicationRecord generator.generate end + def as_directo_json + inv = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self)) + inv['customer_code'] = buyer.accounting_customer_code + inv['issue_date'] = issue_date.strftime('%Y-%m-%d') + inv['transaction_date'] = account_activity.bank_transaction&.paid_at&.strftime('%Y-%m-%d') + inv['language'] = buyer.language + inv['invoice_lines'] = [{ + 'product_id': Setting.directo_receipt_product_name, + 'description': order, + 'quantity': 1, + 'price': ActionController::Base.helpers.number_with_precision(subtotal, precision: 2, separator: ".") + }].as_json + + inv + end + private def apply_default_buyer_vat_no @@ -111,4 +127,4 @@ class Invoice < ApplicationRecord def calculate_total self.total = subtotal + vat_amount end -end \ No newline at end of file +end diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 8f41d62ca..788d7857a 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -1,5 +1,6 @@ class Registrar < ApplicationRecord include Versions # version/registrar_version.rb + include BookKeeping has_many :domains, dependent: :restrict_with_error has_many :contacts, dependent: :restrict_with_error diff --git a/test/jobs/directo_invoice_forward_job_test.rb b/test/jobs/directo_invoice_forward_job_test.rb new file mode 100644 index 000000000..47cf9e6fb --- /dev/null +++ b/test/jobs/directo_invoice_forward_job_test.rb @@ -0,0 +1,20 @@ +require "test_helper" + +class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase + setup do + @invoice = invoices(:one) + end + + def test_xml_is_include_transaction_date + @invoice.update(total: @invoice.account_activity.bank_transaction.sum) + @invoice.account_activity.bank_transaction.update(paid_at: Time.zone.now) + + stub_request(:post, ENV['directo_invoice_url']).with do |request| + request.body.include? 'TransactionDate' + end + + assert_nothing_raised do + DirectoInvoiceForwardJob.run(monthly: false) + end + end +end diff --git a/test/models/directo_test.rb b/test/models/directo_test.rb index 9dbbf64d4..603a38d15 100644 --- a/test/models/directo_test.rb +++ b/test/models/directo_test.rb @@ -1,20 +1,4 @@ require 'test_helper' class DirectoTest < ActiveSupport::TestCase - setup do - @invoice = invoices(:one) - end - - def test_xml_is_include_transaction_date - @invoice.update(total: @invoice.account_activity.bank_transaction.sum) - @invoice.account_activity.bank_transaction.update(paid_at: Time.zone.now) - - stub_request(:post, ENV['directo_invoice_url']).with do |request| - request.body.include? 'TransactionDate' - end - - assert_nothing_raised do - Directo.send_receipts - end - end end From a743c6c56f11e8c6f9cf6e0692a18c2ab8e4a396 Mon Sep 17 00:00:00 2001 From: Georg Kahest Date: Wed, 19 Feb 2020 11:08:54 +0200 Subject: [PATCH 053/110] disable airbrake performance monitoring --- config/initializers/airbrake.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/initializers/airbrake.rb b/config/initializers/airbrake.rb index 917deb02a..5c1983369 100644 --- a/config/initializers/airbrake.rb +++ b/config/initializers/airbrake.rb @@ -3,6 +3,9 @@ Airbrake.configure do |config| config.project_id = ENV['airbrake_project_id'] config.project_key = ENV['airbrake_project_key'] config.root_directory = Rails.root + config.job_stats = false + config.query_stats = false + config.performance_stats = false config.logger = if ENV['RAILS_LOG_TO_STDOUT'].present? Logger.new(STDOUT, level: Rails.logger.level) From 3b332da0bb27160ac07414e5911f000eddbf6c82 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 19 Feb 2020 14:09:45 +0500 Subject: [PATCH 054/110] Add remove clientHold to registrar UI --- app/controllers/registrar/domains_controller.rb | 8 ++++++++ app/models/ability.rb | 1 + app/models/concerns/domain/force_delete.rb | 4 ++++ app/models/concerns/remove_hold.rb | 9 +++++++++ app/models/depp/domain.rb | 1 + app/views/registrar/domains/_domain.html.erb | 4 ++++ config/locales/en.yml | 1 + config/locales/registrar/domains.en.yml | 1 + config/routes.rb | 1 + 9 files changed, 30 insertions(+) create mode 100644 app/models/concerns/remove_hold.rb diff --git a/app/controllers/registrar/domains_controller.rb b/app/controllers/registrar/domains_controller.rb index 5bf1a51f5..8fdfd51fd 100644 --- a/app/controllers/registrar/domains_controller.rb +++ b/app/controllers/registrar/domains_controller.rb @@ -153,6 +153,14 @@ class Registrar render json: scope.pluck(:name, :code).map { |c| { display_key: "#{c.second} #{c.first}", value: c.second } } end + def remove_hold + authorize! :remove_hold, Depp::Domain + return unless params[:domain_name] + + @data = @domain.remove_hold(params) + redirect_to info_registrar_domains_url(domain_name: params[:domain_name]) + end + private def init_domain diff --git a/app/models/ability.rb b/app/models/ability.rb index 9a0676ac8..a727254ad 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -50,6 +50,7 @@ class Ability can(:check, Epp::Domain) can(:create, Epp::Domain) can(:renew, Epp::Domain) { |d| d.registrar_id == @user.registrar_id } + can(:remove_hold, Epp::Domain) { |d| d.registrar_id == @user.registrar_id } can(:update, Epp::Domain) { |d, pw| d.registrar_id == @user.registrar_id || d.transfer_code == pw } can(:transfer, Epp::Domain) can(:delete, Epp::Domain) { |d, pw| d.registrar_id == @user.registrar_id || d.transfer_code == pw } diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index af3aaa7c7..89c121993 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -34,6 +34,10 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength force_delete_start.present? && force_delete_lte_today && force_delete_lte_valid_date end + def client_holded? + statuses.include?(DomainStatus::CLIENT_HOLD) + end + def force_delete_lte_today force_delete_start + Setting.expire_warning_period.days <= Time.zone.now end diff --git a/app/models/concerns/remove_hold.rb b/app/models/concerns/remove_hold.rb new file mode 100644 index 000000000..1da3b5a7f --- /dev/null +++ b/app/models/concerns/remove_hold.rb @@ -0,0 +1,9 @@ +module RemoveHold + extend ActiveSupport::Concern + + def remove_hold(params) + xml = epp_xml.update(name: { value: params[:domain_name] }, + rem: [status: { attrs: { s: 'clientHold' }, value: '' }]) + current_user.request(xml) + end +end diff --git a/app/models/depp/domain.rb b/app/models/depp/domain.rb index e2413a004..3bb3b7473 100644 --- a/app/models/depp/domain.rb +++ b/app/models/depp/domain.rb @@ -1,6 +1,7 @@ module Depp class Domain include ActiveModel::Conversion + include RemoveHold extend ActiveModel::Naming attr_accessor :name, :current_user, :epp_xml diff --git a/app/views/registrar/domains/_domain.html.erb b/app/views/registrar/domains/_domain.html.erb index 74f29dc15..d8910a490 100644 --- a/app/views/registrar/domains/_domain.html.erb +++ b/app/views/registrar/domains/_domain.html.erb @@ -9,5 +9,9 @@ class: 'btn btn-default btn-xs' %> <%= link_to t('.delete_btn'), delete_registrar_domains_path(domain_name: domain.name), class: 'btn btn-default btn-xs' %> + <% if domain.client_holded? %> + <%= link_to t('.client_hold_btn'), remove_hold_registrar_domains_path(domain_name: domain.name), + class: 'btn btn-default btn-xs' %> + <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 74040fe98..15deab604 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -580,6 +580,7 @@ en: tech: Tech contact valid: Valid object_is_not_eligible_for_renewal: 'Object is not eligible for renewal' + object_is_not_holded: 'Object is not holded' bank_statement_desc: 'Import file row will match only when matching following attributes:
ref number
payment amount
invoice number (the first numerical value in comment field)
.' create_bank_statement: 'Create bank statement' create_bank_transaction: 'Create bank transaction' diff --git a/config/locales/registrar/domains.en.yml b/config/locales/registrar/domains.en.yml index c98002b8f..2f5d83240 100644 --- a/config/locales/registrar/domains.en.yml +++ b/config/locales/registrar/domains.en.yml @@ -24,6 +24,7 @@ en: edit_btn: Edit renew_btn: Renew delete_btn: Delete + client_hold_btn: Remove Hold form: save_btn: Save diff --git a/config/routes.rb b/config/routes.rb index 135fe8eb0..8315e78ce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -99,6 +99,7 @@ Rails.application.routes.draw do get 'check' get 'delete' get 'search_contacts' + get 'remove_hold' end end resources :domain_transfers, only: %i[new create] From 1d6040cd5bdf8c0a6ee02b4a686f42a01a6041a3 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 19 Feb 2020 17:47:13 +0500 Subject: [PATCH 055/110] Fix async que job calling --- app/jobs/send_e_invoice_job.rb | 17 +++++++++++------ app/models/registrar.rb | 3 +-- test/jobs/send_e_invoice_job_test.rb | 8 +++++--- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/app/jobs/send_e_invoice_job.rb b/app/jobs/send_e_invoice_job.rb index 6e7b5edb8..e281db14d 100644 --- a/app/jobs/send_e_invoice_job.rb +++ b/app/jobs/send_e_invoice_job.rb @@ -1,21 +1,26 @@ class SendEInvoiceJob < Que::Job - def run(invoice) - destroy if invoice.do_not_send_e_invoice? + def run(invoice_id) + invoice = run_condition(Invoice.find_by(id: invoice_id)) invoice.to_e_invoice.deliver - ActiveRecord::Base.transaction do invoice.update(e_invoice_sent_at: Time.zone.now) log_success(invoice) destroy end - rescue Exception => e + rescue StandardError => e log_error(invoice: invoice, error: e) raise e end private + def run_condition(invoice) + destroy unless invoice + destroy if invoice.do_not_send_e_invoice? + invoice + end + def log_success(invoice) id = invoice.try(:id) || invoice message = "E-Invoice for an invoice with ID # #{id} was sent successfully" @@ -26,8 +31,8 @@ class SendEInvoiceJob < Que::Job id = invoice.try(:id) || invoice message = <<~TEXT.squish There was an error sending e-invoice for invoice with ID # #{id}. - The error message was the following: #{error}. - This job will retry + The error message was the following: #{error} + This job will retry. TEXT logger.error message end diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 94b01517e..f657cdc74 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -99,8 +99,7 @@ class Registrar < ApplicationRecord } ] ) - - SendEInvoiceJob.enqueue(invoice) + SendEInvoiceJob.enqueue(invoice.id) invoice end diff --git a/test/jobs/send_e_invoice_job_test.rb b/test/jobs/send_e_invoice_job_test.rb index 5ea09e576..384479e92 100644 --- a/test/jobs/send_e_invoice_job_test.rb +++ b/test/jobs/send_e_invoice_job_test.rb @@ -13,8 +13,9 @@ class SendEInvoiceJobTest < ActiveSupport::TestCase EInvoice::Providers::TestProvider.deliveries.clear assert_nothing_raised do - SendEInvoiceJob.enqueue(@invoice) + SendEInvoiceJob.enqueue(@invoice.id) end + @invoice.reload assert_not @invoice.e_invoice_sent_at.blank? assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count @@ -28,7 +29,7 @@ class SendEInvoiceJobTest < ActiveSupport::TestCase stub_request(:get, "https://testfinance.post.ee/finance/erp/erpServices.wsdl").to_timeout assert_raise HTTPClient::TimeoutError do - SendEInvoiceJob.enqueue(@invoice) + SendEInvoiceJob.enqueue(@invoice.id) end assert @invoicee_invoice_sent_at.blank? @@ -36,8 +37,9 @@ class SendEInvoiceJobTest < ActiveSupport::TestCase EInvoice::Providers::TestProvider.deliveries.clear assert_nothing_raised do - SendEInvoiceJob.enqueue(@invoice) + SendEInvoiceJob.enqueue(@invoice.id) end + @invoice.reload assert_not @invoice.e_invoice_sent_at.blank? assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count From 5ec2d25ec573e0feff982c9e244a99ebe18f01be Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 19 Feb 2020 18:39:18 +0500 Subject: [PATCH 056/110] Move Remove clientHold button to domain info --- app/controllers/registrar/domains_controller.rb | 7 +++++++ app/models/concerns/domain/force_delete.rb | 4 ---- app/views/registrar/domains/_domain.html.erb | 4 ---- app/views/registrar/domains/info.html.erb | 4 ++++ app/views/registrar/xml_consoles/show.haml | 2 +- config/locales/en.yml | 1 + config/locales/registrar/domains.en.yml | 1 - 7 files changed, 13 insertions(+), 10 deletions(-) diff --git a/app/controllers/registrar/domains_controller.rb b/app/controllers/registrar/domains_controller.rb index 8fdfd51fd..3e721666b 100644 --- a/app/controllers/registrar/domains_controller.rb +++ b/app/controllers/registrar/domains_controller.rb @@ -59,6 +59,7 @@ class Registrar def info authorize! :info, Depp::Domain @data = @domain.info(params[:domain_name]) if params[:domain_name] + @client_holded = client_holded(@data) if response_ok? render 'info' else @@ -158,6 +159,8 @@ class Registrar return unless params[:domain_name] @data = @domain.remove_hold(params) + + flash[:alert] = @data.css('msg').text unless response_ok? redirect_to info_registrar_domains_url(domain_name: params[:domain_name]) end @@ -167,6 +170,10 @@ class Registrar @domain = Depp::Domain.new(current_user: depp_current_user) end + def client_holded(data) + data.css('status')&.map { |element| element.attribute('s').value } + &.any? { |status| status == DomainStatus::CLIENT_HOLD } + end def contacts current_registrar_user.registrar.contacts diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index 89c121993..af3aaa7c7 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -34,10 +34,6 @@ module Concerns::Domain::ForceDelete # rubocop:disable Metrics/ModuleLength force_delete_start.present? && force_delete_lte_today && force_delete_lte_valid_date end - def client_holded? - statuses.include?(DomainStatus::CLIENT_HOLD) - end - def force_delete_lte_today force_delete_start + Setting.expire_warning_period.days <= Time.zone.now end diff --git a/app/views/registrar/domains/_domain.html.erb b/app/views/registrar/domains/_domain.html.erb index d8910a490..74f29dc15 100644 --- a/app/views/registrar/domains/_domain.html.erb +++ b/app/views/registrar/domains/_domain.html.erb @@ -9,9 +9,5 @@ class: 'btn btn-default btn-xs' %> <%= link_to t('.delete_btn'), delete_registrar_domains_path(domain_name: domain.name), class: 'btn btn-default btn-xs' %> - <% if domain.client_holded? %> - <%= link_to t('.client_hold_btn'), remove_hold_registrar_domains_path(domain_name: domain.name), - class: 'btn btn-default btn-xs' %> - <% end %> diff --git a/app/views/registrar/domains/info.html.erb b/app/views/registrar/domains/info.html.erb index 1fcfc23c3..e88882233 100644 --- a/app/views/registrar/domains/info.html.erb +++ b/app/views/registrar/domains/info.html.erb @@ -6,6 +6,10 @@ class: 'btn btn-default') %> <%= link_to(t(:delete), delete_registrar_domains_path(domain_name: params[:domain_name]), class: 'btn btn-default') %> + <% if @client_holded %> + <%= link_to(t(:remove_client_hold), remove_hold_registrar_domains_path(domain_name: params[:domain_name]), + class: 'btn btn-default') %> + <% end %> <% else %> <%= link_to t('.transfer_btn'), new_registrar_domain_transfer_path(domain_name: params[:domain_name]), class: 'btn btn-default' %> diff --git a/app/views/registrar/xml_consoles/show.haml b/app/views/registrar/xml_consoles/show.haml index 5ffcb5279..bb66116ee 100644 --- a/app/views/registrar/xml_consoles/show.haml +++ b/app/views/registrar/xml_consoles/show.haml @@ -31,7 +31,7 @@ Delete , %a.js-load-xml{href: 'javascript:void(0)', data: {obj: 'domain', epp_action: 'client_hold'}} - Client Hold + Remove Client Hold %h4 Poll %a.js-load-xml{href: 'javascript:void(0)', data: {obj: 'poll', epp_action: 'poll'}} diff --git a/config/locales/en.yml b/config/locales/en.yml index 15deab604..cf72b1027 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -206,6 +206,7 @@ en: statuses: 'Statuses' description: 'Description' delete: 'Delete' + remove_client_hold: 'Remove clientHold' are_you_sure: 'Are you sure?' back: 'Back' new_domain: 'New domain' diff --git a/config/locales/registrar/domains.en.yml b/config/locales/registrar/domains.en.yml index 2f5d83240..c98002b8f 100644 --- a/config/locales/registrar/domains.en.yml +++ b/config/locales/registrar/domains.en.yml @@ -24,7 +24,6 @@ en: edit_btn: Edit renew_btn: Renew delete_btn: Delete - client_hold_btn: Remove Hold form: save_btn: Save From 98683f3bcc8111c8533d1c9e56d1c0a6dbeb488f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 19 Feb 2020 11:53:15 +0200 Subject: [PATCH 057/110] Make sure that Directo monthly invoice number frame is not exceeded --- Gemfile.lock | 2 +- app/controllers/concerns/book_keeping.rb | 15 +++-- app/jobs/directo_invoice_forward_job.rb | 76 ++++++++++++++++-------- 3 files changed, 60 insertions(+), 33 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 71abcf70d..e6b82297c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,7 +9,7 @@ GIT GIT remote: https://github.com/internetee/directo.git - revision: 6ac71939da589fcceb5ef3989ba982134679ec97 + revision: 41f4b49da2d4155a76ab57f1cb07bb1d0ba9cdef branch: directo-api specs: directo (0.1.0) diff --git a/app/controllers/concerns/book_keeping.rb b/app/controllers/concerns/book_keeping.rb index 4e25a466f..284b6db71 100644 --- a/app/controllers/concerns/book_keeping.rb +++ b/app/controllers/concerns/book_keeping.rb @@ -11,7 +11,7 @@ module BookKeeping 'customer_code': accounting_customer_code, 'language': language, 'currency': activities.first.currency, - 'date': month.end_of_month.strftime('%Y-%m-%d'), + 'date': month.end_of_month.strftime('%Y-%m-%d') }.as_json lines = [] @@ -43,12 +43,13 @@ module BookKeeping end def new_montly_invoice_line(activity:, duration: nil) - price = DirectoInvoiceForwardJob.load_price(activity) + price = load_price(activity) yearly = price.duration.include?('year') line = { 'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym], 'quantity': 1, 'price': yearly ? (price.price.amount / price.duration.to_i) : price.amount, + 'unit': language == 'en' ? 'pc' : 'tk' } line['description'] = description_in_language(price: price, yearly: yearly) @@ -59,8 +60,9 @@ module BookKeeping def add_product_timeframe(line:, activity:, duration:) create_time = activity.created_at - line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d') - line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d') + start_date = (create_time + (duration - 1).year).end_of_month + end_date = (create_time + (duration - 1).year + 1).end_of_month + line['period'] = start_date..end_date end def description_in_language(price:, yearly:) @@ -84,9 +86,10 @@ module BookKeeping lines.each { |l| total += l['quantity'].to_f * l['price'].to_f } { 'product_id': Setting.directo_receipt_product_name, - 'description': 'Domeenide ettemaks', + 'description': language == 'en' ? 'Domains prepayment' : 'Domeenide ettemaks', 'quantity': -1, - 'price': total + 'price': total, + 'unit': language == 'en' ? 'pc' : 'tk' } end diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index 6eca4c73c..ff584914d 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -1,6 +1,7 @@ class DirectoInvoiceForwardJob < Que::Job def run(monthly: false, dry: false) @dry = dry + @monthly = monthly api_url = ENV['directo_invoice_url'] sales_agent = Setting.directo_sales_agent payment_term = Setting.directo_receipt_payment_term @@ -26,7 +27,7 @@ class DirectoInvoiceForwardJob < Que::Job end def send_monthly_invoices - month = Time.now - 1.month + month = Time.now Registrar.where.not(test_registrar: true).find_each do |registrar| next unless registrar.cash_account @@ -35,10 +36,25 @@ class DirectoInvoiceForwardJob < Que::Job @client.invoices.add_with_schema(invoice: invoice, schema: 'summary') end - # TODO: Invoice number + assign_montly_numbers sync_with_directo end + def assign_montly_numbers + if directo_counter_exceedable?(@client.invoices.count) + raise 'Directo Counter is going to be out of period!' + end + + min_directo = Setting.directo_monthly_number_min.presence.try(:to_i) + directo_number = [Setting.directo_monthly_number_last.presence.try(:to_i), + min_directo].compact.max || 0 + + @client.invoices.each do |inv| + directo_number += 1 + inv.number = directo_number + end + end + def valid_invoice_conditions?(invoice) if invoice.account_activity.nil? || invoice.account_activity.bank_transaction.nil? || invoice.account_activity.bank_transaction.sum.nil? || @@ -57,45 +73,53 @@ class DirectoInvoiceForwardJob < Que::Job return if @dry res = @client.invoices.deliver(ssl_verify: false) - - update_invoice_directo_state(res.body) if res.code == '200' + update_invoice_directo_state(res.body, @client.invoices.as_xml) if res.code == '200' rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError - Rails.logger.info("[Directo] Failed. Responded with code: #{res.code}, body: #{res.body}") + Rails.logger.info('[Directo] Failed to communicate via API') end - def update_invoice_directo_state(xml) + def update_invoice_directo_state(xml, req) + Rails.logger.info "[Directo] - Responded with body: #{xml}" Nokogiri::XML(xml).css('Result').each do |res| - inv = Invoice.find_by(number: res.attributes['docid'].value.to_i) - mark_invoice_as_sent(invoice: inv, data: res) + if @monthly + mark_invoice_as_sent(res: res, req: req) + else + inv = Invoice.find_by(number: res.attributes['docid'].value.to_i) + mark_invoice_as_sent(invoice: inv, res: res, req: req) + end end end - def mark_invoice_as_sent(invoice:, data:) - invoice.directo_records.create!(response: data.as_json.to_h, invoice_number: invoice.number) - invoice.update_columns(in_directo: true) - Rails.logger.info("[DIRECTO] Invoice #{invoice.number} was pushed and return is #{data.as_json.to_h.inspect}") - end - - def self.load_price(account_activity) - @pricelists ||= {} - if @pricelists.key? account_activity.price_id - return @pricelists[account_activity.price_id] + def mark_invoice_as_sent(invoice: nil, res:, req:) + directo_record = Directo.new(response: res.as_json.to_h, + request: req, invoice_number: res.attributes['docid'].value.to_i) + if invoice + directo_record.invoice = invoice + invoice.update_columns(in_directo: true) + else + update_directo_number(num: directo_record.invoice_number) end - @pricelists[account_activity.price_id] = account_activity.price + directo_record.save! end - def last_directo_monthly_number + def update_directo_number(num:) + return unless num.to_i > Setting.directo_monthly_number_last + + Setting.directo_monthly_number_last = num + end + + def directo_counter_exceedable?(invoice_count) min_directo = Setting.directo_monthly_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 + 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' + if max_directo && max_directo < (last_directo + invoice_count) + true + else + false end - - last_directo end end From 26adaa974332fe34771c4ef1224cef1ccff5cbeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 20 Feb 2020 15:05:20 +0200 Subject: [PATCH 058/110] Fix invoice linking with directo record --- app/jobs/directo_invoice_forward_job.rb | 5 ++--- test/jobs/directo_invoice_forward_job_test.rb | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index ff584914d..3f0b11486 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -67,8 +67,7 @@ class DirectoInvoiceForwardJob < Que::Job end def sync_with_directo - Rails.logger.info('[Directo] - attempting to send following XML:') - puts @client.invoices.as_xml + Rails.logger.info("[Directo] - attempting to send following XML:\n #{@client.invoices.as_xml}") return if @dry @@ -95,7 +94,7 @@ class DirectoInvoiceForwardJob < Que::Job directo_record = Directo.new(response: res.as_json.to_h, request: req, invoice_number: res.attributes['docid'].value.to_i) if invoice - directo_record.invoice = invoice + directo_record.item = invoice invoice.update_columns(in_directo: true) else update_directo_number(num: directo_record.invoice_number) diff --git a/test/jobs/directo_invoice_forward_job_test.rb b/test/jobs/directo_invoice_forward_job_test.rb index b50fe378b..ede17ce9e 100644 --- a/test/jobs/directo_invoice_forward_job_test.rb +++ b/test/jobs/directo_invoice_forward_job_test.rb @@ -21,7 +21,7 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase end.to_return(status: 200, body: response) assert_nothing_raised do - Directo.send_receipts + DirectoInvoiceForwardJob.run(monthly: false, dry: false) end assert_not_empty @invoice.directo_records.first.request From afa455988dce4a7776574e31cb0443b7d0a41ef7 Mon Sep 17 00:00:00 2001 From: Georg Kahest Date: Thu, 20 Feb 2020 19:46:23 +0200 Subject: [PATCH 059/110] bump ruby version to 2.6.5 --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index ec1cf33c3..57cf282eb 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6.3 +2.6.5 From 916546ad867aa909975bd33290a254830588a34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Thu, 20 Feb 2020 20:45:17 +0200 Subject: [PATCH 060/110] Update CHANGELOG.md [ci skip] --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b723101ec..b5409f2f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +20.02.2020 +* E-invoice sending to Que to manage resending in case of an error [#1509](https://github.com/internetee/registry/issues/1509) +* Check to make sure all monthly invoices fit in available invoice number range [#277](https://github.com/internetee/registry/issues/277) +* Disabled aurbreak performance monitoring [#1534](https://github.com/internetee/registry/pull/1534) + 14.02.2020 * Fixed Papertrail warnings [#1530](https://github.com/internetee/registry/issues/1530) From e81e24ff238f834cbe22b1a3c1c9c5ddb031fe67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Feb 2020 20:19:46 +0000 Subject: [PATCH 061/110] Bump nokogiri from 1.10.7 to 1.10.8 Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.10.7 to 1.10.8. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/master/CHANGELOG.md) - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.10.7...v1.10.8) Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index fad531c26..b67273812 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -269,7 +269,7 @@ GEM mustermann (>= 1.0.0) netrc (0.11.0) nio4r (2.5.2) - nokogiri (1.10.7) + nokogiri (1.10.8) mini_portile2 (~> 2.4.0) nori (2.6.0) open4 (1.3.4) From 4ddbb08e80879fcf365120b1ad897f9c97675ba7 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 25 Feb 2020 14:19:24 +0500 Subject: [PATCH 062/110] Move data migrations from rake tasks to gem See #1298 --- Gemfile | 2 +- Gemfile.lock | 2 +- .../20150601083516_add_cert_common_name.rb | 19 +++--- db/data/20150601083800_add_cert_md5.rb | 43 +++++++------ db/data/20150609093515_add_renew_setting.rb | 5 +- db/data/20150610111019_add_expire_settings.rb | 7 +-- ...20150612125720_refactor_domain_statuses.rb | 17 +++--- ...0150707103801_refactor_contact_statuses.rb | 17 +++--- ...200225085234_convert_domain_delete_date.rb | 19 ++++++ ...elete_orphaned_registrant_verifications.rb | 18 ++++++ ..._regenerate_registrar_reference_numbers.rb | 19 ++++++ db/data_schema.rb | 2 + lib/tasks/data_migrations/.keep | 0 .../convert_domain_delete_date.rake | 16 ----- ...ete_orphaned_registrant_verifications.rake | 15 ----- ...egenerate_registrar_reference_numbers.rake | 16 ----- ...nerate_registrar_reference_numbers_test.rb | 61 ------------------- .../convert_domain_delete_date_test.rb | 61 ------------------- ..._orphaned_registrant_verifications_test.rb | 43 ------------- 19 files changed, 111 insertions(+), 271 deletions(-) create mode 100644 db/data/20200225085234_convert_domain_delete_date.rb create mode 100644 db/data/20200225085433_delete_orphaned_registrant_verifications.rb create mode 100644 db/data/20200225085539_regenerate_registrar_reference_numbers.rb create mode 100644 db/data_schema.rb create mode 100644 lib/tasks/data_migrations/.keep delete mode 100644 lib/tasks/data_migrations/convert_domain_delete_date.rake delete mode 100644 lib/tasks/data_migrations/delete_orphaned_registrant_verifications.rake delete mode 100644 lib/tasks/data_migrations/regenerate_registrar_reference_numbers.rake delete mode 100644 test/integration/tasks/data_migrations/regenerate_registrar_reference_numbers_test.rb delete mode 100644 test/tasks/data_migrations/convert_domain_delete_date_test.rb delete mode 100644 test/tasks/data_migrations/delete_orphaned_registrant_verifications_test.rb diff --git a/Gemfile b/Gemfile index cab5e0dd6..7b9ee143d 100644 --- a/Gemfile +++ b/Gemfile @@ -36,10 +36,10 @@ gem 'devise', '~> 4.7' gem 'grape' # registry specfic +gem 'data_migrate', '~> 6.1' gem 'isikukood' # for EE-id validation gem 'simpleidn', '0.0.9' # For punycode gem 'money-rails' -gem 'data_migrate' gem 'whenever', '0.9.4', require: false # country listing diff --git a/Gemfile.lock b/Gemfile.lock index b67273812..5053b9468 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -462,7 +462,7 @@ DEPENDENCIES company_register! countries daemons-rails (= 1.2.1) - data_migrate + data_migrate (~> 6.1) database_cleaner devise (~> 4.7) digidoc_client! diff --git a/db/data/20150601083516_add_cert_common_name.rb b/db/data/20150601083516_add_cert_common_name.rb index ef401b871..d0959e5b7 100644 --- a/db/data/20150601083516_add_cert_common_name.rb +++ b/db/data/20150601083516_add_cert_common_name.rb @@ -1,16 +1,15 @@ -class AddCertCommonName < ActiveRecord::Migration +class AddCertCommonName < ActiveRecord::Migration[5.1] def self.up - Certificate.all.each do |x| - if x.crt.blank? && x.csr.present? - pc = x.parsed_csr.try(:subject).try(:to_s) || '' - cn = pc.scan(/\/CN=(.+)/).flatten.first - x.common_name = cn.split('/').first - end - x.save - end + # Certificate.all.each do |x| + # if x.crt.blank? && x.csr.present? + # pc = x.parsed_csr.try(:subject).try(:to_s) || '' + # cn = pc.scan(/\/CN=(.+)/).flatten.first + # x.common_name = cn.split('/').first + # end + # x.save + # end end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20150601083800_add_cert_md5.rb b/db/data/20150601083800_add_cert_md5.rb index 5efe4e596..4db005177 100644 --- a/db/data/20150601083800_add_cert_md5.rb +++ b/db/data/20150601083800_add_cert_md5.rb @@ -1,28 +1,27 @@ -class AddCertMd5 < ActiveRecord::Migration +class AddCertMd5 < ActiveRecord::Migration[5.1] def self.up - Certificate.all.each do |x| - if x.crt.present? && x.csr.present? - x.interface = Certificate::REGISTRAR - x.md5 = OpenSSL::Digest::MD5.new(x.parsed_crt.to_der).to_s - - pc = x.parsed_crt.try(:subject).try(:to_s) || '' - cn = pc.scan(/\/CN=(.+)/).flatten.first - x.common_name = cn.split('/').first - elsif x.crt.present? && x.csr.blank? - x.interface = Certificate::API - x.md5 = OpenSSL::Digest::MD5.new(x.parsed_crt.to_der).to_s - - pc = x.parsed_crt.try(:subject).try(:to_s) || '' - cn = pc.scan(/\/CN=(.+)/).flatten.first - x.common_name = cn.split('/').first - elsif x.crt.blank? && x.csr.present? - x.interface = Certificate::REGISTRAR - end - x.save - end + # Certificate.all.each do |x| + # if x.crt.present? && x.csr.present? + # x.interface = Certificate::REGISTRAR + # x.md5 = OpenSSL::Digest::MD5.new(x.parsed_crt.to_der).to_s + # + # pc = x.parsed_crt.try(:subject).try(:to_s) || '' + # cn = pc.scan(/\/CN=(.+)/).flatten.first + # x.common_name = cn.split('/').first + # elsif x.crt.present? && x.csr.blank? + # x.interface = Certificate::API + # x.md5 = OpenSSL::Digest::MD5.new(x.parsed_crt.to_der).to_s + # + # pc = x.parsed_crt.try(:subject).try(:to_s) || '' + # cn = pc.scan(/\/CN=(.+)/).flatten.first + # x.common_name = cn.split('/').first + # elsif x.crt.blank? && x.csr.present? + # x.interface = Certificate::REGISTRAR + # end + # x.save + # end end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20150609093515_add_renew_setting.rb b/db/data/20150609093515_add_renew_setting.rb index f462c38cb..2d99aa448 100644 --- a/db/data/20150609093515_add_renew_setting.rb +++ b/db/data/20150609093515_add_renew_setting.rb @@ -1,9 +1,8 @@ -class AddRenewSetting < ActiveRecord::Migration +class AddRenewSetting < ActiveRecord::Migration[5.1] def self.up - Setting.days_to_renew_domain_before_expire = 90 + # Setting.days_to_renew_domain_before_expire = 90 end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20150610111019_add_expire_settings.rb b/db/data/20150610111019_add_expire_settings.rb index 9f8b9cce8..6171536dd 100644 --- a/db/data/20150610111019_add_expire_settings.rb +++ b/db/data/20150610111019_add_expire_settings.rb @@ -1,10 +1,9 @@ -class AddExpireSettings < ActiveRecord::Migration +class AddExpireSettings < ActiveRecord::Migration[5.1] def self.up - Setting.expire_warning_period = 15 - Setting.redemption_grace_period = 30 + # Setting.expire_warning_period = 15 + # Setting.redemption_grace_period = 30 end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20150612125720_refactor_domain_statuses.rb b/db/data/20150612125720_refactor_domain_statuses.rb index 00e87b4d0..de0733e3f 100644 --- a/db/data/20150612125720_refactor_domain_statuses.rb +++ b/db/data/20150612125720_refactor_domain_statuses.rb @@ -1,15 +1,14 @@ -class RefactorDomainStatuses < ActiveRecord::Migration +class RefactorDomainStatuses < ActiveRecord::Migration[5.1] def self.up - Domain.find_each do |x| - statuses = [] - x.domain_statuses.each do |ds| - statuses << ds.value - end - x.update_column('statuses', statuses) - end + # Domain.find_each do |x| + # statuses = [] + # x.domain_statuses.each do |ds| + # statuses << ds.value + # end + # x.update_column('statuses', statuses) if x.statuses.blank? + # end end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20150707103801_refactor_contact_statuses.rb b/db/data/20150707103801_refactor_contact_statuses.rb index be6312016..e1833dd66 100644 --- a/db/data/20150707103801_refactor_contact_statuses.rb +++ b/db/data/20150707103801_refactor_contact_statuses.rb @@ -1,15 +1,14 @@ -class RefactorContactStatuses < ActiveRecord::Migration +class RefactorContactStatuses < ActiveRecord::Migration[5.1] def self.up - Contact.find_each do |contact| - statuses = [] - contact.depricated_statuses.each do |ds| - statuses << ds.value - end - contact.update_column('statuses', statuses) - end + # Contact.find_each do |contact| + # statuses = [] + # contact.depricated_statuses.each do |ds| + # statuses << ds.value + # end + # contact.update_column('statuses', statuses) + # end end def self.down - raise ActiveRecord::IrreversibleMigration end end diff --git a/db/data/20200225085234_convert_domain_delete_date.rb b/db/data/20200225085234_convert_domain_delete_date.rb new file mode 100644 index 000000000..81f070927 --- /dev/null +++ b/db/data/20200225085234_convert_domain_delete_date.rb @@ -0,0 +1,19 @@ +class ConvertDomainDeleteDate < ActiveRecord::Migration[5.1] + def up + # processed_domain_count = 0 + # + # Domain.transaction do + # Domain.find_each do |domain| + # next unless domain.delete_date + # + # domain.update_columns(delete_date: domain.delete_date + 1.day) + # processed_domain_count += 1 + # end + # end + # + # puts "Domains processed: #{processed_domain_count}" + end + + def down + end +end diff --git a/db/data/20200225085433_delete_orphaned_registrant_verifications.rb b/db/data/20200225085433_delete_orphaned_registrant_verifications.rb new file mode 100644 index 000000000..73c270a6a --- /dev/null +++ b/db/data/20200225085433_delete_orphaned_registrant_verifications.rb @@ -0,0 +1,18 @@ +class DeleteOrphanedRegistrantVerifications < ActiveRecord::Migration[5.1] + def up + # orphaned_registrant_verifications = RegistrantVerification.where.not(domain_id: Domain.ids) + # orphaned_registrant_verification_count = orphaned_registrant_verifications.count + # processed_registrant_verification_count = 0 + # + # orphaned_registrant_verifications.each do |registrant_verification| + # registrant_verification.destroy! + # processed_registrant_verification_count += 1 + # end + # + # puts "Processed: #{processed_registrant_verification_count} out of" \ + # " #{orphaned_registrant_verification_count}" + end + + def down + end +end diff --git a/db/data/20200225085539_regenerate_registrar_reference_numbers.rb b/db/data/20200225085539_regenerate_registrar_reference_numbers.rb new file mode 100644 index 000000000..fbd2a5c5f --- /dev/null +++ b/db/data/20200225085539_regenerate_registrar_reference_numbers.rb @@ -0,0 +1,19 @@ +class RegenerateRegistrarReferenceNumbers < ActiveRecord::Migration[5.1] + def up + # processed_registrar_count = 0 + # + # Registrar.transaction do + # Registrar.all.each do |registrar| + # next unless registrar.reference_no.start_with?('RF') + # + # registrar.update_columns(reference_no: Billing::ReferenceNo.generate) + # processed_registrar_count += 1 + # end + # end + # + # puts "Registrars processed: #{processed_registrar_count}" + end + + def down + end +end diff --git a/db/data_schema.rb b/db/data_schema.rb new file mode 100644 index 000000000..f4a3f5d8a --- /dev/null +++ b/db/data_schema.rb @@ -0,0 +1,2 @@ +# encoding: UTF-8 +DataMigrate::Data.define(version: 20150707103801) diff --git a/lib/tasks/data_migrations/.keep b/lib/tasks/data_migrations/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/lib/tasks/data_migrations/convert_domain_delete_date.rake b/lib/tasks/data_migrations/convert_domain_delete_date.rake deleted file mode 100644 index 7eeee5cf0..000000000 --- a/lib/tasks/data_migrations/convert_domain_delete_date.rake +++ /dev/null @@ -1,16 +0,0 @@ -namespace :data_migrations do - task convert_domain_delete_date: :environment do - processed_domain_count = 0 - - Domain.transaction do - Domain.find_each do |domain| - next unless domain.delete_date - - domain.update_columns(delete_date: domain.delete_date + 1.day) - processed_domain_count += 1 - end - end - - puts "Domains processed: #{processed_domain_count}" - end -end \ No newline at end of file diff --git a/lib/tasks/data_migrations/delete_orphaned_registrant_verifications.rake b/lib/tasks/data_migrations/delete_orphaned_registrant_verifications.rake deleted file mode 100644 index f65db547e..000000000 --- a/lib/tasks/data_migrations/delete_orphaned_registrant_verifications.rake +++ /dev/null @@ -1,15 +0,0 @@ -namespace :data_migrations do - task delete_orphaned_registrant_verifications: :environment do - orphaned_registrant_verifications = RegistrantVerification.where.not(domain_id: Domain.ids) - orphaned_registrant_verification_count = orphaned_registrant_verifications.count - processed_registrant_verification_count = 0 - - orphaned_registrant_verifications.each do |registrant_verification| - registrant_verification.destroy! - processed_registrant_verification_count += 1 - end - - puts "Processed: #{processed_registrant_verification_count} out of" \ - " #{orphaned_registrant_verification_count}" - end -end diff --git a/lib/tasks/data_migrations/regenerate_registrar_reference_numbers.rake b/lib/tasks/data_migrations/regenerate_registrar_reference_numbers.rake deleted file mode 100644 index 6f6aaebe2..000000000 --- a/lib/tasks/data_migrations/regenerate_registrar_reference_numbers.rake +++ /dev/null @@ -1,16 +0,0 @@ -namespace :data_migrations do - task regenerate_registrar_reference_numbers: [:environment] do - processed_registrar_count = 0 - - Registrar.transaction do - Registrar.all.each do |registrar| - next unless registrar.reference_no.start_with?('RF') - - registrar.update_columns(reference_no: Billing::ReferenceNo.generate) - processed_registrar_count += 1 - end - end - - puts "Registrars processed: #{processed_registrar_count}" - end -end diff --git a/test/integration/tasks/data_migrations/regenerate_registrar_reference_numbers_test.rb b/test/integration/tasks/data_migrations/regenerate_registrar_reference_numbers_test.rb deleted file mode 100644 index 946c6b898..000000000 --- a/test/integration/tasks/data_migrations/regenerate_registrar_reference_numbers_test.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'test_helper' - -class RegenerateRegistrarReferenceNumbersTaskTest < ActiveSupport::TestCase - def test_regenerates_registrar_reference_numbers_to_estonian_format - registrar = registrars(:bestnames) - registrar.update_column(:reference_no, 'RF1111') - - capture_io { run_task } - registrar.reload - - assert_not registrar.reference_no.start_with?('RF') - end - - def test_bypasses_registrar_validation - registrar = registrars(:invalid) - registrar.update_column(:reference_no, 'RF1111') - assert registrar.invalid? - - capture_io { run_task } - registrar.reload - - assert_not registrar.reference_no.start_with?('RF') - end - - def test_does_not_regenerate_when_the_task_is_run_again - registrar = registrars(:bestnames) - registrar.update!(reference_no: '1111') - - capture_io { run_task } - registrar.reload - - assert_equal '1111', registrar.reference_no - end - - def test_keeps_iso_reference_number_on_the_invoice_unchanged - registrar = registrars(:bestnames) - registrar.update_column(:reference_no, 'RF1111') - invoice = invoices(:one) - invoice.update!(reference_no: 'RF2222') - - capture_io { run_task } - invoice.reload - - assert_equal 'RF2222', invoice.reference_no - end - - def test_output - registrar = registrars(:bestnames) - registrar.update_column(:reference_no, 'RF1111') - - assert_output "Registrars processed: 1\n" do - run_task - end - end - - private - - def run_task - Rake::Task['data_migrations:regenerate_registrar_reference_numbers'].execute - end -end diff --git a/test/tasks/data_migrations/convert_domain_delete_date_test.rb b/test/tasks/data_migrations/convert_domain_delete_date_test.rb deleted file mode 100644 index 709334b52..000000000 --- a/test/tasks/data_migrations/convert_domain_delete_date_test.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'test_helper' - -class ConvertDomainDeleteDateTaskTest < ActiveSupport::TestCase - setup do - @domain = domains(:shop) - end - - def test_moves_domain_delete_date_one_day_ahead - @domain.update!(delete_date: '2010-07-05') - - capture_io do - run_task - end - @domain.reload - - assert_equal Date.parse('2010-07-06'), @domain.delete_date - end - - def test_processes_invalid_domains - @domain = domains(:invalid) - @domain.update_columns(delete_date: '2010-07-05') - - capture_io do - run_task - end - @domain.reload - - assert_equal Date.parse('2010-07-06'), @domain.delete_date - end - - def test_skips_non_expired_domains - @domain.update!(delete_date: nil) - - assert_nothing_raised do - capture_io do - run_task - end - end - end - - def test_output - eliminate_effect_of_all_domains_except(@domain) - @domain.update!(delete_date: '2010-07-05') - - assert_output "Domains processed: 1\n" do - run_task - end - end - - private - - def eliminate_effect_of_all_domains_except(domain) - Domain.connection.disable_referential_integrity do - Domain.where("id != #{domain.id}").delete_all - end - end - - def run_task - Rake::Task['data_migrations:convert_domain_delete_date'].execute - end -end \ No newline at end of file diff --git a/test/tasks/data_migrations/delete_orphaned_registrant_verifications_test.rb b/test/tasks/data_migrations/delete_orphaned_registrant_verifications_test.rb deleted file mode 100644 index df576332e..000000000 --- a/test/tasks/data_migrations/delete_orphaned_registrant_verifications_test.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'test_helper' - -class ArchiveOrphanedRegistrantVerificationsTest < ActiveSupport::TestCase - def test_deletes_orphaned_registrant_verifications - create_orphaned_registrant_verification - - assert_difference 'RegistrantVerification.count', -1 do - capture_io do - run_task - end - end - end - - def test_keeps_non_orphaned_registrant_verifications_intact - assert_no_difference 'RegistrantVerification.count' do - capture_io do - run_task - end - end - end - - def test_output - create_orphaned_registrant_verification - - assert_output "Processed: 1 out of 1\n" do - run_task - end - end - - private - - def create_orphaned_registrant_verification - non_existent_domain_id = 55 - assert_not_includes Domain.ids, non_existent_domain_id - - RegistrantVerification.connection.disable_referential_integrity do - registrant_verifications(:one).update_columns(domain_id: non_existent_domain_id) - end - end - - def run_task - Rake::Task['data_migrations:delete_orphaned_registrant_verifications'].execute end -end From 53168a6e2ac2f7f040207ece482f942423ceb226 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 26 Feb 2020 16:19:33 +0500 Subject: [PATCH 063/110] Add verified parameter to registrar domain controller strong params See #1540 --- app/controllers/registrar/domains_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/registrar/domains_controller.rb b/app/controllers/registrar/domains_controller.rb index 5bf1a51f5..2b3b249e7 100644 --- a/app/controllers/registrar/domains_controller.rb +++ b/app/controllers/registrar/domains_controller.rb @@ -190,9 +190,9 @@ class Registrar def domain_params params.require(:domain).permit(:name, :period, :registrant, :registrant_helper, :reserved_pw, - :legal_document, contacts_attributes: {}, - nameservers_attributes: {}, - dnskeys_attributes: {}) + :verified, :legal_document, contacts_attributes: {}, + nameservers_attributes: {}, + dnskeys_attributes: {}) end end end From 99c0abc5a8dfafea4c87c2dc5c4c782e453053c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 26 Feb 2020 14:53:21 +0200 Subject: [PATCH 064/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5409f2f5..47f8baef1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +26.02.2020 +* Implemented consistent and automated data migrations [#1298](https://github.com/internetee/registry/issues/1298) + 20.02.2020 * E-invoice sending to Que to manage resending in case of an error [#1509](https://github.com/internetee/registry/issues/1509) * Check to make sure all monthly invoices fit in available invoice number range [#277](https://github.com/internetee/registry/issues/277) From b859cfc090d7c19f2197bf2664f5bd196afb180c Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Wed, 26 Feb 2020 19:30:38 +0500 Subject: [PATCH 065/110] Fix domain statuses removal Close #1543s --- app/models/domain.rb | 4 ++-- test/system/admin_area/domains_test.rb | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/models/domain.rb b/app/models/domain.rb index ceff9e810..f21317b70 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -485,9 +485,9 @@ class Domain < ApplicationRecord self.delete_date = nil when DomainStatus::SERVER_MANUAL_INZONE # removal causes server hold to set self.outzone_at = Time.zone.now if force_delete_scheduled? - when DomainStatus::DomainStatus::EXPIRED # removal causes server hold to set + when DomainStatus::EXPIRED # removal causes server hold to set self.outzone_at = self.expire_time + 15.day - when DomainStatus::DomainStatus::SERVER_HOLD # removal causes server hold to set + when DomainStatus::SERVER_HOLD # removal causes server hold to set self.outzone_at = nil end end diff --git a/test/system/admin_area/domains_test.rb b/test/system/admin_area/domains_test.rb index abd1d93fb..05e7d60f3 100644 --- a/test/system/admin_area/domains_test.rb +++ b/test/system/admin_area/domains_test.rb @@ -35,4 +35,15 @@ class AdminDomainsTestTest < ApplicationSystemTestCase assert_text 'deleteCandidate status has been removed' assert_no_link 'Remove deleteCandidate status' end + + def test_remove_domain_status + @domain.update!(statuses: [DomainStatus::SERVER_REGISTRANT_CHANGE_PROHIBITED]) + + visit edit_admin_domain_url(@domain) + + click_link_or_button 'Delete' + click_link_or_button 'Save' + + assert_text 'Domain updated!' + end end From 3e2e84f3645d02875b98f4fa6dbe4e6c9b1712c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 26 Feb 2020 17:19:11 +0200 Subject: [PATCH 066/110] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47f8baef1..123ef72a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ 26.02.2020 +* Registrar: added an option to remove clientHold status [#1481](https://github.com/internetee/registry/issues/1481) * Implemented consistent and automated data migrations [#1298](https://github.com/internetee/registry/issues/1298) 20.02.2020 From f4ea9cfeffd06c23ce097a96d1a7defa1fadae15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 26 Feb 2020 17:21:56 +0200 Subject: [PATCH 067/110] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 123ef72a1..94ecb8864 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ 26.02.2020 * Registrar: added an option to remove clientHold status [#1481](https://github.com/internetee/registry/issues/1481) +* Admin: fixed domain status removal issue [#1543](https://github.com/internetee/registry/issues/1543) * Implemented consistent and automated data migrations [#1298](https://github.com/internetee/registry/issues/1298) 20.02.2020 From ee332d8a7f080d9033aaecd63c5d67516c5c9213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Fri, 21 Feb 2020 14:20:04 +0200 Subject: [PATCH 068/110] Tests for DirectoInvoiceForwardJob --- Gemfile.lock | 2 +- app/controllers/concerns/book_keeping.rb | 31 +++-- app/jobs/directo_invoice_forward_job.rb | 6 +- test/fixtures/account_activities.yml | 2 +- test/jobs/directo_invoice_forward_job_test.rb | 114 ++++++++++++++++++ 5 files changed, 144 insertions(+), 11 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4bc35aafc..4ca0aeb22 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,7 +9,7 @@ GIT GIT remote: https://github.com/internetee/directo.git - revision: 41f4b49da2d4155a76ab57f1cb07bb1d0ba9cdef + revision: c688c46134ce04f5a75b7a0563abc18cd9af030a branch: directo-api specs: directo (0.1.0) diff --git a/app/controllers/concerns/book_keeping.rb b/app/controllers/concerns/book_keeping.rb index 284b6db71..e9d3e9ee9 100644 --- a/app/controllers/concerns/book_keeping.rb +++ b/app/controllers/concerns/book_keeping.rb @@ -6,6 +6,8 @@ module BookKeeping def monthly_summary(month:) activities = monthly_activites(month) + return unless activities.any? + inv = { 'number': 1, 'customer_code': accounting_customer_code, @@ -15,6 +17,8 @@ module BookKeeping }.as_json lines = [] + + lines << { 'description': title_for_summary(month) } activities.each do |activity| fetch_invoice_lines(activity, lines) end @@ -25,11 +29,23 @@ module BookKeeping inv end + def title_for_summary(date) + if language == 'en' + I18n.with_locale('en') do + "Domains registrations - #{I18n.l(date, format: '%B %Y')}" + end + else + I18n.with_locale('et') do + "Domeenide registreerimine - #{I18n.l(date, format: '%B %Y')}" + end + end + end + def fetch_invoice_lines(activity, lines) price = load_price(activity) if price.duration.include? 'year' price.duration.to_i.times do |duration| - lines << new_montly_invoice_line(activity: activity, duration: duration + 1).as_json + lines << new_monthly_invoice_line(activity: activity, duration: duration + 1).as_json end else lines << new_monthly_invoice_line(activity: activity).as_json @@ -42,27 +58,28 @@ module BookKeeping .where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]) end - def new_montly_invoice_line(activity:, duration: nil) + def new_monthly_invoice_line(activity:, duration: nil) price = load_price(activity) yearly = price.duration.include?('year') line = { 'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym], 'quantity': 1, - 'price': yearly ? (price.price.amount / price.duration.to_i) : price.amount, + 'price': yearly ? (price.price.amount / price.duration.to_i) : price.price.amount, 'unit': language == 'en' ? 'pc' : 'tk' } line['description'] = description_in_language(price: price, yearly: yearly) - add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1 + if yearly && duration + add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1 + end line end def add_product_timeframe(line:, activity:, duration:) create_time = activity.created_at - start_date = (create_time + (duration - 1).year).end_of_month - end_date = (create_time + (duration - 1).year + 1).end_of_month - line['period'] = start_date..end_date + line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d') + line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d') end def description_in_language(price:, yearly:) diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index 3f0b11486..cd228fdaf 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -33,6 +33,8 @@ class DirectoInvoiceForwardJob < Que::Job next unless registrar.cash_account invoice = registrar.monthly_summary(month: month) + next if invoice.nil? + @client.invoices.add_with_schema(invoice: invoice, schema: 'summary') end @@ -104,9 +106,9 @@ class DirectoInvoiceForwardJob < Que::Job end def update_directo_number(num:) - return unless num.to_i > Setting.directo_monthly_number_last + return unless num.to_i > Setting.directo_monthly_number_last.to_i - Setting.directo_monthly_number_last = num + Setting.directo_monthly_number_last = num.to_i end def directo_counter_exceedable?(invoice_count) diff --git a/test/fixtures/account_activities.yml b/test/fixtures/account_activities.yml index dbe1dc2aa..8f883e424 100644 --- a/test/fixtures/account_activities.yml +++ b/test/fixtures/account_activities.yml @@ -2,4 +2,4 @@ one: account: cash invoice: one bank_transaction: one - created_at: <%= Time.zone.parse('2010-07-05 10:00') %> \ No newline at end of file + created_at: <%= Time.zone.parse('2010-07-05 10:00') %> diff --git a/test/jobs/directo_invoice_forward_job_test.rb b/test/jobs/directo_invoice_forward_job_test.rb index ede17ce9e..bf92d77c0 100644 --- a/test/jobs/directo_invoice_forward_job_test.rb +++ b/test/jobs/directo_invoice_forward_job_test.rb @@ -3,6 +3,15 @@ require "test_helper" class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase setup do @invoice = invoices(:one) + @user = registrars(:bestnames) + travel_to Time.zone.parse('2010-07-06') + end + + def teardown + Setting.clear_cache + Setting.directo_monthly_number_min = 309901 + Setting.directo_monthly_number_max = 309999 + Setting.directo_monthly_number_last = 309901 end def test_xml_is_include_transaction_date @@ -26,4 +35,109 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase assert_not_empty @invoice.directo_records.first.request end + + def test_fails_if_directo_bounds_exceedable + Setting.clear_cache + Setting.directo_monthly_number_max = 30990 + + assert_raises 'RuntimeError' do + DirectoInvoiceForwardJob.run(monthly: true, dry: false) + end + end + + def test_monthly_summary_is_delivered_in_estonian + activity = account_activities(:one) + price = billing_prices(:create_one_year) + activity.update!(activity_type: 'create', price: price) + @user.update(language: 'et') + + response = <<-XML + + + + + XML + + stub_request(:post, ENV['directo_invoice_url']).with do |request| + body = CGI.unescape(request.body) + + (body.include? '.test registreerimine: 1 aasta') && + (body.include? 'Domeenide ettemaks') && + (body.include? '309902') + end.to_return(status: 200, body: response) + + assert_difference 'Setting.directo_monthly_number_last' do + DirectoInvoiceForwardJob.run(monthly: true, dry: false) + end + end + + def test_monthly_summary_is_delivered_in_english + activity = account_activities(:one) + price = billing_prices(:create_one_year) + activity.update(activity_type: 'create', price: price) + @user.update(language: 'en') + + response = <<-XML + + + + + XML + + stub_request(:post, ENV['directo_invoice_url']).with do |request| + body = CGI.unescape(request.body) + (body.include? 'test registration') && + (body.include? 'Domains prepayment') && + (body.include? '309902') + end.to_return(status: 200, body: response) + + assert_difference 'Setting.directo_monthly_number_last' do + DirectoInvoiceForwardJob.run(monthly: true, dry: false) + end + end + + def test_multi_year_purchases_have_duration_assigned + activity = account_activities(:one) + price = billing_prices(:create_one_year) + price.update(duration: '3 years') + activity.update(activity_type: 'create', price: price) + + response = <<-XML + + + + + XML + + stub_request(:post, ENV['directo_invoice_url']).with do |request| + body = CGI.unescape(request.body) + (body.include? 'StartDate') && (body.include? 'EndDate') + end.to_return(status: 200, body: response) + + assert_difference 'Setting.directo_monthly_number_last' do + DirectoInvoiceForwardJob.run(monthly: true, dry: false) + end + end + + def test_monthly_duration_products_are_present_in_summary + activity = account_activities(:one) + price = billing_prices(:create_one_month) + activity.update(activity_type: 'create', price: price) + + response = <<-XML + + + + + XML + + stub_request(:post, ENV['directo_invoice_url']).with do |request| + body = CGI.unescape(request.body) + (body.include? 'months') + end.to_return(status: 200, body: response) + + assert_difference 'Setting.directo_monthly_number_last' do + DirectoInvoiceForwardJob.run(monthly: true, dry: false) + end + end end From a524a931b50fa34c3f781f52f66b1f6e01d95b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Thu, 27 Feb 2020 09:40:38 +0200 Subject: [PATCH 069/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94ecb8864..f2c6a28c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +27.02.2020 +* Ruby version update to 2.6.5 [#1545](https://github.com/internetee/registry/pull/1545) + 26.02.2020 * Registrar: added an option to remove clientHold status [#1481](https://github.com/internetee/registry/issues/1481) * Admin: fixed domain status removal issue [#1543](https://github.com/internetee/registry/issues/1543) From 5816ae16637c27d7dceaa216410e9a138df70187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 27 Feb 2020 11:32:29 +0200 Subject: [PATCH 070/110] Fix Rubocop styling issues --- app/controllers/concerns/book_keeping.rb | 6 +++--- app/jobs/directo_invoice_forward_job.rb | 2 +- app/models/invoice.rb | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/controllers/concerns/book_keeping.rb b/app/controllers/concerns/book_keeping.rb index e9d3e9ee9..486a3c82c 100644 --- a/app/controllers/concerns/book_keeping.rb +++ b/app/controllers/concerns/book_keeping.rb @@ -13,7 +13,7 @@ module BookKeeping 'customer_code': accounting_customer_code, 'language': language, 'currency': activities.first.currency, - 'date': month.end_of_month.strftime('%Y-%m-%d') + 'date': month.end_of_month.strftime('%Y-%m-%d'), }.as_json lines = [] @@ -65,7 +65,7 @@ module BookKeeping 'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym], 'quantity': 1, 'price': yearly ? (price.price.amount / price.duration.to_i) : price.price.amount, - 'unit': language == 'en' ? 'pc' : 'tk' + 'unit': language == 'en' ? 'pc' : 'tk', } line['description'] = description_in_language(price: price, yearly: yearly) @@ -106,7 +106,7 @@ module BookKeeping 'description': language == 'en' ? 'Domains prepayment' : 'Domeenide ettemaks', 'quantity': -1, 'price': total, - 'unit': language == 'en' ? 'pc' : 'tk' + 'unit': language == 'en' ? 'pc' : 'tk', } end diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index cd228fdaf..4daa65058 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -27,7 +27,7 @@ class DirectoInvoiceForwardJob < Que::Job end def send_monthly_invoices - month = Time.now + month = Time.zone.now - 1.month Registrar.where.not(test_registrar: true).find_each do |registrar| next unless registrar.cash_account diff --git a/app/models/invoice.rb b/app/models/invoice.rb index a1fb4cdb7..70053b59c 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -112,7 +112,8 @@ class Invoice < ApplicationRecord 'product_id': Setting.directo_receipt_product_name, 'description': order, 'quantity': 1, - 'price': ActionController::Base.helpers.number_with_precision(subtotal, precision: 2, separator: ".") + 'price': ActionController::Base.helpers + .number_with_precision(subtotal, precision: 2, separator: '.'), }].as_json inv From d30281c421796be63e791a3504a6428136afa1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 27 Feb 2020 11:59:46 +0200 Subject: [PATCH 071/110] Update structure.sql --- db/structure.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/db/structure.sql b/db/structure.sql index d694da536..9adad4a04 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -885,6 +885,7 @@ CREATE TABLE public.invoices ( in_directo boolean DEFAULT false, buyer_vat_no character varying, issue_date date NOT NULL, + e_invoice_sent_at timestamp without time zone, CONSTRAINT invoices_due_date_is_not_before_issue_date CHECK ((due_date >= issue_date)) ); @@ -4460,6 +4461,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20200113091254'), ('20200115102202'), ('20200130092113'), -('20200203143458'); +('20200203143458'), +('20200204103125'); From bb787102e448718e13dc805df3a5cd80868763e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Thu, 27 Feb 2020 12:20:51 +0200 Subject: [PATCH 072/110] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2c6a28c2..2f7a888d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ 27.02.2020 +* Registrar: fixed the verified checkbox bug that did not change the element value to yes in epp request [#1540](https://github.com/internetee/registry/issues/1540) * Ruby version update to 2.6.5 [#1545](https://github.com/internetee/registry/pull/1545) 26.02.2020 From 756a8b0c1cb9569b105846334739ef1b46005af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 27 Feb 2020 14:24:22 +0200 Subject: [PATCH 073/110] Travel 1 month forward to get last month summaries --- test/jobs/directo_invoice_forward_job_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jobs/directo_invoice_forward_job_test.rb b/test/jobs/directo_invoice_forward_job_test.rb index bf92d77c0..fd483d621 100644 --- a/test/jobs/directo_invoice_forward_job_test.rb +++ b/test/jobs/directo_invoice_forward_job_test.rb @@ -4,7 +4,7 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase setup do @invoice = invoices(:one) @user = registrars(:bestnames) - travel_to Time.zone.parse('2010-07-06') + travel_to Time.zone.parse('2010-08-06') end def teardown From 6302462184ecc204d290cd09f8969bf878955220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 27 Feb 2020 16:10:07 +0200 Subject: [PATCH 074/110] Directo job styling fixes --- app/controllers/concerns/book_keeping.rb | 33 +++++++++---------- app/jobs/directo_invoice_forward_job.rb | 16 ++++----- test/jobs/directo_invoice_forward_job_test.rb | 4 +-- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/app/controllers/concerns/book_keeping.rb b/app/controllers/concerns/book_keeping.rb index 486a3c82c..24d6f5725 100644 --- a/app/controllers/concerns/book_keeping.rb +++ b/app/controllers/concerns/book_keeping.rb @@ -11,11 +11,16 @@ module BookKeeping inv = { 'number': 1, 'customer_code': accounting_customer_code, - 'language': language, - 'currency': activities.first.currency, + 'language': language, 'currency': activities.first.currency, 'date': month.end_of_month.strftime('%Y-%m-%d'), }.as_json + inv['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities) + + inv + end + + def prepare_invoice_lines(month:, activities:) lines = [] lines << { 'description': title_for_summary(month) } @@ -24,9 +29,7 @@ module BookKeeping end lines << prepayment_for_all(lines) - inv['invoice_lines'] = lines.as_json - - inv + lines.as_json end def title_for_summary(date) @@ -83,19 +86,15 @@ module BookKeeping end def description_in_language(price:, yearly:) - if language == 'en' - registration_length = yearly ? 'year' : 'month' - prefix = ".#{price.zone_name} registration: #{price.duration.to_i} #{registration_length}" - suffix = 's' - else - registration_length = yearly ? 'aasta' : 'kuu' - prefix = ".#{price.zone_name} registreerimine: #{price.duration.to_i} #{registration_length}" - suffix = yearly ? 't' : 'd' - end + en = language == 'en' + registration_length = if yearly + en ? 'year(s)' : 'aasta(t)' + else + en ? 'month(s)' : 'kuu(d)' + end - return "#{prefix}#{suffix}" if price.duration.to_i > 1 - - prefix + registration = en ? 'registration' : 'registreerimine' + ".#{price.zone_name} #{registration}: #{price.duration.to_i} #{registration_length}" end def prepayment_for_all(lines) diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index 4daa65058..3dc92c460 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -1,7 +1,7 @@ class DirectoInvoiceForwardJob < Que::Job def run(monthly: false, dry: false) @dry = dry - @monthly = monthly + (@month = Time.zone.now - 1.month) if monthly api_url = ENV['directo_invoice_url'] sales_agent = Setting.directo_sales_agent payment_term = Setting.directo_receipt_payment_term @@ -27,15 +27,11 @@ class DirectoInvoiceForwardJob < Que::Job end def send_monthly_invoices - month = Time.zone.now - 1.month - - Registrar.where.not(test_registrar: true).find_each do |registrar| + Registrar.where(test_registrar: false).find_each do |registrar| next unless registrar.cash_account - invoice = registrar.monthly_summary(month: month) - next if invoice.nil? - - @client.invoices.add_with_schema(invoice: invoice, schema: 'summary') + invoice = registrar.monthly_summary(month: @month) + @client.invoices.add_with_schema(invoice: invoice, schema: 'summary') unless invoice.nil? end assign_montly_numbers @@ -83,7 +79,7 @@ class DirectoInvoiceForwardJob < Que::Job def update_invoice_directo_state(xml, req) Rails.logger.info "[Directo] - Responded with body: #{xml}" Nokogiri::XML(xml).css('Result').each do |res| - if @monthly + if @month mark_invoice_as_sent(res: res, req: req) else inv = Invoice.find_by(number: res.attributes['docid'].value.to_i) @@ -97,7 +93,7 @@ class DirectoInvoiceForwardJob < Que::Job request: req, invoice_number: res.attributes['docid'].value.to_i) if invoice directo_record.item = invoice - invoice.update_columns(in_directo: true) + invoice.update(in_directo: true) else update_directo_number(num: directo_record.invoice_number) end diff --git a/test/jobs/directo_invoice_forward_job_test.rb b/test/jobs/directo_invoice_forward_job_test.rb index fd483d621..378dd7aec 100644 --- a/test/jobs/directo_invoice_forward_job_test.rb +++ b/test/jobs/directo_invoice_forward_job_test.rb @@ -61,7 +61,7 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase stub_request(:post, ENV['directo_invoice_url']).with do |request| body = CGI.unescape(request.body) - (body.include? '.test registreerimine: 1 aasta') && + (body.include? '.test registreerimine: 1 aasta(t)') && (body.include? 'Domeenide ettemaks') && (body.include? '309902') end.to_return(status: 200, body: response) @@ -133,7 +133,7 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase stub_request(:post, ENV['directo_invoice_url']).with do |request| body = CGI.unescape(request.body) - (body.include? 'months') + body.include? 'month(s)' end.to_return(status: 200, body: response) assert_difference 'Setting.directo_monthly_number_last' do From 8cc42cb170a3ec763d32c7769e53fda34274cf1e Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Fri, 28 Feb 2020 13:54:56 +0500 Subject: [PATCH 075/110] Fix redirect back Closes #1535 --- app/controllers/admin/zonefiles_controller.rb | 2 +- app/controllers/registrar/current_user_controller.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/zonefiles_controller.rb b/app/controllers/admin/zonefiles_controller.rb index 30b4b9a61..4fd84bb77 100644 --- a/app/controllers/admin/zonefiles_controller.rb +++ b/app/controllers/admin/zonefiles_controller.rb @@ -13,7 +13,7 @@ module Admin send_data @zonefile, filename: "#{params[:origin]}.txt" else flash[:alert] = 'Origin not supported' - redirect_to :back + redirect_back(fallback_location: root_path) end end end diff --git a/app/controllers/registrar/current_user_controller.rb b/app/controllers/registrar/current_user_controller.rb index 624ee294e..3a214322c 100644 --- a/app/controllers/registrar/current_user_controller.rb +++ b/app/controllers/registrar/current_user_controller.rb @@ -6,7 +6,7 @@ class Registrar raise 'Cannot switch to unlinked user' unless current_registrar_user.linked_with?(new_user) sign_in(:registrar_user, new_user) - redirect_to :back, notice: t('.switched', new_user: new_user) + redirect_back(fallback_location: root_path, notice: t('.switched', new_user: new_user)) end private From b1f90df1ab976c1cefc8b21562e7d922ca2ef350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Fri, 28 Feb 2020 15:25:23 +0200 Subject: [PATCH 076/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f7a888d0..f7fcf7b36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +28.02.2020 +* Registrara: fixed account switching [#1535](https://github.com/internetee/registry/issues/1535) + 27.02.2020 * Registrar: fixed the verified checkbox bug that did not change the element value to yes in epp request [#1540](https://github.com/internetee/registry/issues/1540) * Ruby version update to 2.6.5 [#1545](https://github.com/internetee/registry/pull/1545) From 6c328438e69a6c48a6611938c12b948904d98812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Thu, 27 Feb 2020 17:06:25 +0200 Subject: [PATCH 077/110] Reduce condition sizes for Directo job --- app/controllers/concerns/book_keeping.rb | 14 +++++++++---- app/jobs/directo_invoice_forward_job.rb | 21 ++++++++++++------- app/models/invoice.rb | 17 ++++++++------- test/jobs/directo_invoice_forward_job_test.rb | 7 +++++-- 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/app/controllers/concerns/book_keeping.rb b/app/controllers/concerns/book_keeping.rb index 24d6f5725..41cd4646e 100644 --- a/app/controllers/concerns/book_keeping.rb +++ b/app/controllers/concerns/book_keeping.rb @@ -12,7 +12,7 @@ module BookKeeping 'number': 1, 'customer_code': accounting_customer_code, 'language': language, 'currency': activities.first.currency, - 'date': month.end_of_month.strftime('%Y-%m-%d'), + 'date': month.end_of_month.strftime('%Y-%m-%d') }.as_json inv['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities) @@ -63,16 +63,22 @@ module BookKeeping def new_monthly_invoice_line(activity:, duration: nil) price = load_price(activity) - yearly = price.duration.include?('year') line = { 'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym], 'quantity': 1, - 'price': yearly ? (price.price.amount / price.duration.to_i) : price.price.amount, 'unit': language == 'en' ? 'pc' : 'tk', } + finalize_invoice_line(line, price: price, duration: duration, activity: activity) + end + + def finalize_invoice_line(line, price:, activity:, duration:) + yearly = price.duration.include?('year') + + line['price'] = yearly ? (price.price.amount / price.duration.to_i) : price.price.amount line['description'] = description_in_language(price: price, yearly: yearly) - if yearly && duration + + if duration.present? add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1 end diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index 3dc92c460..768c7db0b 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -27,18 +27,23 @@ class DirectoInvoiceForwardJob < Que::Job end def send_monthly_invoices - Registrar.where(test_registrar: false).find_each do |registrar| - next unless registrar.cash_account - - invoice = registrar.monthly_summary(month: @month) - @client.invoices.add_with_schema(invoice: invoice, schema: 'summary') unless invoice.nil? + Registrar.where.not(test_registrar: true).find_each do |registrar| + fetch_monthly_summary(registrar: registrar) end - assign_montly_numbers + return unless @client.invoices.count.positive? + sync_with_directo end - def assign_montly_numbers + def fetch_monthly_summary(registrar:) + return unless registrar.cash_account + + summary = registrar.monthly_summary(month: @month) + @client.invoices.add_with_schema(invoice: summary, schema: 'summary') unless summary.nil? + end + + def assign_monthly_numbers if directo_counter_exceedable?(@client.invoices.count) raise 'Directo Counter is going to be out of period!' end @@ -66,9 +71,9 @@ class DirectoInvoiceForwardJob < Que::Job def sync_with_directo Rails.logger.info("[Directo] - attempting to send following XML:\n #{@client.invoices.as_xml}") - return if @dry + assign_monthly_numbers if @month res = @client.invoices.deliver(ssl_verify: false) update_invoice_directo_state(res.body, @client.invoices.as_xml) if res.code == '200' rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 70053b59c..61b35ab98 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -70,7 +70,7 @@ class Invoice < ApplicationRecord Country.new(buyer_country_code) end -# order is used for directo/banklink description + # order is used for directo/banklink description def order "Order nr. #{number}" end @@ -108,17 +108,18 @@ class Invoice < ApplicationRecord inv['issue_date'] = issue_date.strftime('%Y-%m-%d') inv['transaction_date'] = account_activity.bank_transaction&.paid_at&.strftime('%Y-%m-%d') inv['language'] = buyer.language - inv['invoice_lines'] = [{ - 'product_id': Setting.directo_receipt_product_name, - 'description': order, - 'quantity': 1, - 'price': ActionController::Base.helpers - .number_with_precision(subtotal, precision: 2, separator: '.'), - }].as_json + inv['invoice_lines'] = compose_directo_product inv end + def compose_directo_product + [{ 'product_id': Setting.directo_receipt_product_name, 'description': order, + 'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision( + subtotal, precision: 2, separator: '.' + ) }].as_json + end + def do_not_send_e_invoice? e_invoice_sent? || cancelled? || paid? end diff --git a/test/jobs/directo_invoice_forward_job_test.rb b/test/jobs/directo_invoice_forward_job_test.rb index 378dd7aec..8a4fb43aa 100644 --- a/test/jobs/directo_invoice_forward_job_test.rb +++ b/test/jobs/directo_invoice_forward_job_test.rb @@ -37,8 +37,11 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase end def test_fails_if_directo_bounds_exceedable - Setting.clear_cache - Setting.directo_monthly_number_max = 30990 + activity = account_activities(:one) + price = billing_prices(:create_one_year) + activity.update!(activity_type: 'create', price: price) + + Setting.directo_monthly_number_max = 30991 assert_raises 'RuntimeError' do DirectoInvoiceForwardJob.run(monthly: true, dry: false) From 035bb14d9f1ade829273d65b98fd97e036eb3aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Mon, 2 Mar 2020 12:23:15 +0200 Subject: [PATCH 078/110] Move directo translations from logic to I18n --- app/controllers/concerns/book_keeping.rb | 13 +++++-------- app/jobs/directo_invoice_forward_job.rb | 8 +++----- config/locales/registrars.en.yml | 5 ++++- config/locales/registrars.et.yml | 4 ++++ 4 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 config/locales/registrars.et.yml diff --git a/app/controllers/concerns/book_keeping.rb b/app/controllers/concerns/book_keeping.rb index 41cd4646e..f50393822 100644 --- a/app/controllers/concerns/book_keeping.rb +++ b/app/controllers/concerns/book_keeping.rb @@ -92,15 +92,12 @@ module BookKeeping end def description_in_language(price:, yearly:) - en = language == 'en' - registration_length = if yearly - en ? 'year(s)' : 'aasta(t)' - else - en ? 'month(s)' : 'kuu(d)' - end + timeframe_string = yearly ? 'yearly' : 'monthly' + locale_string = ".registrars.invoice_#{timeframe_string}_product_description" - registration = en ? 'registration' : 'registreerimine' - ".#{price.zone_name} #{registration}: #{price.duration.to_i} #{registration_length}" + I18n.with_locale(language == 'en' ? 'en' : 'et') do + I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.to_i) + end end def prepayment_for_all(lines) diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index 768c7db0b..a423ffc2e 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -118,10 +118,8 @@ class DirectoInvoiceForwardJob < Que::Job last_directo = [Setting.directo_monthly_number_last.presence.try(:to_i), min_directo].compact.max || 0 - if max_directo && max_directo < (last_directo + invoice_count) - true - else - false - end + return true if max_directo && max_directo < (last_directo + invoice_count) + + false end end diff --git a/config/locales/registrars.en.yml b/config/locales/registrars.en.yml index 609f9f94a..c5071c3f8 100644 --- a/config/locales/registrars.en.yml +++ b/config/locales/registrars.en.yml @@ -1,4 +1,7 @@ en: + registrars: + invoice_yearly_product_description: '%{tld} registration: %{length} year(s)' + invoice_monthly_product_description: '%{tld} registration: %{length} month(s)' activerecord: errors: models: @@ -8,4 +11,4 @@ en: forbidden: is forbidden vat_rate: present: >- - must be blank when a registrar is VAT-registered in the same country as registry \ No newline at end of file + must be blank when a registrar is VAT-registered in the same country as registry diff --git a/config/locales/registrars.et.yml b/config/locales/registrars.et.yml new file mode 100644 index 000000000..4151183ea --- /dev/null +++ b/config/locales/registrars.et.yml @@ -0,0 +1,4 @@ +et: + registrars: + invoice_yearly_product_description: '%{tld} registration: %{length} year(s)' + invoice_monthly_product_description: '%{tld} registration: %{length} month(s)' From 0efd35516c74fe8b18675a50c343c9aa7cc9f1c5 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Mon, 2 Mar 2020 12:43:20 +0200 Subject: [PATCH 079/110] Fix statuses filtering in registrar contacts index --- app/controllers/registrar/contacts_controller.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/controllers/registrar/contacts_controller.rb b/app/controllers/registrar/contacts_controller.rb index bd1e29a7c..18af3a29f 100644 --- a/app/controllers/registrar/contacts_controller.rb +++ b/app/controllers/registrar/contacts_controller.rb @@ -17,12 +17,13 @@ class Registrar search_params[:registrant_domains_id_not_null] = 1 end - if params[:statuses_contains] - contacts = current_registrar_user.registrar.contacts.includes(:registrar).where( - "contacts.statuses @> ?::varchar[]", "{#{params[:statuses_contains].join(',')}}" - ) - else - contacts = current_registrar_user.registrar.contacts.includes(:registrar) + contacts = current_registrar_user.registrar.contacts.includes(:registrar) + status_list = params[:statuses_contains] + + if status_list + contacts_ids = contacts.select { |c| (c.statuses & status_list.to_a) == status_list.to_a } + .map(&:id) + contacts = contacts.where(id: contacts_ids) end normalize_search_parameters do From a5207803faf02631068597e1e7c0ebced511cb8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Mon, 2 Mar 2020 15:19:04 +0200 Subject: [PATCH 080/110] Update CHANGELOG.md --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7fcf7b36..f02a959f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ +02.03.2020 +* Registrar: fixed statuses based contact filtering [#1004](https://github.com/internetee/registry/issues/1004) + 28.02.2020 -* Registrara: fixed account switching [#1535](https://github.com/internetee/registry/issues/1535) +* Registrar: fixed account switching [#1535](https://github.com/internetee/registry/issues/1535) 27.02.2020 * Registrar: fixed the verified checkbox bug that did not change the element value to yes in epp request [#1540](https://github.com/internetee/registry/issues/1540) From 3f92640ad2f24a92c8bf746afb4cf52e90e11e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Mon, 2 Mar 2020 13:54:46 +0200 Subject: [PATCH 081/110] Move registrar directo logic to concern, touch up translations --- app/controllers/concerns/book_keeping.rb | 121 ------------------ app/jobs/directo_invoice_forward_job.rb | 6 +- app/models/concerns/invoice/book_keeping.rb | 25 ++++ app/models/concerns/registrar/book_keeping.rb | 120 +++++++++++++++++ app/models/invoice.rb | 19 +-- app/models/registrar.rb | 2 +- config/locales/registrars.en.yml | 3 +- config/locales/registrars.et.yml | 7 +- 8 files changed, 156 insertions(+), 147 deletions(-) delete mode 100644 app/controllers/concerns/book_keeping.rb create mode 100644 app/models/concerns/invoice/book_keeping.rb create mode 100644 app/models/concerns/registrar/book_keeping.rb diff --git a/app/controllers/concerns/book_keeping.rb b/app/controllers/concerns/book_keeping.rb deleted file mode 100644 index f50393822..000000000 --- a/app/controllers/concerns/book_keeping.rb +++ /dev/null @@ -1,121 +0,0 @@ -module BookKeeping - extend ActiveSupport::Concern - - DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI', - 'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze - - def monthly_summary(month:) - activities = monthly_activites(month) - return unless activities.any? - - inv = { - 'number': 1, - 'customer_code': accounting_customer_code, - 'language': language, 'currency': activities.first.currency, - 'date': month.end_of_month.strftime('%Y-%m-%d') - }.as_json - - inv['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities) - - inv - end - - def prepare_invoice_lines(month:, activities:) - lines = [] - - lines << { 'description': title_for_summary(month) } - activities.each do |activity| - fetch_invoice_lines(activity, lines) - end - lines << prepayment_for_all(lines) - - lines.as_json - end - - def title_for_summary(date) - if language == 'en' - I18n.with_locale('en') do - "Domains registrations - #{I18n.l(date, format: '%B %Y')}" - end - else - I18n.with_locale('et') do - "Domeenide registreerimine - #{I18n.l(date, format: '%B %Y')}" - end - end - end - - def fetch_invoice_lines(activity, lines) - price = load_price(activity) - if price.duration.include? 'year' - price.duration.to_i.times do |duration| - lines << new_monthly_invoice_line(activity: activity, duration: duration + 1).as_json - end - else - lines << new_monthly_invoice_line(activity: activity).as_json - end - end - - def monthly_activites(month) - AccountActivity.where(account_id: account_ids) - .where(created_at: month.beginning_of_month..month.end_of_month) - .where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]) - end - - def new_monthly_invoice_line(activity:, duration: nil) - price = load_price(activity) - line = { - 'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym], - 'quantity': 1, - 'unit': language == 'en' ? 'pc' : 'tk', - } - - finalize_invoice_line(line, price: price, duration: duration, activity: activity) - end - - def finalize_invoice_line(line, price:, activity:, duration:) - yearly = price.duration.include?('year') - - line['price'] = yearly ? (price.price.amount / price.duration.to_i) : price.price.amount - line['description'] = description_in_language(price: price, yearly: yearly) - - if duration.present? - add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1 - end - - line - end - - def add_product_timeframe(line:, activity:, duration:) - create_time = activity.created_at - line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d') - line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d') - end - - def description_in_language(price:, yearly:) - timeframe_string = yearly ? 'yearly' : 'monthly' - locale_string = ".registrars.invoice_#{timeframe_string}_product_description" - - I18n.with_locale(language == 'en' ? 'en' : 'et') do - I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.to_i) - end - end - - def prepayment_for_all(lines) - total = 0 - lines.each { |l| total += l['quantity'].to_f * l['price'].to_f } - { - 'product_id': Setting.directo_receipt_product_name, - 'description': language == 'en' ? 'Domains prepayment' : 'Domeenide ettemaks', - 'quantity': -1, - 'price': total, - 'unit': language == 'en' ? 'pc' : 'tk', - } - end - - def load_price(account_activity) - @pricelists ||= {} - return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id - - @pricelists[account_activity.price_id] = account_activity.price - end -end diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index a423ffc2e..6c3eb034c 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -70,18 +70,18 @@ class DirectoInvoiceForwardJob < Que::Job end def sync_with_directo + assign_monthly_numbers if @month Rails.logger.info("[Directo] - attempting to send following XML:\n #{@client.invoices.as_xml}") return if @dry - assign_monthly_numbers if @month res = @client.invoices.deliver(ssl_verify: false) - update_invoice_directo_state(res.body, @client.invoices.as_xml) if res.code == '200' + process_directo_response(res.body, @client.invoices.as_xml) rescue SocketError, Errno::ECONNREFUSED, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError Rails.logger.info('[Directo] Failed to communicate via API') end - def update_invoice_directo_state(xml, req) + def process_directo_response(xml, req) Rails.logger.info "[Directo] - Responded with body: #{xml}" Nokogiri::XML(xml).css('Result').each do |res| if @month diff --git a/app/models/concerns/invoice/book_keeping.rb b/app/models/concerns/invoice/book_keeping.rb new file mode 100644 index 000000000..828ad7848 --- /dev/null +++ b/app/models/concerns/invoice/book_keeping.rb @@ -0,0 +1,25 @@ +module Concerns + module Invoice + module BookKeeping + extend ActiveSupport::Concern + + def as_directo_json + inv = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self)) + inv['customer_code'] = buyer.accounting_customer_code + inv['issue_date'] = issue_date.strftime('%Y-%m-%d') + inv['transaction_date'] = account_activity.bank_transaction&.paid_at&.strftime('%Y-%m-%d') + inv['language'] = buyer.language == 'en' ? 'ENG' : '' + inv['invoice_lines'] = compose_directo_product + + inv + end + + def compose_directo_product + [{ 'product_id': Setting.directo_receipt_product_name, 'description': order, + 'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision( + subtotal, precision: 2, separator: '.' + ) }].as_json + end + end + end +end diff --git a/app/models/concerns/registrar/book_keeping.rb b/app/models/concerns/registrar/book_keeping.rb new file mode 100644 index 000000000..c85aac317 --- /dev/null +++ b/app/models/concerns/registrar/book_keeping.rb @@ -0,0 +1,120 @@ +module Concerns + module Registrar + module BookKeeping + extend ActiveSupport::Concern + + DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI', + 'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze + + def monthly_summary(month:) + activities = monthly_activites(month) + return unless activities.any? + + inv = { + 'number': 1, + 'customer_code': accounting_customer_code, + 'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency, + 'date': month.end_of_month.strftime('%Y-%m-%d') + }.as_json + + inv['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities) + + inv + end + + def prepare_invoice_lines(month:, activities:) + lines = [] + + lines << { 'description': title_for_summary(month) } + activities.each do |activity| + fetch_invoice_lines(activity, lines) + end + lines << prepayment_for_all(lines) + + lines.as_json + end + + def title_for_summary(date) + I18n.with_locale(language == 'en' ? 'en' : 'et') do + I18n.t('registrar.monthly_summary_title', date: I18n.l(date, format: '%B %Y')) + end + end + + def fetch_invoice_lines(activity, lines) + price = load_price(activity) + if price.duration.include? 'year' + price.duration.to_i.times do |duration| + lines << new_monthly_invoice_line(activity: activity, duration: duration + 1).as_json + end + else + lines << new_monthly_invoice_line(activity: activity).as_json + end + end + + def monthly_activites(month) + AccountActivity.where(account_id: account_ids) + .where(created_at: month.beginning_of_month..month.end_of_month) + .where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]) + end + + def new_monthly_invoice_line(activity:, duration: nil) + price = load_price(activity) + line = { + 'product_id': DOMAIN_TO_PRODUCT[price.zone_name.to_sym], + 'quantity': 1, + 'unit': language == 'en' ? 'pc' : 'tk', + } + + finalize_invoice_line(line, price: price, duration: duration, activity: activity) + end + + def finalize_invoice_line(line, price:, activity:, duration:) + yearly = price.duration.include?('year') + + line['price'] = yearly ? (price.price.amount / price.duration.to_i) : price.price.amount + line['description'] = description_in_language(price: price, yearly: yearly) + + if duration.present? + add_product_timeframe(line: line, activity: activity, duration: duration) if duration > 1 + end + + line + end + + def add_product_timeframe(line:, activity:, duration:) + create_time = activity.created_at + line['start_date'] = (create_time + (duration - 1).year).end_of_month.strftime('%Y-%m-%d') + line['end_date'] = (create_time + (duration - 1).year + 1).end_of_month.strftime('%Y-%m-%d') + end + + def description_in_language(price:, yearly:) + timeframe_string = yearly ? 'yearly' : 'monthly' + locale_string = "registrar.invoice_#{timeframe_string}_product_description" + + I18n.with_locale(language == 'en' ? 'en' : 'et') do + I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.to_i) + end + end + + def prepayment_for_all(lines) + total = 0 + en = language == 'en' + lines.each { |l| total += l['quantity'].to_f * l['price'].to_f } + { + 'product_id': Setting.directo_receipt_product_name, + 'description': en ? 'Domains prepayment' : 'Domeenide ettemaks', + 'quantity': -1, + 'price': total, + 'unit': en ? 'pc' : 'tk', + } + end + + def load_price(account_activity) + @pricelists ||= {} + return @pricelists[account_activity.price_id] if @pricelists.key? account_activity.price_id + + @pricelists[account_activity.price_id] = account_activity.price + end + end + end +end diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 61b35ab98..7e1fee91b 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -2,6 +2,7 @@ class Invoice < ApplicationRecord include Versions include Concerns::Invoice::Cancellable include Concerns::Invoice::Payable + include Concerns::Invoice::BookKeeping belongs_to :buyer, class_name: 'Registrar' has_one :account_activity @@ -102,24 +103,6 @@ class Invoice < ApplicationRecord generator.generate end - def as_directo_json - inv = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self)) - inv['customer_code'] = buyer.accounting_customer_code - inv['issue_date'] = issue_date.strftime('%Y-%m-%d') - inv['transaction_date'] = account_activity.bank_transaction&.paid_at&.strftime('%Y-%m-%d') - inv['language'] = buyer.language - inv['invoice_lines'] = compose_directo_product - - inv - end - - def compose_directo_product - [{ 'product_id': Setting.directo_receipt_product_name, 'description': order, - 'quantity': 1, 'price': ActionController::Base.helpers.number_with_precision( - subtotal, precision: 2, separator: '.' - ) }].as_json - end - def do_not_send_e_invoice? e_invoice_sent? || cancelled? || paid? end diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 8aae1e89e..c3522859e 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -1,6 +1,6 @@ class Registrar < ApplicationRecord include Versions # version/registrar_version.rb - include BookKeeping + include Concerns::Registrar::BookKeeping has_many :domains, dependent: :restrict_with_error has_many :contacts, dependent: :restrict_with_error diff --git a/config/locales/registrars.en.yml b/config/locales/registrars.en.yml index c5071c3f8..c57f2e891 100644 --- a/config/locales/registrars.en.yml +++ b/config/locales/registrars.en.yml @@ -1,7 +1,8 @@ en: - registrars: + registrar: invoice_yearly_product_description: '%{tld} registration: %{length} year(s)' invoice_monthly_product_description: '%{tld} registration: %{length} month(s)' + monthly_summary_title: 'Domain registrations - %{date}' activerecord: errors: models: diff --git a/config/locales/registrars.et.yml b/config/locales/registrars.et.yml index 4151183ea..1001638c1 100644 --- a/config/locales/registrars.et.yml +++ b/config/locales/registrars.et.yml @@ -1,4 +1,5 @@ et: - registrars: - invoice_yearly_product_description: '%{tld} registration: %{length} year(s)' - invoice_monthly_product_description: '%{tld} registration: %{length} month(s)' + registrar: + invoice_yearly_product_description: '%{tld} registreerimine: %{length} aasta(t)' + invoice_monthly_product_description: '%{tld} registreerimine: %{length} kuu(d)' + monthly_summary_title: 'Domeenide registreerimine - %{date}' From 0c30e8b8ee353457b804411e85e1daebe4ce5f21 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 3 Mar 2020 10:43:20 +0200 Subject: [PATCH 082/110] Create bank statement export dir if not present Fixes #1551 --- app/models/bank_statement.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/models/bank_statement.rb b/app/models/bank_statement.rb index 942ae3907..e1d582f90 100644 --- a/app/models/bank_statement.rb +++ b/app/models/bank_statement.rb @@ -25,10 +25,16 @@ class BankStatement < ApplicationRecord bank_transactions.build(bt_params) end + prepare_dir self.import_file_path = "#{ENV['bank_statement_import_dir']}/#{Time.zone.now.to_formatted_s(:number)}.txt" File.open(import_file_path, 'w') { |f| f.write(th6_file.open.read) } end + def prepare_dir + dirname = ENV['bank_statement_import_dir'] + FileUtils.mkdir_p(dirname) unless File.directory?(dirname) + end + def parse_th6_row(row) return parse_th6_header(row) if row[4, 3].strip == '000' return if row[4, 3].strip == '999' # skip footer From 6655ac6354617b934a441fc6209af4f55452dc99 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 3 Mar 2020 11:15:52 +0200 Subject: [PATCH 083/110] Add bank statement import test --- test/fixtures/files/bank_statement_test.txt | 7 +++++++ test/system/admin_area/bank_statement_test.rb | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 test/fixtures/files/bank_statement_test.txt create mode 100644 test/system/admin_area/bank_statement_test.rb diff --git a/test/fixtures/files/bank_statement_test.txt b/test/fixtures/files/bank_statement_test.txt new file mode 100644 index 000000000..d3f561a7d --- /dev/null +++ b/test/fixtures/files/bank_statement_test.txt @@ -0,0 +1,7 @@ +VV 000689NL85RABO74981124931508051533 +VV 220150805 M NL85RABO7498112493EUR Algsaldo C 26397 +VV 12015080520890321MK NL85RABO7498112493EUR401NL93ABNA8027105943 Registrar Second Prepayment Invoice no.3131071 C 72055 +VV 12015080520890321MK NL85RABO7498112493EUR401NL93ABNA8027105943 eedirect Prepayment Invoice no. 13 C 480 +VV 12015080521042372MK NL85RABO7498112493EUR767EE021222121767323770 Line Suva 8 Arve nr 2015-01 D 55000 +VV 320150805 M NL85RABO7498112493EUR Lõppsaldo C 5417 +VV 999 176980 diff --git a/test/system/admin_area/bank_statement_test.rb b/test/system/admin_area/bank_statement_test.rb new file mode 100644 index 000000000..c95035a8d --- /dev/null +++ b/test/system/admin_area/bank_statement_test.rb @@ -0,0 +1,16 @@ +require 'application_system_test_case' + +class BankStatementTest < ApplicationSystemTestCase + setup do + sign_in users(:admin) + travel_to Time.zone.parse('2010-07-05 00:30:00') + end + + def test_import_statement + assert_difference 'BankStatement.count', 1 do + visit import_admin_bank_statements_path + attach_file 'Th6 file', Rails.root.join('test', 'fixtures', 'files', 'bank_statement_test.txt').to_s + click_link_or_button 'Save' + end + end +end From e1576b04a2dc6abf953c5b7b7deb9f864bb0039e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Tue, 3 Mar 2020 13:40:52 +0200 Subject: [PATCH 084/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f02a959f8..165176a9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +03.03.2020 +* Admin: fixed import of th6 bank statement [#1551](https://github.com/internetee/registry/issues/1551) + 02.03.2020 * Registrar: fixed statuses based contact filtering [#1004](https://github.com/internetee/registry/issues/1004) From 093bd7cf57b97a756e2a67ac21c030d689b1686b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2020 20:28:06 +0000 Subject: [PATCH 085/110] Bump puma from 4.3.1 to 4.3.3 Bumps [puma](https://github.com/puma/puma) from 4.3.1 to 4.3.3. - [Release notes](https://github.com/puma/puma/releases) - [Changelog](https://github.com/puma/puma/blob/master/History.md) - [Commits](https://github.com/puma/puma/compare/v4.3.1...v4.3.3) Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5053b9468..b74c45a3e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -284,7 +284,7 @@ GEM method_source (~> 0.8.1) slop (~> 3.4) public_suffix (4.0.3) - puma (4.3.1) + puma (4.3.3) nio4r (~> 2.0) que (0.14.3) que-web (0.7.2) From 1b672b219d00993fabf41a00650384cb19d33407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 4 Mar 2020 10:52:56 +0200 Subject: [PATCH 086/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 165176a9a..9b9976d44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +04.03.2020 +* Bump Puma to 4.3.3 [#1557](https://github.com/internetee/registry/pull/1557) + 03.03.2020 * Admin: fixed import of th6 bank statement [#1551](https://github.com/internetee/registry/issues/1551) From ef04b6f87b2c4c26d0561eb467cebe1db778573e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Fri, 6 Mar 2020 14:12:36 +0200 Subject: [PATCH 087/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b9976d44..b5e11261f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +06.03.2020 +* Record payment method and failed payments [#1422](https://github.com/internetee/registry/issues/1422) + 04.03.2020 * Bump Puma to 4.3.3 [#1557](https://github.com/internetee/registry/pull/1557) From 21543d8416ad0586deade9ee163e1382e80703fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Tue, 3 Mar 2020 12:07:05 +0200 Subject: [PATCH 088/110] Better naming for variables --- Gemfile.lock | 2 +- app/models/concerns/invoice/book_keeping.rb | 15 ++++++++------- app/models/concerns/registrar/book_keeping.rb | 6 +++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8875293cf..3b36f1935 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,7 +9,7 @@ GIT GIT remote: https://github.com/internetee/directo.git - revision: 6fb158c1589c609b2519d8e8658c11de52bd3d9d + revision: 7bac1d5ca413e3cce25a7adad3c0e8d7f8cd673e branch: directo-api specs: directo (0.1.0) diff --git a/app/models/concerns/invoice/book_keeping.rb b/app/models/concerns/invoice/book_keeping.rb index 828ad7848..2469f45eb 100644 --- a/app/models/concerns/invoice/book_keeping.rb +++ b/app/models/concerns/invoice/book_keeping.rb @@ -4,14 +4,15 @@ module Concerns extend ActiveSupport::Concern def as_directo_json - inv = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self)) - inv['customer_code'] = buyer.accounting_customer_code - inv['issue_date'] = issue_date.strftime('%Y-%m-%d') - inv['transaction_date'] = account_activity.bank_transaction&.paid_at&.strftime('%Y-%m-%d') - inv['language'] = buyer.language == 'en' ? 'ENG' : '' - inv['invoice_lines'] = compose_directo_product + invoice = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(self)) + invoice['customer_code'] = buyer.accounting_customer_code + invoice['issue_date'] = issue_date.strftime('%Y-%m-%d') + invoice['transaction_date'] = account_activity + .bank_transaction&.paid_at&.strftime('%Y-%m-%d') + invoice['language'] = buyer.language == 'en' ? 'ENG' : '' + invoice['invoice_lines'] = compose_directo_product - inv + invoice end def compose_directo_product diff --git a/app/models/concerns/registrar/book_keeping.rb b/app/models/concerns/registrar/book_keeping.rb index c85aac317..27645d2cb 100644 --- a/app/models/concerns/registrar/book_keeping.rb +++ b/app/models/concerns/registrar/book_keeping.rb @@ -10,16 +10,16 @@ module Concerns activities = monthly_activites(month) return unless activities.any? - inv = { + invoice = { 'number': 1, 'customer_code': accounting_customer_code, 'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency, 'date': month.end_of_month.strftime('%Y-%m-%d') }.as_json - inv['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities) + invoice['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities) - inv + invoice end def prepare_invoice_lines(month:, activities:) From 251ea0000d6354ab272550faa106291194877189 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Tue, 10 Mar 2020 17:35:52 +0500 Subject: [PATCH 089/110] Update lhv, e-invoice & corporate_register gem due to security updates --- Gemfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b74c45a3e..31b48d360 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/internetee/company_register.git - revision: da7130542304fc543c90d54cd037d019a777c526 + revision: 86d691997aa7def9f86d88f6c92cabb86cd65487 branch: master specs: company_register (0.1.0) @@ -9,7 +9,7 @@ GIT GIT remote: https://github.com/internetee/e_invoice.git - revision: 3a754974ed25569aa85d99a87ae9e131b7c10a24 + revision: b374ffd7be77b559b30c7a0210dc0df5ac3ed723 branch: master specs: e_invoice (0.1.0) @@ -36,7 +36,7 @@ GIT GIT remote: https://github.com/internetee/lhv.git - revision: 145f66e21d65a4a7543f6b28a4124440d36fec98 + revision: cf0d30816ca9cd6a35d206aa1007c378f8acb502 branch: master specs: lhv (0.1.0) @@ -136,7 +136,7 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.1.5) + concurrent-ruby (1.1.6) countries (3.0.0) i18n_data (~> 0.8.0) sixarm_ruby_unaccent (~> 1.1) @@ -269,7 +269,7 @@ GEM mustermann (>= 1.0.0) netrc (0.11.0) nio4r (2.5.2) - nokogiri (1.10.8) + nokogiri (1.10.9) mini_portile2 (~> 2.4.0) nori (2.6.0) open4 (1.3.4) @@ -291,7 +291,7 @@ GEM erubis que (~> 0.8) sinatra - rack (2.1.2) + rack (2.2.2) rack-accept (0.4.5) rack (>= 0.4) rack-protection (2.0.8.1) From ef220cdf829ac2f1b423eaad80044da3cb916746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Tue, 10 Mar 2020 16:33:08 +0200 Subject: [PATCH 090/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5e11261f..28edf0157 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +10.03.2020 +* Updated lhv, e-invoice & company_register gem due to security updates [#1564](https://github.com/internetee/registry/pull/1564) + 06.03.2020 * Record payment method and failed payments [#1422](https://github.com/internetee/registry/issues/1422) From 1728ccaa5abfd08511af1b0813b8049467e7e0c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 11 Mar 2020 13:49:52 +0200 Subject: [PATCH 091/110] Modify SQL function to create glue for 2-level domains --- ...114649_update_zone_generation_migration.rb | 247 ++++++++++++++++++ db/structure.sql | 8 +- 2 files changed, 251 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20200311114649_update_zone_generation_migration.rb diff --git a/db/migrate/20200311114649_update_zone_generation_migration.rb b/db/migrate/20200311114649_update_zone_generation_migration.rb new file mode 100644 index 000000000..2c516474d --- /dev/null +++ b/db/migrate/20200311114649_update_zone_generation_migration.rb @@ -0,0 +1,247 @@ +class UpdateZoneGenerationMigration < ActiveRecord::Migration[5.1] + def up + execute <<-SQL + CREATE OR REPLACE FUNCTION generate_zonefile(i_origin character varying) RETURNS text + LANGUAGE plpgsql + AS $_$ + DECLARE + zone_header text := concat('$ORIGIN ', i_origin, '.'); + serial_num varchar; + include_filter varchar := ''; + exclude_filter varchar := ''; + tmp_var text; + ret text; + BEGIN + -- define filters + include_filter = '%.' || i_origin; + + -- for %.%.% + IF i_origin ~ '.' THEN + exclude_filter := ''; + -- for %.% + ELSE + exclude_filter := '%.%.' || i_origin; + END IF; + + SELECT ROUND(extract(epoch from now() at time zone 'utc')) INTO serial_num; + + -- zonefile header + SELECT concat( + format('%-10s', '$ORIGIN .'), chr(10), + format('%-10s', '$TTL'), zf.ttl, chr(10), chr(10), + format('%-10s', i_origin || '.'), 'IN SOA ', zf.master_nameserver, '. ', zf.email, '. (', chr(10), + format('%-17s', ''), format('%-12s', serial_num), '; serial number', chr(10), + format('%-17s', ''), format('%-12s', zf.refresh), '; refresh, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.retry), '; retry, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.expire), '; expire, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.minimum_ttl), '; minimum TTL, seconds', chr(10), + format('%-17s', ''), ')' + ) FROM zones zf WHERE i_origin = zf.origin INTO tmp_var; + + ret = concat(tmp_var, chr(10), chr(10)); + + -- origin ns records + SELECT ns_records FROM zones 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( + SELECT concat(d.name_puny, '. IN NS ', coalesce(ns.hostname_puny, ns.hostname), '.') + 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,inactive}' && d.statuses) + ORDER BY d.name + ), + chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- origin a glue records + SELECT a_records FROM zones 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( + array( + SELECT concat(coalesce(ns.hostname_puny, ns.hostname), '. IN A ', unnest(ns.ipv4)) + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND (ns.hostname LIKE '%.' || d.name) OR (ns.hostname LIKE d.name) + AND d.name <> i_origin + AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '{}' + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ), chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- origin aaaa glue records + SELECT a4_records FROM zones 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( + array( + SELECT concat(coalesce(ns.hostname_puny, ns.hostname), '. IN AAAA ', unnest(ns.ipv6)) + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter + AND (ns.hostname LIKE '%.' || d.name) OR (ns.hostname LIKE d.name) + AND d.name <> i_origin + AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '{}' + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ), chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- ds records + SELECT array_to_string( + array( + SELECT concat( + d.name_puny, '. 3600 IN DS ', dk.ds_key_tag, ' ', + dk.ds_alg, ' ', dk.ds_digest_type, ' ', dk.ds_digest + ) + 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 AND dk.flags = 257 + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ), + chr(10) + ) INTO tmp_var; + + ret := concat(ret, '; Zone DS Records', chr(10), tmp_var, chr(10)); + + RETURN ret; + END; + $_$; + SQL + end + + def down + execute <<-SQL + CREATE OR REPLACE FUNCTION generate_zonefile(i_origin character varying) RETURNS text + LANGUAGE plpgsql + AS $_$ + DECLARE + zone_header text := concat('$ORIGIN ', i_origin, '.'); + serial_num varchar; + include_filter varchar := ''; + exclude_filter varchar := ''; + tmp_var text; + ret text; + BEGIN + -- define filters + include_filter = '%.' || i_origin; + + -- for %.%.% + IF i_origin ~ '.' THEN + exclude_filter := ''; + -- for %.% + ELSE + exclude_filter := '%.%.' || i_origin; + END IF; + + SELECT ROUND(extract(epoch from now() at time zone 'utc')) INTO serial_num; + + -- zonefile header + SELECT concat( + format('%-10s', '$ORIGIN .'), chr(10), + format('%-10s', '$TTL'), zf.ttl, chr(10), chr(10), + format('%-10s', i_origin || '.'), 'IN SOA ', zf.master_nameserver, '. ', zf.email, '. (', chr(10), + format('%-17s', ''), format('%-12s', serial_num), '; serial number', chr(10), + format('%-17s', ''), format('%-12s', zf.refresh), '; refresh, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.retry), '; retry, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.expire), '; expire, seconds', chr(10), + format('%-17s', ''), format('%-12s', zf.minimum_ttl), '; minimum TTL, seconds', chr(10), + format('%-17s', ''), ')' + ) FROM zones zf WHERE i_origin = zf.origin INTO tmp_var; + + ret = concat(tmp_var, chr(10), chr(10)); + + -- origin ns records + SELECT ns_records FROM zones 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( + SELECT concat(d.name_puny, '. IN NS ', coalesce(ns.hostname_puny, ns.hostname), '.') + 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,inactive}' && d.statuses) + ORDER BY d.name + ), + chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- origin a glue records + SELECT a_records FROM zones 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( + array( + SELECT concat(coalesce(ns.hostname_puny, ns.hostname), '. IN A ', unnest(ns.ipv4)) + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + 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 ('{serverHold,clientHold,inactive}' && d.statuses) + ), chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- origin aaaa glue records + SELECT a4_records FROM zones 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( + array( + SELECT concat(coalesce(ns.hostname_puny, ns.hostname), '. IN AAAA ', unnest(ns.ipv6)) + FROM nameservers ns + JOIN domains d ON d.id = ns.domain_id + 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 ('{serverHold,clientHold,inactive}' && d.statuses) + ), chr(10) + ) INTO tmp_var; + + ret := concat(ret, tmp_var, chr(10), chr(10)); + + -- ds records + SELECT array_to_string( + array( + SELECT concat( + d.name_puny, '. 3600 IN DS ', dk.ds_key_tag, ' ', + dk.ds_alg, ' ', dk.ds_digest_type, ' ', dk.ds_digest + ) + 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 AND dk.flags = 257 + AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) + ), + chr(10) + ) INTO tmp_var; + + ret := concat(ret, '; Zone DS Records', chr(10), tmp_var, chr(10)); + + RETURN ret; + END; + $_$; + SQL + end +end diff --git a/db/structure.sql b/db/structure.sql index 4132266e7..604238d4c 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -140,7 +140,7 @@ CREATE FUNCTION public.generate_zonefile(i_origin character varying) RETURNS tex FROM nameservers ns JOIN domains d ON d.id = ns.domain_id WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter - AND ns.hostname LIKE '%.' || d.name + AND (ns.hostname LIKE '%.' || d.name) OR (ns.hostname LIKE d.name) AND d.name <> i_origin AND ns.ipv4 IS NOT NULL AND ns.ipv4 <> '{}' AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) @@ -160,7 +160,7 @@ CREATE FUNCTION public.generate_zonefile(i_origin character varying) RETURNS tex FROM nameservers ns JOIN domains d ON d.id = ns.domain_id WHERE d.name LIKE include_filter AND d.name NOT LIKE exclude_filter - AND ns.hostname LIKE '%.' || d.name + AND (ns.hostname LIKE '%.' || d.name) OR (ns.hostname LIKE d.name) AND d.name <> i_origin AND ns.ipv6 IS NOT NULL AND ns.ipv6 <> '{}' AND NOT ('{serverHold,clientHold,inactive}' && d.statuses) @@ -4462,6 +4462,6 @@ INSERT INTO "schema_migrations" (version) VALUES ('20200115102202'), ('20200130092113'), ('20200203143458'), -('20200204103125'); - +('20200204103125'), +('20200311114649'); From ecbed47a68e51ed7ca2bf3deee276cc260df6867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 11 Mar 2020 16:24:42 +0200 Subject: [PATCH 092/110] Render EPP error when IP missing for glue record --- app/models/nameserver.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/nameserver.rb b/app/models/nameserver.rb index bf76868dc..3ddf1d1c5 100644 --- a/app/models/nameserver.rb +++ b/app/models/nameserver.rb @@ -48,7 +48,7 @@ class Nameserver < ApplicationRecord [:ipv6, :invalid, { value: { obj: 'hostAddr', val: ipv6 } }] ], '2003' => [ - [:ipv4, :blank] + %i[base ip_required], ] } end @@ -83,6 +83,7 @@ class Nameserver < ApplicationRecord def glue_record_required? return unless hostname? && domain + DomainName(hostname).domain == domain.name end From a8a9092bdef771990c89b63998bf4a936fbe0abf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 11 Mar 2020 17:21:11 +0200 Subject: [PATCH 093/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28edf0157..c55e4b03b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +11.03.2020 +* Fixed glue record issues when using 2nd level domain as host [#1562](https://github.com/internetee/registry/issues/1562) + 10.03.2020 * Updated lhv, e-invoice & company_register gem due to security updates [#1564](https://github.com/internetee/registry/pull/1564) From 3e01963b3eb2bd34952523ad70d96c1a4d7cd1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 18 Mar 2020 19:02:28 +0200 Subject: [PATCH 094/110] Reference master branch of Directo gem --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 80375026d..9ed6b8090 100644 --- a/Gemfile +++ b/Gemfile @@ -68,7 +68,7 @@ gem 'domain_name' gem 'haml', '~> 5.0' gem 'wkhtmltopdf-binary' -gem 'directo', github: 'internetee/directo', branch: 'directo-api' +gem 'directo', github: 'internetee/directo', branch: 'master' group :development do # deploy diff --git a/Gemfile.lock b/Gemfile.lock index 3b36f1935..98f999311 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,10 +9,10 @@ GIT GIT remote: https://github.com/internetee/directo.git - revision: 7bac1d5ca413e3cce25a7adad3c0e8d7f8cd673e - branch: directo-api + revision: 8cb63d2fb91c640b264d5af05f4a6afbcfd46979 + branch: master specs: - directo (0.1.0) + directo (1.0.0) money (~> 6.13) nokogiri (~> 1.10) From d00450d67e1062e20b241217bbd2512f5138ed1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 25 Mar 2020 11:27:08 +0200 Subject: [PATCH 095/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c55e4b03b..48d173cfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +25.03.2020 +* Implemented Directo gem [#1547](https://github.com/internetee/registry/pull/1547) + 11.03.2020 * Fixed glue record issues when using 2nd level domain as host [#1562](https://github.com/internetee/registry/issues/1562) From 1747de8eb5542efaacb5e82628290858f9f33fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Tue, 14 Apr 2020 09:01:15 +0300 Subject: [PATCH 096/110] Pump dependencies to support Rails 5.2 --- Gemfile | 8 ++-- Gemfile.lock | 110 ++++++++++++++++++++++++++++----------------------- 2 files changed, 65 insertions(+), 53 deletions(-) diff --git a/Gemfile b/Gemfile index 9ed6b8090..c9516fa26 100644 --- a/Gemfile +++ b/Gemfile @@ -1,8 +1,8 @@ source 'https://rubygems.org' # core -gem 'iso8601', '0.12.1' # for dates and times -gem 'rails', '~> 5.1.7' +gem 'iso8601', '0.12.1' # for dates and times +gem 'rails', '~> 5.2.4.2' gem 'rest-client' gem 'uglifier' @@ -10,10 +10,10 @@ gem 'uglifier' gem 'figaro', '1.1.1' # model related -gem 'paper_trail', '~> 8.1' +gem 'paper_trail', '~> 9.2' gem 'pg', '1.2.2' # 1.8 is for Rails < 5.0 -gem 'ransack', '~> 1.8' +gem 'ransack', '~> 2.3' gem 'validates_email_format_of', '1.6.3' # validates email against RFC 2822 and RFC 3696 # 0.7.3 is the latest for Rails 4.2, however, it is absent on Rubygems server diff --git a/Gemfile.lock b/Gemfile.lock index f0871bf85..5aedfda95 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -68,39 +68,43 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (5.1.7) - actionpack (= 5.1.7) + actioncable (5.2.4.2) + actionpack (= 5.2.4.2) nio4r (~> 2.0) - websocket-driver (~> 0.6.1) - actionmailer (5.1.7) - actionpack (= 5.1.7) - actionview (= 5.1.7) - activejob (= 5.1.7) + websocket-driver (>= 0.6.1) + actionmailer (5.2.4.2) + actionpack (= 5.2.4.2) + actionview (= 5.2.4.2) + activejob (= 5.2.4.2) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.1.7) - actionview (= 5.1.7) - activesupport (= 5.1.7) - rack (~> 2.0) + actionpack (5.2.4.2) + actionview (= 5.2.4.2) + activesupport (= 5.2.4.2) + rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.1.7) - activesupport (= 5.1.7) + actionview (5.2.4.2) + activesupport (= 5.2.4.2) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.1.7) - activesupport (= 5.1.7) + activejob (5.2.4.2) + activesupport (= 5.2.4.2) globalid (>= 0.3.6) - activemodel (5.1.7) - activesupport (= 5.1.7) - activerecord (5.1.7) - activemodel (= 5.1.7) - activesupport (= 5.1.7) - arel (~> 8.0) - activesupport (5.1.7) + activemodel (5.2.4.2) + activesupport (= 5.2.4.2) + activerecord (5.2.4.2) + activemodel (= 5.2.4.2) + activesupport (= 5.2.4.2) + arel (>= 9.0) + activestorage (5.2.4.2) + actionpack (= 5.2.4.2) + activerecord (= 5.2.4.2) + marcel (~> 0.3.1) + activesupport (5.2.4.2) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -114,7 +118,7 @@ GEM akami (1.3.1) gyoku (>= 0.4.0) nokogiri - arel (8.0.0) + arel (9.0.0) autodoc (0.7.3) actionpack activesupport (>= 3.0.0) @@ -247,15 +251,18 @@ GEM keystores (0.4.0) libxml-ruby (3.1.0) logger (1.4.2) - loofah (2.4.0) + loofah (2.5.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) + marcel (0.3.3) + mimemagic (~> 0.3.2) method_source (0.8.2) mime-types (3.3.1) mime-types-data (~> 3.2015) mime-types-data (3.2019.1009) + mimemagic (0.3.4) mina (0.3.1) open4 (~> 1.3.4) rake @@ -283,11 +290,15 @@ GEM nori (2.6.0) open4 (1.3.4) orm_adapter (0.5.0) - paper_trail (8.1.2) - activerecord (>= 4.2, < 5.2) + paper_trail (9.2.0) + activerecord (>= 4.2, < 5.3) + paper_trail-association_tracking (< 2) request_store (~> 1.1) + paper_trail-association_tracking (1.1.1) pdfkit (0.8.4.1) pg (1.2.2) + polyamorous (2.3.2) + activerecord (>= 5.2.1) pry (0.10.1) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -308,17 +319,18 @@ GEM rack-test (1.1.0) rack (>= 1.0, < 3) railroady (1.3.0) - rails (5.1.7) - actioncable (= 5.1.7) - actionmailer (= 5.1.7) - actionpack (= 5.1.7) - actionview (= 5.1.7) - activejob (= 5.1.7) - activemodel (= 5.1.7) - activerecord (= 5.1.7) - activesupport (= 5.1.7) + rails (5.2.4.2) + actioncable (= 5.2.4.2) + actionmailer (= 5.2.4.2) + actionpack (= 5.2.4.2) + actionview (= 5.2.4.2) + activejob (= 5.2.4.2) + activemodel (= 5.2.4.2) + activerecord (= 5.2.4.2) + activestorage (= 5.2.4.2) + activesupport (= 5.2.4.2) bundler (>= 1.3.0) - railties (= 5.1.7) + railties (= 5.2.4.2) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) @@ -327,18 +339,18 @@ GEM loofah (~> 2.3) rails-settings-cached (0.7.2) rails (>= 4.2.0) - railties (5.1.7) - actionpack (= 5.1.7) - activesupport (= 5.1.7) + railties (5.2.4.2) + actionpack (= 5.2.4.2) + activesupport (= 5.2.4.2) method_source rake (>= 0.8.7) - thor (>= 0.18.1, < 2.0) + thor (>= 0.19.0, < 2.0) rake (13.0.1) - ransack (1.8.10) - actionpack (>= 3.0, < 5.2) - activerecord (>= 3.0, < 5.2) - activesupport (>= 3.0, < 5.2) + ransack (2.3.2) + activerecord (>= 5.2.1) + activesupport (>= 5.2.1) i18n + polyamorous (= 2.3.2) rb-fsevent (0.10.3) rb-inotify (0.10.1) ffi (~> 1.0) @@ -425,7 +437,7 @@ GEM thor (0.20.3) thread_safe (0.3.6) tilt (2.0.10) - tzinfo (1.2.6) + tzinfo (1.2.7) thread_safe (~> 0.1) uglifier (4.2.0) execjs (>= 0.3.0, < 3) @@ -448,7 +460,7 @@ GEM addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - websocket-driver (0.6.5) + websocket-driver (0.7.1) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.4) whenever (0.9.4) @@ -493,7 +505,7 @@ DEPENDENCIES minitest (~> 5.14) money-rails nokogiri - paper_trail (~> 8.1) + paper_trail (~> 9.2) pdfkit pg (= 1.2.2) pry (= 0.10.1) @@ -501,9 +513,9 @@ DEPENDENCIES que que-web railroady (= 1.3.0) - rails (~> 5.1.7) + rails (~> 5.2.4.2) rails-settings-cached (= 0.7.2) - ransack (~> 1.8) + ransack (~> 2.3) rest-client sass-rails (= 5.0.6) sdoc (= 0.4.1) From 7c7bcf4b41e0740ec193447f519748ab3321887a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 15 Apr 2020 09:19:43 +0300 Subject: [PATCH 097/110] Binaries / New configs from Rails 5.2 app:update --- bin/bundle | 2 +- bin/setup | 12 +++--- bin/update | 6 ++- bin/yarn | 6 +-- .../initializers/content_security_policy.rb | 25 ++++++++++++ .../new_framework_defaults_5_2.rb | 38 +++++++++++++++++++ config/storage.yml | 34 +++++++++++++++++ 7 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 config/initializers/content_security_policy.rb create mode 100644 config/initializers/new_framework_defaults_5_2.rb create mode 100644 config/storage.yml diff --git a/bin/bundle b/bin/bundle index 66e9889e8..f19acf5b5 100755 --- a/bin/bundle +++ b/bin/bundle @@ -1,3 +1,3 @@ #!/usr/bin/env ruby -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) load Gem.bin_path('bundler', 'bundle') diff --git a/bin/setup b/bin/setup index b5ca43ac5..94fd4d797 100755 --- a/bin/setup +++ b/bin/setup @@ -1,9 +1,9 @@ #!/usr/bin/env ruby -require 'pathname' +require 'fileutils' include FileUtils # path to your application root. -APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) +APP_ROOT = File.expand_path('..', __dir__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") @@ -20,10 +20,10 @@ chdir APP_ROOT do # Install JavaScript dependencies if using Yarn # system('bin/yarn') - puts "\n== Copying sample files ==" - unless File.exist?('config/database.yml') - system! 'cp config/database.yml.sample config/database.yml' - end + # puts "\n== Copying sample files ==" + # unless File.exist?('config/database.yml') + # cp 'config/database.yml.sample', 'config/database.yml' + # end puts "\n== Preparing database ==" system! 'bin/rails db:setup' diff --git a/bin/update b/bin/update index a8e4462f2..58bfaed51 100755 --- a/bin/update +++ b/bin/update @@ -1,10 +1,9 @@ #!/usr/bin/env ruby -require 'pathname' require 'fileutils' include FileUtils # path to your application root. -APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) +APP_ROOT = File.expand_path('..', __dir__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") @@ -18,6 +17,9 @@ chdir APP_ROOT do system! 'gem install bundler --conservative' system('bundle check') || system!('bundle install') + # Install JavaScript dependencies if using Yarn + # system('bin/yarn') + puts "\n== Updating database ==" system! 'bin/rails db:migrate' diff --git a/bin/yarn b/bin/yarn index c2bacef83..460dd565b 100755 --- a/bin/yarn +++ b/bin/yarn @@ -1,8 +1,8 @@ #!/usr/bin/env ruby -VENDOR_PATH = File.expand_path('..', __dir__) -Dir.chdir(VENDOR_PATH) do +APP_ROOT = File.expand_path('..', __dir__) +Dir.chdir(APP_ROOT) do begin - exec "yarnpkg #{ARGV.join(" ")}" + exec "yarnpkg", *ARGV rescue Errno::ENOENT $stderr.puts "Yarn executable was not detected in the system." $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb new file mode 100644 index 000000000..d3bcaa5ec --- /dev/null +++ b/config/initializers/content_security_policy.rb @@ -0,0 +1,25 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy +# For further information see the following documentation +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + +# Rails.application.config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https + +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end + +# If you are using UJS then enable automatic nonce generation +# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } + +# Report CSP violations to a specified URI +# For further information see the following documentation: +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only +# Rails.application.config.content_security_policy_report_only = true diff --git a/config/initializers/new_framework_defaults_5_2.rb b/config/initializers/new_framework_defaults_5_2.rb new file mode 100644 index 000000000..c383d072b --- /dev/null +++ b/config/initializers/new_framework_defaults_5_2.rb @@ -0,0 +1,38 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 5.2 upgrade. +# +# Once upgraded flip defaults one by one to migrate to the new default. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. + +# Make Active Record use stable #cache_key alongside new #cache_version method. +# This is needed for recyclable cache keys. +# Rails.application.config.active_record.cache_versioning = true + +# Use AES-256-GCM authenticated encryption for encrypted cookies. +# Also, embed cookie expiry in signed or encrypted cookies for increased security. +# +# This option is not backwards compatible with earlier Rails versions. +# It's best enabled when your entire app is migrated and stable on 5.2. +# +# Existing cookies will be converted on read then written with the new scheme. +# Rails.application.config.action_dispatch.use_authenticated_cookie_encryption = true + +# Use AES-256-GCM authenticated encryption as default cipher for encrypting messages +# instead of AES-256-CBC, when use_authenticated_message_encryption is set to true. +# Rails.application.config.active_support.use_authenticated_message_encryption = true + +# Add default protection from forgery to ActionController::Base instead of in +# ApplicationController. +# Rails.application.config.action_controller.default_protect_from_forgery = true + +# Store boolean values are in sqlite3 databases as 1 and 0 instead of 't' and +# 'f' after migrating old data. +# Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true + +# Use SHA-1 instead of MD5 to generate non-sensitive digests, such as the ETag header. +# Rails.application.config.active_support.use_sha1_digests = true + +# Make `form_with` generate id attributes for any generated HTML tags. +# Rails.application.config.action_view.form_with_generates_ids = true diff --git a/config/storage.yml b/config/storage.yml new file mode 100644 index 000000000..d32f76e8f --- /dev/null +++ b/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket + +# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] From e040ac6a45c5f69f73d3c22c5813014fe19f819e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 15 Apr 2020 10:01:35 +0300 Subject: [PATCH 098/110] Exclude DomainStatus static model from Papertrail --- app/models/domain_status.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index fba75737c..dc3032c74 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -1,5 +1,4 @@ class DomainStatus < ApplicationRecord - include Versions # version/domain_status_version.rb include EppErrors belongs_to :domain From 43200f68dec07b53ca3d926af2d00531d3f820b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Wed, 15 Apr 2020 12:25:28 +0300 Subject: [PATCH 099/110] Revert unnessecary updates to binaries --- app/models/domain_status.rb | 1 - bin/bundle | 2 +- bin/setup | 14 ++++++++------ bin/update | 6 ++---- bin/yarn | 12 +++++------- 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/app/models/domain_status.rb b/app/models/domain_status.rb index dc3032c74..4b1c49916 100644 --- a/app/models/domain_status.rb +++ b/app/models/domain_status.rb @@ -1,6 +1,5 @@ class DomainStatus < ApplicationRecord include EppErrors - belongs_to :domain # Requests to delete the object MUST be rejected. diff --git a/bin/bundle b/bin/bundle index f19acf5b5..8bfc37be6 100755 --- a/bin/bundle +++ b/bin/bundle @@ -1,3 +1,3 @@ #!/usr/bin/env ruby -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __dir__) load Gem.bin_path('bundler', 'bundle') diff --git a/bin/setup b/bin/setup index 94fd4d797..ab3c84d9b 100755 --- a/bin/setup +++ b/bin/setup @@ -1,9 +1,11 @@ #!/usr/bin/env ruby -require 'fileutils' +# frozen_string_literal: true + +require 'pathname' include FileUtils # path to your application root. -APP_ROOT = File.expand_path('..', __dir__) +APP_ROOT = Pathname.new File.expand_path('../../', __dir__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") @@ -20,10 +22,10 @@ chdir APP_ROOT do # Install JavaScript dependencies if using Yarn # system('bin/yarn') - # puts "\n== Copying sample files ==" - # unless File.exist?('config/database.yml') - # cp 'config/database.yml.sample', 'config/database.yml' - # end + puts "\n== Copying sample files ==" + unless File.exist?('config/database.yml') + system! 'cp config/database.yml.sample config/database.yml' + end puts "\n== Preparing database ==" system! 'bin/rails db:setup' diff --git a/bin/update b/bin/update index 58bfaed51..a8e4462f2 100755 --- a/bin/update +++ b/bin/update @@ -1,9 +1,10 @@ #!/usr/bin/env ruby +require 'pathname' require 'fileutils' include FileUtils # path to your application root. -APP_ROOT = File.expand_path('..', __dir__) +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") @@ -17,9 +18,6 @@ chdir APP_ROOT do system! 'gem install bundler --conservative' system('bundle check') || system!('bundle install') - # Install JavaScript dependencies if using Yarn - # system('bin/yarn') - puts "\n== Updating database ==" system! 'bin/rails db:migrate' diff --git a/bin/yarn b/bin/yarn index 460dd565b..adabdd976 100755 --- a/bin/yarn +++ b/bin/yarn @@ -1,11 +1,9 @@ #!/usr/bin/env ruby APP_ROOT = File.expand_path('..', __dir__) Dir.chdir(APP_ROOT) do - begin - exec "yarnpkg", *ARGV - rescue Errno::ENOENT - $stderr.puts "Yarn executable was not detected in the system." - $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" - exit 1 - end + exec 'yarnpkg', *ARGV +rescue Errno::ENOENT + $stderr.puts 'Yarn executable was not detected in the system.' + $stderr.puts 'Download Yarn at https://yarnpkg.com/en/docs/install' + exit 1 end From 7970f51353d0918b0a03851ae221025f8c998d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Wed, 15 Apr 2020 23:29:03 +0300 Subject: [PATCH 100/110] Update CHANGELOG.md Rails 5.2 update --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48d173cfc..81d4eb7fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +15.04.2020 +* Updated Rails to 5.2 and fixed acitionview security issue [#1568](https://github.com/internetee/registry/issues/1568) + 25.03.2020 * Implemented Directo gem [#1547](https://github.com/internetee/registry/pull/1547) From 8161d21f9837c0a8f3f2cffcb475c02987fb8bb2 Mon Sep 17 00:00:00 2001 From: Georg Kahest Date: Mon, 7 Oct 2019 23:01:30 +0300 Subject: [PATCH 101/110] clickable commit hash link --- app/views/layouts/admin/base.haml | 2 +- app/views/layouts/registrant/application.html.erb | 2 +- app/views/layouts/registrar/base.html.erb | 2 +- app/views/layouts/registrar/sessions.html.erb | 2 +- config/initializers/current_commit_hash.rb | 1 + 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/views/layouts/admin/base.haml b/app/views/layouts/admin/base.haml index 792a8cc0b..b5194892d 100644 --- a/app/views/layouts/admin/base.haml +++ b/app/views/layouts/admin/base.haml @@ -32,5 +32,5 @@ .footer.text-right Version - = CURRENT_COMMIT_HASH + = link_to "#{CURRENT_COMMIT_HASH}", "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}" = javascript_include_tag 'admin-manifest', async: true diff --git a/app/views/layouts/registrant/application.html.erb b/app/views/layouts/registrant/application.html.erb index 66fdf3e16..a3b69a78a 100644 --- a/app/views/layouts/registrant/application.html.erb +++ b/app/views/layouts/registrant/application.html.erb @@ -76,7 +76,7 @@
Version - <%= CURRENT_COMMIT_HASH %> + <%= link_to(CURRENT_COMMIT_HASH, CURRENT_COMMIT_REPO/commits/CURRENT_COMMIT_HASH) %>
diff --git a/app/views/layouts/registrar/base.html.erb b/app/views/layouts/registrar/base.html.erb index 4d4f1b972..57fab3336 100644 --- a/app/views/layouts/registrar/base.html.erb +++ b/app/views/layouts/registrar/base.html.erb @@ -54,7 +54,7 @@
Version - <%= CURRENT_COMMIT_HASH %> + <%= link_to(CURRENT_COMMIT_HASH, CURRENT_COMMIT_REPO/commits/CURRENT_COMMIT_HASH) %>
diff --git a/app/views/layouts/registrar/sessions.html.erb b/app/views/layouts/registrar/sessions.html.erb index 3cb345ef9..004689ded 100644 --- a/app/views/layouts/registrar/sessions.html.erb +++ b/app/views/layouts/registrar/sessions.html.erb @@ -44,7 +44,7 @@
Version - <%= CURRENT_COMMIT_HASH %> + <%= link_to(CURRENT_COMMIT_HASH, CURRENT_COMMIT_REPO/commits/CURRENT_COMMIT_HASH) %>
diff --git a/config/initializers/current_commit_hash.rb b/config/initializers/current_commit_hash.rb index b018b46fd..3038fa33b 100644 --- a/config/initializers/current_commit_hash.rb +++ b/config/initializers/current_commit_hash.rb @@ -1 +1,2 @@ CURRENT_COMMIT_HASH = `git rev-parse --short HEAD` +CURRENT_COMMIT_REPO = `git remote get-url origin` \ No newline at end of file From 700967b58dd79d6e47f070d246f38efb9a16189d Mon Sep 17 00:00:00 2001 From: Georg Kahest Date: Mon, 7 Oct 2019 23:41:07 +0300 Subject: [PATCH 102/110] fix strings, use better colours --- app/views/layouts/admin/base.haml | 2 +- app/views/layouts/registrant/application.html.erb | 2 +- app/views/layouts/registrar/base.html.erb | 2 +- app/views/layouts/registrar/sessions.html.erb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/layouts/admin/base.haml b/app/views/layouts/admin/base.haml index b5194892d..d893da853 100644 --- a/app/views/layouts/admin/base.haml +++ b/app/views/layouts/admin/base.haml @@ -32,5 +32,5 @@ .footer.text-right Version - = link_to "#{CURRENT_COMMIT_HASH}", "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}" + = link_to "#{CURRENT_COMMIT_HASH}", "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", style: 'color:#000000;' = javascript_include_tag 'admin-manifest', async: true diff --git a/app/views/layouts/registrant/application.html.erb b/app/views/layouts/registrant/application.html.erb index a3b69a78a..5e6820246 100644 --- a/app/views/layouts/registrant/application.html.erb +++ b/app/views/layouts/registrant/application.html.erb @@ -76,7 +76,7 @@
Version - <%= link_to(CURRENT_COMMIT_HASH, CURRENT_COMMIT_REPO/commits/CURRENT_COMMIT_HASH) %> + <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", style: 'color:#FFFFFF;') %>
diff --git a/app/views/layouts/registrar/base.html.erb b/app/views/layouts/registrar/base.html.erb index 57fab3336..88d20c319 100644 --- a/app/views/layouts/registrar/base.html.erb +++ b/app/views/layouts/registrar/base.html.erb @@ -54,7 +54,7 @@
Version - <%= link_to(CURRENT_COMMIT_HASH, CURRENT_COMMIT_REPO/commits/CURRENT_COMMIT_HASH) %> + <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", style: 'color:#FFFFFF;') %>
diff --git a/app/views/layouts/registrar/sessions.html.erb b/app/views/layouts/registrar/sessions.html.erb index 004689ded..ca5059ab4 100644 --- a/app/views/layouts/registrar/sessions.html.erb +++ b/app/views/layouts/registrar/sessions.html.erb @@ -44,7 +44,7 @@
Version - <%= link_to(CURRENT_COMMIT_HASH, CURRENT_COMMIT_REPO/commits/CURRENT_COMMIT_HASH) %> + <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", style: 'color:#FFFFFF;') %>
From 1fabdb6a7266eb3151d9f4fb491de577e086a193 Mon Sep 17 00:00:00 2001 From: Georg Kahest Date: Wed, 16 Oct 2019 21:17:09 +0300 Subject: [PATCH 103/110] Address review comments: https://github.com/internetee/registry/pull/1345#discussion_r333904209 --- app/assets/stylesheets/shared/general.sass | 3 +++ app/views/layouts/admin/base.haml | 2 +- app/views/layouts/registrant/application.html.erb | 2 +- app/views/layouts/registrar/base.html.erb | 2 +- app/views/layouts/registrar/sessions.html.erb | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/shared/general.sass b/app/assets/stylesheets/shared/general.sass index 07b92cdbe..6d1c4956d 100644 --- a/app/assets/stylesheets/shared/general.sass +++ b/app/assets/stylesheets/shared/general.sass @@ -15,6 +15,9 @@ body > .container padding-top: 15px font-size: 10px +a.footer-version-link + color: black + .nowrap white-space: nowrap diff --git a/app/views/layouts/admin/base.haml b/app/views/layouts/admin/base.haml index d893da853..1ea29753d 100644 --- a/app/views/layouts/admin/base.haml +++ b/app/views/layouts/admin/base.haml @@ -32,5 +32,5 @@ .footer.text-right Version - = link_to "#{CURRENT_COMMIT_HASH}", "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", style: 'color:#000000;' + = link_to "#{CURRENT_COMMIT_HASH}", "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", class: 'footer-version-link' = javascript_include_tag 'admin-manifest', async: true diff --git a/app/views/layouts/registrant/application.html.erb b/app/views/layouts/registrant/application.html.erb index 5e6820246..9c3341bd3 100644 --- a/app/views/layouts/registrant/application.html.erb +++ b/app/views/layouts/registrant/application.html.erb @@ -76,7 +76,7 @@
Version - <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", style: 'color:#FFFFFF;') %> + <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", class: 'footer-version-link') %>
diff --git a/app/views/layouts/registrar/base.html.erb b/app/views/layouts/registrar/base.html.erb index 88d20c319..2fc4cf4a2 100644 --- a/app/views/layouts/registrar/base.html.erb +++ b/app/views/layouts/registrar/base.html.erb @@ -54,7 +54,7 @@
Version - <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", style: 'color:#FFFFFF;') %> + <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", class: 'footer-version-link') %>
diff --git a/app/views/layouts/registrar/sessions.html.erb b/app/views/layouts/registrar/sessions.html.erb index ca5059ab4..88662a008 100644 --- a/app/views/layouts/registrar/sessions.html.erb +++ b/app/views/layouts/registrar/sessions.html.erb @@ -44,7 +44,7 @@
Version - <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", style: 'color:#FFFFFF;') %> + <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", class: 'footer-version-link') %>
From 197d19921561ad08e66cc82ee5e6dc8ff40ce6be Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 16 Apr 2020 16:01:34 +0500 Subject: [PATCH 104/110] Move url generation to helper, made it reliable with ssh git checkout --- app/helpers/application_helper.rb | 11 ++++++++++- app/views/layouts/admin/base.haml | 2 +- app/views/layouts/registrant/application.html.erb | 2 +- app/views/layouts/registrar/base.html.erb | 2 +- app/views/layouts/registrar/sessions.html.erb | 2 +- config/initializers/current_commit_hash.rb | 2 +- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a4a8e4912..608ddded7 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -33,6 +33,15 @@ module ApplicationHelper end end + def current_commit_link + hash = CURRENT_COMMIT_HASH + current_repo = CURRENT_COMMIT_REPO.gsub('com:', 'com/') + .gsub('git@', 'https://') + .gsub('.git', '') + + link_to hash.to_s, "#{current_repo}/commit/#{hash}", class: 'footer-version-link' + end + def creator_link(model) return 'not present' if model.blank? return 'unknown' if model.creator.blank? @@ -96,4 +105,4 @@ module ApplicationHelper def body_css_class [controller_path.split('/').map!(&:dasherize), action_name.dasherize, 'page'].join('-') end -end \ No newline at end of file +end diff --git a/app/views/layouts/admin/base.haml b/app/views/layouts/admin/base.haml index 1ea29753d..928629ce6 100644 --- a/app/views/layouts/admin/base.haml +++ b/app/views/layouts/admin/base.haml @@ -32,5 +32,5 @@ .footer.text-right Version - = link_to "#{CURRENT_COMMIT_HASH}", "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", class: 'footer-version-link' + = current_commit_link = javascript_include_tag 'admin-manifest', async: true diff --git a/app/views/layouts/registrant/application.html.erb b/app/views/layouts/registrant/application.html.erb index 9c3341bd3..c5290b70f 100644 --- a/app/views/layouts/registrant/application.html.erb +++ b/app/views/layouts/registrant/application.html.erb @@ -76,7 +76,7 @@
Version - <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", class: 'footer-version-link') %> + <%= current_commit_link %>
diff --git a/app/views/layouts/registrar/base.html.erb b/app/views/layouts/registrar/base.html.erb index 2fc4cf4a2..5881dd400 100644 --- a/app/views/layouts/registrar/base.html.erb +++ b/app/views/layouts/registrar/base.html.erb @@ -54,7 +54,7 @@
Version - <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", class: 'footer-version-link') %> + <%= current_commit_link %>
diff --git a/app/views/layouts/registrar/sessions.html.erb b/app/views/layouts/registrar/sessions.html.erb index 88662a008..ace645199 100644 --- a/app/views/layouts/registrar/sessions.html.erb +++ b/app/views/layouts/registrar/sessions.html.erb @@ -44,7 +44,7 @@
Version - <%= link_to(CURRENT_COMMIT_HASH, "#{CURRENT_COMMIT_REPO}/commits/#{CURRENT_COMMIT_HASH}", class: 'footer-version-link') %> + <%= current_commit_link %>
diff --git a/config/initializers/current_commit_hash.rb b/config/initializers/current_commit_hash.rb index 3038fa33b..edba19a42 100644 --- a/config/initializers/current_commit_hash.rb +++ b/config/initializers/current_commit_hash.rb @@ -1,2 +1,2 @@ CURRENT_COMMIT_HASH = `git rev-parse --short HEAD` -CURRENT_COMMIT_REPO = `git remote get-url origin` \ No newline at end of file +CURRENT_COMMIT_REPO = `git remote get-url origin` From 6e30737bf0b859af351b279d7a7c951391dbe1c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Fri, 17 Apr 2020 18:39:22 +0300 Subject: [PATCH 105/110] Update CHANGELOG.md Clickable version string #1345 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81d4eb7fb..be1445146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +17.04.2020 +* Webinterfaces have now clickable version string pointing to the latest deployed commit in github [#1345](https://github.com/internetee/registry/pull/1345) + 15.04.2020 * Updated Rails to 5.2 and fixed acitionview security issue [#1568](https://github.com/internetee/registry/issues/1568) From 23642355bfbea8a73a4234761d52585a989067e9 Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Mon, 20 Apr 2020 13:40:03 +0500 Subject: [PATCH 106/110] Fix mina deploy issue (#1573) Use git command to get origin/repo --- app/helpers/application_helper.rb | 13 ++++++++----- config/initializers/current_commit_hash.rb | 2 -- 2 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 config/initializers/current_commit_hash.rb diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 608ddded7..8de3fdc70 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -34,12 +34,15 @@ module ApplicationHelper end def current_commit_link - hash = CURRENT_COMMIT_HASH - current_repo = CURRENT_COMMIT_REPO.gsub('com:', 'com/') - .gsub('git@', 'https://') - .gsub('.git', '') + hash = `git rev-parse --short HEAD` + current_repo = `git remote get-url origin`.gsub('com:', 'com/') + .gsub('git@', 'https://') + .gsub('.git', '') - link_to hash.to_s, "#{current_repo}/commit/#{hash}", class: 'footer-version-link' + link_to hash.to_s, "#{current_repo}/commit/#{hash}", + class: 'footer-version-link', + target: '_blank', + rel: 'noopener' end def creator_link(model) diff --git a/config/initializers/current_commit_hash.rb b/config/initializers/current_commit_hash.rb deleted file mode 100644 index edba19a42..000000000 --- a/config/initializers/current_commit_hash.rb +++ /dev/null @@ -1,2 +0,0 @@ -CURRENT_COMMIT_HASH = `git rev-parse --short HEAD` -CURRENT_COMMIT_REPO = `git remote get-url origin` From eff87d002b60d9a896361ed2423df1af1d7b12ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Erik=20=C3=95unapuu?= Date: Mon, 27 Apr 2020 15:31:54 +0300 Subject: [PATCH 107/110] Rollback SimpleCov to 0.17.1 --- Gemfile | 2 +- Gemfile.lock | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index c9516fa26..851094689 100644 --- a/Gemfile +++ b/Gemfile @@ -87,7 +87,7 @@ group :test do gem 'capybara' gem 'database_cleaner' gem 'minitest', '~> 5.14' - gem 'simplecov', require: false + gem 'simplecov', '0.17.1', require: false # CC last supported v0.17 gem 'webdrivers' gem 'webmock' end diff --git a/Gemfile.lock b/Gemfile.lock index 5aedfda95..fe737f7ac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -413,10 +413,11 @@ GEM selenium-webdriver (3.142.7) childprocess (>= 0.5, < 4.0) rubyzip (>= 1.2.2) - simplecov (0.18.1) + simplecov (0.17.1) docile (~> 1.1) - simplecov-html (~> 0.11.0) - simplecov-html (0.11.0) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.2) simpleidn (0.0.9) sinatra (2.0.8.1) mustermann (~> 1.0) @@ -521,7 +522,7 @@ DEPENDENCIES sdoc (= 0.4.1) select2-rails (= 3.5.9.3) selectize-rails (= 0.12.1) - simplecov + simplecov (= 0.17.1) simpleidn (= 0.0.9) uglifier validates_email_format_of (= 1.6.3) From 8b6a615dfd62299e38ea726c609b0f36d5a510d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Mon, 27 Apr 2020 21:26:40 +0300 Subject: [PATCH 108/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be1445146..a43dcff83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +27.04.2020 +* Downgrade SimpleCov to 0.17 due to incompatibiilty with CodeClimate [#1575](https://github.com/internetee/registry/pull/1575) + 17.04.2020 * Webinterfaces have now clickable version string pointing to the latest deployed commit in github [#1345](https://github.com/internetee/registry/pull/1345) From c4e46149e88d815ea9b21c4f4f17e707cb7f5dfb Mon Sep 17 00:00:00 2001 From: Alex Sherman Date: Thu, 30 Apr 2020 13:01:01 +0500 Subject: [PATCH 109/110] Fix presence of ignored fields in history Closes #1576 --- app/models/concerns/versions.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/concerns/versions.rb b/app/models/concerns/versions.rb index 9ffd17e9a..01766b233 100644 --- a/app/models/concerns/versions.rb +++ b/app/models/concerns/versions.rb @@ -70,7 +70,8 @@ module Versions valid_columns = ver.item_type.constantize&.column_names o = new(ver.object&.slice(*valid_columns)) o.version_loader = ver - ver.object_changes.to_h.each { |k, v| o.public_send("#{k}=", v[-1]) } + changes = ver.object_changes.to_h&.slice(*valid_columns) + changes.each { |k, v| o.public_send("#{k}=", v[-1]) } o end not_in_history = where(id: (ids.to_a - from_history.map(&:id))) From 1a58d85f15fc5a3791bc11d3824d659b7aa93935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20V=C3=B5hmar?= Date: Thu, 30 Apr 2020 12:20:30 +0300 Subject: [PATCH 110/110] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a43dcff83..cdc184c6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +30.04.2020 +* Fix for internal error on opening domain history with legacy id record [#1576](https://github.com/internetee/registry/issues/1576) + 27.04.2020 * Downgrade SimpleCov to 0.17 due to incompatibiilty with CodeClimate [#1575](https://github.com/internetee/registry/pull/1575)