rock_books 0.4.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -2
- data/RELEASE_NOTES.md +33 -0
- data/assets/fonts/JetBrainsMono-Medium.ttf +0 -0
- data/lib/rock_books/cmd_line/command_line_interface.rb +6 -6
- data/lib/rock_books/cmd_line/main.rb +1 -9
- data/lib/rock_books/documents/book_set.rb +4 -136
- data/lib/rock_books/documents/chart_of_accounts.rb +29 -12
- data/lib/rock_books/documents/journal.rb +2 -6
- data/lib/rock_books/documents/journal_entry.rb +7 -2
- data/lib/rock_books/documents/journal_entry_builder.rb +4 -0
- data/lib/rock_books/helpers/book_set_loader.rb +3 -3
- data/lib/rock_books/reports/balance_sheet.rb +9 -43
- data/lib/rock_books/reports/book_set_reporter.rb +207 -0
- data/lib/rock_books/reports/data/bs_is_data.rb +61 -0
- data/lib/rock_books/reports/data/bs_is_section_data.rb +28 -0
- data/lib/rock_books/reports/data/journal_data.rb +37 -0
- data/lib/rock_books/reports/data/multidoc_txn_by_account_data.rb +40 -0
- data/lib/rock_books/reports/data/multidoc_txn_report_data.rb +39 -0
- data/lib/rock_books/reports/data/receipts_report_data.rb +47 -0
- data/lib/rock_books/reports/data/tx_one_account_data.rb +37 -0
- data/lib/rock_books/reports/helpers/erb_helper.rb +21 -0
- data/lib/rock_books/reports/helpers/html_report_helper.rb +35 -0
- data/lib/rock_books/reports/helpers/text_report_helper.rb +134 -0
- data/lib/rock_books/reports/income_statement.rb +9 -47
- data/lib/rock_books/reports/journal_report.rb +72 -0
- data/lib/rock_books/reports/multidoc_txn_by_account_report.rb +32 -0
- data/lib/rock_books/reports/multidoc_txn_report.rb +25 -0
- data/lib/rock_books/reports/receipts_report.rb +6 -55
- data/lib/rock_books/reports/templates/html/index.html.erb +141 -0
- data/lib/rock_books/reports/templates/html/report_page.html.erb +12 -0
- data/lib/rock_books/reports/templates/text/_receipt_section.txt.erb +17 -0
- data/lib/rock_books/reports/templates/text/_totals.txt.erb +8 -0
- data/lib/rock_books/reports/templates/text/balance_sheet.txt.erb +21 -0
- data/lib/rock_books/reports/templates/text/income_statement.txt.erb +21 -0
- data/lib/rock_books/reports/templates/text/journal.txt.erb +20 -0
- data/lib/rock_books/reports/templates/text/multidoc_txn_by_account_report.txt.erb +28 -0
- data/lib/rock_books/reports/templates/text/multidoc_txn_report.txt.erb +22 -0
- data/lib/rock_books/reports/templates/text/receipts_report.txt.erb +13 -0
- data/lib/rock_books/reports/templates/text/tx_one_account.txt.erb +18 -0
- data/lib/rock_books/reports/tx_one_account.rb +10 -45
- data/lib/rock_books/types/account.rb +13 -1
- data/lib/rock_books/types/account_type.rb +18 -7
- data/lib/rock_books/version.rb +1 -1
- data/rock_books.gemspec +5 -3
- metadata +64 -16
- data/lib/rock_books/documents/index.html.erb +0 -156
- data/lib/rock_books/documents/receipts.html.erb +0 -54
- data/lib/rock_books/reports/multidoc_transaction_report.rb +0 -66
- data/lib/rock_books/reports/reporter.rb +0 -118
- data/lib/rock_books/reports/transaction_report.rb +0 -105
- data/lib/rock_books/reports/tx_by_account.rb +0 -82
@@ -14,6 +14,10 @@ class JournalEntryBuilder < Struct.new(:journal_entry_context)
|
|
14
14
|
def chart_of_accounts; journal_entry_context.chart_of_accounts; end
|
15
15
|
|
16
16
|
|
17
|
+
# A "token" in this context means an account name and account amount pair, e.g. "pnc.checking 1234.56".
|
18
|
+
# @param tokens the account name/amount pairs found in the source text
|
19
|
+
# @date transaction date
|
20
|
+
# @return array of AcctAmount instances
|
17
21
|
def acct_amounts_from_tokens(tokens, date)
|
18
22
|
acct_amounts = []
|
19
23
|
|
@@ -7,6 +7,7 @@ module RockBooks
|
|
7
7
|
|
8
8
|
module_function
|
9
9
|
|
10
|
+
# @return a hash whose keys are the filespecs and values are the document types
|
10
11
|
def get_files_with_types(directory)
|
11
12
|
files = Dir[File.join(directory, '*.txt')]
|
12
13
|
files.each_with_object({}) do |filespec, files_with_types|
|
@@ -42,7 +43,7 @@ module RockBooks
|
|
42
43
|
|
43
44
|
# Uses all *.txt files in the specified directory; uses @doc_type to determine which
|
44
45
|
# is the chart of accounts and which are journals.
|
45
|
-
# To exclude a file, make the extension other than .
|
46
|
+
# To exclude a file, make the extension something other than .txt.
|
46
47
|
def load(run_options)
|
47
48
|
|
48
49
|
files_with_types = get_files_with_types(run_options.input_dir)
|
@@ -54,9 +55,8 @@ module RockBooks
|
|
54
55
|
validate_journal_file_count(journal_files)
|
55
56
|
|
56
57
|
chart_of_accounts = ChartOfAccounts.from_file(chart_of_account_files.first)
|
57
|
-
journals = journal_files.map { |
|
58
|
+
journals = journal_files.map { |filespec| Journal.from_file(chart_of_accounts, filespec) }
|
58
59
|
BookSet.new(run_options, chart_of_accounts, journals)
|
59
60
|
end
|
60
|
-
|
61
61
|
end
|
62
62
|
end
|
@@ -1,6 +1,5 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative 'report_context'
|
1
|
+
require_relative 'helpers/erb_helper'
|
2
|
+
require_relative 'helpers/text_report_helper'
|
4
3
|
|
5
4
|
module RockBooks
|
6
5
|
|
@@ -9,52 +8,19 @@ module RockBooks
|
|
9
8
|
# in order to calculate the correct balances, so we ignore the global $filter.
|
10
9
|
class BalanceSheet
|
11
10
|
|
12
|
-
include
|
11
|
+
include TextReportHelper
|
12
|
+
include ErbHelper
|
13
13
|
|
14
|
-
attr_accessor :context
|
14
|
+
attr_accessor :context, :data
|
15
15
|
|
16
|
-
def initialize(report_context)
|
16
|
+
def initialize(report_context, data)
|
17
17
|
@context = report_context
|
18
|
+
@data = data
|
18
19
|
end
|
19
20
|
|
20
21
|
|
21
|
-
def
|
22
|
-
|
22
|
+
def generate
|
23
|
+
ErbHelper.render_hashes('text/balance_sheet.txt.erb', data, template_presentation_context)
|
23
24
|
end
|
24
|
-
|
25
|
-
|
26
|
-
def generate_header
|
27
|
-
lines = [banner_line]
|
28
|
-
lines << center(context.entity || 'Unspecified Entity')
|
29
|
-
lines << center("Balance Sheet for Period Ending #{end_date}")
|
30
|
-
lines << banner_line
|
31
|
-
lines << ''
|
32
|
-
lines << ''
|
33
|
-
lines << ''
|
34
|
-
lines.join("\n")
|
35
|
-
end
|
36
|
-
|
37
|
-
|
38
|
-
def generate_report
|
39
|
-
filter = RockBooks::JournalEntryFilters.date_on_or_before(end_date)
|
40
|
-
acct_amounts = Journal.acct_amounts_in_documents(context.journals, filter)
|
41
|
-
totals = AcctAmount.aggregate_amounts_by_account(acct_amounts)
|
42
|
-
output = generate_header
|
43
|
-
|
44
|
-
asset_output, asset_total = generate_account_type_section('Assets', totals, :asset, false)
|
45
|
-
liab_output, liab_total = generate_account_type_section('Liabilities', totals, :liability, true)
|
46
|
-
equity_output, equity_total = generate_account_type_section('Equity', totals, :equity, true)
|
47
|
-
|
48
|
-
output << [asset_output, liab_output, equity_output].join("\n\n")
|
49
|
-
|
50
|
-
grand_total = asset_total - (liab_total + equity_total)
|
51
|
-
|
52
|
-
output << "\n#{"%12.2f Assets - (Liabilities + Equity)" % grand_total}\n============\n"
|
53
|
-
output
|
54
|
-
end
|
55
|
-
|
56
|
-
alias_method :to_s, :generate_report
|
57
|
-
alias_method :call, :generate_report
|
58
|
-
|
59
25
|
end
|
60
26
|
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require_relative '../documents/book_set'
|
2
|
+
|
3
|
+
require_relative 'balance_sheet'
|
4
|
+
require_relative 'data/bs_is_data'
|
5
|
+
require_relative 'data/receipts_report_data'
|
6
|
+
require_relative 'income_statement'
|
7
|
+
require_relative 'multidoc_txn_report'
|
8
|
+
require_relative 'receipts_report'
|
9
|
+
require_relative 'report_context'
|
10
|
+
require_relative 'journal_report'
|
11
|
+
require_relative 'multidoc_txn_by_account_report'
|
12
|
+
require_relative 'tx_one_account'
|
13
|
+
require_relative 'helpers/erb_helper'
|
14
|
+
require_relative 'helpers/text_report_helper'
|
15
|
+
require_relative 'helpers/html_report_helper'
|
16
|
+
|
17
|
+
require 'prawn'
|
18
|
+
|
19
|
+
module RockBooks
|
20
|
+
class BookSetReporter
|
21
|
+
|
22
|
+
extend Forwardable
|
23
|
+
|
24
|
+
attr_reader :book_set, :output_dir, :filter, :context
|
25
|
+
|
26
|
+
def_delegator :book_set, :all_entries
|
27
|
+
def_delegator :book_set, :journals
|
28
|
+
def_delegator :book_set, :chart_of_accounts
|
29
|
+
def_delegator :book_set, :run_options
|
30
|
+
|
31
|
+
FONT_FILESPEC = File.absolute_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'assets', 'fonts', 'JetBrainsMono-Medium.ttf'))
|
32
|
+
|
33
|
+
|
34
|
+
def initialize(book_set, output_dir, filter = nil)
|
35
|
+
@book_set = book_set
|
36
|
+
@output_dir = output_dir
|
37
|
+
@filter = filter
|
38
|
+
@context = ReportContext.new(book_set.chart_of_accounts, book_set.journals, 80)
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def generate
|
43
|
+
create_directories
|
44
|
+
create_index_html
|
45
|
+
|
46
|
+
do_statements
|
47
|
+
do_journals
|
48
|
+
do_transaction_reports
|
49
|
+
do_single_account_reports
|
50
|
+
do_receipts_report
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
# All methods after this point are private.
|
55
|
+
|
56
|
+
private def do_statements
|
57
|
+
bs_is_data = BsIsData.new(context)
|
58
|
+
|
59
|
+
bal_sheet_text_report = BalanceSheet.new(context, bs_is_data.bal_sheet_data).generate
|
60
|
+
write_report(:balance_sheet, bal_sheet_text_report)
|
61
|
+
|
62
|
+
inc_stat_text_report = IncomeStatement.new(context, bs_is_data.inc_stat_data).generate
|
63
|
+
write_report(:income_statement, inc_stat_text_report)
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
private def do_journals
|
68
|
+
journals.each do |journal|
|
69
|
+
report_data = JournalData.new(journal, context, filter).fetch
|
70
|
+
text_report = JournalReport.new(report_data, context, filter).generate
|
71
|
+
write_report(journal.short_name, text_report)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
private def do_transaction_reports
|
77
|
+
|
78
|
+
do_date_or_amount_report = ->(sort_field, short_name) do
|
79
|
+
data = MultidocTxnReportData.new(context, sort_field, filter).fetch
|
80
|
+
text_report = MultidocTransactionReport.new(data, context).generate
|
81
|
+
write_report(short_name, text_report)
|
82
|
+
end
|
83
|
+
|
84
|
+
do_acct_report = -> do
|
85
|
+
data = MultidocTxnByAccountData.new(context).fetch
|
86
|
+
text_report = MultidocTransactionByAccountReport.new(data, context).generate
|
87
|
+
write_report(:all_txns_by_acct, text_report)
|
88
|
+
end
|
89
|
+
|
90
|
+
do_date_or_amount_report.(:date, :all_txns_by_date)
|
91
|
+
do_date_or_amount_report.(:amount, :all_txns_by_amount)
|
92
|
+
do_acct_report.()
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
private def do_single_account_reports
|
97
|
+
chart_of_accounts.accounts.each do |account|
|
98
|
+
short_name = ('acct_' + account.code).to_sym
|
99
|
+
data = TxOneAccountData.new(context, account.code).fetch
|
100
|
+
text_report = TxOneAccount.new(data, context).generate
|
101
|
+
write_report(short_name, text_report)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
private def do_receipts_report
|
107
|
+
data = ReceiptsReportData.new(book_set.all_entries, run_options.receipt_dir).fetch
|
108
|
+
text_report = ReceiptsReport.new(context, data).generate
|
109
|
+
write_report(:receipts, text_report)
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
private def create_directories
|
114
|
+
%w(txt pdf html).each do |format|
|
115
|
+
dir = File.join(output_dir, format, SINGLE_ACCT_SUBDIR)
|
116
|
+
FileUtils.mkdir_p(dir)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
# "./pdf/short_name.pdf" or "./pdf/single_account/short_name.pdf"
|
122
|
+
private def build_filespec(directory, short_name, file_format)
|
123
|
+
fragments = [directory, file_format, "#{short_name}.#{file_format}"]
|
124
|
+
is_acct_report = /^acct_/.match(short_name)
|
125
|
+
if is_acct_report
|
126
|
+
fragments.insert(2, SINGLE_ACCT_SUBDIR)
|
127
|
+
end
|
128
|
+
File.join(*fragments)
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
private def create_index_html
|
133
|
+
filespec = build_filespec(output_dir, 'index', 'html')
|
134
|
+
File.write(filespec, index_html_content)
|
135
|
+
puts "Created index.html"
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
private def prawn_create_document(pdf_filespec, text)
|
140
|
+
Prawn::Document.generate(pdf_filespec) do
|
141
|
+
font(FONT_FILESPEC, size: 10)
|
142
|
+
|
143
|
+
utf8_nonbreaking_space = "\uC2A0"
|
144
|
+
unicode_nonbreaking_space = "\u00A0"
|
145
|
+
text(text.gsub(' ', unicode_nonbreaking_space))
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
private def write_report(short_name, text_report)
|
151
|
+
|
152
|
+
txt_filespec = build_filespec(output_dir, short_name, 'txt')
|
153
|
+
html_filespec = build_filespec(output_dir, short_name, 'html')
|
154
|
+
pdf_filespec = build_filespec(output_dir, short_name, 'pdf')
|
155
|
+
|
156
|
+
create_text_report = -> { File.write(txt_filespec, text_report) }
|
157
|
+
|
158
|
+
create_pdf_report = -> { prawn_create_document(pdf_filespec, text_report) }
|
159
|
+
|
160
|
+
create_html_report = -> do
|
161
|
+
data = { report_body: text_report, title: "#{short_name} Report -- RockBooks" }
|
162
|
+
html_raw_report = ErbHelper.render_hashes("html/report_page.html.erb", data, {})
|
163
|
+
html_report = HtmlReportHelper.convert_receipts_to_hyperlinks(html_raw_report, html_filespec)
|
164
|
+
File.write(html_filespec, html_report)
|
165
|
+
end
|
166
|
+
|
167
|
+
create_text_report.()
|
168
|
+
create_pdf_report.()
|
169
|
+
create_html_report.()
|
170
|
+
|
171
|
+
puts "Created text, PDF, and HTML reports for #{short_name}."
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
private def missing_existing_unused_receipts
|
176
|
+
missing_receipts = []
|
177
|
+
existing_receipts = []
|
178
|
+
receipt_full_filespec = ->(receipt_filespec) { File.join(run_options.receipt_dir, receipt_filespec) }
|
179
|
+
|
180
|
+
# We will start out putting all filespecs in the unused array, and delete them as they are found in the transactions.
|
181
|
+
unused_receipt_filespecs = Dir['receipts/**/*'].select { |s| File.file?(s) } \
|
182
|
+
.sort \
|
183
|
+
.map { |s| "./" + s } # Prepend './' to match the data
|
184
|
+
|
185
|
+
all_entries.each do |entry|
|
186
|
+
entry.receipts.each do |receipt|
|
187
|
+
filespec = receipt_full_filespec.(receipt)
|
188
|
+
unused_receipt_filespecs.delete(filespec)
|
189
|
+
file_exists = File.file?(filespec)
|
190
|
+
list = (file_exists ? existing_receipts : missing_receipts)
|
191
|
+
list << { receipt: receipt, journal: entry.doc_short_name }
|
192
|
+
end
|
193
|
+
end
|
194
|
+
[missing_receipts, existing_receipts, unused_receipt_filespecs]
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
private def index_html_content
|
199
|
+
erb_filespec = File.join(File.dirname(__FILE__), 'templates', 'html', 'index.html.erb')
|
200
|
+
erb = ERB.new(File.read(erb_filespec))
|
201
|
+
erb.result_with_hash(
|
202
|
+
journals: journals,
|
203
|
+
chart_of_accounts: chart_of_accounts,
|
204
|
+
run_options: run_options)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative 'bs_is_section_data'
|
2
|
+
require_relative '../../filters/journal_entry_filters'
|
3
|
+
require_relative '../../documents/journal'
|
4
|
+
require_relative '../report_context'
|
5
|
+
|
6
|
+
module RockBooks
|
7
|
+
|
8
|
+
class BsIsData
|
9
|
+
|
10
|
+
attr_reader :journals_acct_totals, :context, :start_date, :end_date, :totals
|
11
|
+
|
12
|
+
def initialize(context)
|
13
|
+
@context = context
|
14
|
+
@start_date = context.chart_of_accounts.start_date
|
15
|
+
@end_date = context.chart_of_accounts.end_date
|
16
|
+
filter = JournalEntryFilters.date_on_or_before(end_date)
|
17
|
+
acct_amounts = Journal.acct_amounts_in_documents(context.journals, filter)
|
18
|
+
@journals_acct_totals = AcctAmount.aggregate_amounts_by_account(acct_amounts)
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def section_data(type)
|
23
|
+
BsIsSectionData.new(type, context, journals_acct_totals).fetch
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def bal_sheet_data
|
28
|
+
{
|
29
|
+
end_date: end_date,
|
30
|
+
entity: context.entity,
|
31
|
+
sections: {
|
32
|
+
asset: section_data(:asset),
|
33
|
+
liability: section_data(:liability),
|
34
|
+
equity: section_data(:equity),
|
35
|
+
},
|
36
|
+
grand_total: journals_acct_totals.values.sum.round(2)
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
def inc_stat_data
|
42
|
+
income_section_data = section_data(:income)
|
43
|
+
expense_section_data = section_data(:expense)
|
44
|
+
net_income = (income_section_data[:acct_totals].values.sum.round(2) -
|
45
|
+
expense_section_data[:acct_totals].values.sum.round(2)
|
46
|
+
).round(2)
|
47
|
+
|
48
|
+
{
|
49
|
+
start_date: start_date,
|
50
|
+
end_date: end_date,
|
51
|
+
entity: context.entity,
|
52
|
+
sections: {
|
53
|
+
income: income_section_data,
|
54
|
+
expense: expense_section_data,
|
55
|
+
},
|
56
|
+
net_income: net_income
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RockBooks
|
2
|
+
|
3
|
+
BsIsSectionData = Struct.new(:type, :context, :journals_acct_totals)
|
4
|
+
class BsIsSectionData
|
5
|
+
|
6
|
+
def fetch
|
7
|
+
{
|
8
|
+
acct_totals: totals,
|
9
|
+
total: totals.map(&:last).sum.round(2)
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
private def totals
|
14
|
+
@totals ||= calc_section_acct_totals
|
15
|
+
end
|
16
|
+
|
17
|
+
private def calc_section_acct_totals
|
18
|
+
codes = context.chart_of_accounts.account_codes_of_type(type)
|
19
|
+
totals = journals_acct_totals.select { |code, _amount| codes.include?(code) }
|
20
|
+
need_to_reverse_sign = %i{liability equity income}.include?(type)
|
21
|
+
if need_to_reverse_sign
|
22
|
+
totals.keys.each { |code| totals[code] = -totals[code] }
|
23
|
+
end
|
24
|
+
totals
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative '../../types/acct_amount'
|
2
|
+
|
3
|
+
module RockBooks
|
4
|
+
class JournalData
|
5
|
+
|
6
|
+
attr_reader :journal, :context, :filter
|
7
|
+
|
8
|
+
def initialize(journal, report_context, filter = nil)
|
9
|
+
@journal = journal
|
10
|
+
@context = report_context
|
11
|
+
@filter = filter
|
12
|
+
end
|
13
|
+
|
14
|
+
def entries
|
15
|
+
return @entries if @entries
|
16
|
+
@entries = journal.entries
|
17
|
+
@entries = @entries.select { |entry| filter.(entry) } if filter
|
18
|
+
@entries
|
19
|
+
end
|
20
|
+
|
21
|
+
def fetch
|
22
|
+
totals = AcctAmount.aggregate_amounts_by_account(JournalEntry.entries_acct_amounts(entries))
|
23
|
+
{
|
24
|
+
code: journal.account_code,
|
25
|
+
name: journal.chart_of_accounts.name_for_code(journal.account_code),
|
26
|
+
title: journal.title,
|
27
|
+
short_name: journal.short_name,
|
28
|
+
start_date: context.chart_of_accounts.start_date,
|
29
|
+
end_date: context.chart_of_accounts.end_date,
|
30
|
+
entries: entries,
|
31
|
+
totals: totals,
|
32
|
+
grand_total: totals.values.sum.round(2),
|
33
|
+
max_acct_code_len: context.chart_of_accounts.max_account_code_length
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RockBooks
|
2
|
+
class MultidocTxnByAccountData
|
3
|
+
|
4
|
+
include TextReportHelper
|
5
|
+
|
6
|
+
attr_reader :context, :account_code
|
7
|
+
|
8
|
+
|
9
|
+
def initialize(report_context)
|
10
|
+
@context = report_context
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def fetch
|
15
|
+
all_journal_entries = Journal.entries_in_documents(context.journals)
|
16
|
+
totals = AcctAmount.aggregate_amounts_by_account(JournalEntry.entries_acct_amounts(all_journal_entries))
|
17
|
+
{
|
18
|
+
journals: context.journals,
|
19
|
+
entries: all_journal_entries,
|
20
|
+
totals: totals,
|
21
|
+
grand_total: totals.values.sum.round(2),
|
22
|
+
acct_sections: fetch_acct_sections(all_journal_entries),
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
private def fetch_acct_sections(all_journal_entries)
|
28
|
+
context.chart_of_accounts.accounts.map do |account|
|
29
|
+
code = account.code
|
30
|
+
acct_entries = JournalEntry.entries_containing_account_code(all_journal_entries, code)
|
31
|
+
total = JournalEntry.total_for_code(acct_entries, code)
|
32
|
+
{
|
33
|
+
code: code,
|
34
|
+
entries: acct_entries,
|
35
|
+
total: total
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|