diff --git a/.gitignore b/.gitignore index 1c4a85f46..08606ba47 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,6 @@ /config/deploy.rb /config/master.key /.idea - +/config/master.key # Do not commit one. Instead, download the latest from https://github.com/internetee/style-guide. .rubocop.yml diff --git a/Gemfile b/Gemfile index c907eb267..d4f5cb7e7 100644 --- a/Gemfile +++ b/Gemfile @@ -104,3 +104,6 @@ gem 'pghero' gem 'pg_query', '>= 0.9.0' gem 'newrelic_rpm' gem 'newrelic-infinite_tracing' + +# token +gem 'jwt' diff --git a/Gemfile.lock b/Gemfile.lock index fa0a18470..9b88bbbbd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -275,6 +275,7 @@ GEM activesupport (>= 4.2) aes_key_wrap bindata + jwt (2.3.0) kaminari (1.2.1) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.1) @@ -560,6 +561,7 @@ DEPENDENCIES iso8601 (= 0.13.0) jquery-rails jquery-ui-rails (= 6.0.1) + jwt kaminari lhv! mime-types-data diff --git a/app/assets/images/everypay.png b/app/assets/images/everypay.png new file mode 100644 index 000000000..c1456c4be Binary files /dev/null and b/app/assets/images/everypay.png differ diff --git a/app/controllers/admin/invoices_controller.rb b/app/controllers/admin/invoices_controller.rb index 223257605..caf1e3a95 100644 --- a/app/controllers/admin/invoices_controller.rb +++ b/app/controllers/admin/invoices_controller.rb @@ -13,6 +13,7 @@ module Admin if @invoice&.persisted? flash[:notice] = t(:record_created) + # send_invoice_data_to_billing_system redirect_to [:admin, @invoice] else flash.now[:alert] = t(:failed_to_create_record) @@ -48,6 +49,8 @@ module Admin def cancel @invoice.cancel + EisBilling::SendInvoiceStatus.send_info(invoice_number: @invoice.number, status: 'cancelled') + redirect_to [:admin, @invoice], notice: t('.cancelled') end diff --git a/app/controllers/eis_billing/base_controller.rb b/app/controllers/eis_billing/base_controller.rb new file mode 100644 index 000000000..a475472b9 --- /dev/null +++ b/app/controllers/eis_billing/base_controller.rb @@ -0,0 +1,59 @@ +module EisBilling + class BaseController < ApplicationController + protect_from_forgery with: :null_session + skip_authorization_check # Temporary solution + # skip_before_action :verify_authenticity_token # Temporary solution + before_action :persistent + before_action :authorized + + INITIATOR = 'billing'.freeze + + def encode_token(payload) + JWT.encode(payload, ENV['secret_word']) + end + + def auth_header + # { Authorization: 'Bearer ' } + request.headers['Authorization'] + end + + def decoded_token + return unless auth_header + + token = auth_header.split(' ')[1] + begin + JWT.decode(token, billing_secret_key, true, algorithm: 'HS256') + rescue JWT::DecodeError + nil + end + end + + def accessable_service + return decoded_token[0]['initiator'] == INITIATOR if decoded_token + + false + end + + def logged_in? + !!accessable_service + end + + def authorized + render json: { message: 'Access denied' }, status: :unauthorized unless logged_in? + end + + def billing_secret_key + ENV['billing_secret'] + end + + def logger + Rails.logger + end + + def persistent + return true if Feature.billing_system_integrated? + + render json: { message: "We don't work yet!" }, status: :unauthorized + end + end +end diff --git a/app/controllers/eis_billing/directo_response_controller.rb b/app/controllers/eis_billing/directo_response_controller.rb new file mode 100644 index 000000000..9549ec0a6 --- /dev/null +++ b/app/controllers/eis_billing/directo_response_controller.rb @@ -0,0 +1,36 @@ +class EisBilling::DirectoResponseController < EisBilling::BaseController + def update + response = params[:response] + xml_data = params[:xml_data] + @month = params.fetch(:month, false) + + process_directo_response(xml_data, response) + render status: :ok, json: { messege: 'Should return new directo number' } + end + + private + + def process_directo_response(xml, req) + Rails.logger.info "[Directo] - Responded with body: #{xml}" + Nokogiri::XML(req).css('Result').each do |res| + if @month + 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: 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.item = invoice + invoice.update(in_directo: true) + end + + directo_record.save! + end +end diff --git a/app/controllers/eis_billing/e_invoice_response_controller.rb b/app/controllers/eis_billing/e_invoice_response_controller.rb new file mode 100644 index 000000000..208c8864f --- /dev/null +++ b/app/controllers/eis_billing/e_invoice_response_controller.rb @@ -0,0 +1,15 @@ +class EisBilling::EInvoiceResponseController < EisBilling::BaseController + def update + invoice_number = params[:invoice_number] + + mark_e_invoice_sent_at(invoice_number) + render status: :ok, json: { message: 'Response received' } + end + + private + + def mark_e_invoice_sent_at(invoice_number) + invoice = Invoice.find_by(number: invoice_number) + invoice.update(e_invoice_sent_at: Time.zone.now) + end +end diff --git a/app/controllers/eis_billing/lhv_connect_transactions_controller.rb b/app/controllers/eis_billing/lhv_connect_transactions_controller.rb new file mode 100644 index 000000000..09688e68f --- /dev/null +++ b/app/controllers/eis_billing/lhv_connect_transactions_controller.rb @@ -0,0 +1,48 @@ +module EisBilling + class LhvConnectTransactionsController < EisBilling::BaseController + def create + params['_json'].each do |incoming_transaction| + process_transactions(incoming_transaction) + end + + render status: :ok, json: { message: 'RECEIVED', params: params } + end + + private + + def process_transactions(incoming_transaction) + logger.info 'Got incoming transactions' + logger.info incoming_transaction + + bank_statement = BankStatement.new(bank_code: Setting.registry_bank_code, + iban: Setting.registry_iban) + bank_statement_transaction(bank_statement: bank_statement, incoming_transaction: incoming_transaction) + end + + def bank_statement_transaction(bank_statement:, incoming_transaction:) + ActiveRecord::Base.transaction do + bank_statement.save! + transaction = create_transaction(incoming_transaction: incoming_transaction, bank_statement: bank_statement) + + next if transaction.registrar.blank? + + create_invoice_if_missing(transaction) unless transaction.non_canceled? + end + end + + def create_invoice_if_missing(transaction) + Invoice.create_from_transaction!(transaction) unless transaction.autobindable? + transaction.autobind_invoice + end + + def create_transaction(incoming_transaction:, bank_statement:) + transaction_attributes = { sum: incoming_transaction['amount'], + currency: incoming_transaction['currency'], + paid_at: incoming_transaction['date'], + reference_no: incoming_transaction['payment_reference_number'], + description: incoming_transaction['payment_description'] } + + bank_statement.bank_transactions.create!(transaction_attributes) + end + end +end diff --git a/app/controllers/eis_billing/payment_status_controller.rb b/app/controllers/eis_billing/payment_status_controller.rb new file mode 100644 index 000000000..cb8e70803 --- /dev/null +++ b/app/controllers/eis_billing/payment_status_controller.rb @@ -0,0 +1,54 @@ +module EisBilling + class PaymentStatusController < EisBilling::BaseController + TYPE = 'PaymentOrders::EveryPay'.freeze + + def update + payment_status = define_payment_status(params[:payment_state]) + invoice = Invoice.find_by(number: params[:order_reference]) + bank = create_bank_transfer(invoice: invoice, sum: params[:standing_amount], paid_at: params[:transaction_time]) + create_payment_order(invoice: invoice, everypay_response: params, payment_status: payment_status) + + registrar = invoice.buyer + bank.create_activity(registrar, invoice) + + respond_to do |format| + format.json do + render status: :ok, content_type: 'application/json', layout: false, json: { message: 'ok' } + end + end + end + + private + + def define_payment_status(status) + return :paid if PaymentOrders::EveryPay::SUCCESSFUL_PAYMENT.include? status + + :failed + end + + def create_payment_order(invoice:, everypay_response:, payment_status:) + payment = PaymentOrder.new + payment.type = TYPE + payment.invoice = invoice + payment.response = everypay_response + payment.status = payment_status + payment.save + + payment + end + + def create_bank_transfer(invoice:, sum:, paid_at:) + bank = BankTransaction.new + bank.description = invoice.order + bank.reference_no = invoice.reference_no + bank.currency = invoice.currency + bank.iban = invoice.seller_iban + bank.sum = sum + bank.paid_at = paid_at + bank.buyer_name = invoice.buyer_name + bank.save + + bank + end + end +end diff --git a/app/controllers/registrar/invoices_controller.rb b/app/controllers/registrar/invoices_controller.rb index 34f6c17ae..2a17b72b0 100644 --- a/app/controllers/registrar/invoices_controller.rb +++ b/app/controllers/registrar/invoices_controller.rb @@ -17,6 +17,8 @@ class Registrar def cancel @invoice.cancel + EisBilling::SendInvoiceStatus.send_info(invoice_number: @invoice.number, status: 'cancelled') + redirect_to [:registrar, @invoice], notice: t('.cancelled') end diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index 43a537ade..04da1a424 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -21,6 +21,7 @@ class DirectoInvoiceForwardJob < ApplicationJob 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 @@ -69,6 +70,7 @@ class DirectoInvoiceForwardJob < ApplicationJob 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 diff --git a/app/jobs/directo_invoice_forward_two_job.rb b/app/jobs/directo_invoice_forward_two_job.rb new file mode 100644 index 000000000..e0d8d946b --- /dev/null +++ b/app/jobs/directo_invoice_forward_two_job.rb @@ -0,0 +1,84 @@ +class DirectoInvoiceForwardTwoJob < ApplicationJob + def perform(monthly: false, dry: false) + data = nil + + if monthly + @month = Time.zone.now - 1.month + data = collect_monthly_data + else + data = collect_receipts_data + end + + EisBilling::SendDataToDirecto.send_request(object_data: data, monthly: monthly, dry: dry) + end + + def collect_receipts_data + unsent_invoices = Invoice.where(in_directo: false).non_cancelled + collected_data = [] + + unsent_invoices.each do |invoice| + unless valid_invoice_conditions?(invoice) + Rails.logger.info "[DIRECTO] Invoice #{invoice.number} has been skipped" + next + end + + collected_data << invoice.as_directo_json + end + + collected_data + 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 collect_monthly_data + registrars_data = [] + + Registrar.where.not(test_registrar: true).find_each do |registrar| + registrars_data << { + registrar: registrar, + registrar_summery: registrar.monthly_summary(month: @month), + } + end + + registrars_data + end + + 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.item = invoice + invoice.update(in_directo: true) + else + update_directo_number(num: directo_record.invoice_number) + end + + directo_record.save! + end + + def update_directo_number(num:) + return unless num.to_i > Setting.directo_monthly_number_last.to_i + + Setting.directo_monthly_number_last = num.to_i + 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 + + return true if max_directo && max_directo < (last_directo + invoice_count) + + false + end +end diff --git a/app/jobs/send_e_invoice_two_job.rb b/app/jobs/send_e_invoice_two_job.rb new file mode 100644 index 000000000..bb8f993ca --- /dev/null +++ b/app/jobs/send_e_invoice_two_job.rb @@ -0,0 +1,44 @@ +class SendEInvoiceTwoJob < ApplicationJob + discard_on HTTPClient::TimeoutError + + def perform(invoice_id, payable: true) + logger.info "Started to process e-invoice for invoice_id #{invoice_id}" + invoice = Invoice.find_by(id: invoice_id) + return unless need_to_process_invoice?(invoice: invoice, payable: payable) + + send_invoice_to_eis_billing(invoice: invoice, payable: payable) + invoice.update(e_invoice_sent_at: Time.zone.now) + rescue StandardError => e + log_error(invoice: invoice, error: e) + raise e + end + + private + + def need_to_process_invoice?(invoice:, payable:) + logger.info "Checking if need to process e-invoice #{invoice}, payable: #{payable}" + return false if invoice.blank? + return false if invoice.do_not_send_e_invoice? && payable + + true + end + + def send_invoice_to_eis_billing(invoice:, payable:) + result = EisBilling::SendEInvoice.send_request(invoice: invoice, payable: payable) + logger.info result.body + 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 # #{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/app/models/billing/reference_no.rb b/app/models/billing/reference_no.rb index fbb9218c4..3ed84d7f1 100644 --- a/app/models/billing/reference_no.rb +++ b/app/models/billing/reference_no.rb @@ -4,8 +4,13 @@ module Billing MULTI_REGEXP = /(\d{2,20})/ def self.generate - base = Base.generate - "#{base}#{base.check_digit}" + if Feature.billing_system_integrated? + result = EisBilling::GetReferenceNumber.send_request + JSON.parse(result.body)['reference_number'] + else + base = Base.generate + "#{base}#{base.check_digit}" + end end def self.valid?(ref) diff --git a/app/models/feature.rb b/app/models/feature.rb index 4143f108e..7a0d6d78b 100644 --- a/app/models/feature.rb +++ b/app/models/feature.rb @@ -1,13 +1,7 @@ class Feature - # def self.obj_and_extensions_statuses_enabled? - # return false if ENV['obj_and_extensions_prohibited'] == 'false' - # - # ENV['obj_and_extensions_prohibited'] || false - # end - # - # def self.enable_lock_domain_with_new_statuses? - # return false if ENV['enable_lock_domain_with_new_statuses'] == 'false' - # - # ENV['enable_lock_domain_with_new_statuses'] || false - # end + def self.billing_system_integrated? + return false if ENV['billing_system_integrated'] == 'false' + + ENV['billing_system_integrated'] || false + end end diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 6ba3a158d..66d3faf86 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -40,8 +40,38 @@ class Invoice < ApplicationRecord attribute :vat_rate, ::Type::VatRate.new - def set_invoice_number - last_no = Invoice.order(number: :desc).limit(1).pick(:number) + def validate_invoice_number(result) + response = JSON.parse(result.body) + + billing_restrictions_issue if response['code'] == '403' + billing_out_of_range_issue if response['error'] == 'out of range' + end + + def billing_restrictions_issue + errors.add(:base, I18n.t('cannot get access')) + logger.error('PROBLEM WITH TOKEN') + throw(:abort) + end + + def billing_out_of_range_issue + errors.add(:base, I18n.t('failed_to_generate_invoice_invoice_number_limit_reached')) + logger.error('INVOICE NUMBER LIMIT REACHED, COULD NOT GENERATE INVOICE') + throw(:abort) + end + + def invoice_number_from_billing + result = EisBilling::GetInvoiceNumber.send_invoice + validate_invoice_number(result) + + self.number = JSON.parse(result.body)['invoice_number'].to_i + end + + def generate_invoice_number_legacy + last_no = Invoice.all + .where(number: Setting.invoice_number_min.to_i...Setting.invoice_number_max.to_i) + .order(number: :desc) + .limit(1) + .pick(:number) if last_no && last_no >= Setting.invoice_number_min.to_i self.number = last_no + 1 @@ -51,9 +81,15 @@ class Invoice < ApplicationRecord return if number <= Setting.invoice_number_max.to_i - errors.add(:base, I18n.t('failed_to_generate_invoice_invoice_number_limit_reached')) - logger.error('INVOICE NUMBER LIMIT REACHED, COULD NOT GENERATE INVOICE') - throw(:abort) + billing_out_of_range_issue + end + + def set_invoice_number + if Feature.billing_system_integrated? + invoice_number_from_billing + else + generate_invoice_number_legacy + end end def to_s diff --git a/app/models/registrar.rb b/app/models/registrar.rb index aafc391cd..caefaddd6 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -107,7 +107,20 @@ class Registrar < ApplicationRecord .deliver_later(wait: 1.minute) end - SendEInvoiceJob.set(wait: 1.minute).perform_now(invoice.id, payable: payable) + if Feature.billing_system_integrated? + add_invoice_instance = EisBilling::AddDeposits.new(invoice) + result = add_invoice_instance.send_invoice + + link = JSON.parse(result.body)['everypay_link'] + + invoice.update(payment_link: link) + end + + if Feature.billing_system_integrated? + SendEInvoiceTwoJob.set(wait: 1.minute).perform_now(invoice.id, payable: payable) + else + SendEInvoiceJob.set(wait: 1.minute).perform_now(invoice.id, payable: payable) + end invoice end diff --git a/app/services/eis_billing/add_deposits.rb b/app/services/eis_billing/add_deposits.rb new file mode 100644 index 000000000..c9a47d360 --- /dev/null +++ b/app/services/eis_billing/add_deposits.rb @@ -0,0 +1,37 @@ +module EisBilling + class AddDeposits < EisBilling::Base + attr_reader :invoice + + def initialize(invoice) + @invoice = invoice + end + + def send_invoice + send_request(json_obj: parse_invoice) + end + + private + + def parse_invoice + data = {} + data[:transaction_amount] = invoice.total.to_s + data[:order_reference] = invoice.number + data[:customer_name] = invoice.buyer_name + data[:customer_email] = invoice.buyer_email + data[:custom_field1] = invoice.description + data[:custom_field2] = INITIATOR + data[:invoice_number] = invoice.number + + data + end + + def send_request(json_obj:) + http = EisBilling::Base.base_request(url: invoice_generator_url) + http.post(invoice_generator_url, json_obj.to_json, EisBilling::Base.headers) + end + + def invoice_generator_url + "#{BASE_URL}/api/v1/invoice_generator/invoice_generator" + end + end +end diff --git a/app/services/eis_billing/base.rb b/app/services/eis_billing/base.rb new file mode 100644 index 000000000..e0cb71b4a --- /dev/null +++ b/app/services/eis_billing/base.rb @@ -0,0 +1,35 @@ +module EisBilling + class Base + BASE_URL = ENV['eis_billing_system_base_url'] || 'https://st-billing.infra.tld.ee' + INITIATOR = 'registry'.freeze + + def self.base_request(url:) + uri = URI(url) + http = Net::HTTP.new(uri.host, uri.port) + + http.use_ssl = true unless Rails.env.development? + http.verify_mode = OpenSSL::SSL::VERIFY_NONE if Rails.env.development? + + http + end + + def self.generate_token + JWT.encode(payload, billing_secret) + end + + def self.payload + { initiator: INITIATOR } + end + + def self.headers + { + 'Authorization' => "Bearer #{generate_token}", + 'Content-Type' => 'application/json', + } + end + + def self.billing_secret + ENV['billing_secret'] + end + end +end diff --git a/app/services/eis_billing/get_invoice_number.rb b/app/services/eis_billing/get_invoice_number.rb new file mode 100644 index 000000000..1ef31eeb0 --- /dev/null +++ b/app/services/eis_billing/get_invoice_number.rb @@ -0,0 +1,16 @@ +module EisBilling + class GetInvoiceNumber < EisBilling::Base + def self.send_invoice + send_request + end + + def self.send_request + http = EisBilling::Base.base_request(url: invoice_number_generator_url) + http.post(invoice_number_generator_url, nil, EisBilling::Base.headers) + end + + def self.invoice_number_generator_url + "#{BASE_URL}/api/v1/invoice_generator/invoice_number_generator" + end + end +end diff --git a/app/services/eis_billing/get_reference_number.rb b/app/services/eis_billing/get_reference_number.rb new file mode 100644 index 000000000..e200a8dff --- /dev/null +++ b/app/services/eis_billing/get_reference_number.rb @@ -0,0 +1,22 @@ +module EisBilling + class GetReferenceNumber < EisBilling::Base + def self.send_request + send_it + end + + def self.obj_data + { + initiator: INITIATOR, + } + end + + def self.send_it + http = EisBilling::Base.base_request(url: reference_number_generator_url) + http.post(reference_number_generator_url, obj_data.to_json, EisBilling::Base.headers) + end + + def self.reference_number_generator_url + "#{EisBilling::Base::BASE_URL}/api/v1/invoice_generator/reference_number_generator" + end + end +end diff --git a/app/services/eis_billing/send_data_to_directo.rb b/app/services/eis_billing/send_data_to_directo.rb new file mode 100644 index 000000000..266475b31 --- /dev/null +++ b/app/services/eis_billing/send_data_to_directo.rb @@ -0,0 +1,23 @@ +module EisBilling + class SendDataToDirecto < EisBilling::Base + def self.send_request(object_data:, monthly:, dry:) + send_info(object_data: object_data, monthly: monthly, dry: dry) + end + + def self.send_info(object_data:, monthly:, dry:) + prepared_data = { + invoice_data: object_data, + monthly: monthly, + dry: dry, + initiator: INITIATOR, + } + + http = EisBilling::Base.base_request(url: directo_url) + http.post(directo_url, prepared_data.to_json, EisBilling::Base.headers) + end + + def self.directo_url + "#{BASE_URL}/api/v1/directo/directo" + end + end +end diff --git a/app/services/eis_billing/send_e_invoice.rb b/app/services/eis_billing/send_e_invoice.rb new file mode 100644 index 000000000..e2a9cfaf6 --- /dev/null +++ b/app/services/eis_billing/send_e_invoice.rb @@ -0,0 +1,52 @@ +module EisBilling + class SendEInvoice < EisBilling::Base + def self.send_request(invoice:, payable:) + send_info(invoice: invoice, payable: payable) + end + + def self.send_info(invoice:, payable:) + items = [] + prepared_data = prepare_data(invoice: invoice, payable: payable) + + invoice.items.each do |invoice_item| + items << prepare_item(invoice_item) + end + + prepared_data[:items] = items + + http = EisBilling::Base.base_request(url: e_invoice_url) + http.post(e_invoice_url, prepared_data.to_json, EisBilling::Base.headers) + end + + def self.prepare_item(invoice_item) + { + description: invoice_item.description, + price: invoice_item.price, + quantity: invoice_item.quantity, + unit: invoice_item.unit, + subtotal: invoice_item.subtotal, + vat_rate: invoice_item.vat_rate, + vat_amount: invoice_item.vat_amount, + total: invoice_item.total, + } + end + + def self.prepare_data(invoice:, payable:) + { + invoice: invoice, + vat_amount: invoice.vat_amount, + invoice_subtotal: invoice.subtotal, + buyer_billing_email: invoice.buyer.billing_email, + buyer_e_invoice_iban: invoice.buyer.e_invoice_iban, + seller_country_code: invoice.seller_country_code, + buyer_country_code: invoice.buyer_country_code, + payable: payable, + initiator: EisBilling::Base::INITIATOR, + } + end + + def self.e_invoice_url + "#{BASE_URL}/api/v1/e_invoice/e_invoice" + end + end +end diff --git a/app/services/eis_billing/send_invoice_status.rb b/app/services/eis_billing/send_invoice_status.rb new file mode 100644 index 000000000..61007675e --- /dev/null +++ b/app/services/eis_billing/send_invoice_status.rb @@ -0,0 +1,21 @@ +module EisBilling + class SendInvoiceStatus < EisBilling::Base + def self.send_info(invoice_number:, status:) + send_request(invoice_number: invoice_number, status: status) + end + + def self.send_request(invoice_number:, status:) + json_obj = { + invoice_number: invoice_number, + status: status, + } + + http = EisBilling::Base.base_request(url: invoice_status_url) + http.post(invoice_status_url, json_obj.to_json, EisBilling::Base.headers) + end + + def self.invoice_status_url + "#{BASE_URL}/api/v1/invoice_generator/invoice_status" + end + end +end diff --git a/app/views/eis_billing/directo_response/update.html.erb b/app/views/eis_billing/directo_response/update.html.erb new file mode 100644 index 000000000..693715b2d --- /dev/null +++ b/app/views/eis_billing/directo_response/update.html.erb @@ -0,0 +1,2 @@ +

EisBilling::DirectoResponse#update

+

Find me in app/views/eis_billing/directo_response/update.html.erb

diff --git a/app/views/eis_billing/e_invoice_response/update.html.erb b/app/views/eis_billing/e_invoice_response/update.html.erb new file mode 100644 index 000000000..32fb7d171 --- /dev/null +++ b/app/views/eis_billing/e_invoice_response/update.html.erb @@ -0,0 +1,2 @@ +

EisBilling::EInvoiceResponse#update

+

Find me in app/views/eis_billing/e_invoice_response/update.html.erb

diff --git a/app/views/eis_billing/update.json.erb b/app/views/eis_billing/update.json.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/registrar/invoices/partials/_banklinks.haml b/app/views/registrar/invoices/partials/_banklinks.haml index d9cbe1f21..339ae4705 100644 --- a/app/views/registrar/invoices/partials/_banklinks.haml +++ b/app/views/registrar/invoices/partials/_banklinks.haml @@ -1,7 +1,8 @@ %h4= t('registrar.invoices.pay_invoice') %hr -- locals[:payment_channels].each do |meth| - - meth = meth.strip - = link_to registrar_payment_with_path(meth, invoice_id: params[:id]), id: meth do - = image_tag("#{meth}.png") + - if @invoice.payment_link.present? + = link_to @invoice.payment_link, target: :_blank do + = image_tag("everypay.png", class: 'everypay', style: "width: 100px; height: 20px;") + - else + = "No everypay link" diff --git a/config/application.yml.sample b/config/application.yml.sample index 02b230ff4..b25b09fa8 100644 --- a/config/application.yml.sample +++ b/config/application.yml.sample @@ -235,3 +235,11 @@ registry_demo_accredited_users_url: 'http://registry.test/api/v1/accreditation_c a_and_aaaa_validation_timeout: '1' nameserver_validation_timeout: '1' +eis_billing_system_base_url: 'http://eis_billing_system:3000' +billing_secret: acd50ed44524d24c826d724fda922b790ca4130b02d62bcc8f85f1b863195ba8d155c4346037364eb59135d1e9dcba6cd8a4046ee4aef3c3a0878fcdf8e85efd +billing_system_integrated: 'true' + +secret_access_word: 'please-Give-Me-accesS' +secret_word: 'this-secret-should-be-change' +allow_accr_endspoints: 'true' + diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc new file mode 100644 index 000000000..919d8d9c1 --- /dev/null +++ b/config/credentials.yml.enc @@ -0,0 +1 @@ +bXY8qqnyzpMtyIDA74p4C1GiW+cLO7yeUXl5nwZB7yy1Lkv0XbF8juV07MCm7mBgh0BfjK9Ey2sx+QiXH/PimvhNDtgy6vSNbgb5AcQBJ6XwHlXei/DNF7Bt+r5V+ixrDU6FJZ8Y9EQyjZC9zcPiAaMhDMmA71bfiE2vO2TT1T6BZcjD5P4GKmYM7pMDgKATrwauzd6ejuYfTpSBHR51zuUEEBL1uZKSXW/i6vNAE+yuRxNOULWISA0zDPaCipnrMwjf8yWkp9L4qLIcggYpepZm6t+OyAD2XMTz/5skfQRtZ0PGDs7gzJLdAYD6ErUTU9N+n6SPhPpWu0zPFMR/A9t6AudgupmLeADGnkzUyRa4jCLzOnklV4rzAT1vM4zdVhGCgd3JXQL6zptrgHgRQN8i3BhBY2w3KXtFV1N61M6cMuuvTHMMFVI+V9sbRJ58Nok9EVbu5U/WRpuJElKq7xo1bgtY/0NOFq2K+TqZT6RBtSH5sWIdUGJJIbI6VngzfZpUNPiyg9eyShK2Wa2v1BlyLK3zYRD8F9/kNUvLCX7vgSjI/pwifokVAF51GhykhlmpfOyLmEEc011DwD+F4xjkYN1xHY8=--YBWnRjhG+BqNrfar--RcZCpjUq+MNhMOydjZWWTA== \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 4ba44300d..8fd80f923 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,6 +11,13 @@ Rails.application.routes.draw do mount PgHero::Engine, at: "pghero" end + namespace :eis_billing do + put '/payment_status', to: 'payment_status#update', as: 'payment_status', :format => false, :defaults => { :format => 'json' } + put '/directo_response', to: 'directo_response#update', as: 'directo_response' + put '/e_invoice_response', to: 'e_invoice_response#update', as: 'e_invoice_response' + post '/lhv_connect_transactions', to: 'lhv_connect_transactions#create', as: 'lhv_connect_transactions' + end + namespace :epp do constraints(EppConstraint.new(:session)) do get 'session/hello', to: 'sessions#hello', as: 'hello' diff --git a/db/migrate/20220124105717_add_payment_link_to_invoice.rb b/db/migrate/20220124105717_add_payment_link_to_invoice.rb new file mode 100644 index 000000000..a2b283ea8 --- /dev/null +++ b/db/migrate/20220124105717_add_payment_link_to_invoice.rb @@ -0,0 +1,5 @@ +class AddPaymentLinkToInvoice < ActiveRecord::Migration[6.1] + def change + add_column :invoices, :payment_link, :string + end +end diff --git a/db/structure.sql b/db/structure.sql index 66152fe27..76bfe8b43 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -5411,6 +5411,5 @@ INSERT INTO "schema_migrations" (version) VALUES ('20220413073315'), ('20220413084536'), ('20220413084748'), -('20220504090512'); - - +('20220504090512'), +('20220406085500'); diff --git a/lib/tasks/eis_billing_import_data.rake b/lib/tasks/eis_billing_import_data.rake new file mode 100644 index 000000000..cb5aa2561 --- /dev/null +++ b/lib/tasks/eis_billing_import_data.rake @@ -0,0 +1,85 @@ +BASE_URL = ENV['eis_billing_system_base_url'] || 'https://st-billing.infra.tld.ee' +INITIATOR = 'registry'.freeze + +namespace :eis_billing do + desc 'One time task to export invoice data to billing system' + task export_invoices: :environment do + parsed_data = [] + status = 'unpaid' + + Invoice.all.each do |invoice| + if invoice.cancelled? + status = 'cancelled' + else + status = invoice.paid? ? 'paid' : 'unpaid' + end + + transaction_time = invoice.receipt_date if invoice.paid? + + parsed_data << { + invoice_number: invoice.number, + initiator: 'registry', + transaction_amount: invoice.total, + status: status, + in_directo: invoice.in_directo, + e_invoice_sent_at: invoice.e_invoice_sent_at, + transaction_time: transaction_time + } + end + + base_request(url: import_invoice_data_url, json_obj: parsed_data) + end + + desc 'One time task to export reference number of registrars to billing system' + task export_references: :environment do + parsed_data = [] + Registrar.all.each do |registrar| + parsed_data << { + reference_number: registrar.reference_no, + initiator: 'registry', + registrar_name: registrar.name + } + end + + base_request(url: import_reference_data_url, json_obj: parsed_data) + end +end + +def import_reference_data_url + "#{BASE_URL}/api/v1/import_data/reference_data" +end + +def import_invoice_data_url + "#{BASE_URL}/api/v1/import_data/invoice_data" +end + +def base_request(url:, json_obj:) + uri = URI(url) + http = Net::HTTP.new(uri.host, uri.port) + + unless Rails.env.development? + http.use_ssl = true + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + end + + http.post(url, json_obj.to_json, headers) +end + +def generate_token + JWT.encode(payload, billing_secret) +end + +def payload + { initiator: INITIATOR } +end + +def headers + { + 'Authorization' => "Bearer #{generate_token}", + 'Content-Type' => 'application/json', + } +end + +def self.billing_secret + ENV['billing_secret'] +end diff --git a/lib/tasks/registrars/reload_balance.rake b/lib/tasks/registrars/reload_balance.rake index 937af45f7..2fdc01675 100644 --- a/lib/tasks/registrars/reload_balance.rake +++ b/lib/tasks/registrars/reload_balance.rake @@ -17,7 +17,7 @@ namespace :registrars do next if reload_pending || !threshold_reached Registrar.transaction do - registrar.issue_prepayment_invoice(reload_amount) + registrar.issue_prepayment_invoice(reload_amount, 'reload balance') registrar.settings['balance_auto_reload']['pending'] = true registrar.save! end diff --git a/test/integration/admin_area/invoices_test.rb b/test/integration/admin_area/invoices_test.rb index 01c1a29d7..9c831250e 100644 --- a/test/integration/admin_area/invoices_test.rb +++ b/test/integration/admin_area/invoices_test.rb @@ -24,14 +24,30 @@ class AdminAreaInvoicesIntegrationTest < ApplicationIntegrationTest end def test_create_new_invoice - visit new_admin_invoice_path + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number - assert_text 'Create new invoice' - select 'Best Names', from: 'deposit_registrar_id', match: :first - fill_in 'Amount', with: '1000' - click_on 'Save' + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator"). + to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) - assert_equal page.status_code, 200 + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + + visit new_admin_invoice_path + + assert_text 'Create new invoice' + select 'Best Names', from: 'deposit_registrar_id', match: :first + fill_in 'Amount', with: '1000' + click_on 'Save' + + assert_equal page.status_code, 200 + end end def test_visit_list_of_invoices_pages diff --git a/test/integration/eis_billing/directo_response_test.rb b/test/integration/eis_billing/directo_response_test.rb new file mode 100644 index 000000000..4b2c30ba2 --- /dev/null +++ b/test/integration/eis_billing/directo_response_test.rb @@ -0,0 +1,43 @@ +require 'test_helper' + +class DirectoResponseTest < ApplicationIntegrationTest + setup do + sign_in users(:api_bestnames) + + @invoice = invoices(:one) + @response_xml = "" + Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) + end + + def test_should_created_directo_instance + if Feature.billing_system_integrated? + directo_response_from_billing = { + response: @response_xml, + month: true + } + + assert_difference 'Directo.count', 1 do + put eis_billing_directo_response_path, params: JSON.parse(directo_response_from_billing.to_json), + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + end + end + + def test_should_update_related_invoice + if Feature.billing_system_integrated? + directo_response_from_billing = { + response: @response_xml + } + + refute @invoice.in_directo + + assert_difference 'Directo.count', 1 do + put eis_billing_directo_response_path, params: JSON.parse(directo_response_from_billing.to_json), + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + + @invoice.reload + assert @invoice.in_directo + end + end +end diff --git a/test/integration/eis_billing/e_invoice_response_test.rb b/test/integration/eis_billing/e_invoice_response_test.rb new file mode 100644 index 000000000..c282962c5 --- /dev/null +++ b/test/integration/eis_billing/e_invoice_response_test.rb @@ -0,0 +1,17 @@ +require 'test_helper' + +class EInvoiceResponseTest < ApplicationIntegrationTest + setup do + sign_in users(:api_bestnames) + @invoice = invoices(:one) + Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) + end + + def test_invoice_should_be_mark_as_sent + assert_nil @invoice.e_invoice_sent_at + put eis_billing_e_invoice_response_path, params: { invoice_number: @invoice.number} + + @invoice.reload + assert_not_nil @invoice.e_invoice_sent_at + end +end diff --git a/test/integration/eis_billing/lhv_connect_transactions_test.rb b/test/integration/eis_billing/lhv_connect_transactions_test.rb new file mode 100644 index 000000000..f6d0f59d0 --- /dev/null +++ b/test/integration/eis_billing/lhv_connect_transactions_test.rb @@ -0,0 +1,43 @@ +require 'test_helper' + +class LhvConnectTransactionsIntegrationTest < ApplicationIntegrationTest + setup do + @invoice = invoices(:unpaid) + sign_in users(:api_bestnames) + Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) + end + + def test_should_saved_transaction_data + if Feature.billing_system_integrated? + test_transaction_1 = OpenStruct.new(amount: 0.1, + currency: 'EUR', + date: Time.zone.today, + payment_reference_number: '2199812', + payment_description: "description 2199812") + + test_transaction_2 = OpenStruct.new(amount: 0.1, + currency: 'EUR', + date: Time.zone.today, + payment_reference_number: '2199813', + payment_description: "description 2199813") + + test_transaction_3 = OpenStruct.new(amount: 0.1, + currency: 'EUR', + date: Time.zone.today, + payment_reference_number: '2199814', + payment_description: "description 2199814") + + lhv_transactions = [] + lhv_transactions << test_transaction_1 + lhv_transactions << test_transaction_2 + lhv_transactions << test_transaction_3 + + assert_difference 'BankStatement.count', 3 do + assert_difference 'BankTransaction.count', 3 do + post eis_billing_lhv_connect_transactions_path, params: { "_json" => JSON.parse(lhv_transactions.to_json) }, + headers: { 'HTTP_COOKIE' => 'session=api_bestnames' } + end + end + end + end +end diff --git a/test/models/bank_transaction_test.rb b/test/models/bank_transaction_test.rb index 0520e8783..8a3a664b5 100644 --- a/test/models/bank_transaction_test.rb +++ b/test/models/bank_transaction_test.rb @@ -16,72 +16,87 @@ class BankTransactionTest < ActiveSupport::TestCase end def test_binds_if_this_sum_invoice_already_present - create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') - another_invoice = @invoice.dup - another_invoice.save(validate: false) - another_invoice.update(reference_no: '7654321', number: '2221') + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') + another_invoice = @invoice.dup + another_invoice.save(validate: false) + another_invoice.update(reference_no: '7654321', number: '2221') - another_item = @invoice.items.first.dup - another_item.invoice = another_invoice - another_item.save - another_invoice.reload + another_item = @invoice.items.first.dup + another_item.invoice = another_invoice + another_item.save + another_invoice.reload - first_transaction = BankTransaction.new(sum: 10, - description: 'Order nr 1 from registrar 1234567 second number 2345678') + first_transaction = BankTransaction.new(sum: 10, + description: 'Order nr 1 from registrar 1234567 second number 2345678') - first_transaction.create_activity(another_invoice.buyer, another_invoice) + first_transaction.create_activity(another_invoice.buyer, another_invoice) - transaction = BankTransaction.new(sum: 10, - description: 'Order nr 1 from registrar 1234567 second number 2345678') + transaction = BankTransaction.new(sum: 10, + description: 'Order nr 1 from registrar 1234567 second number 2345678') - assert_difference 'AccountActivity.count' do - transaction.autobind_invoice + assert_difference 'AccountActivity.count' do + transaction.autobind_invoice + end end end def test_binds_if_this_sum_cancelled_invoice_already_present - create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') - another_invoice = @invoice.dup - another_invoice.save(validate: false) + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') + another_invoice = @invoice.dup + another_invoice.save(validate: false) - another_item = @invoice.items.first.dup - another_item.invoice = another_invoice + another_item = @invoice.items.first.dup + another_item.invoice = another_invoice - another_item.save - another_invoice.reload - another_invoice.update(reference_no: '1234567', number: '2221', cancelled_at: Time.zone.now) + another_item.save + another_invoice.reload + another_invoice.update(reference_no: '1234567', number: '2221', cancelled_at: Time.zone.now) - transaction = BankTransaction.new(sum: 10, - description: 'Order nr 1 from registrar 1234567 second number 2345678') + transaction = BankTransaction.new(sum: 10, + description: 'Order nr 1 from registrar 1234567 second number 2345678') - assert_difference 'AccountActivity.count' do - transaction.autobind_invoice + assert_difference 'AccountActivity.count' do + transaction.autobind_invoice + end end end def test_marks_the_first_one_as_paid_if_same_sum - create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') - another_invoice = @invoice.dup - another_invoice.save(validate: false) - another_invoice.update(reference_no: '7654321', number: '2221') + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + create_payable_invoice(number: '2222', total: 10, reference_no: '1234567') + another_invoice = @invoice.dup + another_invoice.save(validate: false) + another_invoice.update(reference_no: '7654321', number: '2221') - another_item = @invoice.items.first.dup - another_item.invoice = another_invoice - another_item.save - another_invoice.reload + another_item = @invoice.items.first.dup + another_item.invoice = another_invoice + another_item.save + another_invoice.reload - transaction = BankTransaction.new(sum: 10, - description: 'Order nr 1 from registrar 1234567 second number 2345678') + transaction = BankTransaction.new(sum: 10, + description: 'Order nr 1 from registrar 1234567 second number 2345678') - assert_difference 'AccountActivity.count' do - transaction.autobind_invoice + assert_difference 'AccountActivity.count' do + transaction.autobind_invoice + end + + @invoice.reload + another_invoice.reload + assert(@invoice.paid?) + assert_not(another_invoice.paid?) end - - @invoice.reload - another_invoice.reload - assert(@invoice.paid?) - assert_not(another_invoice.paid?) end def test_matches_against_invoice_nubmber_and_reference_number_in_description diff --git a/test/models/billing/reference_no_test.rb b/test/models/billing/reference_no_test.rb index d7bf78597..15ac65dc4 100644 --- a/test/models/billing/reference_no_test.rb +++ b/test/models/billing/reference_no_test.rb @@ -7,7 +7,12 @@ class ReferenceNoTest < ActiveSupport::TestCase end def test_generated_reference_number_conforms_to_format - reference_no = Billing::ReferenceNo.generate - assert_match Billing::ReferenceNo::REGEXP, reference_no + if Feature.billing_system_integrated? + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/reference_number_generator") + .to_return(status: 200, body: "{\"reference_number\":\"12332\"}", headers: {}) + + reference_no = Billing::ReferenceNo.generate + assert_match Billing::ReferenceNo::REGEXP, reference_no + end end end diff --git a/test/models/invoice_test.rb b/test/models/invoice_test.rb index 150e8032c..d0cadb4ee 100644 --- a/test/models/invoice_test.rb +++ b/test/models/invoice_test.rb @@ -5,6 +5,7 @@ class InvoiceTest < ActiveSupport::TestCase setup do @invoice = invoices(:one) + Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) end def test_fixture_is_valid @@ -79,6 +80,10 @@ class InvoiceTest < ActiveSupport::TestCase end def test_buyer_vat_no_is_taken_from_registrar_by_default + invoice_n = Invoice.order(number: :desc).last.number + response = OpenStruct.new(body: "{\"invoice_number\":\"#{invoice_n + 3}\"}") + Spy.on(EisBilling::GetInvoiceNumber, :send_invoice).and_return(response) + registrar = registrars(:bestnames) registrar.vat_no = 'US1234' invoice = @invoice.dup @@ -113,31 +118,69 @@ class InvoiceTest < ActiveSupport::TestCase end def test_creates_invoice_with_bank_transaction_total - registrar = registrars(:bestnames) - transaction = bank_transactions(:one).dup - transaction.reference_no = registrar.reference_no - transaction.sum = 250 + if Feature.billing_system_integrated? + registrar = registrars(:bestnames) + transaction = bank_transactions(:one).dup + transaction.reference_no = registrar.reference_no + transaction.sum = 250 - invoice = Invoice.create_from_transaction!(transaction) - assert_equal 250, invoice.total + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator") + .to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) - transaction.sum = 146.88 - invoice = Invoice.create_from_transaction!(transaction) - assert_equal 146.88, invoice.total + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator") + .to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) - transaction.sum = 0.99 - invoice = Invoice.create_from_transaction!(transaction) - assert_equal 0.99, invoice.total + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + + invoice = Invoice.create_from_transaction!(transaction) + assert_equal 250, invoice.total + + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 4}\"}", headers: {}) + + transaction.sum = 146.88 + invoice = Invoice.create_from_transaction!(transaction) + assert_equal 146.88, invoice.total + + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 5}\"}", headers: {}) + + transaction.sum = 0.99 + invoice = Invoice.create_from_transaction!(transaction) + assert_equal 0.99, invoice.total + end end def test_emails_invoice_after_creating_topup_invoice - registrar = registrars(:bestnames) - transaction = bank_transactions(:one).dup - transaction.reference_no = registrar.reference_no - transaction.sum = 250 + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator"). + to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) - assert_emails 1 do - Invoice.create_from_transaction!(transaction) + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + + registrar = registrars(:bestnames) + transaction = bank_transactions(:one).dup + transaction.reference_no = registrar.reference_no + transaction.sum = 250 + + response = OpenStruct.new(body: "{\"invoice_number\":\"#{invoice_n + 3}\"}") + Spy.on(EisBilling::GetInvoiceNumber, :send_invoice).and_return(response) + + assert_emails 1 do + Invoice.create_from_transaction!(transaction) + end end end end diff --git a/test/models/registrar_test.rb b/test/models/registrar_test.rb index 6dbdff3e8..71ebe0fc0 100644 --- a/test/models/registrar_test.rb +++ b/test/models/registrar_test.rb @@ -6,6 +6,7 @@ class RegistrarTest < ActiveJob::TestCase @original_default_language = Setting.default_language @original_days_to_keep_invoices_active = Setting.days_to_keep_invoices_active @old_validation_type = Truemail.configure.default_validation_type + Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) end teardown do @@ -144,23 +145,55 @@ class RegistrarTest < ActiveJob::TestCase end def test_issues_new_invoice - travel_to Time.zone.parse('2010-07-05') - Setting.days_to_keep_invoices_active = 10 + if Feature.billing_system_integrated? + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator"). + to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) - invoice = @registrar.issue_prepayment_invoice(100) + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) - assert_equal Date.parse('2010-07-05'), invoice.issue_date - assert_equal Date.parse('2010-07-15'), invoice.due_date + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + + travel_to Time.zone.parse('2010-07-05') + Setting.days_to_keep_invoices_active = 10 + + invoice = @registrar.issue_prepayment_invoice(100) + + assert_equal Date.parse('2010-07-05'), invoice.issue_date + assert_equal Date.parse('2010-07-15'), invoice.due_date + end end def test_issues_e_invoice_along_with_invoice + if Feature.billing_system_integrated? + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator"). + to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) + + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + end + EInvoice::Providers::TestProvider.deliveries.clear perform_enqueued_jobs do @registrar.issue_prepayment_invoice(100) end - assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count + unless Feature.billing_system_integrated? + assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count + end end def test_invalid_without_address_street diff --git a/test/services/send_data_to_directo_test.rb b/test/services/send_data_to_directo_test.rb new file mode 100644 index 000000000..b853a17f3 --- /dev/null +++ b/test/services/send_data_to_directo_test.rb @@ -0,0 +1,15 @@ +require 'test_helper' + +class SendDataToDirectoTest < ActiveSupport::TestCase + setup do + Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) + end + + def test_should_send_data_to_billing_directo + stub_request(:post, "https://eis_billing_system:3000/api/v1/directo/directo"). + to_return(status: 200, body: "ok", headers: {}) + + res = EisBilling::SendDataToDirecto.send_request(object_data: [], monthly: true, dry: true) + assert_equal res.body, "ok" + end +end diff --git a/test/system/admin_area/bank_statement_test.rb b/test/system/admin_area/bank_statement_test.rb index 1405081e2..f86e6ef53 100644 --- a/test/system/admin_area/bank_statement_test.rb +++ b/test/system/admin_area/bank_statement_test.rb @@ -6,6 +6,7 @@ class AdminAreaBankStatementTest < ApplicationSystemTestCase travel_to Time.zone.parse('2010-07-05 00:30:00') @invoice = invoices(:one) + Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) end def test_update_bank_statement @@ -54,24 +55,39 @@ class AdminAreaBankStatementTest < ApplicationSystemTestCase end def test_can_bind_statement_transactions - registrar = registrars(:bestnames) - registrar.issue_prepayment_invoice(500) - invoice = registrar.invoices.last + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator") + .to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + registrar = registrars(:bestnames) - create_bank_statement - click_link_or_button 'Add' - assert_text 'Create bank transaction' + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator") + .to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) - fill_in 'Description', with: "Invoice with id #{invoice.number}" - fill_in 'Reference number', with: invoice.reference_no - fill_in 'Sum', with: invoice.total - fill_in 'Paid at', with: Time.zone.today.to_s - click_link_or_button 'Save' + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response") + .to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) - click_link_or_button 'Back to bank statement' - click_link_or_button 'Bind invoices' + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice") + .to_return(status: 200, body: "", headers: {}) - assert_text 'Invoices were fully binded' + registrar.issue_prepayment_invoice(500) + invoice = registrar.invoices.last + + create_bank_statement + click_link_or_button 'Add' + assert_text 'Create bank transaction' + + fill_in 'Description', with: "Invoice with id #{invoice.number}" + fill_in 'Reference number', with: invoice.reference_no + fill_in 'Sum', with: invoice.total + fill_in 'Paid at', with: Time.zone.today.to_s + click_link_or_button 'Save' + + click_link_or_button 'Back to bank statement' + click_link_or_button 'Bind invoices' + + assert_text 'Invoices were fully binded' + end end def create_bank_statement diff --git a/test/system/admin_area/invoices_test.rb b/test/system/admin_area/invoices_test.rb index a8d0a8a75..f8cdcc70a 100644 --- a/test/system/admin_area/invoices_test.rb +++ b/test/system/admin_area/invoices_test.rb @@ -11,6 +11,7 @@ class AdminAreaInvoicesTest < ApplicationSystemTestCase end def test_cancels_an_invoice + Spy.on(EisBilling::SendInvoiceStatus, :send_info).and_return(true) @invoice.account_activity = nil assert @invoice.cancellable? diff --git a/test/system/admin_area/registrars_test.rb b/test/system/admin_area/registrars_test.rb index 570517078..757875d1f 100644 --- a/test/system/admin_area/registrars_test.rb +++ b/test/system/admin_area/registrars_test.rb @@ -14,25 +14,30 @@ class AdminRegistrarsSystemTest < ApplicationSystemTestCase end def test_creates_new_registrar - assert_nil Registrar.find_by(name: 'Acme Ltd') + if Feature.billing_system_integrated? + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/reference_number_generator"). + to_return(status: 200, body: "{\"reference_number\":\"12332\"}", headers: {}) - visit admin_registrars_path - click_on 'New registrar' + assert_nil Registrar.find_by(name: 'Acme Ltd') - fill_in 'Name', with: 'Acme Ltd' - fill_in 'Reg no', with: '1234' - fill_in 'Contact e-mail', with: 'any@acme.test' - fill_in 'Street', with: 'any' - fill_in 'City', with: 'any' - fill_in 'State / Province', with: 'any' - fill_in 'Zip', with: 'any' - select 'United States', from: 'Country' - fill_in 'Accounting customer code', with: 'test' - fill_in 'Code', with: 'test' - click_on 'Create registrar' + visit admin_registrars_path + click_on 'New registrar' - assert_text 'Registrar has been successfully created' - assert_text 'Acme Ltd' + fill_in 'Name', with: 'Acme Ltd' + fill_in 'Reg no', with: '1234' + fill_in 'Contact e-mail', with: 'any@acme.test' + fill_in 'Street', with: 'any' + fill_in 'City', with: 'any' + fill_in 'State / Province', with: 'any' + fill_in 'Zip', with: 'any' + select 'United States', from: 'Country' + fill_in 'Accounting customer code', with: 'test' + fill_in 'Code', with: 'test' + click_on 'Create registrar' + + assert_text 'Registrar has been successfully created' + assert_text 'Acme Ltd' + end end def test_updates_registrar diff --git a/test/system/registrar_area/add_deposits_test.rb b/test/system/registrar_area/add_deposits_test.rb new file mode 100644 index 000000000..3ca7691ce --- /dev/null +++ b/test/system/registrar_area/add_deposits_test.rb @@ -0,0 +1,12 @@ +require 'application_system_test_case' + +class AddDepositsTest < ApplicationSystemTestCase + include ActionMailer::TestHelper + + setup do + sign_in users(:api_bestnames) + @invoice = invoices(:one) + + ActionMailer::Base.deliveries.clear + end +end diff --git a/test/system/registrar_area/billing/balance_top_up_test.rb b/test/system/registrar_area/billing/balance_top_up_test.rb index be378df97..5cb32361f 100644 --- a/test/system/registrar_area/billing/balance_top_up_test.rb +++ b/test/system/registrar_area/billing/balance_top_up_test.rb @@ -4,6 +4,10 @@ class BalanceTopUpTest < ApplicationSystemTestCase setup do sign_in users(:api_bestnames) @original_registry_vat_rate = Setting.registry_vat_prc + + eis_response = OpenStruct.new(body: "{\"payment_link\":\"http://link.test\"}") + Spy.on_instance_method(EisBilling::AddDeposits, :send_invoice).and_return(eis_response) + Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) end teardown do @@ -11,20 +15,32 @@ class BalanceTopUpTest < ApplicationSystemTestCase end def test_creates_new_invoice - Setting.registry_vat_prc = 0.1 + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) - visit registrar_invoices_url - click_link_or_button 'Add deposit' - fill_in 'Amount', with: '25.5' + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response") + .to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) - assert_difference 'Invoice.count' do - click_link_or_button 'Add' + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice") + .to_return(status: 200, body: "", headers: {}) + + Setting.registry_vat_prc = 0.1 + + visit registrar_invoices_url + click_link_or_button 'Add deposit' + fill_in 'Amount', with: '25.5' + + assert_difference 'Invoice.count' do + click_link_or_button 'Add' + end + + invoice = Invoice.last + + assert_equal BigDecimal(10), invoice.vat_rate + assert_equal BigDecimal('28.05'), invoice.total + assert_text 'Please pay the following invoice' end - - invoice = Invoice.last - - assert_equal BigDecimal(10), invoice.vat_rate - assert_equal BigDecimal('28.05'), invoice.total - assert_text 'Please pay the following invoice' end end diff --git a/test/system/registrar_area/invoices/new_invoice_payment_test.rb b/test/system/registrar_area/invoices/new_invoice_payment_test.rb index ea4b924fe..77050f12a 100644 --- a/test/system/registrar_area/invoices/new_invoice_payment_test.rb +++ b/test/system/registrar_area/invoices/new_invoice_payment_test.rb @@ -3,6 +3,8 @@ require 'application_system_test_case' class NewInvoicePaymentTest < ApplicationSystemTestCase def setup super + eis_response = OpenStruct.new(body: "{\"payment_link\":\"http://link.test\"}") + Spy.on_instance_method(EisBilling::AddDeposits, :send_invoice).and_return(eis_response) @original_vat_prc = Setting.registry_vat_prc Setting.registry_vat_prc = 0.2 @@ -23,26 +25,4 @@ class NewInvoicePaymentTest < ApplicationSystemTestCase fill_in 'Description', with: 'My first invoice' click_link_or_button 'Add' end - - def test_create_new_SEB_payment - create_invoice_and_visit_its_page - click_link_or_button 'seb' - form = page.find('form') - assert_equal('https://www.seb.ee/cgi-bin/dv.sh/ipank.r', form['action']) - assert_equal('post', form['method']) - assert_equal('240.00', form.find_by_id('VK_AMOUNT', visible: false).value) - end - - def test_create_new_Every_Pay_payment - create_invoice_and_visit_its_page - click_link_or_button 'every_pay' - expected_hmac_fields = 'account_id,amount,api_username,callback_url,' + - 'customer_url,hmac_fields,nonce,order_reference,timestamp,transaction_type' - - form = page.find('form') - assert_equal('https://igw-demo.every-pay.com/transactions/', form['action']) - assert_equal('post', form['method']) - assert_equal(expected_hmac_fields, form.find_by_id('hmac_fields', visible: false).value) - assert_equal('240.00', form.find_by_id('amount', visible: false).value) - end end diff --git a/test/system/registrar_area/invoices/new_test.rb b/test/system/registrar_area/invoices/new_test.rb index 26ab34385..a1b66ac47 100644 --- a/test/system/registrar_area/invoices/new_test.rb +++ b/test/system/registrar_area/invoices/new_test.rb @@ -6,6 +6,9 @@ class NewInvoiceTest < ApplicationSystemTestCase @user = users(:api_bestnames) sign_in @user + + eis_response = OpenStruct.new(body: "{\"payment_link\":\"http://link.test\"}") + Spy.on_instance_method(EisBilling::AddDeposits, :send_invoice).and_return(eis_response) end def test_show_balance @@ -14,35 +17,59 @@ class NewInvoiceTest < ApplicationSystemTestCase end def test_create_new_invoice_with_positive_amount - visit registrar_invoices_path - click_link_or_button 'Add deposit' - fill_in 'Amount', with: '200.00' - fill_in 'Description', with: 'My first invoice' + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) - assert_difference 'Invoice.count', 1 do - click_link_or_button 'Add' + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + + visit registrar_invoices_path + click_link_or_button 'Add deposit' + fill_in 'Amount', with: '200.00' + fill_in 'Description', with: 'My first invoice' + + assert_difference 'Invoice.count', 1 do + click_link_or_button 'Add' + end + + assert_text 'Please pay the following invoice' + assert_text "Invoice no. #{invoice_n + 3}" + assert_text 'Subtotal 200,00 €' + assert_text 'Pay invoice' end - - assert_text 'Please pay the following invoice' - assert_text 'Invoice no. 131050' - assert_text 'Subtotal 200,00 €' - assert_text 'Pay invoice' end def test_create_new_invoice_with_comma_in_number - visit registrar_invoices_path - click_link_or_button 'Add deposit' - fill_in 'Amount', with: '200,00' - fill_in 'Description', with: 'My first invoice' + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) - assert_difference 'Invoice.count', 1 do - click_link_or_button 'Add' + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + + visit registrar_invoices_path + click_link_or_button 'Add deposit' + fill_in 'Amount', with: '200,00' + fill_in 'Description', with: 'My first invoice' + + assert_difference 'Invoice.count', 1 do + click_link_or_button 'Add' + end + + assert_text 'Please pay the following invoice' + assert_text "Invoice no. #{invoice_n + 3}" + assert_text 'Subtotal 200,00 €' + assert_text 'Pay invoice' end - - assert_text 'Please pay the following invoice' - assert_text 'Invoice no. 131050' - assert_text 'Subtotal 200,00 €' - assert_text 'Pay invoice' end def test_create_new_invoice_fails_when_amount_is_0 diff --git a/test/system/registrar_area/invoices_test.rb b/test/system/registrar_area/invoices_test.rb index e64204165..1c6d1d780 100644 --- a/test/system/registrar_area/invoices_test.rb +++ b/test/system/registrar_area/invoices_test.rb @@ -8,9 +8,13 @@ class RegistrarAreaInvoicesTest < ApplicationSystemTestCase @invoice = invoices(:one) ActionMailer::Base.deliveries.clear + eis_response = OpenStruct.new(body: "{\"payment_link\":\"http://link.test\"}") + Spy.on_instance_method(EisBilling::AddDeposits, :send_invoice).and_return(eis_response) end def test_cancels_an_invoice + Spy.on(EisBilling::SendInvoiceStatus, :send_info).and_return(true) + @invoice.account_activity = nil assert @invoice.cancellable? @@ -40,4 +44,18 @@ class RegistrarAreaInvoicesTest < ApplicationSystemTestCase assert_current_path registrar_invoice_path(@invoice) assert_text 'Invoice has been sent' end -end \ No newline at end of file + + def test_if_invoice_unpaid_and_not_generated_link_comes_then_should_render_no_everypay_link + invoice = invoices(:unpaid) + visit registrar_invoice_url(invoice) + + assert_text 'No everypay link' + end + + def test_if_invoice_aldready_paid_there_should_not_any_everypay_link + visit registrar_invoice_url(@invoice) + + assert_no_text 'No everypay link' + assert_no_text 'Everypay link' + end +end diff --git a/test/tasks/invoices/process_payments_test.rb b/test/tasks/invoices/process_payments_test.rb index a078dfec1..e368c5369 100644 --- a/test/tasks/invoices/process_payments_test.rb +++ b/test/tasks/invoices/process_payments_test.rb @@ -77,15 +77,33 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase end def test_if_invoice_is_overdue_than_48_hours - assert_not @invoice.paid? + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number - @account_activity.update(activity_type: "add_credit", bank_transaction: nil, created_at: Time.zone.today - 3.days, creator_str: 'AdminUser') - @invoice.update(account_activity: @account_activity, total: @payment_amount) - assert @invoice.paid? + Spy.on_instance_method(SendEInvoiceTwoJob, :perform_now).and_return(true) - assert_difference 'AccountActivity.count' do - assert_difference 'Invoice.count' do - capture_io { run_task } + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator"). + to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) + + assert_not @invoice.paid? + + @account_activity.update(activity_type: "add_credit", bank_transaction: nil, created_at: Time.zone.today - 3.days, creator_str: 'AdminUser') + @invoice.update(account_activity: @account_activity, total: @payment_amount) + assert @invoice.paid? + + assert_difference 'AccountActivity.count' do + assert_difference 'Invoice.count' do + capture_io { run_task } + end end end end @@ -143,15 +161,32 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase assert payment_order.failed? end - def test_credits_registrar_account_without_invoice_beforehand - registrar = registrars(:bestnames) + def test_credits_registrar_athout_invoice_beforehand + if Feature.billing_system_integrated? + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}") - assert_changes -> { registrar.accounts.first.balance } do - run_task - end + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator"). + to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) - assert_changes -> { registrar.invoices.count } do - run_task + Spy.on_instance_method(SendEInvoiceTwoJob, :perform_now).and_return(true) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + registrar = registrars(:bestnames) + + assert_changes -> { registrar.accounts.first.balance } do + run_task + end + + assert_changes -> { registrar.invoices.count } do + run_task + end end end @@ -163,25 +198,40 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase end def test_topup_creates_invoice_and_send_it_as_paid - registrar = registrars(:bestnames) - @invoice.payment_orders.destroy_all - @invoice.destroy + if Feature.billing_system_integrated? + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) - perform_enqueued_jobs do - run_task + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator"). + to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) + + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + registrar = registrars(:bestnames) + @invoice.payment_orders.destroy_all + @invoice.destroy + + perform_enqueued_jobs do + run_task + end + + invoice = Invoice.last + assert invoice.paid? + assert_not invoice.e_invoice_sent_at.blank? + + pdf_source = Invoice::PdfGenerator.new(invoice) + pdf_source.send(:invoice_html).include?('Receipt date') + + email= ActionMailer::Base.deliveries.last + assert email.subject.include?('already paid') + + assert_equal 0.1, registrar.invoices.last.total end - - invoice = Invoice.last - assert invoice.paid? - assert_not invoice.e_invoice_sent_at.blank? - - pdf_source = Invoice::PdfGenerator.new(invoice) - pdf_source.send(:invoice_html).include?('Receipt date') - - email= ActionMailer::Base.deliveries.last - assert email.subject.include?('already paid') - - assert_equal 0.1, registrar.invoices.last.total end def test_output diff --git a/test/tasks/registrars/reload_balance_test.rb b/test/tasks/registrars/reload_balance_test.rb index 0c14f95c9..0888fe3f4 100644 --- a/test/tasks/registrars/reload_balance_test.rb +++ b/test/tasks/registrars/reload_balance_test.rb @@ -5,6 +5,7 @@ class ReloadBalanceTaskTest < ActiveSupport::TestCase setup do @registrar = registrars(:bestnames) + Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) end def test_issues_invoice_when_auto_reload_is_enabled_and_threshold_reached @@ -20,15 +21,30 @@ class ReloadBalanceTaskTest < ActiveSupport::TestCase end def test_issues_invoice_when_auto_reload_is_enabled_and_threshold_reached - reload_amount = 100 - registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount) + if Feature.billing_system_integrated? + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator"). + to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) - assert_difference -> { registrar.invoices.count } do - capture_io { run_task } + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + + reload_amount = 100 + registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount) + + assert_difference -> { registrar.invoices.count } do + capture_io { run_task } + end + + invoice = registrar.invoices.last + assert_equal Time.zone.today, invoice.e_invoice_sent_at.to_date end - - invoice = registrar.invoices.last - assert_equal Time.zone.today, invoice.e_invoice_sent_at.to_date end def test_skips_issuing_invoice_when_threshold_is_not_reached @@ -50,21 +66,51 @@ class ReloadBalanceTaskTest < ActiveSupport::TestCase end def test_marks_registrar_as_pending_balance_reload - registrar = registrar_with_auto_reload_enabled_and_threshold_reached + if Feature.billing_system_integrated? + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator"). + to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) - capture_io { run_task } - registrar.reload + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) - assert registrar.settings['balance_auto_reload']['pending'] + registrar = registrar_with_auto_reload_enabled_and_threshold_reached + + capture_io { run_task } + registrar.reload + + assert registrar.settings['balance_auto_reload']['pending'] + end end def test_output - reload_amount = 100 - registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount) - assert_equal 'Best Names', registrar.name + if Feature.billing_system_integrated? + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator"). + to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) - assert_output %(Registrar "Best Names" got #{number_to_currency(reload_amount, unit: 'EUR')}\nInvoiced total: 1\n) do - run_task + invoice_n = Invoice.order(number: :desc).last.number + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}", headers: {}) + + stub_request(:put, "https://registry:3000/eis_billing/e_invoice_response"). + to_return(status: 200, body: "{\"invoice_number\":\"#{invoice_n + 3}\"}, {\"date\":\"#{Time.zone.now-10.minutes}\"}", headers: {}) + + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) + + reload_amount = 100 + registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount) + assert_equal 'Best Names', registrar.name + + assert_output %(Registrar "Best Names" got #{number_to_currency(reload_amount, unit: 'EUR')}\nInvoiced total: 1\n) do + run_task + end end end