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.
- checksums.yaml +4 -4
- data/README.md +8 -10
- data/RELEASE_NOTES.md +57 -10
- data/assets/fonts/JetBrainsMono-Medium.ttf +0 -0
- data/lib/rock_books/cmd_line/command_line_interface.rb +15 -24
- data/lib/rock_books/cmd_line/main.rb +1 -9
- data/lib/rock_books/documents/book_set.rb +5 -2
- data/lib/rock_books/documents/chart_of_accounts.rb +29 -12
- data/lib/rock_books/documents/journal.rb +3 -8
- 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 +138 -106
- data/lib/rock_books/reports/data/bs_is_data.rb +61 -0
- data/lib/rock_books/reports/data/bs_is_section_data.rb +30 -0
- data/lib/rock_books/reports/data/journal_data.rb +38 -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/receipts_hyperlink_converter.rb +59 -0
- data/lib/rock_books/reports/helpers/text_report_helper.rb +144 -0
- data/lib/rock_books/reports/income_statement.rb +9 -47
- data/lib/rock_books/reports/index_html_page.rb +27 -0
- data/lib/rock_books/reports/journal_report.rb +82 -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 +158 -0
- data/lib/rock_books/reports/templates/html/report_page.html.erb +25 -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 +23 -0
- data/lib/rock_books/reports/templates/text/income_statement.txt.erb +23 -0
- data/lib/rock_books/reports/templates/text/journal.txt.erb +23 -0
- data/lib/rock_books/reports/templates/text/multidoc_txn_by_account_report.txt.erb +31 -0
- data/lib/rock_books/reports/templates/text/multidoc_txn_report.txt.erb +25 -0
- data/lib/rock_books/reports/templates/text/receipts_report.txt.erb +16 -0
- data/lib/rock_books/reports/templates/text/tx_one_account.txt.erb +21 -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 +2 -1
- data/manual.md +13 -16
- data/rock_books.gemspec +2 -0
- metadata +57 -10
- data/lib/rock_books/helpers/html_helper.rb +0 -29
- data/lib/rock_books/reports/index.html.erb +0 -156
- data/lib/rock_books/reports/multidoc_transaction_report.rb +0 -66
- data/lib/rock_books/reports/receipts.html.erb +0 -54
- 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
@@ -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,30 @@
|
|
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 do |code|
|
23
|
+
totals[code] = -totals[code] unless totals[code] == 0.0
|
24
|
+
end
|
25
|
+
end
|
26
|
+
totals
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,38 @@
|
|
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
|
+
debit_or_credit: journal.debit_or_credit,
|
29
|
+
start_date: context.chart_of_accounts.start_date,
|
30
|
+
end_date: context.chart_of_accounts.end_date,
|
31
|
+
entries: entries,
|
32
|
+
totals: totals,
|
33
|
+
grand_total: totals.values.sum.round(2),
|
34
|
+
max_acct_code_len: context.chart_of_accounts.max_account_code_length
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
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
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative '../../documents/journal'
|
2
|
+
require_relative '../../documents/journal_entry'
|
3
|
+
|
4
|
+
module RockBooks
|
5
|
+
class MultidocTxnReportData
|
6
|
+
|
7
|
+
attr_reader :context, :entries, :totals
|
8
|
+
|
9
|
+
def initialize(context, sort_by, filter = nil)
|
10
|
+
@context = context
|
11
|
+
@entries = fetch_entries(sort_by, filter)
|
12
|
+
@totals = fetch_totals(filter)
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch
|
16
|
+
{
|
17
|
+
journals: context.journals,
|
18
|
+
entries: entries,
|
19
|
+
totals: totals,
|
20
|
+
grand_total: totals.values.sum.round(2),
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
private def fetch_entries(sort_by, filter)
|
25
|
+
entries = Journal.entries_in_documents(context.journals, filter)
|
26
|
+
if sort_by == :amount
|
27
|
+
JournalEntry.sort_entries_by_amount_descending!(entries)
|
28
|
+
else
|
29
|
+
JournalEntry.sort_entries_by_date!(entries)
|
30
|
+
end
|
31
|
+
entries
|
32
|
+
end
|
33
|
+
|
34
|
+
private def fetch_totals(filter)
|
35
|
+
acct_amounts = Journal.acct_amounts_in_documents(context.journals, filter)
|
36
|
+
AcctAmount.aggregate_amounts_by_account(acct_amounts)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module RockBooks
|
2
|
+
class ReceiptsReportData
|
3
|
+
|
4
|
+
attr_reader :all_entries, :receipt_dir
|
5
|
+
|
6
|
+
def initialize(all_entries, receipt_dir)
|
7
|
+
@all_entries = all_entries
|
8
|
+
@receipt_dir = receipt_dir
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def fetch
|
13
|
+
missing_receipts = []
|
14
|
+
existing_receipts = []
|
15
|
+
|
16
|
+
# We will start out putting all filespecs in the unused array, and delete them as they are found in the transactions.
|
17
|
+
unused_receipt_filespecs = all_receipt_filespecs
|
18
|
+
|
19
|
+
all_entries.each do |entry|
|
20
|
+
entry.receipts.each do |receipt|
|
21
|
+
filespec = receipt_full_filespec(receipt)
|
22
|
+
unused_receipt_filespecs.delete(filespec)
|
23
|
+
list = (File.file?(filespec) ? existing_receipts : missing_receipts)
|
24
|
+
list << { receipt: receipt, journal: entry.doc_short_name }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
{
|
29
|
+
missing: missing_receipts,
|
30
|
+
unused: unused_receipt_filespecs,
|
31
|
+
existing: existing_receipts
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
private def all_receipt_filespecs
|
37
|
+
Dir['receipts/**/*'].select { |s| File.file?(s) } \
|
38
|
+
.sort \
|
39
|
+
.map { |s| "./" + s } # Prepend './' to match the data
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
private def receipt_full_filespec(receipt_filespec)
|
44
|
+
File.join(receipt_dir, receipt_filespec)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module RockBooks
|
2
|
+
class TxOneAccountData
|
3
|
+
|
4
|
+
include TextReportHelper
|
5
|
+
|
6
|
+
attr_reader :context, :account_code, :account, :entries, :account_total, :totals
|
7
|
+
|
8
|
+
|
9
|
+
def initialize(report_context, account_code)
|
10
|
+
@context = report_context
|
11
|
+
@account_code = account_code
|
12
|
+
end
|
13
|
+
|
14
|
+
def fetch
|
15
|
+
|
16
|
+
account = context.chart_of_accounts.account_for_code(account_code)
|
17
|
+
account_string = "#{account.code} -- #{account.name} (#{account.type.to_s.capitalize})"
|
18
|
+
entries = Journal.entries_in_documents(context.journals, JournalEntryFilters.account_code(account_code))
|
19
|
+
account_total = JournalEntry.total_for_code(entries, account_code)
|
20
|
+
totals = AcctAmount.aggregate_amounts_by_account(JournalEntry.entries_acct_amounts(entries))
|
21
|
+
|
22
|
+
|
23
|
+
{
|
24
|
+
account_string: account_string,
|
25
|
+
entries: entries,
|
26
|
+
total: account_total,
|
27
|
+
totals: AcctAmount.aggregate_amounts_by_account(JournalEntry.entries_acct_amounts(entries)),
|
28
|
+
grand_total: totals.values.sum.round(2)
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
private def fetch_totals(filter)
|
33
|
+
acct_amounts = Journal.acct_amounts_in_documents(context.journals, filter)
|
34
|
+
AcctAmount.aggregate_amounts_by_account(acct_amounts)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ErbHelper
|
2
|
+
|
3
|
+
def self.erb_template(erb_relative_filespec)
|
4
|
+
erb_filespec = File.absolute_path(File.join(File.dirname(__FILE__), '..', 'templates', erb_relative_filespec))
|
5
|
+
eoutvar = "@outvar_#{erb_relative_filespec.split('.').first.split('/').last}" # dots will be evaulated by `eval`, must remove them
|
6
|
+
ERB.new(File.read(erb_filespec), eoutvar: eoutvar, trim_mode: '-')
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
def self.render_binding(erb_relative_filespec, template_binding)
|
11
|
+
result = erb_template(erb_relative_filespec).result(template_binding)
|
12
|
+
result
|
13
|
+
end
|
14
|
+
|
15
|
+
# Takes 2 hashes, one with data, and the other with presentation functions/lambdas, and passes their union to ERB
|
16
|
+
# for rendering.
|
17
|
+
def self.render_hashes(erb_relative_filespec, data_hash, presentation_hash)
|
18
|
+
combined_hash = (data_hash || {}).merge(presentation_hash || {})
|
19
|
+
erb_template(erb_relative_filespec).result_with_hash(combined_hash)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module RockBooks
|
2
|
+
class ReceiptsHyperlinkConverter
|
3
|
+
|
4
|
+
def self.convert(html_string, html_filespec)
|
5
|
+
ReceiptsHyperlinkConverter.new(html_string, html_filespec).convert
|
6
|
+
end
|
7
|
+
|
8
|
+
RECEIPT_REGEX = /Receipt:\s*(\S*)/
|
9
|
+
INVOICE_REGEX = /Invoice:\s*(\S*)/
|
10
|
+
|
11
|
+
attr_reader :html_string, :num_dirs_up
|
12
|
+
|
13
|
+
def initialize(html_string, html_filespec)
|
14
|
+
@html_string = html_string
|
15
|
+
@num_dirs_up = html_filespec.include?('/single-account/') ? 3 : 2
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def convert
|
20
|
+
process_link_type = ->(line, regex, dir_name) do
|
21
|
+
matches = regex.match(line)
|
22
|
+
if matches
|
23
|
+
listed_filespec = matches[1]
|
24
|
+
anchor_line(line, listed_filespec, dir_name)
|
25
|
+
else
|
26
|
+
line
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
html_string.split("\n").map do |line|
|
31
|
+
line = process_link_type.(line, RECEIPT_REGEX, 'receipts')
|
32
|
+
process_link_type.(line, INVOICE_REGEX, 'invoices')
|
33
|
+
end.join("\n")
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# If the HTML file being created is in DATA_DIR/rockbooks-reports/html/single-account, then
|
38
|
+
# the processed link should be '../../../receipts/[receipt_filespec]'
|
39
|
+
# else it's in DATA_DIR/rockbooks-reports/html, and
|
40
|
+
# the processed link should be '../../receipts/[receipt_filespec]'
|
41
|
+
#
|
42
|
+
# `dir_name` will be 'receipts' or 'invoices'
|
43
|
+
private def dirized_filespec(listed_filespec, dir_name)
|
44
|
+
File.join(('../' * num_dirs_up), dir_name, listed_filespec)
|
45
|
+
end
|
46
|
+
|
47
|
+
private def anchor_line(line, listed_filespec, dir_name)
|
48
|
+
label = {
|
49
|
+
'receipts' => 'Receipt',
|
50
|
+
'invoices' => 'Invoice'
|
51
|
+
}.fetch(dir_name)
|
52
|
+
|
53
|
+
line.gsub( \
|
54
|
+
/#{label}:\s*#{listed_filespec}/, \
|
55
|
+
%Q{#{label}: <a href="#{dirized_filespec(listed_filespec, dir_name)}">#{listed_filespec}</a>})
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require_relative '../../documents/journal_entry'
|
2
|
+
require_relative 'erb_helper'
|
3
|
+
|
4
|
+
module RockBooks
|
5
|
+
module TextReportHelper
|
6
|
+
|
7
|
+
SHORT_NAME_MAX_LENGTH = 16
|
8
|
+
|
9
|
+
SHORT_NAME_FORMAT_STRING = "%#{SHORT_NAME_MAX_LENGTH}.#{SHORT_NAME_MAX_LENGTH}s"
|
10
|
+
|
11
|
+
|
12
|
+
def page_width
|
13
|
+
context.page_width || 80
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def account_code_format
|
18
|
+
@account_code_format ||= "%#{max_account_code_length}.#{max_account_code_length}s"
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def account_code_name_type_string(account)
|
23
|
+
"#{account.code} -- #{account.name} (#{account.type.to_s.capitalize})"
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def account_code_name_type_string_for_code(account_code)
|
28
|
+
account = context.chart_of_accounts.account_for_code(account_code)
|
29
|
+
raise "Account for code #{account_code} not found" unless account
|
30
|
+
account_code_name_type_string(account)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# e.g. " 117.70 tr.mileage Travel - Mileage Allowance"
|
35
|
+
def format_acct_amount(acct_amount)
|
36
|
+
sprintf("%s %s %s",
|
37
|
+
sprintf("%9.2f", acct_amount.amount),
|
38
|
+
sprintf(account_code_format, acct_amount.code),
|
39
|
+
context.chart_of_accounts.name_for_code(acct_amount.code))
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def banner_line
|
44
|
+
@banner_line ||= '-' * page_width
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def center(string)
|
49
|
+
indent = [(page_width - string.length) / 2, 0].max
|
50
|
+
(' ' * indent) + string
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def max_account_code_length
|
55
|
+
@max_account_code_length ||= context.chart_of_accounts.max_account_code_length
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def total_with_ok_or_discrepancy(amount)
|
60
|
+
status_message = (amount == 0.0) ? '(Ok)' : '(Discrepancy)'
|
61
|
+
sprintf(line_item_format_string, amount, status_message, '')
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def format_multidoc_entry(entry)
|
66
|
+
acct_amounts = entry.acct_amounts
|
67
|
+
|
68
|
+
# "2017-10-29 hsbc_visa":
|
69
|
+
output = entry.date.to_s << ' ' << (SHORT_NAME_FORMAT_STRING % entry.doc_short_name) << ' '
|
70
|
+
|
71
|
+
indent = ' ' * output.length
|
72
|
+
|
73
|
+
output << format_acct_amount(acct_amounts.first) << "\n"
|
74
|
+
|
75
|
+
acct_amounts[1..-1].each do |acct_amount|
|
76
|
+
output << indent << format_acct_amount(acct_amount) << "\n"
|
77
|
+
end
|
78
|
+
|
79
|
+
if entry.description && entry.description.length > 0
|
80
|
+
output << entry.description
|
81
|
+
end
|
82
|
+
|
83
|
+
output
|
84
|
+
end
|
85
|
+
|
86
|
+
def line_item_format_string
|
87
|
+
@line_item_format_string ||= "%12.2f %-#{context.chart_of_accounts.max_account_code_length}s %s"
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
# :asset => "Assets\n------"
|
92
|
+
def section_heading(section_type)
|
93
|
+
title = AccountType.symbol_to_type(section_type).plural_name
|
94
|
+
"\n\n" + title + "\n" + ('-' * title.length)
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def acct_name(code)
|
99
|
+
context.chart_of_accounts.name_for_code(code)
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def start_date
|
104
|
+
context.chart_of_accounts.start_date
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def end_date
|
109
|
+
context.chart_of_accounts.end_date
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# e.g. "Generated at 2021-01-09 18:22:18 by RockBooks version 0.7.1"
|
114
|
+
def generation_info_display_string
|
115
|
+
now = Time.now
|
116
|
+
timestamp = "#{now} (#{now.utc})"
|
117
|
+
center("Generated at #{timestamp}") + "\n" + center("by RockBooks version #{RockBooks::VERSION}")
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
def template_presentation_context
|
122
|
+
{
|
123
|
+
accounting_period: "#{start_date} to #{end_date}",
|
124
|
+
banner_line: banner_line,
|
125
|
+
end_date: end_date,
|
126
|
+
entity: context.entity,
|
127
|
+
fn_acct_name: method(:acct_name),
|
128
|
+
fn_account_code_name_type_string_for_code: method(:account_code_name_type_string_for_code),
|
129
|
+
fn_center: method(:center),
|
130
|
+
fn_erb_render_binding: ErbHelper.method(:render_binding),
|
131
|
+
fn_erb_render_hashes: ErbHelper.method(:render_hashes),
|
132
|
+
fn_format_multidoc_entry: method(:format_multidoc_entry),
|
133
|
+
fn_section_heading: method(:section_heading),
|
134
|
+
fn_total_with_ok_or_discrepancy: method(:total_with_ok_or_discrepancy),
|
135
|
+
generated: generation_info_display_string,
|
136
|
+
line_item_format_string: line_item_format_string,
|
137
|
+
short_name_format_string: SHORT_NAME_FORMAT_STRING,
|
138
|
+
start_date: start_date,
|
139
|
+
}
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
|