diff --git a/app/models/billing/service/renew.rb b/app/models/billing/service/renew.rb index 6dd41e956..eedc5b9f3 100644 --- a/app/models/billing/service/renew.rb +++ b/app/models/billing/service/renew.rb @@ -27,12 +27,12 @@ def perform provisioning_object.after_failed_renew provisioning_object.after_renew Rails.logger.info { "Not enough balance to renew billing service ##{service.id}" } + nil else service.update!(state_id: Billing::Service::STATE_ID_ACTIVE, renew_at: next_renew_at) - transaction = create_transaction + create_transaction unless service.renew_price.zero? provisioning_object.after_success_renew provisioning_object.after_renew - transaction Rails.logger.info { "Success renew billing service ##{service.id}" } end end @@ -65,6 +65,12 @@ def next_renew_at end def enough_balance? - account.balance - account.min_balance >= service.renew_price + if service.renew_price.positive? + account.balance - service.renew_price >= account.min_balance + elsif service.renew_price.negative? + account.balance - service.renew_price <= account.max_balance + else # service.renew_price.zero? + true + end end end diff --git a/db/custom_seeds/network_prefixes.rb b/db/custom_seeds/network_prefixes.rb index ef6eb94ac..2d046dcf7 100644 --- a/db/custom_seeds/network_prefixes.rb +++ b/db/custom_seeds/network_prefixes.rb @@ -1,43 +1,46 @@ # frozen_string_literal: true -puts 'loading global data' # rubocop:disable Rails/Output +# rubocop:disable Rails/Output +puts 'loading global data' network_types = YAML.load_file('db/network_types.yml') networks = YAML.load_file('db/networks.yml') countries = YAML.load_file('db/countries.yml') network_prefixes = YAML.load_file('db/network_prefixes.yml') System::NetworkPrefix.transaction do - puts 'deleting old data' # rubocop:disable Rails/Output + puts 'deleting old data' System::NetworkPrefix.delete_all System::Network.delete_all System::NetworkType.delete_all System::Country.delete_all - puts 'insert new global' # rubocop:disable Rails/Output + puts 'insert new global' System::NetworkType.insert_all!(network_types) if network_types.any? System::Network.insert_all!(networks) if networks.any? System::Country.insert_all!(countries) if countries.any? System::NetworkPrefix.insert_all!(network_prefixes) if network_prefixes.any? end -Dir.glob('db/network_data/**/*.yml') do |f| - System::NetworkPrefix.transaction do - puts "processing file #{f}:" # rubocop:disable Rails/Output +System::NetworkPrefix.transaction do + network_attrs_list = [] + network_prefix_attrs_list = [] + Dir.glob('db/network_data/**/*.yml') do |f| + puts "load file #{f}:" data = YAML.load_file(f, aliases: true) - n = data['networks'] + network_attrs_list.concat(data['networks']) + network_prefix_attrs_list.concat(data['network_prefixes']) + end - System::Network.insert_all!(n) if n.any? - puts " loaded #{n.length} networks" # rubocop:disable Rails/Output - n_ids = n.map { |ni| ni['id'] }.uniq + System::Network.insert_all!(network_attrs_list) if network_attrs_list.any? + puts " loaded #{network_attrs_list.length} networks" + n_network_ids = network_attrs_list.map { |network_attrs| network_attrs['id'] } - np = data['network_prefixes'] - System::NetworkPrefix.insert_all!(np) if np.any? - puts " loaded #{np.length} network prefixes" # rubocop:disable Rails/Output - np_ids = np.map { |npi| npi['network_id'] }.uniq + System::NetworkPrefix.insert_all!(network_prefix_attrs_list) if network_prefix_attrs_list.any? + puts " loaded #{network_prefix_attrs_list.length} network prefixes" + np_network_ids = network_prefix_attrs_list.map { |network_prefix_attrs| network_prefix_attrs['network_id'] }.uniq - no_prefixes = n_ids - np_ids - puts " networks without prefixes: #{no_prefixes}" if no_prefixes.any? # rubocop:disable Rails/Output - end + no_prefixes = n_network_ids - np_network_ids + puts " networks without prefixes: #{no_prefixes}" if no_prefixes.any? end System::NetworkPrefix.transaction do @@ -46,3 +49,4 @@ SqlCaller::Yeti.execute "SELECT pg_catalog.setval('sys.countries_id_seq', MAX(id), true) FROM sys.countries" SqlCaller::Yeti.execute "SELECT pg_catalog.setval('sys.network_prefixes_id_seq', MAX(id), true) FROM sys.network_prefixes" end +# rubocop:enable Rails/Output diff --git a/spec/models/billing/service/renew_spec.rb b/spec/models/billing/service/renew_spec.rb index d8a6535ab..8aa7c4a99 100644 --- a/spec/models/billing/service/renew_spec.rb +++ b/spec/models/billing/service/renew_spec.rb @@ -17,7 +17,9 @@ expect { subject }.to change { service.reload.renew_at }.by(1.day) expect(service.state_id).to eq(Billing::Service::STATE_ID_ACTIVE) end + end + shared_examples :changes_balance do it 'charges account' do expect { subject }.to change { account.reload.balance }.by(-service.renew_price) end @@ -34,6 +36,14 @@ end end + shared_examples :does_not_change_balance do + it 'does not charge account and does not create Billing::Transaction' do + expect { subject }.not_to change { + [account.reload.balance, Billing::Transaction.count] + } + end + end + shared_examples :suspends_service do it 'calls provisioning object callbacks' do stub = instance_double(Billing::Provisioning::Base) @@ -51,13 +61,7 @@ expect(service.state_id).to eq(Billing::Service::STATE_ID_SUSPENDED) end - it 'does not charge account' do - expect { subject }.not_to change { account.reload.balance } - end - - it 'does not create Billing::Transaction' do - expect { subject }.to change { Billing::Transaction.count }.by(0) - end + include_examples :does_not_change_balance end describe '.perform' do @@ -72,11 +76,11 @@ {} end let!(:account) { create(:account, account_attrs) } - let!(:account_attrs) do + let(:account_attrs) do { balance: 100, min_balance: 0, max_balance: 1000 } end let!(:service) { create(:service, service_attrs) } - let!(:service_attrs) do + let(:service_attrs) do { account:, type: service_type, @@ -89,27 +93,94 @@ context 'when enough money' do include_examples :renews_service + include_examples :changes_balance context 'when account balance will be less than min_balance' do - let!(:account_attrs) do - super().merge min_balance: 90.01 + let(:account_attrs) do + super().merge balance: 100, min_balance: 90.01, max_balance: 1000 end include_examples :suspends_service + + context 'when service_type with force_renew' do + let(:service_type_attrs) do + super().merge force_renew: true + end + + include_examples :renews_service + include_examples :changes_balance + end + end + + context 'when account balance is already greater than max_balance' do + let(:account_attrs) do + super().merge balance: 50, min_balance: 0, max_balance: 40 + end + + include_examples :renews_service + include_examples :changes_balance end end - context 'when not enough money' do - let!(:account_attrs) do - super().merge balance: 9.99 + context 'when service_renew_price is zero' do + let(:service_attrs) do + super().merge renew_price: 0 end - context 'when service_type with force_renew' do - let(:service_type_attrs) do - super().merge force_renew: true + include_examples :renews_service + include_examples :does_not_change_balance + + context 'when account balance is already less than min_balance' do + let(:account_attrs) do + super().merge balance: 50, min_balance: 60, max_balance: 1000 end include_examples :renews_service + include_examples :does_not_change_balance + end + + context 'when account balance is already greater than max_balance' do + let(:account_attrs) do + super().merge balance: 50, min_balance: 0, max_balance: 40 + end + + include_examples :renews_service + include_examples :does_not_change_balance + end + end + + context 'when service_renew_price is negative' do + let(:service_attrs) do + super().merge renew_price: -10 + end + + include_examples :renews_service + include_examples :changes_balance + + context 'when account balance is already be less than min_balance' do + let(:account_attrs) do + super().merge balance: 50, min_balance: 60, max_balance: 1000 + end + + include_examples :renews_service + include_examples :changes_balance + end + + context 'when account balance will be greater than max_balance' do + let(:account_attrs) do + super().merge balance: 50, min_balance: 0, max_balance: 59.99 + end + + include_examples :suspends_service + + xcontext 'when service_type with force_renew' do + let(:service_type_attrs) do + super().merge force_renew: true + end + + include_examples :renews_service + include_examples :changes_balance + end end end end