Skip to content

Commit

Permalink
Include income and expenses in report
Browse files Browse the repository at this point in the history
  • Loading branch information
jonallured authored and github-actions[bot] committed Feb 13, 2024
1 parent 03d4b7c commit 89c4e29
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 11 deletions.
39 changes: 39 additions & 0 deletions app/models/financial_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,32 @@ def starting_amounts
end
end

def income_amounts
grouped_transactions.map do |transactions|
amounts = transactions.map do |transaction|
next unless transaction.amount_cents&.positive?

transaction.amount_cents
end.compact
next if amounts.empty?

amounts.sum
end
end

def expenses_amounts
grouped_transactions.map do |transactions|
amounts = transactions.map do |transaction|
next unless transaction.amount_cents&.negative?

transaction.amount_cents
end.compact
next if amounts.empty?

amounts.sum
end
end

def ending_amounts
grouped_statements.map do |statements|
amounts = statements.map(&:ending_amount_cents).compact
Expand Down Expand Up @@ -82,5 +108,18 @@ def compute_grouped_statements
def grouped_statements
@grouped_statements ||= compute_grouped_statements
end

def compute_grouped_transactions
account_transactions = @accounts.map { |account| account.financial_transactions.for_year(@year) }.flatten
FinancialReport.months_for_year(@year).map do |date|
transactions_for_period = account_transactions.select { |transaction| transaction.posted_on.month == date.month }
transactions_for_period << NullTransaction.instance if transactions_for_period.empty?
transactions_for_period
end
end

def grouped_transactions
@grouped_transactions ||= compute_grouped_transactions
end
end
end
2 changes: 2 additions & 0 deletions app/models/financial_transaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ class FinancialTransaction < ApplicationRecord
belongs_to :financial_account

validates_presence_of :posted_on, :amount_cents, :description

scope :for_year, ->(year) { where("extract(year from posted_on) = ?", year) }
end
6 changes: 6 additions & 0 deletions app/models/null_transaction.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class NullTransaction
include Singleton

def amount_cents
end
end
6 changes: 6 additions & 0 deletions app/views/financial_reports/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
%tr
%td.text-left Starting
= render partial: "amount_cents", collection: checking_data.starting_amounts
%tr
%td.text-left Income
= render partial: "amount_cents", collection: checking_data.income_amounts
%tr
%td.text-left Expenses
= render partial: "amount_cents", collection: checking_data.expenses_amounts
%tr
%td.text-left Ending
= render partial: "amount_cents", collection: checking_data.ending_amounts
Expand Down
129 changes: 118 additions & 11 deletions spec/system/financial_reports/admin_views_financial_report_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
scenario "with no statements for that year" do
visit "/financial_reports/#{last_year}"

header = page.find("header nav h1")
expect(header.text).to eq last_year.year.to_s
header_h1 = page.find("header nav h1")
expect(header_h1.text).to eq last_year.year.to_s

prev_link, next_link = page.all("header nav a").to_a

Expand All @@ -25,22 +25,59 @@
expect(next_link.text).to eq "next"
expect(next_link["href"]).to end_with((last_year.year + 1).to_s)

page.all("table").to_a.each do |table|
month_row, starting_row, ending_row, net_row = table.all("tr").to_a
checking_table, savings_table = page.all("table").to_a

within checking_table do
checking_trs = checking_table.all("tr").to_a

month_tr = checking_trs[0]
starting_tr = checking_trs[1]
income_tr = checking_trs[2]
expenses_tr = checking_trs[3]
ending_tr = checking_trs[4]
net_tr = checking_trs[5]

expect(month_row.all("th").map(&:text)).to eq %w[
expect(month_tr.all("th").map(&:text)).to eq %w[
Month Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
]

expect(starting_row.all("td").map(&:text)).to eq %w[
expect(starting_tr.all("td").map(&:text)).to eq %w[
Starting - - - - - - - - - - - -
]

expect(ending_row.all("td").map(&:text)).to eq %w[
expect(income_tr.all("td").map(&:text)).to eq %w[
Income - - - - - - - - - - - -
]

expect(expenses_tr.all("td").map(&:text)).to eq %w[
Expenses - - - - - - - - - - - -
]

expect(ending_tr.all("td").map(&:text)).to eq %w[
Ending - - - - - - - - - - - -
]

expect(net_row.all("td").map(&:text)).to eq %w[
expect(net_tr.all("td").map(&:text)).to eq %w[
Net - - - - - - - - - - - -
]
end

within savings_table do
month_tr, starting_tr, ending_tr, net_tr = savings_table.all("tr").to_a

expect(month_tr.all("th").map(&:text)).to eq %w[
Month Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
]

expect(starting_tr.all("td").map(&:text)).to eq %w[
Starting - - - - - - - - - - - -
]

expect(ending_tr.all("td").map(&:text)).to eq %w[
Ending - - - - - - - - - - - -
]

expect(net_tr.all("td").map(&:text)).to eq %w[
Net - - - - - - - - - - - -
]
end
Expand All @@ -58,11 +95,23 @@
visit "/financial_reports/#{last_year}"

checking_table = page.all("table").to_a.first
_month_tr, starting_tr, ending_tr, net_tr = checking_table.all("tr").to_a
checking_trs = checking_table.all("tr").to_a

starting_tr = checking_trs[1]
income_tr = checking_trs[2]
expenses_tr = checking_trs[3]
ending_tr = checking_trs[4]
net_tr = checking_trs[5]

may_starting_td = starting_tr.all("td").to_a[5]
expect(may_starting_td.text).to eq "$1,034.89"

may_income_td = income_tr.all("td").to_a[5]
expect(may_income_td.text).to eq "-"

may_expenses_td = expenses_tr.all("td").to_a[5]
expect(may_expenses_td.text).to eq "-"

may_ending_td = ending_tr.all("td").to_a[5]
expect(may_ending_td.text).to eq "$99.00"

Expand Down Expand Up @@ -94,7 +143,11 @@
checking_table, savings_table = page.all("table").to_a

within checking_table do
_month_tr, starting_tr, ending_tr, net_tr = checking_table.all("tr").to_a
checking_trs = checking_table.all("tr").to_a

starting_tr = checking_trs[1]
ending_tr = checking_trs[4]
net_tr = checking_trs[5]

_starting_label, *starting_tds = starting_tr.all("td").to_a
expect(starting_tds.count).to eq 12
Expand Down Expand Up @@ -146,7 +199,11 @@
visit "/financial_reports/#{last_year}"

checking_table = page.all("table").to_a.first
_month_tr, starting_tr, ending_tr, net_tr = checking_table.all("tr").to_a
checking_trs = checking_table.all("tr").to_a

starting_tr = checking_trs[1]
ending_tr = checking_trs[4]
net_tr = checking_trs[5]

may_starting_td = starting_tr.all("td").to_a[5]
expect(may_starting_td.text).to eq "$170.00"
Expand All @@ -157,4 +214,54 @@
may_net_td = net_tr.all("td").to_a[5]
expect(may_net_td.text).to eq "($100.00)"
end

scenario "with one statement in the middle of that year" do
FactoryBot.create(
:financial_statement,
financial_account: FinancialAccount.wf_checking,
period_start_on: Date.parse("#{last_year.year}-05-01"),
starting_amount_cents: 1_034_89,
ending_amount_cents: 99_00
)

FactoryBot.create(
:financial_transaction,
financial_account: FinancialAccount.wf_checking,
posted_on: Date.parse("#{last_year.year}-05-01"),
amount_cents: 900_00
)

FactoryBot.create(
:financial_transaction,
financial_account: FinancialAccount.wf_checking,
posted_on: Date.parse("#{last_year.year}-05-01"),
amount_cents: -1_835_89
)

visit "/financial_reports/#{last_year}"

checking_table = page.all("table").to_a.first
checking_trs = checking_table.all("tr").to_a

starting_tr = checking_trs[1]
income_tr = checking_trs[2]
expenses_tr = checking_trs[3]
ending_tr = checking_trs[4]
net_tr = checking_trs[5]

may_starting_td = starting_tr.all("td").to_a[5]
expect(may_starting_td.text).to eq "$1,034.89"

may_income_td = income_tr.all("td").to_a[5]
expect(may_income_td.text).to eq "$900.00"

may_expenses_td = expenses_tr.all("td").to_a[5]
expect(may_expenses_td.text).to eq "($1,835.89)"

may_ending_td = ending_tr.all("td").to_a[5]
expect(may_ending_td.text).to eq "$99.00"

may_net_td = net_tr.all("td").to_a[5]
expect(may_net_td.text).to eq "($935.89)"
end
end

0 comments on commit 89c4e29

Please sign in to comment.