Skip to content

Commit

Permalink
fix billing service renew with renew_price zero or negative
Browse files Browse the repository at this point in the history
closes #1670
  • Loading branch information
senid231 committed Jan 7, 2025
1 parent d38ff0e commit 013cc80
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 37 deletions.
12 changes: 9 additions & 3 deletions app/models/billing/service/renew.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
38 changes: 21 additions & 17 deletions db/custom_seeds/network_prefixes.rb
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
105 changes: 88 additions & 17 deletions spec/models/billing/service/renew_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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,
Expand All @@ -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
Expand Down

0 comments on commit 013cc80

Please sign in to comment.