Skip to content

Improve update balance #291

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ class Account < ActiveRecord::Base

before_create :add_organization

# Denormalizes the account's balance summing the amount in all its movements.
# It will flag the account if its balance falls out of the min or max limits.
def update_balance
new_balance = movements.sum(:amount)
self.balance = new_balance
if balance_changed?
self.flagged = !allowed?(balance)
end
self.flagged = !within_allowed_limits? if balance_changed?
save
end

Expand Down Expand Up @@ -51,8 +51,34 @@ def add_organization

private

def allowed?(new_balance)
new_balance < (max_allowed_balance || Float::INFINITY) &&
new_balance > (min_allowed_balance || -Float::INFINITY)
# Checks whether the balance falls within the max and min allowed balance,
# none of these included
#
# @return [Boolean]
def within_allowed_limits?
less_than_upper_limit? && greater_than_lower_limit?
end

def less_than_upper_limit?
balance < max_allowed_balance
end

def greater_than_lower_limit?
balance > min_allowed_balance
end

# Returns the maximum allowed balance, falling back to infinite it not set
#
# @return [Integer | Float]
def max_allowed_balance
super || Float::INFINITY
end

# Returns the minimum allowed balance, falling back to minus infinite it not
# set
#
# @return [Integer | Float]
def min_allowed_balance
super || -Float::INFINITY
end
end
64 changes: 64 additions & 0 deletions spec/models/account_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,68 @@
expect(organization.account.organization).to eq organization
end

describe '#update_balance' do
let(:account) { member.account }

context 'when the balance did not change since last balance update' do
before do
account.movements << Movement.new(amount: 5)
account.save
end

it 'updates the account balance' do
# a callback in Movement already called #update_balance after creating
# the movement above
account.update_balance
expect(account.balance).to eq(5)
end

it 'does not flag the account' do
# a callback in Movement already called #update_balance after creating
# the movement above
account.update_balance
expect(account.flagged).to be_falsy
end
end

context 'when the balance changed since last balance update' do
context 'and the new balance falls within the limits allowed' do
before do
account.max_allowed_balance = 100
account.min_allowed_balance = 0

account.movements << Movement.new(amount: 5)
account.save
end

it 'updates the account balance' do
# a callback in Movement calls #update_balance after creating the
# movement above
expect(account.balance).to eq(5)
end

it 'does not flag the account' do
# a callback in Movement calls #update_balance after creating the
# movement above
expect(account.flagged).to be_falsy
end
end

context 'and the new balance does not fall within the limits allowed' do
before do
account.max_allowed_balance = 0
account.min_allowed_balance = 0

account.movements << Movement.new(amount: 5)
account.save
end

it 'does not flag the account' do
# a callback in Movement calls #update_balance after creating the
# movement above
expect(account.flagged).to be_truthy
end
end
end
end
end