diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 5d181dbc0..f4498f4da 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -6,7 +6,7 @@ jobs: test: services: postgres: - image: postgres:12 + image: postgres:14 ports: ["5432:5432"] env: POSTGRES_PASSWORD: password diff --git a/CHANGELOG.md b/CHANGELOG.md index 739854c16..a9b96159e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +08.09.2022 +* Fixed template error for multi-year registered domains in force delete process [#2435](https://github.com/internetee/registry/issues/2435) + +02.09.2022 +* Update invoice status on payment order payments [#2427](https://github.com/internetee/registry/pull/2427) + +01.09.2022 +* Monthly invoice payment status fix [#2428](https://github.com/internetee/registry/issues/2428) + +31.08.2022 +* new fully automated process for registrar monthly invoices [#2424](https://github.com/internetee/registry/pull/2424) + +25.08.2022 +* Contact creation fix to not require postal addresses in Registrar portal [#2421](https://github.com/internetee/registry/pull/2421) + +23.08.2022 +* REPP update to fix search by registrant in Registrar portal [#2425](https://github.com/internetee/registry/pull/2425) + 21.07.2022 * Removed deprecated statuses_before_force_delete field [#2363](https://github.com/internetee/registry/issues/2363) diff --git a/Gemfile b/Gemfile index b8d2b4c38..1c12fe666 100644 --- a/Gemfile +++ b/Gemfile @@ -17,11 +17,11 @@ gem 'figaro', '~> 1.2' # model related gem 'paper_trail', '~> 12.1' -gem 'pg', '1.4.2' +gem 'pg', '1.4.3' # 1.8 is for Rails < 5.0 gem 'ransack', '~> 2.6.0' gem 'truemail', '~> 2.4' # validates email by regexp, mail server existence and address existence -gem 'validates_email_format_of', '1.6.3' # validates email against RFC 2822 and RFC 3696 +gem 'validates_email_format_of', '1.7.2' # 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 # https://github.com/huacnlee/rails-settings-cached/issues/165 diff --git a/Gemfile.lock b/Gemfile.lock index 0ba400459..fb51d2bf1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,10 +18,10 @@ GIT GIT remote: https://github.com/internetee/e_invoice.git - revision: 312cac173935f434e449d1714f3497bfee9f8995 + revision: 9f850465697a2448a31ebddb83c1be5a5a9be3d2 branch: master specs: - e_invoice (0.1.0) + e_invoice (0.1.3) builder (~> 3.2) nokogiri savon @@ -259,7 +259,7 @@ GEM httpi (2.4.5) rack socksify - i18n (1.10.0) + i18n (1.12.0) concurrent-ruby (~> 1.0) i18n_data (0.13.0) isikukood (0.1.2) @@ -291,7 +291,7 @@ GEM kaminari-core (1.2.1) libxml-ruby (3.2.1) logger (1.4.3) - loofah (2.16.0) + loofah (2.18.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) @@ -353,7 +353,7 @@ GEM activerecord (>= 5.2) request_store (~> 1.1) pdfkit (0.8.5) - pg (1.4.2) + pg (1.4.3) pg_query (2.1.2) google-protobuf (>= 3.17.1) pghero (2.8.1) @@ -399,7 +399,7 @@ GEM rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.4.2) + rails-html-sanitizer (1.4.3) loofah (~> 2.3) railties (6.1.4.1) actionpack (= 6.1.4.1) @@ -499,7 +499,7 @@ GEM validate_url (1.0.15) activemodel (>= 3.0.0) public_suffix - validates_email_format_of (1.6.3) + validates_email_format_of (1.7.2) i18n warden (1.2.9) rack (>= 2.0.9) @@ -576,7 +576,7 @@ DEPENDENCIES omniauth-tara! paper_trail (~> 12.1) pdfkit - pg (= 1.4.2) + pg (= 1.4.3) pg_query (>= 0.9.0) pghero pry (= 0.14.1) @@ -596,11 +596,11 @@ DEPENDENCIES spy truemail (~> 2.4) uglifier - validates_email_format_of (= 1.6.3) + validates_email_format_of (= 1.7.2) webdrivers webmock whenever (= 1.0.0) wkhtmltopdf-binary (~> 0.12.5.1) BUNDLED WITH - 2.3.16 + 2.3.21 diff --git a/app/controllers/admin/invoices_controller.rb b/app/controllers/admin/invoices_controller.rb index caf1e3a95..a4ba97310 100644 --- a/app/controllers/admin/invoices_controller.rb +++ b/app/controllers/admin/invoices_controller.rb @@ -81,18 +81,24 @@ module Admin payment_order.update(notes: 'Cancelled') end + # rubocop:disable Metrics/MethodLength def filter_by_status case params[:status] when 'Paid' Invoice.includes(:account_activity, :buyer).where.not(account_activity: { id: nil }) when 'Unpaid' - Invoice.includes(:account_activity, :buyer).where(account_activity: { id: nil }) + Invoice.includes(:account_activity, :buyer).where(account_activity: { id: nil }, + cancelled_at: nil, + monthly_invoice: false) when 'Cancelled' Invoice.includes(:account_activity, :buyer).where.not(cancelled_at: nil) + when 'Monthly' + Invoice.where(monthly_invoice: true, cancelled_at: nil) else Invoice.includes(:account_activity, :buyer) end end + # rubocop:enable Metrics/MethodLength def filter_by_receipt_date(invoices) date_from_param = params[:q][:receipt_date_gteq] if params[:q][:receipt_date_gteq].present? diff --git a/app/controllers/eis_billing/base_controller.rb b/app/controllers/eis_billing/base_controller.rb index a475472b9..ad2b71f3a 100644 --- a/app/controllers/eis_billing/base_controller.rb +++ b/app/controllers/eis_billing/base_controller.rb @@ -3,7 +3,6 @@ module EisBilling 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 @@ -49,11 +48,5 @@ module EisBilling 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/lhv_connect_transactions_controller.rb b/app/controllers/eis_billing/lhv_connect_transactions_controller.rb index 09688e68f..2e5996881 100644 --- a/app/controllers/eis_billing/lhv_connect_transactions_controller.rb +++ b/app/controllers/eis_billing/lhv_connect_transactions_controller.rb @@ -1,8 +1,16 @@ module EisBilling class LhvConnectTransactionsController < EisBilling::BaseController def create + if params['_json'].nil? || params['_json'].empty? + render json: { message: 'MISSING PARAMS' }, status: :unprocessable_entity + return + end + + bank_statement = BankStatement.create(bank_code: Setting.registry_bank_code, + iban: Setting.registry_iban) + params['_json'].each do |incoming_transaction| - process_transactions(incoming_transaction) + process_transactions(incoming_transaction, bank_statement) end render status: :ok, json: { message: 'RECEIVED', params: params } @@ -10,19 +18,13 @@ module EisBilling private - def process_transactions(incoming_transaction) + def process_transactions(incoming_transaction, bank_statement) 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) + transaction = bank_statement.bank_transactions + .create!(transaction_attributes(incoming_transaction)) next if transaction.registrar.blank? @@ -32,17 +34,21 @@ module EisBilling def create_invoice_if_missing(transaction) Invoice.create_from_transaction!(transaction) unless transaction.autobindable? - transaction.autobind_invoice + invoice = transaction.autobind_invoice + return unless invoice.paid? + + EisBilling::SendInvoiceStatus.send_info(invoice_number: invoice.number, + status: 'paid') 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) + def transaction_attributes(incoming_transaction) + { + 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'], + } end end end diff --git a/app/controllers/eis_billing/payment_status_controller.rb b/app/controllers/eis_billing/payment_status_controller.rb index cb8e70803..4fa626e5d 100644 --- a/app/controllers/eis_billing/payment_status_controller.rb +++ b/app/controllers/eis_billing/payment_status_controller.rb @@ -5,6 +5,9 @@ module EisBilling def update payment_status = define_payment_status(params[:payment_state]) invoice = Invoice.find_by(number: params[:order_reference]) + + return if invoice.paid? + 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) diff --git a/app/controllers/repp/v1/base_controller.rb b/app/controllers/repp/v1/base_controller.rb index 10c3c6026..d84c8e37b 100644 --- a/app/controllers/repp/v1/base_controller.rb +++ b/app/controllers/repp/v1/base_controller.rb @@ -163,6 +163,7 @@ module Repp data = current_user.as_json(only: %i[id username roles]) data[:registrar_name] = registrar.name data[:legaldoc_mandatory] = registrar.legaldoc_mandatory? + data[:address_processing] = Contact.address_processing? data[:abilities] = Ability.new(current_user).permissions data end diff --git a/app/controllers/repp/v1/contacts_controller.rb b/app/controllers/repp/v1/contacts_controller.rb index 31be5e09b..6f5e79a64 100644 --- a/app/controllers/repp/v1/contacts_controller.rb +++ b/app/controllers/repp/v1/contacts_controller.rb @@ -193,7 +193,7 @@ module Repp def contact_create_params(required: true) create_params = %i[name email phone] contact_params.require(create_params) if required - contact_params.slice(*create_params) + contact_params.slice(:id, *create_params) end def contact_ident_params(required: true) @@ -211,7 +211,7 @@ module Repp end def contact_params - params.require(:contact).permit(:name, :email, :phone, :legal_document, + params.require(:contact).permit(:id, :name, :email, :phone, :legal_document, legal_document: %i[body type], ident: [%i[ident ident_type ident_country_code]], addr: [%i[country_code city street zip state]]) diff --git a/app/controllers/repp/v1/domains_controller.rb b/app/controllers/repp/v1/domains_controller.rb index 29b259a67..05f1e2c95 100644 --- a/app/controllers/repp/v1/domains_controller.rb +++ b/app/controllers/repp/v1/domains_controller.rb @@ -12,14 +12,14 @@ module Repp desc 'Get all existing domains' def index authorize! :info, Epp::Domain - records = current_user.registrar.domains + records = current_user.registrar.domains.includes(:registrar, :registrant) q = records.ransack(PartialSearchFormatter.format(search_params)) q.sorts = ['valid_to asc', 'created_at desc'] if q.sorts.empty? # use distinct: false here due to ransack bug: # https://github.com/activerecord-hackery/ransack/issues/429 domains = q.result(distinct: false) - limited_domains = domains.limit(limit).offset(offset).includes(:registrar, :registrant) + limited_domains = domains.limit(limit).offset(offset) render_success(data: { new_domain: records.any? ? serialized_domains([records.last]) : [], domains: serialized_domains(limited_domains.to_a.uniq), @@ -238,7 +238,7 @@ module Repp def index_params params.permit(:limit, :offset, :details, :simple, :q, - q: %i[s name_matches registrant_id_eq contacts_ident_eq + q: %i[s name_matches registrant_code_eq contacts_ident_eq nameservers_hostname_eq valid_to_gteq valid_to_lteq statuses_contains_array] + [s: []]) end diff --git a/app/controllers/repp/v1/invoices_controller.rb b/app/controllers/repp/v1/invoices_controller.rb index 204aba096..2d4340b3e 100644 --- a/app/controllers/repp/v1/invoices_controller.rb +++ b/app/controllers/repp/v1/invoices_controller.rb @@ -97,6 +97,7 @@ module Repp account_activity_id_not_null account_activity_id_null cancelled_at_null cancelled_at_not_null number_gteq number_lteq + monthly_invoice_true monthly_invoice_false total_gteq total_lteq s] + [s: []]) end diff --git a/app/interactions/domains/force_delete/notify_registrar.rb b/app/interactions/domains/force_delete/notify_registrar.rb index 25d59bf29..9cb91277d 100644 --- a/app/interactions/domains/force_delete/notify_registrar.rb +++ b/app/interactions/domains/force_delete/notify_registrar.rb @@ -11,7 +11,7 @@ module Domains outzone_date: domain.outzone_date, purge_date: domain.purge_date) - return if domain.registrar.notifications.last.text.include? template + return if domain.registrar&.notifications&.last&.text&.include? template domain.registrar.notifications.create!(text: template) end @@ -23,7 +23,7 @@ module Domains purge_date: domain.purge_date, email: email) - return if domain.registrar.notifications.last.text.include? template + return if domain.registrar&.notifications&.last&.text&.include? template domain.registrar.notifications.create!(text: template) end diff --git a/app/jobs/delete_monthly_invoices_job.rb b/app/jobs/delete_monthly_invoices_job.rb new file mode 100644 index 000000000..daf79827a --- /dev/null +++ b/app/jobs/delete_monthly_invoices_job.rb @@ -0,0 +1,10 @@ +class DeleteMonthlyInvoicesJob < ApplicationJob + queue_as :default + + def perform + @month = Time.zone.now - 1.month + invoices = Invoice.where(monthly_invoice: true, issue_date: @month.end_of_month.to_date, + in_directo: false, e_invoice_sent_at: nil) + invoices.delete_all + end +end diff --git a/app/jobs/directo_invoice_forward_job.rb b/app/jobs/directo_invoice_forward_job.rb index 04da1a424..28a06007a 100644 --- a/app/jobs/directo_invoice_forward_job.rb +++ b/app/jobs/directo_invoice_forward_job.rb @@ -1,60 +1,31 @@ class DirectoInvoiceForwardJob < ApplicationJob def perform(monthly: false, dry: false) - @dry = dry - (@month = Time.zone.now - 1.month) if monthly + data = nil - @client = new_directo_client - monthly ? send_monthly_invoices : send_receipts + 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 new_directo_client - DirectoApi::Client.new(ENV['directo_invoice_url'], Setting.directo_sales_agent, - Setting.directo_receipt_payment_term) - end - - def send_receipts + def collect_receipts_data unsent_invoices = Invoice.where(in_directo: false).non_cancelled + collected_data = [] - 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') + collected_data << invoice.as_directo_json end - sync_with_directo - end - - def send_monthly_invoices - Registrar.where.not(test_registrar: true).find_each do |registrar| - next unless registrar.cash_account - - @client = new_directo_client - send_invoice_for_registrar(registrar) - end - end - - def send_invoice_for_registrar(registrar) - summary = registrar.monthly_summary(month: @month) - @client.invoices.add_with_schema(invoice: summary, schema: 'summary') unless summary.nil? - - sync_with_directo if @client.invoices.count.positive? - end - - def assign_monthly_numbers - raise 'Directo Counter is going to be out of period!' if directo_counter_exceedable?(@client.invoices.count) - - 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 + collected_data end def valid_invoice_conditions?(invoice) @@ -68,29 +39,17 @@ class DirectoInvoiceForwardJob < ApplicationJob true end - def sync_with_directo - assign_monthly_numbers if @month + def collect_monthly_data + registrars_data = [] - Rails.logger.info("[Directo] - attempting to send following XML:\n #{@client.invoices.as_xml}") - return if @dry - - res = @client.invoices.deliver(ssl_verify: false) - 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 process_directo_response(xml, req) - Rails.logger.info "[Directo] - Responded with body: #{xml}" - Nokogiri::XML(xml).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 + 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:) diff --git a/app/jobs/directo_invoice_forward_legacy_job.rb b/app/jobs/directo_invoice_forward_legacy_job.rb new file mode 100644 index 000000000..5534b3c9b --- /dev/null +++ b/app/jobs/directo_invoice_forward_legacy_job.rb @@ -0,0 +1,125 @@ +class DirectoInvoiceForwardLegacyJob < ApplicationJob + def perform(monthly: false, dry: false) + @dry = dry + (@month = Time.zone.now - 1.month) if monthly + + @client = new_directo_client + monthly ? send_monthly_invoices : send_receipts + end + + def new_directo_client + DirectoApi::Client.new(ENV['directo_invoice_url'], Setting.directo_sales_agent, + Setting.directo_receipt_payment_term) + 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 + Registrar.where.not(test_registrar: true).find_each do |registrar| + next unless registrar.cash_account + + @client = new_directo_client + send_invoice_for_registrar(registrar) + end + end + + def send_invoice_for_registrar(registrar) + summary = registrar.monthly_summary(month: @month) + @client.invoices.add_with_schema(invoice: summary, schema: 'summary') unless summary.nil? + + sync_with_directo if @client.invoices.count.positive? + end + + def assign_monthly_numbers + raise 'Directo Counter is going to be out of period!' if directo_counter_exceedable?(@client.invoices.count) + + 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? || + invoice.account_activity.bank_transaction.sum != invoice.total + return false + + end + + true + 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 + + res = @client.invoices.deliver(ssl_verify: false) + 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 process_directo_response(xml, req) + Rails.logger.info "[Directo] - Responded with body: #{xml}" + Nokogiri::XML(xml).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) + 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/directo_invoice_forward_two_job.rb b/app/jobs/directo_invoice_forward_two_job.rb deleted file mode 100644 index e0d8d946b..000000000 --- a/app/jobs/directo_invoice_forward_two_job.rb +++ /dev/null @@ -1,84 +0,0 @@ -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_job.rb b/app/jobs/send_e_invoice_job.rb index 33a2745c6..02cad898c 100644 --- a/app/jobs/send_e_invoice_job.rb +++ b/app/jobs/send_e_invoice_job.rb @@ -6,7 +6,8 @@ class SendEInvoiceJob < ApplicationJob invoice = Invoice.find_by(id: invoice_id) return unless need_to_process_invoice?(invoice: invoice, payable: payable) - process(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 @@ -22,16 +23,9 @@ class SendEInvoiceJob < ApplicationJob true end - def process(invoice:, payable:) - invoice.to_e_invoice(payable: payable).deliver unless Rails.env.development? - invoice.update(e_invoice_sent_at: Time.zone.now) - log_success(invoice) - end - - def log_success(invoice) - id = invoice.try(:id) || invoice - message = "E-Invoice for an invoice with ID # #{id} was sent successfully" - logger.info message + 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:) diff --git a/app/jobs/send_e_invoice_two_job.rb b/app/jobs/send_e_invoice_legacy_job.rb similarity index 64% rename from app/jobs/send_e_invoice_two_job.rb rename to app/jobs/send_e_invoice_legacy_job.rb index bb8f993ca..d9220388b 100644 --- a/app/jobs/send_e_invoice_two_job.rb +++ b/app/jobs/send_e_invoice_legacy_job.rb @@ -1,4 +1,4 @@ -class SendEInvoiceTwoJob < ApplicationJob +class SendEInvoiceLegacyJob < ApplicationJob discard_on HTTPClient::TimeoutError def perform(invoice_id, payable: true) @@ -6,8 +6,7 @@ class SendEInvoiceTwoJob < ApplicationJob 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) + process(invoice: invoice, payable: payable) rescue StandardError => e log_error(invoice: invoice, error: e) raise e @@ -17,15 +16,23 @@ class SendEInvoiceTwoJob < ApplicationJob def need_to_process_invoice?(invoice:, payable:) logger.info "Checking if need to process e-invoice #{invoice}, payable: #{payable}" + unprocessable = invoice.do_not_send_e_invoice? && (invoice.monthly_invoice ? true : payable) return false if invoice.blank? - return false if invoice.do_not_send_e_invoice? && payable + return false if unprocessable true end - def send_invoice_to_eis_billing(invoice:, payable:) - result = EisBilling::SendEInvoice.send_request(invoice: invoice, payable: payable) - logger.info result.body + def process(invoice:, payable:) + invoice.to_e_invoice(payable: payable).deliver unless Rails.env.development? + invoice.update(e_invoice_sent_at: Time.zone.now) + log_success(invoice) + end + + def log_success(invoice) + 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:) diff --git a/app/jobs/send_monthly_invoices_job.rb b/app/jobs/send_monthly_invoices_job.rb new file mode 100644 index 000000000..af37b156e --- /dev/null +++ b/app/jobs/send_monthly_invoices_job.rb @@ -0,0 +1,147 @@ +class SendMonthlyInvoicesJob < ApplicationJob # rubocop:disable Metrics/ClassLength + queue_as :default + + def perform(dry: false) + @dry = dry + @month = Time.zone.now - 1.month + @directo_client = new_directo_client + @min_directo_num = Setting.directo_monthly_number_min.presence.try(:to_i) + @max_directo_num = Setting.directo_monthly_number_max.presence.try(:to_i) + + send_monthly_invoices + end + + def new_directo_client + DirectoApi::Client.new(ENV['directo_invoice_url'], Setting.directo_sales_agent, + Setting.directo_receipt_payment_term) + end + + # rubocop:disable Metrics/MethodLength + def send_monthly_invoices + Registrar.with_cash_accounts.find_each do |registrar| + summary = registrar.monthly_summary(month: @month) + next if summary.nil? + + invoice = registrar.monthly_invoice(month: @month) || create_invoice(summary, registrar) + next if invoice.nil? || @dry + + send_email_to_registrar(invoice: invoice, registrar: registrar) + send_e_invoice(invoice.id) + next if invoice.in_directo + + Rails.logger.info("[DIRECTO] Trying to send monthly invoice #{invoice.number}") + @directo_client = new_directo_client + directo_invoices = @directo_client.invoices.add_with_schema(invoice: summary, + schema: 'summary') + next unless directo_invoices.size.positive? + + directo_invoices.last.number = invoice.number + sync_with_directo + end + end + + # rubocop:enable Metrics/MethodLength + + def send_email_to_registrar(invoice:, registrar:) + InvoiceMailer.invoice_email(invoice: invoice, + recipient: registrar.billing_email) + .deliver_now + end + + def send_e_invoice(invoice_id) + SendEInvoiceLegacyJob.set(wait: 1.minute).perform_later(invoice_id, payable: false) + end + + def create_invoice(summary, registrar) + invoice = registrar.init_monthly_invoice(normalize(summary)) + invoice.number = assign_monthly_number + return unless invoice.save! + + update_monthly_invoice_number(num: invoice.number) + invoice + end + + def sync_with_directo + invoices_xml = @directo_client.invoices.as_xml + + Rails.logger.info("[Directo] - attempting to send following XML:\n #{invoices_xml}") + + res = @directo_client.invoices.deliver(ssl_verify: false) + process_directo_response(res.body, invoices_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 assign_monthly_number + last_directo_num = [Setting.directo_monthly_number_last.presence.try(:to_i), + @min_directo_num].compact.max || 0 + raise 'Directo Counter is out of period!' if directo_counter_exceedable?(1, last_directo_num) + + last_directo_num + 1 + end + + def directo_counter_exceedable?(invoices_count, last_directo_num) + return true if @max_directo_num && @max_directo_num < (last_directo_num + invoices_count) + + false + end + + def process_directo_response(body, req) + Rails.logger.info "[Directo] - Responded with body: #{body}" + Nokogiri::XML(body).css('Result').each do |res| + inv = Invoice.find_by(number: res.attributes['docid'].value.to_i) + mark_invoice_as_sent_to_directo(res: res, req: req, invoice: inv) + end + end + + def mark_invoice_as_sent_to_directo(res:, req:, invoice: nil) + directo_record = Directo.new(response: res.as_json.to_h, + request: req, invoice_number: res.attributes['docid'].value.to_i) + directo_record.item = invoice + invoice.update(in_directo: true) + + directo_record.save! + end + + def update_monthly_invoice_number(num:) + return unless num.to_i > Setting.directo_monthly_number_last.to_i + + Setting.directo_monthly_number_last = num.to_i + end + + private + + # rubocop:disable Metrics/MethodLength + def normalize(summary, lines: []) + sum = summary.dup + line_map = Hash.new 0 + sum['invoice_lines'].each { |l| line_map[l] += 1 } + + line_map.each_key do |count| + count['quantity'] = line_map[count] unless count['unit'].nil? + regex = /Domeenide ettemaks|Domains prepayment/ + count['quantity'] = -1 if count['description'].match?(regex) + lines << count + end + + sum['invoice_lines'] = summarize_lines(lines) + sum + end + # rubocop:enable Metrics/MethodLength + + def summarize_lines(invoice_lines, lines: []) + line_map = Hash.new 0 + invoice_lines.each do |l| + hash = l.with_indifferent_access.except(:start_date, :end_date) + line_map[hash] += 1 + end + + line_map.each_key do |count| + count['price'] = (line_map[count] * count['price'].to_f).round(3) unless count['price'].nil? + lines << count + end + + lines + end +end diff --git a/app/mailers/invoice_mailer.rb b/app/mailers/invoice_mailer.rb index a9d544d63..95b7fefd6 100644 --- a/app/mailers/invoice_mailer.rb +++ b/app/mailers/invoice_mailer.rb @@ -4,6 +4,7 @@ class InvoiceMailer < ApplicationMailer subject = default_i18n_subject(invoice_number: invoice.number) subject << I18n.t('invoice.already_paid') if paid + subject << I18n.t('invoice.monthly_invoice') if invoice.monthly_invoice attachments["invoice-#{invoice.number}.pdf"] = invoice.as_pdf mail(to: recipient, subject: subject) end diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index 68b48995f..ef2ab3370 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -33,10 +33,10 @@ class BankTransaction < ApplicationRecord return unless autobindable? channel = manual ? 'admin_payment' : 'system_payment' - create_internal_payment_record(channel: channel, invoice: invoice, registrar: registrar) + create_internal_payment_record(invoice: invoice, registrar: registrar, channel: channel) end - def create_internal_payment_record(channel: nil, invoice:, registrar:) + def create_internal_payment_record(invoice:, registrar:, channel: nil) if channel.nil? create_activity(invoice.buyer, invoice) return @@ -47,9 +47,12 @@ class BankTransaction < ApplicationRecord if create_activity(registrar, invoice) payment_order.paid! + EisBilling::SendInvoiceStatus.send_info(invoice_number: invoice.number, + status: 'paid') else payment_order.update(notes: 'Failed to create activity', status: 'failed') end + invoice end def bind_invoice(invoice_no, manual: false) @@ -62,8 +65,8 @@ class BankTransaction < ApplicationRecord validate_invoice_data(invoice) return if errors.any? - create_internal_payment_record(channel: (manual ? 'admin_payment' : nil), invoice: invoice, - registrar: invoice.buyer) + create_internal_payment_record(invoice: invoice, registrar: invoice.buyer, + channel: (manual ? 'admin_payment' : nil)) end def validate_invoice_data(invoice) diff --git a/app/models/billing/reference_no.rb b/app/models/billing/reference_no.rb index 3ed84d7f1..050db73d4 100644 --- a/app/models/billing/reference_no.rb +++ b/app/models/billing/reference_no.rb @@ -4,13 +4,8 @@ module Billing MULTI_REGEXP = /(\d{2,20})/ def self.generate - 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 + result = EisBilling::GetReferenceNumber.send_request + JSON.parse(result.body)['reference_number'] end def self.valid?(ref) diff --git a/app/models/concerns/domain/force_delete.rb b/app/models/concerns/domain/force_delete.rb index 7dd309c41..3fa3bf627 100644 --- a/app/models/concerns/domain/force_delete.rb +++ b/app/models/concerns/domain/force_delete.rb @@ -34,7 +34,13 @@ module Domain::ForceDelete reason = explicit&.downcase return reason if %w[invalid_email invalid_phone].include?(reason) - registrant.org? ? 'legal_person' : 'private_person' + if contact_emails_verification_failed.present? + 'invalid_email' + elsif registrant.org? + 'legal_person' + else + 'private_person' + end end def force_delete_scheduled? diff --git a/app/models/concerns/email_verifable.rb b/app/models/concerns/email_verifable.rb index be9603031..2d2191d8f 100644 --- a/app/models/concerns/email_verifable.rb +++ b/app/models/concerns/email_verifable.rb @@ -5,6 +5,10 @@ module EmailVerifable scope :recently_not_validated, -> { where.not(id: ValidationEvent.validated_ids_by(name)) } end + def email_verification_failed? + need_to_start_force_delete? + end + def validate_email_data(level:, count:) validation_events.order(created_at: :desc).limit(count).all? do |event| event.check_level == level.to_s && event.failed? diff --git a/app/models/concerns/registrar/book_keeping.rb b/app/models/concerns/registrar/book_keeping.rb index 76535ce12..fc1defe9a 100644 --- a/app/models/concerns/registrar/book_keeping.rb +++ b/app/models/concerns/registrar/book_keeping.rb @@ -1,22 +1,27 @@ -module Registrar::BookKeeping +module Registrar::BookKeeping # rubocop:disable Metrics/ModuleLength extend ActiveSupport::Concern DOMAIN_TO_PRODUCT = { 'ee': '01EE', 'com.ee': '02COM', 'pri.ee': '03PRI', 'fie.ee': '04FIE', 'med.ee': '05MED' }.freeze + included do + scope :with_cash_accounts, (lambda do + joins(:accounts).where('accounts.account_type = ? AND test_registrar != ?', + Account::CASH, + true) + end) + end + def monthly_summary(month:) activities = monthly_activites(month) return unless activities.any? invoice = { - 'number': 1, - 'customer': compose_directo_customer, + 'number': 1, 'customer': compose_directo_customer, 'language': language == 'en' ? 'ENG' : '', 'currency': activities.first.currency, 'date': month.end_of_month.strftime('%Y-%m-%d') }.as_json - invoice['invoice_lines'] = prepare_invoice_lines(month: month, activities: activities) - invoice end @@ -55,20 +60,25 @@ module Registrar::BookKeeping .where(activity_type: [AccountActivity::CREATE, AccountActivity::RENEW]) end + def monthly_invoice(month:) + invoices.where(monthly_invoice: true, issue_date: month.end_of_month.to_date, + cancelled_at: nil).first + 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', - } + }.with_indifferent_access finalize_invoice_line(line, price: price, duration: duration, activity: activity) end def finalize_invoice_line(line, price:, activity:, duration:) yearly = price.duration.in_years.to_i >= 1 - line['price'] = yearly ? (price.price.amount / price.duration.in_years.to_i) : price.price.amount + line['price'] = yearly ? (price.price.amount / price.duration.in_years.to_i).to_f : price.price.amount.to_f line['description'] = description_in_language(price: price, yearly: yearly) add_product_timeframe(line: line, activity: activity, duration: duration) if duration.present? && (duration > 1) @@ -79,15 +89,16 @@ module Registrar::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') + line['end_date'] = (create_time + duration.year).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" + length = yearly ? price.duration.in_years.to_i : price.duration.in_months.to_i I18n.with_locale(language == 'en' ? 'en' : 'et') do - I18n.t(locale_string, tld: ".#{price.zone_name}", length: price.duration.in_years.to_i) + I18n.t(locale_string, tld: ".#{price.zone_name}", length: length) end end diff --git a/app/models/contact.rb b/app/models/contact.rb index 58c25f777..e4628e3c0 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -24,6 +24,11 @@ class Contact < ApplicationRecord alias_attribute :kind, :ident_type alias_attribute :copy_from_id, :original_id # Old attribute name; for PaperTrail + scope :email_verification_failed, lambda { + joins('LEFT JOIN email_address_verifications emv ON contacts.email = emv.email') + .where('success = false and verified_at IS NOT NULL') + } + scope :with_different_company_name, (lambda do |company| where("ident = ? AND ident_country_code = 'EE' AND name != ?", company.registration_number, diff --git a/app/models/domain.rb b/app/models/domain.rb index d79da3bc8..a8fc323a0 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -725,6 +725,10 @@ class Domain < ApplicationRecord DNS::DomainName.new(name) end + def contact_emails_verification_failed + contacts.select(&:email_verification_failed?)&.map(&:email)&.uniq + end + def as_csv_row [ name, diff --git a/app/models/invoice.rb b/app/models/invoice.rb index b7e60abfb..80d6cf5d2 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -32,11 +32,14 @@ class Invoice < ApplicationRecord # rubocop:enable Layout/LineLength # rubocop:enable Style/MultilineBlockLayout validates :due_date, :currency, :seller_name, - :seller_iban, :buyer_name, :items, presence: true + :seller_iban, :buyer_name, presence: true + validates :items, presence: true, unless: -> { monthly_invoice } before_create :set_invoice_number before_create :calculate_total, unless: :total? before_create :apply_default_buyer_vat_no, unless: :buyer_vat_no? + skip_callback :create, :before, :set_invoice_number, if: -> { monthly_invoice } + skip_callback :create, :before, :calculate_total, if: -> { monthly_invoice } attribute :vat_rate, ::Type::VatRate.new @@ -59,39 +62,13 @@ class Invoice < ApplicationRecord throw(:abort) end - def invoice_number_from_billing + def set_invoice_number 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 - else - self.number = Setting.invoice_number_min.to_i - end - - return if number <= Setting.invoice_number_max.to_i - - 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 I18n.t('invoice_no', no: number) end @@ -118,7 +95,7 @@ class Invoice < ApplicationRecord end def subtotal - items.map(&:item_sum_without_vat).reduce(:+) + items.map(&:item_sum_without_vat).reduce(:+) || 0 end def vat_amount @@ -131,7 +108,11 @@ class Invoice < ApplicationRecord end def each(&block) - items.each(&block) + if monthly_invoice + metadata['items'].map { |el| OpenStruct.new(el) }.each(&block) + else + items.each(&block) + end end def as_pdf diff --git a/app/models/invoice/e_invoice_generator.rb b/app/models/invoice/e_invoice_generator.rb index 2361656a7..8d9675475 100644 --- a/app/models/invoice/e_invoice_generator.rb +++ b/app/models/invoice/e_invoice_generator.rb @@ -41,22 +41,16 @@ class Invoice e_invoice_invoice_items = [] invoice.each do |invoice_item| - e_invoice_invoice_item = EInvoice::InvoiceItem.new.tap do |i| - i.description = invoice_item.description - i.price = invoice_item.price - i.quantity = invoice_item.quantity - i.unit = invoice_item.unit - i.subtotal = invoice_item.subtotal - i.vat_rate = invoice_item.vat_rate - i.vat_amount = invoice_item.vat_amount - i.total = invoice_item.total - end + e_invoice_invoice_item = generate_invoice_item(invoice, invoice_item) e_invoice_invoice_items << e_invoice_invoice_item end + e_invoice_name_item = e_invoice_invoice_items.shift if invoice.monthly_invoice + e_invoice_invoice = EInvoice::Invoice.new.tap do |i| i.seller = seller i.buyer = buyer + i.name = e_invoice_name_item&.description i.items = e_invoice_invoice_items i.number = invoice.number i.date = invoice.issue_date @@ -72,9 +66,33 @@ class Invoice i.currency = invoice.currency i.delivery_channel = %i[internet_bank portal] i.payable = payable + i.monthly_invoice = invoice.monthly_invoice end EInvoice::EInvoice.new(date: Time.zone.today, invoice: e_invoice_invoice) end + + private + + def generate_invoice_item(invoice, item) + EInvoice::InvoiceItem.new.tap do |i| + i.description = item.description + i.unit = item.unit + i.price = item.price + i.quantity = item.quantity + if invoice.monthly_invoice && item.price && item.quantity + i.product_id = item.product_id + i.vat_rate = invoice.vat_rate + i.subtotal = (item.price * item.quantity).round(3) + i.vat_amount = i.subtotal * (i.vat_rate / 100) + i.total = i.subtotal + i.vat_amount + else + i.subtotal = item.subtotal + i.vat_rate = item.vat_rate + i.vat_amount = item.vat_amount + i.total = item.total + end + end + end end end diff --git a/app/models/invoice/pdf_generator.rb b/app/models/invoice/pdf_generator.rb index 14fb99814..7762456c4 100644 --- a/app/models/invoice/pdf_generator.rb +++ b/app/models/invoice/pdf_generator.rb @@ -14,7 +14,8 @@ class Invoice private def invoice_html - ApplicationController.render(template: 'invoice/pdf', assigns: { invoice: invoice }) + template = invoice.monthly_invoice ? 'invoice/monthly_pdf' : 'invoice/pdf' + ApplicationController.render(template: template, assigns: { invoice: invoice }) end end end diff --git a/app/models/registrar.rb b/app/models/registrar.rb index 4c0098de0..07d7d4795 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -1,4 +1,4 @@ -class Registrar < ApplicationRecord +class Registrar < ApplicationRecord # rubocop:disable Metrics/ClassLength include Versions # version/registrar_version.rb include Registrar::BookKeeping include EmailVerifable @@ -56,9 +56,48 @@ class Registrar < ApplicationRecord end end - def issue_prepayment_invoice(amount, description = nil, payable: true) - vat_rate = ::Invoice::VatRateCalculator.new(registrar: self).calculate + # rubocop:disable Metrics/MethodLength + def init_monthly_invoice(summary) + Invoice.new( + issue_date: summary['date'].to_date, + due_date: summary['date'].to_date, + currency: 'EUR', + description: I18n.t('invoice.monthly_invoice_description'), + seller_name: Setting.registry_juridical_name, + seller_reg_no: Setting.registry_reg_no, + seller_iban: Setting.registry_iban, + seller_bank: Setting.registry_bank, + seller_swift: Setting.registry_swift, + seller_vat_no: Setting.registry_vat_no, + seller_country_code: Setting.registry_country_code, + seller_state: Setting.registry_state, + seller_street: Setting.registry_street, + seller_city: Setting.registry_city, + seller_zip: Setting.registry_zip, + seller_phone: Setting.registry_phone, + seller_url: Setting.registry_url, + seller_email: Setting.registry_email, + seller_contact_name: Setting.registry_invoice_contact, + buyer: self, + buyer_name: name, + buyer_reg_no: reg_no, + buyer_country_code: address_country_code, + buyer_state: address_state, + buyer_street: address_street, + buyer_city: address_city, + buyer_zip: address_zip, + buyer_phone: phone, + buyer_url: website, + buyer_email: email, + reference_no: reference_no, + vat_rate: calculate_vat_rate, + monthly_invoice: true, + metadata: { items: summary['invoice_lines'] }, + total: 0 + ) + end + def issue_prepayment_invoice(amount, description = nil, payable: true) invoice = invoices.create!( issue_date: Time.zone.today, due_date: (Time.zone.now + Setting.days_to_keep_invoices_active.days).to_date, @@ -91,7 +130,7 @@ class Registrar < ApplicationRecord buyer_url: website, buyer_email: email, reference_no: reference_no, - vat_rate: vat_rate, + vat_rate: calculate_vat_rate, items_attributes: [ { description: 'prepayment', @@ -107,23 +146,17 @@ class Registrar < ApplicationRecord .deliver_later(wait: 1.minute) end - if Feature.billing_system_integrated? - add_invoice_instance = EisBilling::AddDeposits.new(invoice) - result = add_invoice_instance.send_invoice + add_invoice_instance = EisBilling::AddDeposits.new(invoice) + result = add_invoice_instance.send_invoice - link = JSON.parse(result.body)['everypay_link'] + 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.update(payment_link: link) + SendEInvoiceJob.set(wait: 1.minute).perform_now(invoice.id, payable: payable) invoice end + # rubocop:enable Metrics/MethodLength def cash_account accounts.find_by(account_type: Account::CASH) @@ -265,4 +298,8 @@ class Registrar < ApplicationRecord def vat_liable_in_foreign_country? !vat_liable_locally? end + + def calculate_vat_rate + ::Invoice::VatRateCalculator.new(registrar: self).calculate + end end diff --git a/app/presenters/domain_presenter.rb b/app/presenters/domain_presenter.rb index f19bbb62f..812881742 100644 --- a/app/presenters/domain_presenter.rb +++ b/app/presenters/domain_presenter.rb @@ -52,6 +52,10 @@ class DomainPresenter end end + def contact_emails_verification_failed + domain.contact_emails_verification_failed.join(', ') + end + def remove_registry_lock_btn return unless domain.locked_by_registrant? diff --git a/app/services/eis_billing/add_deposits.rb b/app/services/eis_billing/add_deposits.rb index c9a47d360..3ccd2db88 100644 --- a/app/services/eis_billing/add_deposits.rb +++ b/app/services/eis_billing/add_deposits.rb @@ -21,6 +21,7 @@ module EisBilling data[:custom_field1] = invoice.description data[:custom_field2] = INITIATOR data[:invoice_number] = invoice.number + data[:reference_number] = invoice.reference_no data end diff --git a/app/views/admin/invoices/_search_form.html.erb b/app/views/admin/invoices/_search_form.html.erb index 7739387b2..91ccf4421 100644 --- a/app/views/admin/invoices/_search_form.html.erb +++ b/app/views/admin/invoices/_search_form.html.erb @@ -12,7 +12,7 @@
<%= f.label t(:status) %> - <%= select_tag :status, options_for_select(%w(Paid Unpaid Cancelled),params[:status]), + <%= select_tag :status, options_for_select(%w(Paid Unpaid Cancelled Monthly),params[:status]), { multiple: false, include_blank: true, selected: params[:status], class: 'form-control selectize'} %>
diff --git a/app/views/admin/invoices/index.haml b/app/views/admin/invoices/index.haml index 046772d68..8b8fe12c3 100644 --- a/app/views/admin/invoices/index.haml +++ b/app/views/admin/invoices/index.haml @@ -31,6 +31,8 @@ %td= l invoice.receipt_date - elsif invoice.cancelled? %td.text-grey= t(:cancelled) + - elsif invoice.monthly_invoice + %td= l invoice.issue_date - else %td.text-danger= t(:unpaid) diff --git a/app/views/admin/invoices/show.haml b/app/views/admin/invoices/show.haml index b121c8337..42f7d769c 100644 --- a/app/views/admin/invoices/show.haml +++ b/app/views/admin/invoices/show.haml @@ -4,11 +4,12 @@ = @invoice .col-sm-8 %h1.text-right.text-center-xs - - if @invoice.unpaid? - = link_to(t(:payment_received), new_admin_bank_statement_path(invoice_id: @invoice.id), class: 'btn btn-default') + - unless @invoice.monthly_invoice + - if @invoice.unpaid? + = link_to(t(:payment_received), new_admin_bank_statement_path(invoice_id: @invoice.id), class: 'btn btn-default') - - if @invoice.paid? and !@invoice.cancelled? - = link_to(t(:cancel_payment), cancel_paid_admin_invoices_path(invoice_id: @invoice.id), method: 'post', data: { confirm: t(:are_you_sure) }, class: 'btn btn-warning') + - if @invoice.paid? && !@invoice.cancelled? + = link_to(t(:cancel_payment), cancel_paid_admin_invoices_path(invoice_id: @invoice.id), method: 'post', data: { confirm: t(:are_you_sure) }, class: 'btn btn-warning') = link_to(t('.download_btn'), download_admin_invoice_path(@invoice), class: 'btn btn-default') = link_to(t('.deliver_btn'), new_admin_invoice_delivery_path(@invoice), class: 'btn btn-default') @@ -24,6 +25,9 @@ .col-md-6= render 'registrar/invoices/partials/seller' .col-md-6= render 'registrar/invoices/partials/buyer' .row - .col-md-12= render 'registrar/invoices/partials/items' + - if @invoice.monthly_invoice + .col-md-12= render 'registrar/invoices/partials/monthly_invoice_items' + - else + .col-md-12= render 'registrar/invoices/partials/items' .row .col-md-12= render 'registrar/invoices/partials/payment_orders' diff --git a/app/views/invoice/monthly_pdf.haml b/app/views/invoice/monthly_pdf.haml new file mode 100644 index 000000000..c7e179d03 --- /dev/null +++ b/app/views/invoice/monthly_pdf.haml @@ -0,0 +1,277 @@ +%html{lang: I18n.locale.to_s} + %head + %meta{charset: "utf-8"} + :css + .container { + margin: auto; + font-size: 12px; + } + + .col-md-12 { + + } + + .col-md-6 { + width: 49%; + display: inline-block; + } + + .col-xs-4 { + width: 33%; + } + + .col-xs-2 { + width: 16%; + } + + .col-md-3 { + width: 24%; + display: inline-block; + } + + .left { + float: left; + } + + .left { + padding-right: 5px; + } + + .right { + float: right; + } + + .text-right { + text-align: right; + } + + dt { + float: left; + width: 100px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-weight: bold; + line-height: 1.42857; + } + + dd { + margin-left: 120px; + line-height: 1.42857; + } + + table { + width: 100%; + border-collapse: collapse; + font-size: 12px; + } + + th { + text-align: left; + border: 0px; + border-top: 1px solid #DDD; + padding: 6px; + } + + thead th { + border-bottom: 2px solid #DDD; + border-top: 0px; + } + + td { + border-top: 1px solid #DDD; + } + + td { + padding: 6px; + } + + .no-border { + border: 0px; + } + + hr { + height: 1px; + border: 0; + color: #DDD; + background-color: #DDD; + } + + .clear { + clear: both; + } + + .pull-down { + margin-top: 50px; + } + + #header { + position: relative; + min-height: 100px; + } + + img { + width: 106px; + height: 102px; + } + + #header-content { + position: absolute; + bottom: 0; + } + + #footer { + position: absolute; + bottom: 0px; + width: 99%; + } + + h1 { + margin-bottom: 5px; + } + %body + .container + #header.row + .col-sm-6.left + #header-content + %h1 + = @invoice + .col-sm-6.right + %img{src: "#{Rails.root}/public/eis-logo-black-et.png"} + .clear + %hr + .row + .col-md-6.left + %h4 + Details + %hr + %dl.dl-horizontal + %dt= t(:issue_date) + %dd= l @invoice.issue_date + + - if @invoice.cancelled? + %dt= Invoice.human_attribute_name :cancelled_at + %dd= l @invoice.cancelled_at + + %dt= t(:due_date) + - if @invoice.cancelled? + %dd= t(:cancelled) + - else + %dd= l @invoice.due_date + + %dt= t(:issuer) + %dd= @invoice.seller_contact_name + + - if @invoice.description.present? + %dt= t(:description) + %dd=@invoice.description + + %dt= Invoice.human_attribute_name :reference_no + %dd= @invoice.reference_no + + .col-md-6.right + %h4= t(:client) + %hr + %dl.dl-horizontal + %dt= t(:name) + %dd= @invoice.buyer_name + + %dt= t(:reg_no) + %dd= @invoice.buyer_reg_no + + - if @invoice.buyer_address.present? + %dt= Invoice.human_attribute_name :address + %dd= @invoice.buyer_address + + - if @invoice.buyer_country.present? + %dt= t(:country) + %dd= @invoice.buyer_country + + - if @invoice.buyer_phone.present? + %dt= t(:phone) + %dd= @invoice.buyer_phone + + - if @invoice.buyer_url.present? + %dt= t(:url) + %dd= @invoice.buyer_url + + - if @invoice.buyer_email.present? + %dt= t(:email) + %dd= @invoice.buyer_email + + .clear + .row.pull-down + .col-md-12 + .table-responsive + %table.table.table-hover.table-condensed + %thead + %tr + %th{class: 'col-xs-1'}= t(:code) + %th{class: 'col-xs-1'}= InvoiceItem.human_attribute_name :quantity + %th{class: 'col-xs-1'}= t(:unit) + %th{class: 'col-xs-5'}= t(:description) + %th{class: 'col-xs-2'}= t(:price) + %th{class: 'col-xs-2'}= t(:total) + %tbody + - @invoice.each do |invoice_item| + %tr + %td= invoice_item.product_id + %td= invoice_item.quantity + %td= invoice_item.unit + %td= invoice_item.description + - if invoice_item.price && invoice_item.quantity + %td= currency(invoice_item.price) + %td= "#{currency((invoice_item.price * invoice_item.quantity).round(3))} #{@invoice.currency}" + - else + %td= '' + %td= '' + %tfoot + %tr + %th{colspan: 4} + %th= Invoice.human_attribute_name :subtotal + %td= number_to_currency(0) + %tr + %th.no-border{colspan: 4} + %th= "VAT #{number_to_percentage(@invoice.vat_rate, precision: 1)}" + %td= number_to_currency(0) + %tr + %th.no-border{colspan: 4} + %th= t(:total) + %td= number_to_currency(0) + + #footer + %hr + .row + .col-md-3.left + = @invoice.seller_name + %br + = @invoice.seller_address + %br + = @invoice.seller_country + %br + = "#{t('reg_no')} #{@invoice.seller_reg_no}" + %br + = "#{Registrar.human_attribute_name :vat_no} #{@invoice.seller_vat_no}" + + .col-md-3.left + = @invoice.seller_phone + %br + = @invoice.seller_email + %br + = @invoice.seller_url + + .col-md-3.text-right.left + = t(:bank) + %br + = t(:iban) + %br + = t(:swift) + + .col-md-3.left + = @invoice.seller_bank + %br + = @invoice.seller_iban + %br + = @invoice.seller_swift \ No newline at end of file diff --git a/app/views/invoice/pdf.haml b/app/views/invoice/pdf.haml index 9f10acdad..dc3d4370a 100644 --- a/app/views/invoice/pdf.haml +++ b/app/views/invoice/pdf.haml @@ -234,7 +234,7 @@ %td= invoice_item.unit %td= invoice_item.quantity %td= currency(invoice_item.price) - %td= "#{currency(invoice_item.item_sum_without_vat)} #{@invoice.currency}" + %td= "#{currency(invoice_item.item_sum_without_vat)} #{@invoice.currency}" %tfoot %tr %th{colspan: 3} diff --git a/app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb b/app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb new file mode 100644 index 000000000..60497a9da --- /dev/null +++ b/app/views/mailers/domain_delete_mailer/forced/invalid_email.html.erb @@ -0,0 +1,45 @@ +

Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt

+ +

Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et domeeni <%= @domain.name %> kontaktandmed on puudulikud - eposti aadress <%= @domain.contact_emails_verification_failed %>.

+ +

Et see olukord on vastuolus .ee domeenireeglitega algatas EIS <%= @delete_period_length %> päeva pikkuse kustutusmenetluse. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.

+ +

Andmete parandamiseks pöörduge palun oma registripidaja <%= @registrar.name %> poole või isiklike ja oma ettevõtte andmete puhul registreerija portaali.

+ +

Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.

+ +

Lisaküsimuste korral võtke palun ühendust oma registripidajaga:

+<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %> +<%= render 'mailers/shared/signatures/signature.et.html' %> + +
+ +

Dear registrant/administrative contact of .ee domain,

+ +

Estonian Internet Foundation has learned that contact data of the domain <%= @domain.name %> s invalid - email(s) <%= @domain.contact_emails_verification_failed %>.

+ +

Since this is a violation of Estonian domain regulations, <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.

+ +

Please, contact your registrar <%= @registrar.name %> with updated contact data, or in case of your personal or business data use .ee portal for registrants

+ +

If the data is not fixed within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction environment. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results here.

+ +

Should you have additional questions, please contact your registrar:

+<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %> +<%= render 'mailers/shared/signatures/signature.en.html' %> +
+ +

Уважаемый регистрант/административный контакт домена .ee

+ +

Целевому учреждению Eesti Internet (EIS) стало известно, что контактные данные домена <%= @registrant.reg_no %> неверны - электронная почта <%= @domain.contact_emails_verification_failed %>.

+ +

Так как это является нарушением Правил домена .ee, <%= @delete_period_length %>-дневный процесс удаления начат для доменного имени <%= @domain.name %>. В течение первых <%= @expire_warning_period %> дней домен будет доступен в интернете.

+ +

Для уточнения контактных данных, пожалуйста, свяжитесь с регистратором <%= @registrar.name %>, либо воспользуйтесь порталом для регистрантов

+ +

Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в аукционной среде.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте здесь.

+ +

В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором: +<%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>

+ +<%= render 'mailers/shared/signatures/signature.ru.html' %> diff --git a/app/views/mailers/domain_delete_mailer/forced/invalid_email.text.erb b/app/views/mailers/domain_delete_mailer/forced/invalid_email.text.erb new file mode 100644 index 000000000..870db25aa --- /dev/null +++ b/app/views/mailers/domain_delete_mailer/forced/invalid_email.text.erb @@ -0,0 +1,45 @@ +

Lugupeetud domeeni <%= @domain.name %> registreerija/halduskontakt

+ +

Eesti Interneti Sihtasutusele (EIS) on saanud teatavaks, et domeeni <%= @domain.name %> kontaktandmed on puudulikud - eposti aadress <%= @domain.contact_emails_verification_failed %>

+ +

Et see olukord on vastuolus .ee domeenireeglitega algatas EIS <%= @delete_period_length %> päeva pikkuse kustutusmenetluse. Menetluse käigus on domeen <%= @expire_warning_period %> esimest päeva internetis kättesaadav.

+ +

Andmete parandamiseks pöörduge palun oma registripidaja <%= @registrar.name %> poole või isiklike ja oma ettevõtte andmete puhul registreerija portaali.

+ +

Kui kontaktandmed ei ole <%= @delete_period_length %> päeva jooksul parandatud, läheb domeen <%= @domain.name %> <%= @domain.force_delete_date %> domeenioksjonile .ee oksjonikeskkonda. Juhul kui domeenile <%= @domain.name %> ei tehta oksjonil 24h möödudes pakkumist, domeen vabaneb ja on registreerimiseks vabalt kättesaadav kõigile huvilistele. Muude võimalike oksjoni tulemuste kohta loe siit.

+ +

Lisaküsimuste korral võtke palun ühendust oma registripidajaga:

+<%= render 'mailers/shared/registrar/registrar.et.html', registrar: @registrar %> +<%= render 'mailers/shared/signatures/signature.et.html' %> + +
+ +

Dear registrant/administrative contact of .ee domain,

+ +

Estonian Internet Foundation has learned that contact data of the domain <%= @domain.name %> s invalid - email(s) <%= @domain.contact_emails_verification_failed %>.

+ +

Since this is a violation of Estonian domain regulations, <%= @delete_period_length %>-day deletion process has started for the <%= @domain.name %> domain. For the first <%= @expire_warning_period %> days the domain will remain available on the Internet during the deletion process.

+ +

Please, contact your registrar <%= @registrar.name %> with updated contact data, or in case of your personal or business data use .ee portal for registrants

+ +

If the data is not fixed within <%= @delete_period_length %> days, the domain <%= @domain.name %> will go to domain auction on <%= @domain.force_delete_date %> in the .ee auction environment. If no offer is made for the domain <%= @domain.name %> at auction within 24 hours, the domain will be released and made freely available for registration to anyone interested on a first-come, first-served basis. Read more about other potential auction results here.

+ +

Should you have additional questions, please contact your registrar:

+<%= render 'mailers/shared/registrar/registrar.en.html', registrar: @registrar %> +<%= render 'mailers/shared/signatures/signature.en.html' %> +
+ +

Уважаемый регистрант/административный контакт домена .ee

+ +

Целевому учреждению Eesti Internet (EIS) стало известно, что контактные данные домена <%= @registrant.reg_no %> неверны - электронная почта <%= @domain.contact_emails_verification_failed %>.

+ +

Так как это является нарушением Правил домена .ee, <%= @delete_period_length %>-дневный процесс удаления начат для доменного имени <%= @domain.name %>. В течение первых <%= @expire_warning_period %> дней домен будет доступен в интернете.

+ +

Для уточнения контактных данных, пожалуйста, свяжитесь с регистратором <%= @registrar.name %>, либо воспользуйтесь порталом для регистрантов

+ +

Если контактные данные не будут исправлены в течение <%= @delete_period_length %> дней, домен <%= @domain.name %> отправится <%= @domain.force_delete_date %> на доменный аукцион в аукционной среде.ee. Если в течение 24 часов в отношении домена <%= @domain.name %> е поступит предложений, домен освободится и станет доступным для всех желающих по принципу «кто раньше». О других возможных результатах аукциона читайте здесь.

+ +

В случае возникновения дополнительных вопросов свяжитесь, пожалуйста, со своим регистратором: + <%= render 'mailers/shared/registrar/registrar.ru.html', registrar: @registrar %>

+ +<%= render 'mailers/shared/signatures/signature.ru.html' %> \ No newline at end of file diff --git a/app/views/registrar/invoices/partials/_details.haml b/app/views/registrar/invoices/partials/_details.haml index c5e6193a4..acc0e6589 100644 --- a/app/views/registrar/invoices/partials/_details.haml +++ b/app/views/registrar/invoices/partials/_details.haml @@ -19,6 +19,8 @@ %dd= l @invoice.receipt_date - elsif @invoice.cancelled? %dd.text-grey= t(:cancelled) + - elsif @invoice.monthly_invoice + %dd= l @invoice.issue_date - else %dd{class: 'text-danger'}= t(:unpaid) diff --git a/app/views/registrar/invoices/partials/_monthly_invoice_items.haml b/app/views/registrar/invoices/partials/_monthly_invoice_items.haml new file mode 100644 index 000000000..787218ea3 --- /dev/null +++ b/app/views/registrar/invoices/partials/_monthly_invoice_items.haml @@ -0,0 +1,38 @@ +%h4= t(:items) +%hr +.table-responsive + %table.table.table-hover.table-condensed + %thead + %tr + %th{class: 'col-xs-1'}= t(:code) + %th{class: 'col-xs-1'}= InvoiceItem.human_attribute_name :quantity + %th{class: 'col-xs-1'}= t(:unit) + %th{class: 'col-xs-5'}= t(:description) + %th{class: 'col-xs-2'}= t(:price) + %th{class: 'col-xs-2'}= t(:total) + %tbody + - @invoice.each do |invoice_item| + %tr + %td= invoice_item.product_id + %td= invoice_item.quantity + %td= invoice_item.unit + %td= invoice_item.description + - if invoice_item.price && invoice_item.quantity + %td= currency(invoice_item.price) + %td= "#{currency((invoice_item.price * invoice_item.quantity).round(3))} #{@invoice.currency}" + - else + %td= '' + %td= '' + %tfoot + %tr + %th{colspan: 4} + %th= Invoice.human_attribute_name :subtotal + %td= number_to_currency(0) + %tr + %th.no-border{colspan: 4} + %th= "VAT #{number_to_percentage(@invoice.vat_rate, precision: 1)}" + %td= number_to_currency(0) + %tr + %th.no-border{colspan: 4} + %th= t(:total) + %td= number_to_currency(0) \ No newline at end of file diff --git a/app/views/registrar/invoices/show.haml b/app/views/registrar/invoices/show.haml index 5e6104091..dd19a0bea 100644 --- a/app/views/registrar/invoices/show.haml +++ b/app/views/registrar/invoices/show.haml @@ -13,7 +13,10 @@ .col-md-6= render 'registrar/invoices/partials/seller' .col-md-6= render 'registrar/invoices/partials/buyer' .row - .col-md-12= render 'registrar/invoices/partials/items' + - if @invoice.monthly_invoice + .col-md-12= render 'registrar/invoices/partials/monthly_invoice_items' + - else + .col-md-12= render 'registrar/invoices/partials/items' - if @invoice.payable? .row.semifooter diff --git a/config/locales/en.yml b/config/locales/en.yml index ec8953a84..9021eff60 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -484,6 +484,8 @@ en: invoice: title: 'Invoice' already_paid: " (already paid)" + monthly_invoice: " (monthly invoice)" + monthly_invoice_description: 'Monthly invoice' bank_statements: 'Bank statements' back_to_bank_statements: 'Back to bank statements' back_to_bank_statement: 'Back to bank statement' diff --git a/config/locales/et.yml b/config/locales/et.yml index ad04db007..84672ed3c 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -9,3 +9,5 @@ et: invoice: title: 'Arve' already_paid: " (juba makstud)" + monthly_invoice: " (kuuaruanne)" + monthly_invoice_description: 'Kuuaruanne' diff --git a/db/migrate/20220818075833_add_monthly_invoice_type_columns.rb b/db/migrate/20220818075833_add_monthly_invoice_type_columns.rb new file mode 100644 index 000000000..33c98124c --- /dev/null +++ b/db/migrate/20220818075833_add_monthly_invoice_type_columns.rb @@ -0,0 +1,6 @@ +class AddMonthlyInvoiceTypeColumns < ActiveRecord::Migration[6.1] + def change + add_column :invoices, :monthly_invoice, :boolean, default: false + add_column :invoices, :metadata, :jsonb + end +end diff --git a/db/structure.sql b/db/structure.sql index a96474d53..03fca59a8 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -955,14 +955,14 @@ CREATE TABLE public.domains ( pending_json jsonb, force_delete_date date, statuses character varying[], + status_notes public.hstore, upid integer, up_date timestamp without time zone, uuid uuid DEFAULT public.gen_random_uuid() NOT NULL, locked_by_registrant_at timestamp without time zone, force_delete_start timestamp without time zone, force_delete_data public.hstore, - json_statuses_history jsonb, - status_notes public.hstore + json_statuses_history jsonb ); @@ -985,6 +985,98 @@ CREATE SEQUENCE public.domains_id_seq ALTER SEQUENCE public.domains_id_seq OWNED BY public.domains.id; +-- +-- Name: email_address_verifications; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.email_address_verifications ( + id bigint NOT NULL, + email public.citext NOT NULL, + verified_at timestamp without time zone, + success boolean DEFAULT false NOT NULL, + domain public.citext NOT NULL +); + + +-- +-- Name: email_address_verifications_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.email_address_verifications_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: email_address_verifications_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.email_address_verifications_id_seq OWNED BY public.email_address_verifications.id; + + +-- +-- Name: email_addresses_validations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.email_addresses_validations ( + id bigint NOT NULL, + email character varying NOT NULL, + validated_at timestamp without time zone +); + + +-- +-- Name: email_addresses_validations_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.email_addresses_validations_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: email_addresses_validations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.email_addresses_validations_id_seq OWNED BY public.email_addresses_validations.id; + + +-- +-- Name: email_addresses_verifications; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.email_addresses_verifications ( + id bigint NOT NULL, + email character varying NOT NULL, + validated_at timestamp without time zone +); + + +-- +-- Name: email_addresses_verifications_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.email_addresses_verifications_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: email_addresses_verifications_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.email_addresses_verifications_id_seq OWNED BY public.email_addresses_verifications.id; + + -- -- Name: epp_sessions; Type: TABLE; Schema: public; Owner: - -- @@ -1104,6 +1196,8 @@ CREATE TABLE public.invoices ( issue_date date NOT NULL, e_invoice_sent_at timestamp without time zone, payment_link character varying, + monthly_invoice boolean DEFAULT false, + metadata jsonb, CONSTRAINT invoices_due_date_is_not_before_issue_date CHECK ((due_date >= issue_date)) ); @@ -2190,6 +2284,74 @@ CREATE SEQUENCE public.payment_orders_id_seq ALTER SEQUENCE public.payment_orders_id_seq OWNED BY public.payment_orders.id; +-- +-- Name: pghero_query_stats; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.pghero_query_stats ( + id bigint NOT NULL, + database text, + "user" text, + query text, + query_hash bigint, + total_time double precision, + calls bigint, + captured_at timestamp without time zone +); + + +-- +-- Name: pghero_query_stats_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.pghero_query_stats_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: pghero_query_stats_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.pghero_query_stats_id_seq OWNED BY public.pghero_query_stats.id; + + +-- +-- Name: pghero_space_stats; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.pghero_space_stats ( + id bigint NOT NULL, + database text, + schema text, + relation text, + size bigint, + captured_at timestamp without time zone +); + + +-- +-- Name: pghero_space_stats_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.pghero_space_stats_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: pghero_space_stats_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.pghero_space_stats_id_seq OWNED BY public.pghero_space_stats.id; + + -- -- Name: prices; Type: TABLE; Schema: public; Owner: - -- @@ -2228,6 +2390,48 @@ CREATE SEQUENCE public.prices_id_seq ALTER SEQUENCE public.prices_id_seq OWNED BY public.prices.id; +-- +-- Name: que_jobs; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.que_jobs ( + priority smallint DEFAULT 100 NOT NULL, + run_at timestamp with time zone DEFAULT now() NOT NULL, + job_id bigint NOT NULL, + job_class text NOT NULL, + args json DEFAULT '[]'::json NOT NULL, + error_count integer DEFAULT 0 NOT NULL, + last_error text, + queue text DEFAULT ''::text NOT NULL +); + + +-- +-- Name: TABLE que_jobs; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON TABLE public.que_jobs IS '3'; + + +-- +-- Name: que_jobs_job_id_seq; Type: SEQUENCE; Schema: public; Owner: - +-- + +CREATE SEQUENCE public.que_jobs_job_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: que_jobs_job_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - +-- + +ALTER SEQUENCE public.que_jobs_job_id_seq OWNED BY public.que_jobs.job_id; + + -- -- Name: registrant_verifications; Type: TABLE; Schema: public; Owner: - -- @@ -2508,8 +2712,7 @@ CREATE TABLE public.validation_events ( validation_eventable_type character varying, validation_eventable_id bigint, created_at timestamp(6) without time zone NOT NULL, - updated_at timestamp(6) without time zone NOT NULL, - event_type public.validation_type + updated_at timestamp(6) without time zone NOT NULL ); @@ -2813,6 +3016,27 @@ ALTER TABLE ONLY public.domain_transfers ALTER COLUMN id SET DEFAULT nextval('pu ALTER TABLE ONLY public.domains ALTER COLUMN id SET DEFAULT nextval('public.domains_id_seq'::regclass); +-- +-- Name: email_address_verifications id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.email_address_verifications ALTER COLUMN id SET DEFAULT nextval('public.email_address_verifications_id_seq'::regclass); + + +-- +-- Name: email_addresses_validations id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.email_addresses_validations ALTER COLUMN id SET DEFAULT nextval('public.email_addresses_validations_id_seq'::regclass); + + +-- +-- Name: email_addresses_verifications id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.email_addresses_verifications ALTER COLUMN id SET DEFAULT nextval('public.email_addresses_verifications_id_seq'::regclass); + + -- -- Name: epp_sessions id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3030,6 +3254,20 @@ ALTER TABLE ONLY public.notifications ALTER COLUMN id SET DEFAULT nextval('publi ALTER TABLE ONLY public.payment_orders ALTER COLUMN id SET DEFAULT nextval('public.payment_orders_id_seq'::regclass); +-- +-- Name: pghero_query_stats id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.pghero_query_stats ALTER COLUMN id SET DEFAULT nextval('public.pghero_query_stats_id_seq'::regclass); + + +-- +-- Name: pghero_space_stats id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.pghero_space_stats ALTER COLUMN id SET DEFAULT nextval('public.pghero_space_stats_id_seq'::regclass); + + -- -- Name: prices id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3037,6 +3275,13 @@ ALTER TABLE ONLY public.payment_orders ALTER COLUMN id SET DEFAULT nextval('publ ALTER TABLE ONLY public.prices ALTER COLUMN id SET DEFAULT nextval('public.prices_id_seq'::regclass); +-- +-- Name: que_jobs job_id; Type: DEFAULT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.que_jobs ALTER COLUMN job_id SET DEFAULT nextval('public.que_jobs_job_id_seq'::regclass); + + -- -- Name: registrant_verifications id; Type: DEFAULT; Schema: public; Owner: - -- @@ -3274,6 +3519,30 @@ ALTER TABLE ONLY public.domains ADD CONSTRAINT domains_pkey PRIMARY KEY (id); +-- +-- Name: email_address_verifications email_address_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.email_address_verifications + ADD CONSTRAINT email_address_verifications_pkey PRIMARY KEY (id); + + +-- +-- Name: email_addresses_validations email_addresses_validations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.email_addresses_validations + ADD CONSTRAINT email_addresses_validations_pkey PRIMARY KEY (id); + + +-- +-- Name: email_addresses_verifications email_addresses_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.email_addresses_verifications + ADD CONSTRAINT email_addresses_verifications_pkey PRIMARY KEY (id); + + -- -- Name: epp_sessions epp_sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -3522,6 +3791,22 @@ ALTER TABLE ONLY public.payment_orders ADD CONSTRAINT payment_orders_pkey PRIMARY KEY (id); +-- +-- Name: pghero_query_stats pghero_query_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.pghero_query_stats + ADD CONSTRAINT pghero_query_stats_pkey PRIMARY KEY (id); + + +-- +-- Name: pghero_space_stats pghero_space_stats_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.pghero_space_stats + ADD CONSTRAINT pghero_space_stats_pkey PRIMARY KEY (id); + + -- -- Name: prices prices_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -3530,6 +3815,14 @@ ALTER TABLE ONLY public.prices ADD CONSTRAINT prices_pkey PRIMARY KEY (id); +-- +-- Name: que_jobs que_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.que_jobs + ADD CONSTRAINT que_jobs_pkey PRIMARY KEY (queue, priority, run_at, job_id); + + -- -- Name: registrant_verifications registrant_verifications_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -3941,6 +4234,13 @@ CREATE INDEX index_domains_on_registrar_id ON public.domains USING btree (regist CREATE INDEX index_domains_on_statuses ON public.domains USING gin (statuses); +-- +-- Name: index_email_address_verifications_on_domain; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_email_address_verifications_on_domain ON public.email_address_verifications USING btree (domain); + + -- -- Name: index_epp_sessions_on_updated_at; Type: INDEX; Schema: public; Owner: - -- @@ -4277,6 +4577,20 @@ CREATE INDEX index_notifications_on_registrar_id ON public.notifications USING b CREATE INDEX index_payment_orders_on_invoice_id ON public.payment_orders USING btree (invoice_id); +-- +-- Name: index_pghero_query_stats_on_database_and_captured_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_pghero_query_stats_on_database_and_captured_at ON public.pghero_query_stats USING btree (database, captured_at); + + +-- +-- Name: index_pghero_space_stats_on_database_and_captured_at; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX index_pghero_space_stats_on_database_and_captured_at ON public.pghero_space_stats USING btree (database, captured_at); + + -- -- Name: index_prices_on_zone_id; Type: INDEX; Schema: public; Owner: - -- @@ -4333,13 +4647,6 @@ CREATE INDEX index_users_on_registrar_id ON public.users USING btree (registrar_ CREATE INDEX index_validation_events_on_event_data ON public.validation_events USING gin (event_data); --- --- Name: index_validation_events_on_event_type; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX index_validation_events_on_event_type ON public.validation_events USING btree (event_type); - - -- -- Name: index_validation_events_on_validation_eventable; Type: INDEX; Schema: public; Owner: - -- @@ -5085,9 +5392,11 @@ INSERT INTO "schema_migrations" (version) VALUES ('20210708131814'), ('20210729131100'), ('20210729134625'), -('20210827185249'), -('20211029073644'), +('20211028122103'), +('20211028125245'), +('20211029082225'), ('20211124071418'), +('20211124084308'), ('20211125181033'), ('20211125184334'), ('20211126085139'), @@ -5096,6 +5405,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20220113201642'), ('20220113220809'), ('20220124105717'), +('20220216113112'), ('20220228093211'), ('20220316140727'), ('20220406085500'), @@ -5104,6 +5414,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20220413084536'), ('20220413084748'), ('20220504090512'), -('20220524130709'); +('20220524130709'), +('20220818075833'); diff --git a/lib/serializers/repp/invoice.rb b/lib/serializers/repp/invoice.rb index 3b8efbd58..686eaac99 100644 --- a/lib/serializers/repp/invoice.rb +++ b/lib/serializers/repp/invoice.rb @@ -23,7 +23,8 @@ module Serializers created_at: obj.created_at, updated_at: obj.updated_at, due_date: obj.due_date, currency: obj.currency, seller: seller, buyer: buyer, items: items, - recipient: obj.buyer.billing_email + recipient: obj.buyer.billing_email, + monthly_invoice: obj.monthly_invoice } end @@ -54,11 +55,15 @@ module Serializers end def items - invoice.items.map do |item| - { description: item.description, unit: item.unit, - quantity: item.quantity, price: item.price, - sum_without_vat: item.item_sum_without_vat, - vat_amount: item.vat_amount, total: item.total } + if invoice.monthly_invoice + invoice.metadata['items'] + else + invoice.items.map do |item| + { description: item.description, unit: item.unit, + quantity: item.quantity, price: item.price, + sum_without_vat: item.item_sum_without_vat, + vat_amount: item.vat_amount, total: item.total } + end end end @@ -75,6 +80,7 @@ module Serializers due_date: invoice.due_date, total: invoice.total, recipient: invoice.buyer.billing_email, + monthly_invoice: invoice.monthly_invoice, } end # rubocop:enable Metrics/MethodLength diff --git a/test/integration/admin_area/invoices_test.rb b/test/integration/admin_area/invoices_test.rb index 9c831250e..7cf93ca81 100644 --- a/test/integration/admin_area/invoices_test.rb +++ b/test/integration/admin_area/invoices_test.rb @@ -24,30 +24,28 @@ class AdminAreaInvoicesIntegrationTest < ApplicationIntegrationTest end def test_create_new_invoice - if Feature.billing_system_integrated? - invoice_n = Invoice.order(number: :desc).last.number + 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: {}) + 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(: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_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(: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: {}) + 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 + 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_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 + assert_equal page.status_code, 200 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 index 4b2c30ba2..5125434e8 100644 --- a/test/integration/eis_billing/directo_response_test.rb +++ b/test/integration/eis_billing/directo_response_test.rb @@ -10,34 +10,30 @@ class DirectoResponseTest < ApplicationIntegrationTest end def test_should_created_directo_instance - if Feature.billing_system_integrated? - directo_response_from_billing = { - response: @response_xml, - month: true - } + 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 + 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 def test_should_update_related_invoice - if Feature.billing_system_integrated? - directo_response_from_billing = { - response: @response_xml - } + directo_response_from_billing = { + response: @response_xml + } - refute @invoice.in_directo + 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 + 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 diff --git a/test/integration/eis_billing/lhv_connect_transactions_test.rb b/test/integration/eis_billing/lhv_connect_transactions_test.rb index f6d0f59d0..6e89808c8 100644 --- a/test/integration/eis_billing/lhv_connect_transactions_test.rb +++ b/test/integration/eis_billing/lhv_connect_transactions_test.rb @@ -8,35 +8,33 @@ class LhvConnectTransactionsIntegrationTest < ApplicationIntegrationTest 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_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_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") + 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 + 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 + assert_difference 'BankStatement.count', 1 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 diff --git a/test/integration/eis_billing/payment_status_test.rb b/test/integration/eis_billing/payment_status_test.rb new file mode 100644 index 000000000..69c50e120 --- /dev/null +++ b/test/integration/eis_billing/payment_status_test.rb @@ -0,0 +1,32 @@ +require 'test_helper' + +class PaymentStatusTest < ApplicationIntegrationTest + setup do + sign_in users(:api_bestnames) + @invoice = invoices(:one) + @unpaid = invoices(:unpaid) + @registrar = registrars(:bestnames) + Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) + end + + def shoudl_update_buyer_balance + assert @invoice.paid? + assert_equal @invoice.buyer.balance.to_f, 100.0 + + payload = { + payment_state: 'settled', + order_reference: @unpaid.number, + standing_amount: @unpaid.total, + transaction_time: Time.zone.now, + } + + put eis_billing_payment_status_path, params: payload + + @invoice.reload + @invoice.buyer.reload + @registrar.reload + + assert @invoice.paid? + assert_equal @invoice.buyer.balance.to_f, 100.0 + end +end diff --git a/test/integration/repp/v1/invoices/add_credit_test.rb b/test/integration/repp/v1/invoices/add_credit_test.rb index 71f2c77d3..fe250de7d 100644 --- a/test/integration/repp/v1/invoices/add_credit_test.rb +++ b/test/integration/repp/v1/invoices/add_credit_test.rb @@ -12,6 +12,18 @@ class ReppV1InvoicesAddCreditTest < ActionDispatch::IntegrationTest eis_response = OpenStruct.new(body: '{"everypay_link":"https://link.test"}') Spy.on_instance_method(EisBilling::AddDeposits, :send_invoice).and_return(eis_response) Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) + + invoice = Invoice.last + msg = { + invoice_number: invoice.number + 3 + } + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/invoice_number_generator") + .to_return(status: 200, body: msg.to_json, headers: {}) + + msg2 = { + message: 'success' + } + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice").to_return(status: 200, body: msg2.to_json, headers: {}) end teardown do @@ -28,13 +40,11 @@ class ReppV1InvoicesAddCreditTest < ActionDispatch::IntegrationTest Setting.registry_vat_prc = 0.1 ENV['billing_system_integrated'] = 'true' - 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: {}) - stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice') - .to_return(status: 200, body: '', headers: {}) - end + 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/e_invoice/e_invoice') + .to_return(status: 200, body: '', headers: {}) post '/repp/v1/invoices/add_credit', headers: @auth_headers, params: request_body diff --git a/test/jobs/directo_invoice_forward_job_test.rb b/test/jobs/directo_invoice_forward_job_test.rb index 33a05f644..5e72b84f8 100644 --- a/test/jobs/directo_invoice_forward_job_test.rb +++ b/test/jobs/directo_invoice_forward_job_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase +class DirectoInvoiceForwardLegacyJobTest < ActiveSupport::TestCase setup do @invoice = invoices(:one) @user = registrars(:bestnames) @@ -8,9 +8,9 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase end def teardown - Setting.directo_monthly_number_min = 309901 - Setting.directo_monthly_number_max = 309999 - Setting.directo_monthly_number_last = 309901 + Setting.directo_monthly_number_min = 309_901 + Setting.directo_monthly_number_max = 309_999 + Setting.directo_monthly_number_last = 309_901 end def test_directo_json_sends_customer_as_hash @@ -38,7 +38,7 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase end.to_return(status: 200, body: response) assert_nothing_raised do - DirectoInvoiceForwardJob.perform_now(monthly: false, dry: false) + DirectoInvoiceForwardLegacyJob.perform_now(monthly: false, dry: false) end assert_not_empty @invoice.directo_records.first.request @@ -49,10 +49,10 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase price = billing_prices(:create_one_year) activity.update!(activity_type: 'create', price: price) - Setting.directo_monthly_number_max = 30991 + Setting.directo_monthly_number_max = 30_991 assert_raises 'RuntimeError' do - DirectoInvoiceForwardJob.perform_now(monthly: true, dry: false) + DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false) end end @@ -78,7 +78,7 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase end.to_return(status: 200, body: response) assert_difference 'Setting.directo_monthly_number_last' do - DirectoInvoiceForwardJob.perform_now(monthly: true, dry: false) + DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false) end end @@ -103,7 +103,7 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase end.to_return(status: 200, body: response) assert_difference 'Setting.directo_monthly_number_last' do - DirectoInvoiceForwardJob.perform_now(monthly: true, dry: false) + DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false) end end @@ -126,7 +126,7 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase end.to_return(status: 200, body: response) assert_difference 'Setting.directo_monthly_number_last' do - DirectoInvoiceForwardJob.perform_now(monthly: true, dry: false) + DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false) end end @@ -148,7 +148,7 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase end.to_return(status: 200, body: response) assert_difference 'Setting.directo_monthly_number_last' do - DirectoInvoiceForwardJob.perform_now(monthly: true, dry: false) + DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false) end end @@ -186,7 +186,7 @@ class DirectoInvoiceForwardJobTest < ActiveSupport::TestCase (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'goodnames') end.to_return(status: 200, body: response) - DirectoInvoiceForwardJob.perform_now(monthly: true, dry: false) + DirectoInvoiceForwardLegacyJob.perform_now(monthly: true, dry: false) assert_requested first_registrar_stub assert_requested second_registrar_stub diff --git a/test/jobs/send_e_invoice_job_test.rb b/test/jobs/send_e_invoice_legacy_job_test.rb similarity index 66% rename from test/jobs/send_e_invoice_job_test.rb rename to test/jobs/send_e_invoice_legacy_job_test.rb index 0f2c683f2..35d5f5328 100644 --- a/test/jobs/send_e_invoice_job_test.rb +++ b/test/jobs/send_e_invoice_legacy_job_test.rb @@ -1,10 +1,14 @@ require 'test_helper' -class SendEInvoiceJobTest < ActiveJob::TestCase +class SendEInvoiceLegacyJobTest < ActiveJob::TestCase def teardown EInvoice.provider = EInvoice::Providers::TestProvider.new EInvoice::Providers::TestProvider.deliveries.clear + + msg = { message: 'success' } + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice") + .to_return(status: 200, body: msg.to_json, headers: {}) end def test_if_invoice_is_sent @@ -15,7 +19,7 @@ class SendEInvoiceJobTest < ActiveJob::TestCase assert_nothing_raised do perform_enqueued_jobs do - SendEInvoiceJob.perform_now(@invoice.id, payable: true) + SendEInvoiceLegacyJob.perform_now(@invoice.id, payable: true) end end @invoice.reload diff --git a/test/jobs/send_monthly_invoices_job_test.rb b/test/jobs/send_monthly_invoices_job_test.rb new file mode 100644 index 000000000..9fc5137ef --- /dev/null +++ b/test/jobs/send_monthly_invoices_job_test.rb @@ -0,0 +1,279 @@ +require 'test_helper' + +class SendMonthlyInvoicesJobTest < ActiveSupport::TestCase + include ActionMailer::TestHelper + + setup do + @user = registrars(:bestnames) + @date = Time.zone.parse('2010-08-06') + travel_to @date + ActionMailer::Base.deliveries.clear + EInvoice.provider = EInvoice::Providers::TestProvider.new + EInvoice::Providers::TestProvider.deliveries.clear + + response = { message: 'sucess' } + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice") + .to_return(status: 200, body: response.to_json, headers: {}) + end + + def teardown + Setting.directo_monthly_number_min = 309_901 + Setting.directo_monthly_number_max = 309_999 + Setting.directo_monthly_number_last = 309_901 + EInvoice.provider = EInvoice::Providers::TestProvider.new + EInvoice::Providers::TestProvider.deliveries.clear + end + + def test_fails_if_directo_bounds_exceedable + activity = account_activities(:one) + price = billing_prices(:create_one_year) + activity.update!(activity_type: 'create', price: price) + + Setting.directo_monthly_number_max = 30_991 + + assert_no_difference 'Directo.count' do + assert_raises 'RuntimeError' do + SendMonthlyInvoicesJob.perform_now + end + end + + assert_nil Invoice.find_by_monthly_invoice(true) + assert_emails 0 + assert_equal 0, EInvoice::Providers::TestProvider.deliveries.count + end + + def test_monthly_summary_is_not_delivered_if_dry + activity = account_activities(:one) + price = billing_prices(:create_one_year) + activity.update!(activity_type: 'create', price: price) + @user.update(language: 'et') + + assert_difference 'Setting.directo_monthly_number_last' do + assert_no_difference 'Directo.count' do + SendMonthlyInvoicesJob.perform_now(dry: true) + end + end + + invoice = Invoice.last + assert_equal 309_902, invoice.number + refute invoice.in_directo + assert invoice.e_invoice_sent_at.blank? + + assert_emails 0 + assert_equal 0, EInvoice::Providers::TestProvider.deliveries.count + end + + def test_monthly_summary_is_delivered_if_invoice_already_exists + @monthly_invoice = invoices(:one) + @monthly_invoice.update(number: 309_902, monthly_invoice: true, + issue_date: @date.last_month.end_of_month, + due_date: @date.last_month.end_of_month, + metadata: metadata, + in_directo: false, + e_invoice_sent_at: nil) + + 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(t)') && + (body.include? 'Domeenide ettemaks') && + (body.include? '309902') + end.to_return(status: 200, body: response) + + assert_no_difference 'Setting.directo_monthly_number_last' do + assert_difference('Directo.count', 1) do + SendMonthlyInvoicesJob.perform_now + end + end + + perform_enqueued_jobs + + invoice = Invoice.last + assert_equal 309_902, invoice.number + assert invoice.in_directo + assert_not invoice.e_invoice_sent_at.blank? + + assert_emails 1 + email = ActionMailer::Base.deliveries.last + assert_equal ['billing@bestnames.test'], email.to + assert_equal 'Invoice no. 309902 (monthly invoice)', email.subject + assert email.attachments['invoice-309902.pdf'] + + # assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count + end + + def test_monthly_summary_is_delivered_in_estonian + activity = account_activities(:one) + price = billing_prices(:create_one_month) + 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: 3 kuu(d)') && + (body.include? 'Domeenide ettemaks') && + (body.include? '309902') + end.to_return(status: 200, body: response) + + assert_difference 'Setting.directo_monthly_number_last' do + assert_difference('Directo.count', 1) do + SendMonthlyInvoicesJob.perform_now + end + end + + perform_enqueued_jobs + + invoice = Invoice.last + assert_equal 309_902, invoice.number + assert invoice.in_directo + assert_not invoice.e_invoice_sent_at.blank? + + assert_emails 1 + email = ActionMailer::Base.deliveries.last + assert_equal ['billing@bestnames.test'], email.to + assert_equal 'Invoice no. 309902 (monthly invoice)', email.subject + assert email.attachments['invoice-309902.pdf'] + + # assert_equal 1, EInvoice::Providers::TestProvider.deliveries.count + 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 + SendMonthlyInvoicesJob.perform_now + end + + perform_enqueued_jobs + + invoice = Invoice.last + assert_equal 309_902, invoice.number + assert invoice.in_directo + assert_not invoice.e_invoice_sent_at.blank? + 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? 'month(s)' + end.to_return(status: 200, body: response) + + assert_difference 'Setting.directo_monthly_number_last' do + SendMonthlyInvoicesJob.perform_now + end + + perform_enqueued_jobs + + invoice = Invoice.last + assert_equal 309_902, invoice.number + assert invoice.in_directo + assert_not invoice.e_invoice_sent_at.blank? + end + + def test_sends_each_monthly_invoice_separately + WebMock.reset! + + activity = account_activities(:one) + price = billing_prices(:create_one_year) + price.update(duration: 3.years) + activity.update(activity_type: 'create', price: price) + + # Creating account activity for second action + another_activity = activity.dup + another_activity.account = accounts(:two) + + AccountActivity.skip_callback(:create, :after, :update_balance) + another_activity.created_at = Time.zone.parse('2010-07-05 10:00') + another_activity.save + AccountActivity.set_callback(:create, :after, :update_balance) + + response = <<-XML + + + + + XML + + first_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request| + body = CGI.unescape(request.body) + (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'bestnames') + end.to_return(status: 200, body: response) + + second_registrar_stub = stub_request(:post, ENV['directo_invoice_url']).with do |request| + body = CGI.unescape(request.body) + (body.include? 'StartDate') && (body.include? 'EndDate') && (body.include? 'goodnames') + end.to_return(status: 200, body: response) + + assert_difference('Invoice.count', 2) do + assert_difference('Directo.count', 2) do + SendMonthlyInvoicesJob.perform_now + end + end + + perform_enqueued_jobs + + assert_requested first_registrar_stub + assert_requested second_registrar_stub + + assert_emails 2 + assert_equal 2, EInvoice::Providers::TestProvider.deliveries.count + end + + private + + def metadata + { + "items" => [ + { "description" => "Domeenide registreerimine - Juuli 2010" }, + { "product_id" => nil, "quantity" => 1, "unit" => "tk", "price" => 10.0, "description" => ".test registreerimine: 1 aasta(t)" }, + { "product_id" => "ETTEM06", "description" => "Domeenide ettemaks", "quantity" => -1, "price" => 10.0, "unit" => "tk" }, + ], + } + end +end \ No newline at end of file diff --git a/test/mailers/domain_delete_mailer_test.rb b/test/mailers/domain_delete_mailer_test.rb index 8e568846c..8bd2e0e92 100644 --- a/test/mailers/domain_delete_mailer_test.rb +++ b/test/mailers/domain_delete_mailer_test.rb @@ -73,4 +73,21 @@ class DomainDeleteMailerTest < ActionMailer::TestCase ' / Domain shop.test is in deletion process' \ ' / Домен shop.test в процессе удаления', email.subject end + + def test_forced_invalid_email + @domain.update(template_name: 'invalid_email') + @domain.reload + + email = DomainDeleteMailer.forced(domain: @domain, + registrar: @domain.registrar, + registrant: @domain.registrant, + template_name: @domain.template_name).deliver_now + + assert_emails 1 + assert_equal ['legal@registry.test'], email.from + assert @domain.force_delete_contact_emails.sort == email.to.sort + assert_equal 'Domeen shop.test on kustutusmenetluses' \ + ' / Domain shop.test is in deletion process' \ + ' / Домен shop.test в процессе удаления', email.subject + end end diff --git a/test/models/bank_transaction_test.rb b/test/models/bank_transaction_test.rb index 8a3a664b5..fbf2fdc59 100644 --- a/test/models/bank_transaction_test.rb +++ b/test/models/bank_transaction_test.rb @@ -4,6 +4,12 @@ class BankTransactionTest < ActiveSupport::TestCase setup do @registrar = registrars(:bestnames) @invoice = invoices(:one) + + response_message = { + message: 'got it' + } + stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_status') + .to_return(status: 200, body: response_message.to_json, headers: {}) end def test_matches_against_invoice_nubmber_and_reference_number @@ -16,87 +22,80 @@ class BankTransactionTest < ActiveSupport::TestCase end def test_binds_if_this_sum_invoice_already_present - 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') + 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 - end + assert_difference 'AccountActivity.count' do + transaction.autobind_invoice end end def test_binds_if_this_sum_cancelled_invoice_already_present - 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) + 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 - end + assert_difference 'AccountActivity.count' do + transaction.autobind_invoice end end def test_marks_the_first_one_as_paid_if_same_sum - 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') + 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 - end - - @invoice.reload - another_invoice.reload - assert(@invoice.paid?) - assert_not(another_invoice.paid?) + assert_difference 'AccountActivity.count' do + transaction.autobind_invoice 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 @@ -192,7 +191,7 @@ class BankTransactionTest < ActiveSupport::TestCase def test_parsed_ref_no_returns_nil_if_ref_not_found statement = BankTransaction.new - statement.description = "all invalid 12 123 55 77777 --" + statement.description = 'all invalid 12 123 55 77777 --' assert_nil statement.parsed_ref_number end @@ -208,6 +207,7 @@ class BankTransactionTest < ActiveSupport::TestCase transaction.bind_invoice('2222') end end + private def create_payable_invoice(attributes) diff --git a/test/models/billing/reference_no_test.rb b/test/models/billing/reference_no_test.rb index 15ac65dc4..5f22ff780 100644 --- a/test/models/billing/reference_no_test.rb +++ b/test/models/billing/reference_no_test.rb @@ -7,12 +7,10 @@ class ReferenceNoTest < ActiveSupport::TestCase end def test_generated_reference_number_conforms_to_format - 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: {}) + 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 + reference_no = Billing::ReferenceNo.generate + assert_match Billing::ReferenceNo::REGEXP, reference_no end end diff --git a/test/models/feature_test.rb b/test/models/feature_test.rb index f71979f11..9352deb70 100644 --- a/test/models/feature_test.rb +++ b/test/models/feature_test.rb @@ -1,53 +1,4 @@ require 'test_helper' class FeatureTest < ActiveSupport::TestCase - # setup do - # @domain = domains(:shop) - # @domain.apply_registry_lock(extensions_prohibited: false) - # end - # - # def test_if_obj_and_extensions_prohibited_enabled - # ENV['obj_and_extensions_prohibited'] = 'true' - # - # assert Feature.obj_and_extensions_statuses_enabled? - # - # statuses = DomainStatus.admin_statuses - # assert statuses.include? DomainStatus::SERVER_OBJ_UPDATE_PROHIBITED - # end - # - # def test_if_obj_and_extensions_prohibited_is_nil - # ENV['obj_and_extensions_prohibited'] = nil - # - # assert_not Feature.obj_and_extensions_statuses_enabled? - # - # statuses = DomainStatus.admin_statuses - # assert_not statuses.include? DomainStatus::SERVER_OBJ_UPDATE_PROHIBITED - # end - # - # def test_if_obj_and_extensions_prohibited_is_false - # ENV['obj_and_extensions_prohibited'] = 'false' - # - # assert_not Feature.obj_and_extensions_statuses_enabled? - # - # statuses = DomainStatus.admin_statuses - # assert_not statuses.include? DomainStatus::SERVER_OBJ_UPDATE_PROHIBITED - # end - # - # def test_if_enable_lock_domain_with_new_statuses_is_nil - # ENV['enable_lock_domain_with_new_statuses'] = nil - # - # assert_not Feature.enable_lock_domain_with_new_statuses? - # - # assert_equal @domain.statuses, ["serverObjUpdateProhibited", "serverDeleteProhibited", "serverTransferProhibited"] - # assert @domain.locked_by_registrant? - # end - # - # def test_if_enable_lock_domain_with_new_statuses_is_false - # ENV['enable_lock_domain_with_new_statuses'] = 'false' - # - # assert_not Feature.enable_lock_domain_with_new_statuses? - # - # assert_equal @domain.statuses, ["serverObjUpdateProhibited", "serverDeleteProhibited", "serverTransferProhibited"] - # assert @domain.locked_by_registrant? - # end end diff --git a/test/models/invoice_test.rb b/test/models/invoice_test.rb index d0cadb4ee..344af9dcc 100644 --- a/test/models/invoice_test.rb +++ b/test/models/invoice_test.rb @@ -118,69 +118,65 @@ class InvoiceTest < ActiveSupport::TestCase end def test_creates_invoice_with_bank_transaction_total - if Feature.billing_system_integrated? - registrar = registrars(:bestnames) - transaction = bank_transactions(:one).dup - transaction.reference_no = registrar.reference_no - transaction.sum = 250 + registrar = registrars(:bestnames) + transaction = bank_transactions(:one).dup + transaction.reference_no = registrar.reference_no + transaction.sum = 250 - 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: {}) + 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(: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: {}) + 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: {}) + 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 = 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: {}) + 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 + 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: {}) + 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 + transaction.sum = 0.99 + invoice = Invoice.create_from_transaction!(transaction) + assert_equal 0.99, invoice.total end def test_emails_invoice_after_creating_topup_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_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_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: {}) + 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: {}) + 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 + 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) + 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 + assert_emails 1 do + Invoice.create_from_transaction!(transaction) end end end diff --git a/test/models/registrar_test.rb b/test/models/registrar_test.rb index 71ebe0fc0..da9eeed9a 100644 --- a/test/models/registrar_test.rb +++ b/test/models/registrar_test.rb @@ -145,55 +145,47 @@ class RegistrarTest < ActiveJob::TestCase end def test_issues_new_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: {}) + 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: {}) + 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(: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: {}) + 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 + travel_to Time.zone.parse('2010-07-05') + Setting.days_to_keep_invoices_active = 10 - invoice = @registrar.issue_prepayment_invoice(100) + 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 + assert_equal Date.parse('2010-07-05'), invoice.issue_date + assert_equal Date.parse('2010-07-15'), invoice.due_date 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: {}) + 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: {}) + 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(: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 + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) EInvoice::Providers::TestProvider.deliveries.clear perform_enqueued_jobs do @registrar.issue_prepayment_invoice(100) end - - 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/system/admin_area/bank_statement_test.rb b/test/system/admin_area/bank_statement_test.rb index f86e6ef53..4117cf7ba 100644 --- a/test/system/admin_area/bank_statement_test.rb +++ b/test/system/admin_area/bank_statement_test.rb @@ -7,6 +7,9 @@ class AdminAreaBankStatementTest < ApplicationSystemTestCase @invoice = invoices(:one) Spy.on_instance_method(EisBilling::BaseController, :authorized).and_return(true) + response_message = { message: 'got it' } + stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_status') + .to_return(status: 200, body: response_message.to_json, headers: {}) end def test_update_bank_statement @@ -55,39 +58,37 @@ class AdminAreaBankStatementTest < ApplicationSystemTestCase end def test_can_bind_statement_transactions - 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) + 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) - 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(: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: {}) + 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: {}) + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice") + .to_return(status: 200, body: "", headers: {}) - registrar.issue_prepayment_invoice(500) - invoice = registrar.invoices.last + registrar.issue_prepayment_invoice(500) + invoice = registrar.invoices.last - create_bank_statement - click_link_or_button 'Add' - assert_text 'Create bank transaction' + 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' + 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' + click_link_or_button 'Back to bank statement' + click_link_or_button 'Bind invoices' - assert_text 'Invoices were fully binded' - end + assert_text 'Invoices were fully binded' end def create_bank_statement diff --git a/test/system/admin_area/registrars_test.rb b/test/system/admin_area/registrars_test.rb index 757875d1f..f3ee31020 100644 --- a/test/system/admin_area/registrars_test.rb +++ b/test/system/admin_area/registrars_test.rb @@ -14,30 +14,28 @@ class AdminRegistrarsSystemTest < ApplicationSystemTestCase end def test_creates_new_registrar - 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: {}) + stub_request(:post, "https://eis_billing_system:3000/api/v1/invoice_generator/reference_number_generator"). + to_return(status: 200, body: "{\"reference_number\":\"12332\"}", headers: {}) - assert_nil Registrar.find_by(name: 'Acme Ltd') + assert_nil Registrar.find_by(name: 'Acme Ltd') - visit admin_registrars_path - click_on 'New registrar' + visit admin_registrars_path + click_on 'New registrar' - 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' + 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 + assert_text 'Registrar has been successfully created' + assert_text 'Acme Ltd' end def test_updates_registrar 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 5cb32361f..3dfeb5a26 100644 --- a/test/system/registrar_area/billing/balance_top_up_test.rb +++ b/test/system/registrar_area/billing/balance_top_up_test.rb @@ -15,32 +15,30 @@ class BalanceTopUpTest < ApplicationSystemTestCase end def test_creates_new_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: {}) + 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(: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: {}) + 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 + Setting.registry_vat_prc = 0.1 - visit registrar_invoices_url - click_link_or_button 'Add deposit' - fill_in 'Amount', with: '25.5' + 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' + 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 end diff --git a/test/system/registrar_area/invoices/new_test.rb b/test/system/registrar_area/invoices/new_test.rb index a1b66ac47..16e30aeb7 100644 --- a/test/system/registrar_area/invoices/new_test.rb +++ b/test/system/registrar_area/invoices/new_test.rb @@ -17,59 +17,55 @@ class NewInvoiceTest < ApplicationSystemTestCase end def test_create_new_invoice_with_positive_amount - 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: {}) + 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(: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: {}) + 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' + 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' + 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 def test_create_new_invoice_with_comma_in_number - 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: {}) + 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(: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: {}) + 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' + 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' + 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 def test_create_new_invoice_fails_when_amount_is_0 diff --git a/test/tasks/invoices/process_payments_test.rb b/test/tasks/invoices/process_payments_test.rb index e368c5369..1ed65dc12 100644 --- a/test/tasks/invoices/process_payments_test.rb +++ b/test/tasks/invoices/process_payments_test.rb @@ -16,6 +16,12 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase @account_activity = account_activities(:one) @account = accounts(:cash) + response_message = { + message: 'got it' + } + stub_request(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_status') + .to_return(status: 200, body: response_message.to_json, headers: {}) + Setting.registry_iban = beneficiary_iban Lhv::ConnectApi.class_eval do @@ -63,7 +69,8 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase def test_cannot_create_new_invoice_if_transaction_binded_to_paid_invoice assert_not @invoice.paid? - @account_activity.update(activity_type: "add_credit", bank_transaction: nil, created_at: Time.zone.today - 1.day, creator_str: 'AdminUser') + @account_activity.update(activity_type: 'add_credit', bank_transaction: nil, + created_at: Time.zone.today - 1.day, creator_str: 'AdminUser') @invoice.update(account_activity: @account_activity, total: @payment_amount) assert @invoice.paid? @@ -77,33 +84,32 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase end def test_if_invoice_is_overdue_than_48_hours - if Feature.billing_system_integrated? - invoice_n = Invoice.order(number: :desc).last.number + invoice_n = Invoice.order(number: :desc).last.number - Spy.on_instance_method(SendEInvoiceTwoJob, :perform_now).and_return(true) + Spy.on_instance_method(SendEInvoiceJob, :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(: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(: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_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(: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? + 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? + @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 + assert_difference 'AccountActivity.count' do + assert_difference 'Invoice.count' do + capture_io { run_task } end end end @@ -162,31 +168,31 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase end 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}\"}") + 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}\"}") - 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(:post, 'https://eis_billing_system:3000/api/v1/invoice_generator/invoice_generator') + .to_return(status: 200, body: "{\"everypay_link\":\"http://link.test\"}", headers: {}) - Spy.on_instance_method(SendEInvoiceTwoJob, :perform_now).and_return(true) + Spy.on_instance_method(SendEInvoiceJob, :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(: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(: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) + registrar = registrars(:bestnames) - assert_changes -> { registrar.accounts.first.balance } do - run_task - end + assert_changes -> { registrar.accounts.first.balance } do + run_task + end - assert_changes -> { registrar.invoices.count } do - run_task - end + assert_changes -> { registrar.invoices.count } do + run_task end end @@ -198,40 +204,40 @@ class ProcessPaymentsTaskTest < ActiveJob::TestCase end def test_topup_creates_invoice_and_send_it_as_paid - 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: {}) + stub_request(:post, 'https://eis_billing_system:3000/api/v1/e_invoice/e_invoice') + .to_return(status: 200, body: '', 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: {}) + 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(: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: {}) + 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 + 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 + 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 def test_output diff --git a/test/tasks/registrars/reload_balance_test.rb b/test/tasks/registrars/reload_balance_test.rb index 0888fe3f4..934c6f6d0 100644 --- a/test/tasks/registrars/reload_balance_test.rb +++ b/test/tasks/registrars/reload_balance_test.rb @@ -21,30 +21,28 @@ class ReloadBalanceTaskTest < ActiveSupport::TestCase end def test_issues_invoice_when_auto_reload_is_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: {}) + 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: {}) + 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(: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: {}) + 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) + 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 + 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 def test_skips_issuing_invoice_when_threshold_is_not_reached @@ -66,51 +64,47 @@ class ReloadBalanceTaskTest < ActiveSupport::TestCase end def test_marks_registrar_as_pending_balance_reload - 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: {}) + 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: {}) + 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: {}) - registrar = registrar_with_auto_reload_enabled_and_threshold_reached + stub_request(:post, "https://eis_billing_system:3000/api/v1/e_invoice/e_invoice"). + to_return(status: 200, body: "", headers: {}) - capture_io { run_task } - registrar.reload + registrar = registrar_with_auto_reload_enabled_and_threshold_reached - assert registrar.settings['balance_auto_reload']['pending'] - end + capture_io { run_task } + registrar.reload + + assert registrar.settings['balance_auto_reload']['pending'] end def test_output - 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: {}) + 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: {}) + 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(: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: {}) + 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 + 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 + assert_output %(Registrar "Best Names" got #{number_to_currency(reload_amount, unit: 'EUR')}\nInvoiced total: 1\n) do + run_task end end