From 62c38d1f99ad50a51222e5016b6096778e07ae46 Mon Sep 17 00:00:00 2001 From: Artur Beljajev Date: Thu, 6 Sep 2018 12:09:57 +0300 Subject: [PATCH] Add balance auto reload Closes #329 --- Gemfile | 1 + Gemfile.lock | 11 +++ .../registrar/account_controller.rb | 5 ++ .../balance_auto_reload_controller.rb | 52 ++++++++++++ app/models/ability.rb | 1 + .../balance_auto_reload_types/threshold.rb | 25 ++++++ app/models/bank_transaction.rb | 26 ++++-- app/models/invoice.rb | 5 ++ app/models/invoice/e_invoice_generator.rb | 77 ++++++++++++++++++ app/models/registrar.rb | 4 + .../account/_balance_auto_reload.html.erb | 30 +++++++ app/views/registrar/account/show.html.erb | 10 ++- .../balance_auto_reload/_form.html.erb | 1 + .../balance_auto_reload/edit.html.erb | 10 +++ .../form/types/_threshold.erb | 40 ++++++++++ config/application-example.yml | 4 + config/initializers/e_invoice.rb | 3 + config/locales/registrar/account.en.yml | 9 +++ .../settings/balance_auto_reload.en.yml | 19 +++++ config/routes.rb | 4 + .../20190426174225_add_registrars_settings.rb | 5 ++ db/structure.sql | 5 +- lib/tasks/registrars/reload_balance.rake | 35 ++++++++ .../settings/balance_auto_reload_test.rb | 32 ++++++++ .../threshold_test.rb | 62 +++++++++++++++ test/models/bank_transaction_test.rb | 41 ++++++++-- test/models/registrar_test.rb | 6 ++ .../settings/balance_auto_reload_test.rb | 74 +++++++++++++++++ test/tasks/registrars/reload_balance_test.rb | 79 +++++++++++++++++++ 29 files changed, 660 insertions(+), 16 deletions(-) create mode 100644 app/controllers/registrar/settings/balance_auto_reload_controller.rb create mode 100644 app/models/balance_auto_reload_types/threshold.rb create mode 100644 app/models/invoice/e_invoice_generator.rb create mode 100644 app/views/registrar/account/_balance_auto_reload.html.erb create mode 100644 app/views/registrar/settings/balance_auto_reload/_form.html.erb create mode 100644 app/views/registrar/settings/balance_auto_reload/edit.html.erb create mode 100644 app/views/registrar/settings/balance_auto_reload/form/types/_threshold.erb create mode 100644 config/initializers/e_invoice.rb create mode 100644 config/locales/registrar/settings/balance_auto_reload.en.yml create mode 100644 db/migrate/20190426174225_add_registrars_settings.rb create mode 100644 lib/tasks/registrars/reload_balance.rake create mode 100644 test/integration/registrar_area/settings/balance_auto_reload_test.rb create mode 100644 test/models/balance_auto_reload_types/threshold_test.rb create mode 100644 test/system/registrar_area/settings/balance_auto_reload_test.rb create mode 100644 test/tasks/registrars/reload_balance_test.rb diff --git a/Gemfile b/Gemfile index f50f6f06a..a9b78afdb 100644 --- a/Gemfile +++ b/Gemfile @@ -90,6 +90,7 @@ gem 'active_model-errors_details' # Backport from Rails 5, https://github.com/ra gem 'airbrake' gem 'company_register', github: 'internetee/company_register', branch: :master +gem 'e_invoice', github: 'internetee/e_invoice', branch: :master group :development do # deploy diff --git a/Gemfile.lock b/Gemfile.lock index 5b8262a24..02c588704 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,6 +15,16 @@ GIT data_migrate (1.3.0) rails (>= 4.1.0) +GIT + remote: https://github.com/internetee/e_invoice.git + revision: 7817bbefd4ed0b140ed781172bd64a856b622273 + branch: master + specs: + e_invoice (0.1.0) + builder (~> 3.2) + nokogiri + savon + GIT remote: https://github.com/internetee/epp-xml.git revision: 5dd542e67ef26d58365f30e553254d6db809277d @@ -456,6 +466,7 @@ DEPENDENCIES database_cleaner devise (~> 4.0) digidoc_client! + e_invoice! epp (= 1.5.0)! epp-xml (= 1.1.0)! factory_bot_rails diff --git a/app/controllers/registrar/account_controller.rb b/app/controllers/registrar/account_controller.rb index 0bb40ae3c..2f486dccc 100644 --- a/app/controllers/registrar/account_controller.rb +++ b/app/controllers/registrar/account_controller.rb @@ -2,6 +2,7 @@ class Registrar class AccountController < BaseController skip_authorization_check helper_method :iban_max_length + helper_method :balance_auto_reload_setting def show; end @@ -25,5 +26,9 @@ class Registrar def iban_max_length Iban.max_length end + + def balance_auto_reload_setting + current_registrar_user.registrar.settings['balance_auto_reload'] + end end end \ No newline at end of file diff --git a/app/controllers/registrar/settings/balance_auto_reload_controller.rb b/app/controllers/registrar/settings/balance_auto_reload_controller.rb new file mode 100644 index 000000000..ad970855a --- /dev/null +++ b/app/controllers/registrar/settings/balance_auto_reload_controller.rb @@ -0,0 +1,52 @@ +class Registrar + module Settings + class BalanceAutoReloadController < BaseController + before_action :authorize + + def edit + @type = if current_registrar.settings['balance_auto_reload'] + type_params = current_registrar.settings['balance_auto_reload']['type'] + .except('name') + BalanceAutoReloadTypes::Threshold.new(type_params) + else + BalanceAutoReloadTypes::Threshold.new + end + end + + def update + type = BalanceAutoReloadTypes::Threshold.new(type_params) + current_registrar.update!(settings: { balance_auto_reload: { type: type } }) + + redirect_to registrar_account_path, notice: t('.saved') + end + + def destroy + current_registrar.settings.delete('balance_auto_reload') + current_registrar.save! + + redirect_to registrar_account_path, notice: t('.disabled') + end + + private + + def type_params + permitted_params = params.require(:type).permit(:amount, :threshold) + normalize_params(permitted_params) + end + + def normalize_params(params) + params[:amount] = params[:amount].to_f + params[:threshold] = params[:threshold].to_f + params + end + + def authorize + authorize!(:manage, :balance_auto_reload) + end + + def current_registrar + current_registrar_user.registrar + end + end + end +end \ No newline at end of file diff --git a/app/models/ability.rb b/app/models/ability.rb index 8ca94d89b..33c276492 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -72,6 +72,7 @@ class Ability can(:manage, Invoice) { |i| i.buyer_id == @user.registrar_id } can :manage, :deposit can :read, AccountActivity + can :manage, :balance_auto_reload end def customer_service # Admin/admin_user dynamic role diff --git a/app/models/balance_auto_reload_types/threshold.rb b/app/models/balance_auto_reload_types/threshold.rb new file mode 100644 index 000000000..e14f8886b --- /dev/null +++ b/app/models/balance_auto_reload_types/threshold.rb @@ -0,0 +1,25 @@ +module BalanceAutoReloadTypes + class Threshold + include ActiveModel::Model + + attr_accessor :amount + attr_accessor :threshold + + validates :amount, numericality: { greater_than_or_equal_to: :min_amount } + validates :threshold, numericality: { greater_than_or_equal_to: 0 } + + def min_amount + Setting.minimum_deposit + end + + def as_json(options) + { name: name }.merge(super) + end + + private + + def name + self.class.name.demodulize.underscore + end + end +end \ No newline at end of file diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index aa4348262..eb8c84622 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -79,13 +79,23 @@ class BankTransaction < ActiveRecord::Base end def create_activity(registrar, invoice) - create_account_activity( - account: registrar.cash_account, - invoice: invoice, - sum: invoice.subtotal, - currency: currency, - description: description, - activity_type: AccountActivity::ADD_CREDIT - ) + ActiveRecord::Base.transaction do + create_account_activity!(account: registrar.cash_account, + invoice: invoice, + sum: invoice.subtotal, + currency: currency, + description: description, + activity_type: AccountActivity::ADD_CREDIT) + reset_pending_registrar_balance_reload + end + end + + private + + def reset_pending_registrar_balance_reload + return unless registrar.settings['balance_auto_reload'] + + registrar.settings['balance_auto_reload'].delete('pending') + registrar.save! end end diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 7a8512e28..a36825848 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -98,6 +98,11 @@ class Invoice < ActiveRecord::Base generator.as_pdf end + def to_e_invoice + generator = Invoice::EInvoiceGenerator.new(self) + generator.generate + end + private def apply_default_buyer_vat_no diff --git a/app/models/invoice/e_invoice_generator.rb b/app/models/invoice/e_invoice_generator.rb new file mode 100644 index 000000000..8ade3ae7f --- /dev/null +++ b/app/models/invoice/e_invoice_generator.rb @@ -0,0 +1,77 @@ +class Invoice + class EInvoiceGenerator + attr_reader :invoice + + def initialize(invoice) + @invoice = invoice + end + + def generate + seller = EInvoice::Seller.new + seller.name = invoice.seller_name + seller.registration_number = invoice.seller_reg_no + seller.vat_number = invoice.seller_vat_no + + seller_legal_address = EInvoice::Address.new + seller_legal_address.line1 = invoice.seller_street + seller_legal_address.line2 = invoice.seller_state + seller_legal_address.postal_code = invoice.seller_zip + seller_legal_address.city = invoice.seller_city + seller_legal_address.country = invoice.seller_country + seller.legal_address = seller_legal_address + + buyer = EInvoice::Buyer.new + buyer.name = invoice.buyer_name + buyer.registration_number = invoice.buyer_reg_no + buyer.vat_number = invoice.buyer_vat_no + buyer.email = invoice.buyer.billing_email + + buyer_bank_account = EInvoice::BankAccount.new + buyer_bank_account.number = invoice.buyer.e_invoice_iban + buyer.bank_account = buyer_bank_account + + buyer_legal_address = EInvoice::Address.new + buyer_legal_address.line1 = invoice.buyer_street + buyer_legal_address.line2 = invoice.buyer_state + buyer_legal_address.postal_code = invoice.buyer_zip + buyer_legal_address.city = invoice.buyer_city + buyer_legal_address.country = invoice.buyer_country + buyer.legal_address = buyer_legal_address + + 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_items << e_invoice_invoice_item + end + + e_invoice_invoice = EInvoice::Invoice.new.tap do |i| + i.seller = seller + i.buyer = buyer + i.items = e_invoice_invoice_items + i.number = invoice.number + i.date = invoice.issue_date + i.recipient_id_code = invoice.buyer_reg_no + i.reference_number = invoice.reference_no + i.due_date = invoice.due_date + i.beneficiary_name = invoice.seller_name + i.beneficiary_account_number = invoice.seller_iban + i.payer_name = invoice.buyer_name + i.subtotal = invoice.subtotal + i.vat_amount = invoice.vat_amount + i.total = invoice.total + i.currency = invoice.currency + end + + EInvoice::EInvoice.new(date: Time.zone.today, invoice: e_invoice_invoice) + end + end +end \ No newline at end of file diff --git a/app/models/registrar.rb b/app/models/registrar.rb index d3efa9dff..5c457a6ab 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -165,6 +165,10 @@ class Registrar < ActiveRecord::Base notifications.create!(text: text) end + def e_invoice_iban + iban + end + private def set_defaults diff --git a/app/views/registrar/account/_balance_auto_reload.html.erb b/app/views/registrar/account/_balance_auto_reload.html.erb new file mode 100644 index 000000000..9b6f2791a --- /dev/null +++ b/app/views/registrar/account/_balance_auto_reload.html.erb @@ -0,0 +1,30 @@ +
+
+ <%= t '.header' %> +
+ +
+ <% if setting %> + <%= t '.enabled' %> + <%= t '.enabled_state_details', amount: number_to_currency(setting['type']['amount']), + threshold: number_to_currency(setting['type']['threshold']) %> + <% else %> + <%= t '.disabled' %> + <% end %> +
+ + +
\ No newline at end of file diff --git a/app/views/registrar/account/show.html.erb b/app/views/registrar/account/show.html.erb index 46813fa96..75d0ce400 100644 --- a/app/views/registrar/account/show.html.erb +++ b/app/views/registrar/account/show.html.erb @@ -12,4 +12,12 @@
<%= render 'linked_users', linked_users: current_registrar_user.linked_users %>
- \ No newline at end of file + + +<% if can?(:manage, :balance_auto_reload) %> +
+
+ <%= render 'balance_auto_reload', setting: balance_auto_reload_setting %> +
+
+<% end %> \ No newline at end of file diff --git a/app/views/registrar/settings/balance_auto_reload/_form.html.erb b/app/views/registrar/settings/balance_auto_reload/_form.html.erb new file mode 100644 index 000000000..ecd34980e --- /dev/null +++ b/app/views/registrar/settings/balance_auto_reload/_form.html.erb @@ -0,0 +1 @@ +<%= render 'registrar/settings/balance_auto_reload/form/types/threshold', type: @type %> \ No newline at end of file diff --git a/app/views/registrar/settings/balance_auto_reload/edit.html.erb b/app/views/registrar/settings/balance_auto_reload/edit.html.erb new file mode 100644 index 000000000..20aa88d2d --- /dev/null +++ b/app/views/registrar/settings/balance_auto_reload/edit.html.erb @@ -0,0 +1,10 @@ + + + + +<%= render 'form' %> \ No newline at end of file diff --git a/app/views/registrar/settings/balance_auto_reload/form/types/_threshold.erb b/app/views/registrar/settings/balance_auto_reload/form/types/_threshold.erb new file mode 100644 index 000000000..bcb649421 --- /dev/null +++ b/app/views/registrar/settings/balance_auto_reload/form/types/_threshold.erb @@ -0,0 +1,40 @@ +

<%= t '.description' %>

+ +<%= form_for type, as: :type, url: registrar_settings_balance_auto_reload_path, method: :patch, + html: { class: 'form-horizontal' } do |f| %> + <%= render 'form_errors', target: type %> + +
+ <%= f.label :amount, class: 'col-md-2 control-label' %> + +
+
+ <%= f.money_field :amount, required: true, autofocus: true, class: 'form-control' %> +
<%= Money::default_currency.symbol %>
+
+
+ +
+ <%= t '.amount_hint', min_amount: f.object.min_amount %> +
+
+ +
+ <%= f.label :threshold, class: 'col-md-2 control-label' %> + +
+
+ <%= f.money_field :threshold, required: true, class: 'form-control' %> +
<%= Money::default_currency.symbol %>
+
+
+
+ +
+ +
+
+ <%= f.submit t('.submit_btn'), class: 'btn btn-success' %> +
+
+<% end %> \ No newline at end of file diff --git a/config/application-example.yml b/config/application-example.yml index 0d4417e3c..0738a9278 100644 --- a/config/application-example.yml +++ b/config/application-example.yml @@ -135,6 +135,10 @@ payments_every_pay_seller_account: 'EUR3D1' payments_every_pay_api_user: 'api_user' payments_every_pay_api_key: 'api_key' +e_invoice_provider_name: 'omniva' +e_invoice_provider_password: +e_invoice_provider_test_mode: 'false' + user_session_timeout: '3600' # 1 hour secure_session_cookies: 'false' # true|false same_site_session_cookies: 'false' # false|strict|lax diff --git a/config/initializers/e_invoice.rb b/config/initializers/e_invoice.rb new file mode 100644 index 000000000..d6d791c7b --- /dev/null +++ b/config/initializers/e_invoice.rb @@ -0,0 +1,3 @@ +provider_config = { password: ENV['e_invoice_provider_password'], + test_mode: ENV['e_invoice_provider_test_mode'] == 'true' } +EInvoice.provider = EInvoice::Providers::OmnivaProvider.new(provider_config) \ No newline at end of file diff --git a/config/locales/registrar/account.en.yml b/config/locales/registrar/account.en.yml index a4f3f8f2a..f572c77c4 100644 --- a/config/locales/registrar/account.en.yml +++ b/config/locales/registrar/account.en.yml @@ -21,3 +21,12 @@ en: linked_users: header: Linked users switch_btn: Switch + + balance_auto_reload: + header: Balance Auto-Reload + enabled: Enabled + enabled_state_details: Reload %{amount} when your balance drops to %{threshold} + disabled: Disabled + enable_btn: Enable + disable_btn: Disable + edit_btn: Edit \ No newline at end of file diff --git a/config/locales/registrar/settings/balance_auto_reload.en.yml b/config/locales/registrar/settings/balance_auto_reload.en.yml new file mode 100644 index 000000000..71e8e25f9 --- /dev/null +++ b/config/locales/registrar/settings/balance_auto_reload.en.yml @@ -0,0 +1,19 @@ +en: + registrar: + settings: + balance_auto_reload: + edit: + header: Balance Auto-Reload + + form: + types: + threshold: + description: Automatically reload your balance when it drops to a minimum threshold + amount_hint: must be greater than or equal to %{min_amount} + submit_btn: Save + + update: + saved: Balance Auto-Reload setting has been updated + + destroy: + disabled: Balance Auto-Reload setting has been disabled \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 216946a08..5ffa5e50b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -115,6 +115,10 @@ Rails.application.routes.draw do put 'pay/return/:bank' => 'payments#back' post 'pay/callback/:bank' => 'payments#callback', as: 'response_payment_with' get 'pay/go/:bank' => 'payments#pay', as: 'payment_with' + + namespace :settings do + resource :balance_auto_reload, controller: :balance_auto_reload, only: %i[edit update destroy] + end end scope :registrar do diff --git a/db/migrate/20190426174225_add_registrars_settings.rb b/db/migrate/20190426174225_add_registrars_settings.rb new file mode 100644 index 000000000..dfed56db9 --- /dev/null +++ b/db/migrate/20190426174225_add_registrars_settings.rb @@ -0,0 +1,5 @@ +class AddRegistrarsSettings < ActiveRecord::Migration + def change + add_column :registrars, :settings, :jsonb, null: false, default: '{}' + end +end \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 629aec4a8..480787b93 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -2201,7 +2201,8 @@ CREATE TABLE public.registrars ( test_registrar boolean DEFAULT false, language character varying NOT NULL, vat_rate numeric(4,3), - iban character varying + iban character varying, + settings jsonb DEFAULT '{}'::jsonb NOT NULL ); @@ -4963,6 +4964,8 @@ INSERT INTO schema_migrations (version) VALUES ('20190328151838'); INSERT INTO schema_migrations (version) VALUES ('20190415120246'); +INSERT INTO schema_migrations (version) VALUES ('20190426174225'); + INSERT INTO schema_migrations (version) VALUES ('20190510090240'); INSERT INTO schema_migrations (version) VALUES ('20190510102549'); diff --git a/lib/tasks/registrars/reload_balance.rake b/lib/tasks/registrars/reload_balance.rake new file mode 100644 index 000000000..7f1cb2497 --- /dev/null +++ b/lib/tasks/registrars/reload_balance.rake @@ -0,0 +1,35 @@ +namespace :registrars do + desc 'Reloads balance of registrars' + + task reload_balance: :environment do + include ActionView::Helpers::NumberHelper + invoiced_registrar_count = 0 + + Registrar.transaction do + Registrar.all.each do |registrar| + balance_auto_reload_setting = registrar.settings['balance_auto_reload'] + next unless balance_auto_reload_setting + + reload_pending = balance_auto_reload_setting['pending'] + threshold_reached = registrar.balance <= balance_auto_reload_setting['type']['threshold'] + reload_amount = balance_auto_reload_setting['type']['amount'] + + next if reload_pending || !threshold_reached + + Registrar.transaction do + invoice = registrar.issue_prepayment_invoice(reload_amount) + e_invoice = invoice.to_e_invoice + e_invoice.deliver + + registrar.settings['balance_auto_reload']['pending'] = true + registrar.save! + end + + puts %(Registrar "#{registrar}" got #{number_to_currency(reload_amount, unit: 'EUR')}) + invoiced_registrar_count += 1 + end + end + + puts "Invoiced total: #{invoiced_registrar_count}" + end +end \ No newline at end of file diff --git a/test/integration/registrar_area/settings/balance_auto_reload_test.rb b/test/integration/registrar_area/settings/balance_auto_reload_test.rb new file mode 100644 index 000000000..2c89630ea --- /dev/null +++ b/test/integration/registrar_area/settings/balance_auto_reload_test.rb @@ -0,0 +1,32 @@ +require 'test_helper' + +class RegistrarAreaSettingsBalanceAutoReloadIntegrationTest < ActionDispatch::IntegrationTest + include Devise::Test::IntegrationHelpers + + setup do + @registrar = registrars(:bestnames) + sign_in users(:api_bestnames) + end + + def test_updates_balance_auto_reload_setting + amount = 100 + threshold = 10 + assert_nil @registrar.settings['balance_auto_reload'] + + patch registrar_settings_balance_auto_reload_path, { type: { amount: amount, + threshold: threshold } } + @registrar.reload + + assert_equal amount, @registrar.settings['balance_auto_reload']['type']['amount'] + assert_equal threshold, @registrar.settings['balance_auto_reload']['type']['threshold'] + end + + def test_disables_balance_auto_reload_setting + @registrar.update!(settings: { balance_auto_reload: { amount: 'any', threshold: 'any' } }) + + delete registrar_settings_balance_auto_reload_path + @registrar.reload + + assert_nil @registrar.settings['balance_auto_reload'] + end +end \ No newline at end of file diff --git a/test/models/balance_auto_reload_types/threshold_test.rb b/test/models/balance_auto_reload_types/threshold_test.rb new file mode 100644 index 000000000..a6a3691d0 --- /dev/null +++ b/test/models/balance_auto_reload_types/threshold_test.rb @@ -0,0 +1,62 @@ +require 'test_helper' + +class BalanceAutoReloadTypes::ThresholdTest < ActiveSupport::TestCase + setup do + @original_min_reload_amount = Setting.minimum_deposit + end + + teardown do + Setting.minimum_deposit = @original_min_reload_amount + end + + def test_valid_fixture_is_valid + assert valid_type.valid? + end + + def test_invalid_without_amount + type = valid_type + type.amount = nil + assert type.invalid? + end + + def test_invalid_when_amount_is_smaller_than_required_minimum + type = valid_type + Setting.minimum_deposit = 0.02 + + type.amount = 0.01 + + assert type.invalid? + end + + def test_valid_when_amount_equals_allowed_minimum + type = valid_type + Setting.minimum_deposit = 0.02 + + type.amount = 0.02 + + assert type.valid? + end + + def test_invalid_without_threshold + type = valid_type + type.threshold = nil + assert type.invalid? + end + + def test_invalid_when_threshold_is_less_than_zero + type = valid_type + type.threshold = -1 + assert type.invalid? + end + + def test_serializes_to_json + type = BalanceAutoReloadTypes::Threshold.new(amount: 100, threshold: 10) + assert_equal ({ name: 'threshold', amount: 100, threshold: 10 }).to_json, type.to_json + end + + private + + def valid_type + BalanceAutoReloadTypes::Threshold.new(amount: Setting.minimum_deposit, threshold: 0) + end +end \ No newline at end of file diff --git a/test/models/bank_transaction_test.rb b/test/models/bank_transaction_test.rb index 4955b020d..0e4d88bd6 100644 --- a/test/models/bank_transaction_test.rb +++ b/test/models/bank_transaction_test.rb @@ -1,8 +1,13 @@ require 'test_helper' class BankTransactionTest < ActiveSupport::TestCase - def test_matches_against_invoice_reference_number - invoices(:one).update!(account_activity: nil, number: '2222', total: 10, reference_no: '1111') + setup do + @registrar = registrars(:bestnames) + @invoice = invoices(:one) + end + + def test_matches_against_invoice_number_and_reference_number + create_payable_invoice(number: '2222', total: 10, reference_no: '1111') transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1111') assert_difference 'AccountActivity.count' do @@ -10,8 +15,19 @@ class BankTransactionTest < ActiveSupport::TestCase end end + def test_resets_pending_registrar_balance_reload + registrar = registrar_with_pending_balance_auto_reload + create_payable_invoice(number: '2222', total: 10, reference_no: '1111') + transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1111') + + transaction.autobind_invoice + registrar.reload + + assert_nil registrar.settings['balance_auto_reload']['pending'] + end + def test_does_not_match_against_registrar_reference_number - registrars(:bestnames).update!(reference_no: '1111') + @registrar.update!(reference_no: '1111') transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1111') assert_no_difference 'AccountActivity.count' do @@ -20,7 +36,7 @@ class BankTransactionTest < ActiveSupport::TestCase end def test_underpayment_is_not_matched_with_invoice - invoices(:one).update!(account_activity: nil, number: '2222', total: 10) + create_payable_invoice(number: '2222', total: 10) transaction = BankTransaction.new(sum: 9) assert_no_difference 'AccountActivity.count' do @@ -30,7 +46,7 @@ class BankTransactionTest < ActiveSupport::TestCase end def test_overpayment_is_not_matched_with_invoice - invoices(:one).update!(account_activity: nil, number: '2222', total: 10) + create_payable_invoice(number: '2222', total: 10) transaction = BankTransaction.new(sum: 11) assert_no_difference 'AccountActivity.count' do @@ -40,7 +56,7 @@ class BankTransactionTest < ActiveSupport::TestCase end def test_cancelled_invoice_is_not_matched - invoices(:one).update!(account_activity: nil, number: '2222', total: 10, cancelled_at: '2010-07-05') + @invoice.update!(account_activity: nil, number: '2222', total: 10, cancelled_at: '2010-07-05') transaction = BankTransaction.new(sum: 10) assert_no_difference 'AccountActivity.count' do @@ -48,4 +64,17 @@ class BankTransactionTest < ActiveSupport::TestCase end assert transaction.errors.full_messages.include?('Cannot bind cancelled invoice') end + + private + + def create_payable_invoice(attributes) + payable_attributes = { account_activity: nil } + @invoice.update!(payable_attributes.merge(attributes)) + @invoice + end + + def registrar_with_pending_balance_auto_reload + @registrar.update!(settings: { balance_auto_reload: { pending: true } }) + @registrar + end end diff --git a/test/models/registrar_test.rb b/test/models/registrar_test.rb index ad5779475..e8eae1f34 100644 --- a/test/models/registrar_test.rb +++ b/test/models/registrar_test.rb @@ -176,6 +176,12 @@ class RegistrarTest < ActiveSupport::TestCase assert_equal vat_country, registrar.vat_country end + def test_returns_iban_for_e_invoice_delivery_channel + iban = 'GB33BUKB20201555555555' + registrar = Registrar.new(iban: iban) + assert_equal iban, registrar.e_invoice_iban + end + private def valid_registrar diff --git a/test/system/registrar_area/settings/balance_auto_reload_test.rb b/test/system/registrar_area/settings/balance_auto_reload_test.rb new file mode 100644 index 000000000..a5ad6dec1 --- /dev/null +++ b/test/system/registrar_area/settings/balance_auto_reload_test.rb @@ -0,0 +1,74 @@ +require 'test_helper' + +class RegistrarAreaSettingsBalanceAutoReloadTest < ApplicationSystemTestCase + setup do + @registrar = registrars(:bestnames) + @user = users(:api_bestnames) + sign_in @user + end + + def test_enables_balance_auto_reload + amount = 100 + threshold = 10 + assert_nil @registrar.settings['balance_auto_reload'] + + visit registrar_account_path + click_on 'Enable' + fill_in 'Amount', with: amount + fill_in 'Threshold', with: threshold + click_button 'Save' + + assert_current_path registrar_account_path + assert_text 'Balance Auto-Reload setting has been updated' + + # Using `number_to_currency` leads to `expected to find text "Reload 100,00 € when your balance + # drops to 10,00 €" in "...Reload 100,00 € when your balance drops to 10,00 €...` + assert_text 'Reload 100,00 € when your balance drops to 10,00 €' + end + + def test_disables_balance_auto_reload + @registrar.update!(settings: { balance_auto_reload: { type: {} } }) + + visit registrar_account_path + click_on 'Disable' + + assert_current_path registrar_account_path + assert_text 'Balance Auto-Reload setting has been disabled' + end + + def test_edits_balance_auto_reload + @registrar.update!(settings: { balance_auto_reload: { type: { name: 'threshold', + amount: 100, + threshold: 10 } } }) + + visit registrar_account_path + within '.balance-auto-reload' do + click_on 'Edit' + end + fill_in 'Amount', with: '101' + fill_in 'Threshold', with: '11' + click_button 'Save' + + assert_current_path registrar_account_path + assert_text 'Balance Auto-Reload setting has been updated' + end + + def test_form_is_pre_populated_when_editing + amount = 100 + threshold = 10 + @registrar.update!(settings: { balance_auto_reload: { type: { name: 'threshold', + amount: amount, + threshold: threshold } } }) + + visit edit_registrar_settings_balance_auto_reload_path + + assert_field 'Amount', with: amount + assert_field 'Threshold', with: threshold + end + + def test_user_of_epp_role_cannot_edit_balance_auto_reload_setting + @user.update!(roles: [ApiUser::EPP]) + visit registrar_account_path + assert_no_text 'Balance Auto-Reload' + end +end \ No newline at end of file diff --git a/test/tasks/registrars/reload_balance_test.rb b/test/tasks/registrars/reload_balance_test.rb new file mode 100644 index 000000000..86b305dfb --- /dev/null +++ b/test/tasks/registrars/reload_balance_test.rb @@ -0,0 +1,79 @@ +require 'test_helper' + +class ReloadBalanceTaskTest < ActiveSupport::TestCase + include ActionView::Helpers::NumberHelper + + setup do + @registrar = registrars(:bestnames) + EInvoice.provider = EInvoice::Providers::TestProvider.new + end + + def test_issues_invoice_when_auto_reload_is_enabled_and_threshold_reached + reload_amount = 100 + registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount) + + assert_difference -> { registrar.invoices.count } do + capture_io { run_task } + end + + invoice = registrar.invoices.last + assert_equal reload_amount, invoice.subtotal + end + + def test_skips_issuing_invoice_when_threshold_is_not_reached + registrar = registrar_with_auto_reload_enabled_and_threshold_not_reached + + assert_no_difference -> { registrar.invoices.count } do + capture_io { run_task } + end + end + + def test_skips_issuing_invoice_when_balance_reload_is_pending + registrar = registrar_with_auto_reload_enabled_and_threshold_reached + registrar.settings['balance_auto_reload']['pending'] = true + registrar.save! + + assert_no_difference -> { registrar.invoices.count } do + capture_io { run_task } + end + end + + def test_marks_registrar_as_pending_balance_reload + registrar = registrar_with_auto_reload_enabled_and_threshold_reached + + capture_io { run_task } + registrar.reload + + assert registrar.settings['balance_auto_reload']['pending'] + end + + def test_output + reload_amount = 100 + registrar = registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount) + assert_equal 'Best Names', registrar.name + + assert_output %(Registrar "Best Names" got #{number_to_currency(reload_amount, unit: 'EUR')}\nInvoiced total: 1\n) do + run_task + end + end + + private + + def registrar_with_auto_reload_enabled_and_threshold_reached(reload_amount = 100) + auto_reload_type = BalanceAutoReloadTypes::Threshold.new(amount: reload_amount, threshold: 10) + @registrar.update!(settings: { balance_auto_reload: { type: auto_reload_type } }) + @registrar.accounts.first.update!(balance: 10) + @registrar + end + + def registrar_with_auto_reload_enabled_and_threshold_not_reached + auto_reload_type = BalanceAutoReloadTypes::Threshold.new(amount: 100, threshold: 10) + @registrar.update!(settings: { balance_auto_reload: { type: auto_reload_type } }) + @registrar.accounts.first.update!(balance: 11) + @registrar + end + + def run_task + Rake::Task['registrars:reload_balance'].execute + end +end \ No newline at end of file