rock_books 0.6.1 → 0.10.0

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -10
  3. data/RELEASE_NOTES.md +57 -10
  4. data/assets/fonts/JetBrainsMono-Medium.ttf +0 -0
  5. data/lib/rock_books/cmd_line/command_line_interface.rb +15 -24
  6. data/lib/rock_books/cmd_line/main.rb +1 -9
  7. data/lib/rock_books/documents/book_set.rb +5 -2
  8. data/lib/rock_books/documents/chart_of_accounts.rb +29 -12
  9. data/lib/rock_books/documents/journal.rb +3 -8
  10. data/lib/rock_books/documents/journal_entry.rb +7 -2
  11. data/lib/rock_books/documents/journal_entry_builder.rb +4 -0
  12. data/lib/rock_books/helpers/book_set_loader.rb +3 -3
  13. data/lib/rock_books/reports/balance_sheet.rb +9 -43
  14. data/lib/rock_books/reports/book_set_reporter.rb +138 -106
  15. data/lib/rock_books/reports/data/bs_is_data.rb +61 -0
  16. data/lib/rock_books/reports/data/bs_is_section_data.rb +30 -0
  17. data/lib/rock_books/reports/data/journal_data.rb +38 -0
  18. data/lib/rock_books/reports/data/multidoc_txn_by_account_data.rb +40 -0
  19. data/lib/rock_books/reports/data/multidoc_txn_report_data.rb +39 -0
  20. data/lib/rock_books/reports/data/receipts_report_data.rb +47 -0
  21. data/lib/rock_books/reports/data/tx_one_account_data.rb +37 -0
  22. data/lib/rock_books/reports/helpers/erb_helper.rb +21 -0
  23. data/lib/rock_books/reports/helpers/receipts_hyperlink_converter.rb +59 -0
  24. data/lib/rock_books/reports/helpers/text_report_helper.rb +144 -0
  25. data/lib/rock_books/reports/income_statement.rb +9 -47
  26. data/lib/rock_books/reports/index_html_page.rb +27 -0
  27. data/lib/rock_books/reports/journal_report.rb +82 -0
  28. data/lib/rock_books/reports/multidoc_txn_by_account_report.rb +32 -0
  29. data/lib/rock_books/reports/multidoc_txn_report.rb +25 -0
  30. data/lib/rock_books/reports/receipts_report.rb +6 -55
  31. data/lib/rock_books/reports/templates/html/index.html.erb +158 -0
  32. data/lib/rock_books/reports/templates/html/report_page.html.erb +25 -0
  33. data/lib/rock_books/reports/templates/text/_receipt_section.txt.erb +17 -0
  34. data/lib/rock_books/reports/templates/text/_totals.txt.erb +8 -0
  35. data/lib/rock_books/reports/templates/text/balance_sheet.txt.erb +23 -0
  36. data/lib/rock_books/reports/templates/text/income_statement.txt.erb +23 -0
  37. data/lib/rock_books/reports/templates/text/journal.txt.erb +23 -0
  38. data/lib/rock_books/reports/templates/text/multidoc_txn_by_account_report.txt.erb +31 -0
  39. data/lib/rock_books/reports/templates/text/multidoc_txn_report.txt.erb +25 -0
  40. data/lib/rock_books/reports/templates/text/receipts_report.txt.erb +16 -0
  41. data/lib/rock_books/reports/templates/text/tx_one_account.txt.erb +21 -0
  42. data/lib/rock_books/reports/tx_one_account.rb +10 -45
  43. data/lib/rock_books/types/account.rb +13 -1
  44. data/lib/rock_books/types/account_type.rb +18 -7
  45. data/lib/rock_books/version.rb +2 -1
  46. data/manual.md +13 -16
  47. data/rock_books.gemspec +2 -0
  48. metadata +57 -10
  49. data/lib/rock_books/helpers/html_helper.rb +0 -29
  50. data/lib/rock_books/reports/index.html.erb +0 -156
  51. data/lib/rock_books/reports/multidoc_transaction_report.rb +0 -66
  52. data/lib/rock_books/reports/receipts.html.erb +0 -54
  53. data/lib/rock_books/reports/reporter.rb +0 -118
  54. data/lib/rock_books/reports/transaction_report.rb +0 -105
  55. data/lib/rock_books/reports/tx_by_account.rb +0 -82
@@ -7,7 +7,7 @@ require_relative '../types/acct_amount'
7
7
  require_relative '../types/journal_entry_context'
8
8
  require_relative 'journal_entry'
9
9
  require_relative 'journal_entry_builder'
10
- require_relative '../reports/reporter'
10
+ require_relative '../reports/helpers/text_report_helper'
11
11
 
12
12
  module RockBooks
13
13
 
@@ -45,9 +45,7 @@ class Journal
45
45
  end
46
46
 
47
47
 
48
-
49
-
50
- def self.acct_amounts_in_documents(documents, entries_filter = nil, acct_amounts_filter = nil)
48
+ def self.acct_amounts_in_documents(documents, entries_filter = nil, acct_amounts_filter = nil)
51
49
  entries = entries_in_documents(documents, entries_filter)
52
50
 
53
51
  acct_amounts = entries.each_with_object([]) do |entry, acct_amounts|
@@ -67,12 +65,10 @@ class Journal
67
65
  attr_reader :short_name, :account_code, :chart_of_accounts, :date_prefix, :debit_or_credit, :doc_type, :title, :entries
68
66
 
69
67
  # short_name is a name that will appear on reports identifying the journal from which a transaction comes
70
- def initialize(chart_of_accounts, input_lines, short_name = nil)
68
+ def initialize(chart_of_accounts, input_lines)
71
69
  @chart_of_accounts = chart_of_accounts
72
- @short_name = short_name
73
70
  @entries = []
74
71
  @date_prefix = ''
75
- @title = ''
76
72
  input_lines.each_with_index do |line, linenum|
77
73
  context = JournalEntryContext.new(self, linenum + 1, line)
78
74
  parse_line(context)
@@ -131,7 +127,6 @@ class Journal
131
127
  end
132
128
 
133
129
 
134
-
135
130
  def acct_amounts
136
131
  entries.each_with_object([]) { |entry, acct_amounts| acct_amounts << entry.acct_amounts }.flatten
137
132
  end
@@ -32,12 +32,17 @@ class JournalEntry < Struct.new(:date, :acct_amounts, :doc_short_name, :descript
32
32
 
33
33
  def self.sort_entries_by_amount_descending!(entries)
34
34
  entries.sort_by! do |entry|
35
- [entry.total_absolute_value, entry.doc_short_name]
35
+ [-entry.total_absolute_value, entry.doc_short_name]
36
36
  end
37
- entries.reverse!
38
37
  end
39
38
 
40
39
 
40
+ def self.sort_entries_by_date!(entries)
41
+ entries.sort_by! { |entry| [entry.date, entry.doc_short_name] }
42
+ end
43
+
44
+
45
+
41
46
  def total_for_code(account_code)
42
47
  acct_amounts_with_code(account_code).map(&:amount).sum
43
48
  end
@@ -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 .rdt.
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 { |fs| Journal.from_file(chart_of_accounts, fs) }
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 '../filters/journal_entry_filters'
2
- require_relative '../documents/journal'
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 Reporter
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 end_date
22
- context.chart_of_accounts.end_date
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
@@ -1,104 +1,153 @@
1
1
  require_relative '../documents/book_set'
2
2
 
3
3
  require_relative 'balance_sheet'
4
+ require_relative 'data/bs_is_data'
5
+ require_relative 'data/receipts_report_data'
4
6
  require_relative 'income_statement'
5
- require_relative 'multidoc_transaction_report'
7
+ require_relative 'index_html_page'
8
+ require_relative 'multidoc_txn_report'
6
9
  require_relative 'receipts_report'
7
10
  require_relative 'report_context'
8
- require_relative 'transaction_report'
9
- require_relative 'tx_by_account'
11
+ require_relative 'journal_report'
12
+ require_relative 'multidoc_txn_by_account_report'
10
13
  require_relative 'tx_one_account'
14
+ require_relative 'helpers/erb_helper'
15
+ require_relative 'helpers/text_report_helper'
16
+ require_relative 'helpers/receipts_hyperlink_converter'
17
+
18
+ require 'prawn'
19
+ require 'tty-progressbar'
11
20
 
12
21
  module RockBooks
13
22
  class BookSetReporter
14
23
 
15
24
  extend Forwardable
16
25
 
17
- attr_reader :book_set, :output_dir, :filter, :context
26
+ attr_reader :book_set, :context, :filter, :output_dir, :progress_bar
18
27
 
19
28
  def_delegator :book_set, :all_entries
20
29
  def_delegator :book_set, :journals
21
30
  def_delegator :book_set, :chart_of_accounts
22
31
  def_delegator :book_set, :run_options
23
32
 
33
+ FONT_FILESPEC = File.absolute_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'assets', 'fonts', 'JetBrainsMono-Medium.ttf'))
34
+
24
35
 
25
36
  def initialize(book_set, output_dir, filter = nil)
26
37
  @book_set = book_set
27
38
  @output_dir = output_dir
28
39
  @filter = filter
29
40
  @context = ReportContext.new(book_set.chart_of_accounts, book_set.journals, 80)
41
+ @progress_bar = TTY::ProgressBar.new("[:bar] :caption", total: report_count + 10)
30
42
  end
31
43
 
32
44
 
33
- def call
34
- check_prequisite_executables
35
- reports = all_reports(filter)
45
+ def generate
36
46
  create_directories
37
47
  create_index_html
38
- write_reports(reports)
48
+
49
+ do_statements
50
+ do_journals
51
+ do_transaction_reports
52
+ do_single_account_reports
53
+ do_receipts_report
54
+ progress_bar.advance(caption: 'Finished generating reports.')
55
+ progress_bar.finish
39
56
  end
40
57
 
41
58
 
42
- # All methods after this point are private.
59
+ def report_count
60
+ bal_sheet_income_statement = 2
61
+ journal_count = journals.size
62
+ txn_report_count = 3
63
+ single_account_count = chart_of_accounts.accounts.size
64
+ receipt_report_count = 1
65
+ bal_sheet_income_statement + journal_count + txn_report_count + single_account_count + receipt_report_count
66
+ end
43
67
 
44
- private def all_reports(filter = nil)
45
68
 
46
- report_hash = journals.each_with_object({}) do |journal, report_hash|
47
- key = journal.short_name.to_sym
48
- report_hash[key] = TransactionReport.new(journal, context).call(filter)
49
- end
69
+ def get_all_report_data
70
+ reports = {}
50
71
 
51
- report_hash[:all_txns_by_date] = MultidocTransactionReport.new(context).call(filter)
52
- report_hash[:all_txns_by_amount] = MultidocTransactionReport.new(context).call(filter, :amount)
53
- report_hash[:all_txns_by_acct] = TxByAccount.new(context).call
54
- report_hash[:balance_sheet] = BalanceSheet.new(context).call
55
- report_hash[:income_statement] = IncomeStatement.new(context).call
72
+ reports[:bs_is] = BsIsData.new(context)
56
73
 
57
- if run_options.do_receipts
58
- report_hash[:receipts] = ReceiptsReport.new(context, *missing_existing_unused_receipts).call
74
+ reports[:journals] = journals.each_with_object({}) do |journal, journals|
75
+ journals[journal.short_name] = JournalData.new(journal, context, filter).fetch
59
76
  end
60
77
 
61
- chart_of_accounts.accounts.each do |account|
62
- key = ('acct_' + account.code).to_sym
63
- report = TxOneAccount.new(context, account.code).call
64
- report_hash[key] = report
78
+ reports[:txn_reports] = {
79
+ by_account: MultidocTxnByAccountData.new(context).fetch,
80
+ by_date: MultidocTxnReportData.new(context, :date, filter).fetch,
81
+ by_amount: MultidocTxnReportData.new(context, :amount, filter).fetch
82
+ }
83
+
84
+ reports[:single_accounts] = chart_of_accounts.accounts.each_with_object({}) do |account, single_accts|
85
+ single_accts[account.code.to_sym] = TxOneAccountData.new(context, account.code).fetch
65
86
  end
66
87
 
67
- report_hash
88
+ reports[:receipts] = ReceiptsReportData.new(book_set.all_entries, run_options.receipt_dir).fetch
89
+ reports
68
90
  end
69
91
 
92
+ # All methods after this point are private.
70
93
 
71
- private def run_command(command)
72
- puts "\n----\nRunning command: #{command}"
73
- stdout, stderr, status = Open3.capture3(command)
74
- puts "Status was #{status}."
75
- unless stdout.size == 0
76
- puts "\nStdout was:\n\n#{stdout}"
77
- end
78
- unless stderr.size == 0
79
- puts "\nStderr was:\n\n#{stderr}"
94
+ private def do_statements
95
+ bs_is_data = BsIsData.new(context)
96
+
97
+ bal_sheet_text_report = BalanceSheet.new(context, bs_is_data.bal_sheet_data).generate
98
+ write_report(:balance_sheet, bal_sheet_text_report)
99
+
100
+ inc_stat_text_report = IncomeStatement.new(context, bs_is_data.inc_stat_data).generate
101
+ write_report(:income_statement, inc_stat_text_report)
102
+ end
103
+
104
+
105
+ private def do_journals
106
+ journals.each do |journal|
107
+ report_data = JournalData.new(journal, context, filter).fetch
108
+ text_report = JournalReport.new(report_data, context, filter).generate
109
+ write_report(journal.short_name, text_report)
80
110
  end
81
- puts
82
- stdout
83
111
  end
84
112
 
85
113
 
86
- private def executable_exists?(name)
87
- `which #{name}`
88
- $?.success?
114
+ private def do_transaction_reports
115
+
116
+ do_date_or_amount_report = ->(sort_field, short_name) do
117
+ data = MultidocTxnReportData.new(context, sort_field, filter).fetch
118
+ text_report = MultidocTransactionReport.new(data, context).generate
119
+ write_report(short_name, text_report)
120
+ end
121
+
122
+ do_acct_report = -> do
123
+ data = MultidocTxnByAccountData.new(context).fetch
124
+ text_report = MultidocTransactionByAccountReport.new(data, context).generate
125
+ write_report(:all_txns_by_acct, text_report)
126
+ end
127
+
128
+ do_date_or_amount_report.(:date, :all_txns_by_date)
129
+ do_date_or_amount_report.(:amount, :all_txns_by_amount)
130
+ do_acct_report.()
89
131
  end
90
132
 
91
133
 
92
- private def check_prequisite_executables
93
- raise "Report generation is not currently supported in Windows." if OS.windows?
94
- required_exes = OS.mac? ? %w(textutil cupsfilter) : %w(txt2html wkhtmltopdf)
95
- missing_exes = required_exes.reject { |exe| executable_exists?(exe) }
96
- if missing_exes.any?
97
- raise "Missing required report generation executable(s): #{missing_exes.join(', ')}. Please install them with your system's package manager."
134
+ private def do_single_account_reports
135
+ chart_of_accounts.accounts.each do |account|
136
+ short_name = ('acct_' + account.code).to_sym
137
+ data = TxOneAccountData.new(context, account.code).fetch
138
+ text_report = TxOneAccount.new(data, context).generate
139
+ write_report(short_name, text_report)
98
140
  end
99
141
  end
100
142
 
101
143
 
144
+ private def do_receipts_report
145
+ data = ReceiptsReportData.new(book_set.all_entries, run_options.receipt_dir).fetch
146
+ text_report = ReceiptsReport.new(context, data).generate
147
+ write_report(:receipts, text_report)
148
+ end
149
+
150
+
102
151
  private def create_directories
103
152
  %w(txt pdf html).each do |format|
104
153
  dir = File.join(output_dir, format, SINGLE_ACCT_SUBDIR)
@@ -118,83 +167,66 @@ class BookSetReporter
118
167
  end
119
168
 
120
169
 
121
- private def create_index_html
122
- filespec = build_filespec(output_dir, 'index', 'html')
123
- File.write(filespec, index_html_content)
124
- puts "Created index.html"
170
+ private def report_metadata(doc_short_name)
171
+ {
172
+ RBCreator: "RockBooks v#{VERSION} (#{PROJECT_URL})",
173
+ RBEntity: context.entity,
174
+ RBCreated: Time.now.to_s,
175
+ RBDocumentCode: doc_short_name.to_s,
176
+ }
125
177
  end
126
178
 
127
179
 
128
- private def write_reports(reports)
180
+ private def prawn_create_document(pdf_filespec, report_text, doc_short_name)
181
+ Prawn::Document.generate(pdf_filespec, info: report_metadata(doc_short_name)) do
182
+ font(FONT_FILESPEC, size: 10)
129
183
 
130
- reports.each do |short_name, report_text|
131
- txt_filespec = build_filespec(output_dir, short_name, 'txt')
132
- html_filespec = build_filespec(output_dir, short_name, 'html')
133
- pdf_filespec = build_filespec(output_dir, short_name, 'pdf')
134
-
135
- File.write(txt_filespec, report_text)
184
+ utf8_nonbreaking_space = "\uC2A0"
185
+ unicode_nonbreaking_space = "\u00A0"
186
+ text(report_text.gsub(' ', unicode_nonbreaking_space))
187
+ end
188
+ end
136
189
 
137
- # Mac OS
138
- textutil = ->(font_size) do
139
- run_command("textutil -convert html -font 'Courier New Bold' -fontsize #{font_size} #{txt_filespec} -output #{html_filespec}")
140
- end
141
- cupsfilter = -> { run_command("cupsfilter #{txt_filespec} > #{pdf_filespec}") }
142
190
 
143
- # Linux
144
- txt2html = -> { run_command("txt2html --preformat_trigger_lines 0 #{txt_filespec} > #{html_filespec}") }
145
- html2pdf = -> { run_command("wkhtmltopdf #{html_filespec} #{pdf_filespec}") }
191
+ private def html_metadata_comment(doc_short_name)
192
+ "\n" + report_metadata(doc_short_name).ai(plain: true) + "\n"
193
+ end
146
194
 
147
- # Use smaller size for the PDF but larger size for the web pages:
148
- if OS.mac?
149
- textutil.(11)
150
- cupsfilter.()
151
- textutil.(14)
152
- else
153
- txt2html.()
154
- html2pdf.()
155
- end
156
195
 
157
- hyperlinkized_text, replacements_made = HtmlHelper.convert_receipts_to_hyperlinks(File.read(html_filespec))
158
- if replacements_made
159
- File.write(html_filespec, hyperlinkized_text)
160
- end
196
+ private def write_report(short_name, text_report)
161
197
 
162
- puts "Created reports in txt, html, and pdf for #{"%-20s" % short_name} at #{File.dirname(txt_filespec)}.\n\n\n"
163
- end
164
- end
198
+ txt_filespec = build_filespec(output_dir, short_name, 'txt')
199
+ html_filespec = build_filespec(output_dir, short_name, 'html')
200
+ pdf_filespec = build_filespec(output_dir, short_name, 'pdf')
165
201
 
202
+ create_text_report = -> { File.write(txt_filespec, text_report) }
166
203
 
167
- private def receipt_full_filespec(receipt_filespec)
168
- File.join(run_options.receipt_dir, receipt_filespec)
169
- end
204
+ create_pdf_report = -> { prawn_create_document(pdf_filespec, text_report, short_name) }
170
205
 
206
+ create_html_report = -> do
207
+ data = {
208
+ report_body: text_report,
209
+ title: "#{short_name} Report -- RockBooks",
210
+ metadata_comment: html_metadata_comment(short_name)
211
+ }
212
+ html_raw_report = ErbHelper.render_hashes("html/report_page.html.erb", data, {})
213
+ html_report = ReceiptsHyperlinkConverter.convert(html_raw_report, html_filespec)
214
+ File.write(html_filespec, html_report)
215
+ end
171
216
 
172
- private def missing_existing_unused_receipts
173
- missing = []
174
- existing = []
175
- unused = Dir['receipts/**/*'].select { |s| File.file?(s) }.sort # Remove files as they are found
176
- unused.map! { |s| "./" + s } # Prepend './' to match the data
217
+ create_text_report.()
218
+ create_pdf_report.()
219
+ create_html_report.()
177
220
 
178
- all_entries.each do |entry|
179
- entry.receipts.each do |receipt|
180
- filespec = receipt_full_filespec(receipt)
181
- unused.delete(filespec)
182
- file_exists = File.file?(filespec)
183
- list = (file_exists ? existing : missing)
184
- list << { receipt: receipt, journal: entry.doc_short_name }
185
- end
186
- end
187
- [missing, existing, unused]
221
+ progress_bar.advance(caption: "Generating report: #{short_name}")
188
222
  end
189
223
 
190
224
 
191
- private def index_html_content
192
- erb_filespec = File.join(File.dirname(__FILE__), 'index.html.erb')
193
- erb = ERB.new(File.read(erb_filespec))
194
- erb.result_with_hash(
195
- journals: journals,
196
- chart_of_accounts: chart_of_accounts,
197
- run_options: run_options)
225
+ private def create_index_html
226
+ progress_bar.advance(caption: 'Generating index.html')
227
+ filespec = build_filespec(output_dir, 'index', 'html')
228
+ content = IndexHtmlPage.new(context, html_metadata_comment('index.html'), run_options).generate
229
+ File.write(filespec, content)
198
230
  end
199
231
  end
200
232
  end