Skip to content

Commit

Permalink
fix(accumulative balance chart): Fix accumulative balance chart for a…
Browse files Browse the repository at this point in the history
…ccount (#34)
  • Loading branch information
VladislavSokov authored Aug 29, 2023
1 parent c36c0a8 commit 261d50f
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 9 deletions.
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ gem "bulma-rails", "~> 0.9.2"
gem 'slim'
gem "font-awesome-rails"
gem 'chartkick'
gem 'groupdate'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'
Expand Down
3 changes: 0 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,6 @@ GEM
railties (>= 3.2, < 7)
globalid (0.5.2)
activesupport (>= 5.0)
groupdate (6.2.1)
activesupport (>= 5.2)
i18n (1.8.10)
concurrent-ruby (~> 1.0)
jbuilder (2.11.2)
Expand Down Expand Up @@ -309,7 +307,6 @@ DEPENDENCIES
factory_bot_rails (~> 6.2)
ffaker
font-awesome-rails
groupdate
jbuilder (~> 2.7)
letter_opener
listen (>= 3.0.5, < 3.2)
Expand Down
22 changes: 21 additions & 1 deletion app/models/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,26 @@ def transactions
end

def accumulative_balance_data
transactions.group_by_day(:created_at).sum(:amount)
result = ActiveRecord::Base.connection.execute(balance_sql)
result.to_h { |transaction| [transaction['date'], transaction['sum']] }
end

private

def balance_sql
<<-SQL
WITH trs AS (
SELECT
id,
created_at::date AS date,
CASE WHEN to_account_id = #{id} THEN amount ELSE -amount END AS amount
FROM transactions
WHERE to_account_id = #{id} OR from_account_id = #{id}
ORDER BY created_at::date
)
SELECT date, SUM(amount) OVER (ORDER BY date)
FROM trs
ORDER BY date;
SQL
end
end
15 changes: 11 additions & 4 deletions spec/models/account_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@
describe '#accumulative_balance_data' do
let(:parent) { create(:account, :parent) }
let(:child) { create(:account, :children, parent: parent) }
let!(:first_transaction) { create(:transaction, to_account: child, from_account: parent, amount: 100, created_at: 1.day.ago) }
let!(:second_transaction) { create(:transaction, to_account: child, from_account: parent, amount: 50, created_at: Time.current) }
let!(:first_transaction) { create(:transaction, to_account: parent, from_account: child, amount: 100.0, created_at: 2.day.ago) }
let!(:second_transaction) { create(:transaction, to_account: child, from_account: parent, amount: 70.0, created_at: 1.day.ago) }
let!(:third_transaction) { create(:transaction, to_account: parent, from_account: child, amount: 50.0, created_at: Time.current) }

it 'calculates accumulative balance data' do
expect(parent.accumulative_balance_data).to eq({ first_transaction.created_at.to_date => 100, second_transaction.created_at.to_date => 50 })
context 'with positive and negative transactions' do
it do
expect(parent.accumulative_balance_data).to eq({
first_transaction.created_at.to_date.strftime('%Y-%m-%d') => 100.0,
second_transaction.created_at.to_date.strftime('%Y-%m-%d') => 30.0,
third_transaction.created_at.to_date.strftime('%Y-%m-%d') => 80.0
})
end
end
end
end

0 comments on commit 261d50f

Please sign in to comment.