rock_books 0.6.1 → 0.7.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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -3
  3. data/RELEASE_NOTES.md +12 -0
  4. data/assets/fonts/JetBrainsMono-Medium.ttf +0 -0
  5. data/lib/rock_books/cmd_line/command_line_interface.rb +6 -6
  6. data/lib/rock_books/cmd_line/main.rb +1 -9
  7. data/lib/rock_books/documents/book_set.rb +1 -1
  8. data/lib/rock_books/documents/chart_of_accounts.rb +29 -12
  9. data/lib/rock_books/documents/journal.rb +2 -6
  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/helpers/html_helper.rb +22 -16
  14. data/lib/rock_books/reports/balance_sheet.rb +8 -42
  15. data/lib/rock_books/reports/book_set_reporter.rb +104 -86
  16. data/lib/rock_books/reports/data/bs_is_data.rb +61 -0
  17. data/lib/rock_books/reports/data/bs_is_section_data.rb +28 -0
  18. data/lib/rock_books/reports/data/journal_data.rb +37 -0
  19. data/lib/rock_books/reports/data/multidoc_txn_by_account_data.rb +40 -0
  20. data/lib/rock_books/reports/data/multidoc_txn_report_data.rb +39 -0
  21. data/lib/rock_books/reports/data/receipts_report_data.rb +47 -0
  22. data/lib/rock_books/reports/data/tx_one_account_data.rb +37 -0
  23. data/lib/rock_books/reports/helpers/erb_helper.rb +26 -0
  24. data/lib/rock_books/reports/helpers/reporter.rb +134 -0
  25. data/lib/rock_books/reports/income_statement.rb +8 -46
  26. data/lib/rock_books/reports/journal_report.rb +72 -0
  27. data/lib/rock_books/reports/multidoc_txn_by_account_report.rb +32 -0
  28. data/lib/rock_books/reports/multidoc_txn_report.rb +25 -0
  29. data/lib/rock_books/reports/receipts_report.rb +5 -54
  30. data/lib/rock_books/reports/templates/html/index.html.erb +141 -0
  31. data/lib/rock_books/reports/templates/html/report_page.html.erb +12 -0
  32. data/lib/rock_books/reports/templates/text/_receipt_section.txt.erb +17 -0
  33. data/lib/rock_books/reports/templates/text/_totals.txt.erb +8 -0
  34. data/lib/rock_books/reports/templates/text/balance_sheet.txt.erb +21 -0
  35. data/lib/rock_books/reports/templates/text/income_statement.txt.erb +21 -0
  36. data/lib/rock_books/reports/templates/text/journal.txt.erb +20 -0
  37. data/lib/rock_books/reports/templates/text/multidoc_txn_by_account_report.txt.erb +28 -0
  38. data/lib/rock_books/reports/templates/text/multidoc_txn_report.txt.erb +22 -0
  39. data/lib/rock_books/reports/templates/text/receipts_report.txt.erb +13 -0
  40. data/lib/rock_books/reports/templates/text/tx_one_account.txt.erb +18 -0
  41. data/lib/rock_books/reports/tx_one_account.rb +9 -44
  42. data/lib/rock_books/types/account.rb +13 -1
  43. data/lib/rock_books/types/account_type.rb +18 -7
  44. data/lib/rock_books/version.rb +1 -1
  45. data/rock_books.gemspec +1 -0
  46. metadata +41 -9
  47. data/lib/rock_books/reports/index.html.erb +0 -156
  48. data/lib/rock_books/reports/multidoc_transaction_report.rb +0 -66
  49. data/lib/rock_books/reports/receipts.html.erb +0 -54
  50. data/lib/rock_books/reports/reporter.rb +0 -118
  51. data/lib/rock_books/reports/transaction_report.rb +0 -105
  52. data/lib/rock_books/reports/tx_by_account.rb +0 -82
@@ -1,5 +1,5 @@
1
- require_relative '../documents/journal'
2
- require_relative 'report_context'
1
+ require_relative 'helpers/erb_helper'
2
+ require_relative 'helpers/reporter'
3
3
 
4
4
  module RockBooks
5
5
 
@@ -7,57 +7,19 @@ module RockBooks
7
7
  class IncomeStatement
8
8
 
9
9
  include Reporter
10
+ include ErbHelper
10
11
 
11
- attr_accessor :context
12
+ attr_reader :data, :context
12
13
 
13
14
 
14
- def initialize(report_context)
15
+ def initialize(report_context, data)
15
16
  @context = report_context
17
+ @data = data
16
18
  end
17
19
 
18
20
 
19
- def start_date
20
- context.chart_of_accounts.start_date
21
+ def generate
22
+ ErbHelper.render_hashes('text/income_statement.txt.erb', data, template_presentation_context)
21
23
  end
22
-
23
-
24
- def end_date
25
- context.chart_of_accounts.end_date
26
- end
27
-
28
-
29
- def generate_header
30
- lines = [banner_line]
31
- lines << center(context.entity || 'Unspecified Entity')
32
- lines << "#{center("Income Statement -- #{start_date} to #{end_date}")}"
33
- lines << banner_line
34
- lines << ''
35
- lines << ''
36
- lines << ''
37
- lines.join("\n")
38
- end
39
-
40
-
41
- def generate_report
42
- filter = RockBooks::JournalEntryFilters.date_in_range(start_date, end_date)
43
- acct_amounts = Journal.acct_amounts_in_documents(context.journals, filter)
44
- totals = AcctAmount.aggregate_amounts_by_account(acct_amounts)
45
- totals.each { |aa| aa[1] = -aa[1] } # income statement shows credits as positive, debits as negative
46
- output = generate_header
47
-
48
- income_output, income_total = generate_account_type_section('Income', totals, :income, true)
49
- expense_output, expense_total = generate_account_type_section('Expenses', totals, :expense, false)
50
-
51
- grand_total = income_total - expense_total
52
-
53
- output << [income_output, expense_output].join("\n\n")
54
- output << "\n#{"%12.2f Net Income" % grand_total}\n============\n"
55
- output
56
- end
57
-
58
- alias_method :to_s, :generate_report
59
- alias_method :call, :generate_report
60
-
61
-
62
24
  end
63
25
  end
@@ -0,0 +1,72 @@
1
+ require_relative 'data/journal_data'
2
+ require_relative 'helpers/erb_helper'
3
+ require_relative 'helpers/reporter'
4
+
5
+ module RockBooks
6
+
7
+ class JournalReport
8
+
9
+ include Reporter
10
+ include ErbHelper
11
+
12
+ attr_accessor :context, :report_data
13
+
14
+
15
+ def initialize(report_data, report_context, filter = nil)
16
+ @report_data = report_data
17
+ @context = report_context
18
+ end
19
+
20
+
21
+ def generate
22
+ presentation_context = template_presentation_context.merge(fn_format_entry: method(:format_entry))
23
+ ErbHelper.render_hashes('text/journal.txt.erb', report_data, presentation_context)
24
+ end
25
+
26
+
27
+ private def format_entry_first_acct_amount(entry)
28
+ entry.date.to_s \
29
+ + ' ' \
30
+ + format_acct_amount(entry.acct_amounts.last) \
31
+ + "\n"
32
+ end
33
+
34
+
35
+ # Formats an entry like this, with entry description added on additional line(s) if it exists:
36
+ # 2018-05-21 $120.00 701 Office Supplies
37
+ private def format_entry_no_split(entry)
38
+ output = format_entry_first_acct_amount(entry)
39
+
40
+ if entry.description && entry.description.length > 0
41
+ output += entry.description
42
+ end
43
+ output
44
+ end
45
+
46
+
47
+ # Formats an entry like this, with entry description added on additional line(s) if it exists::
48
+ # 2018-05-21 $120.00 95.00 701 Office Supplies
49
+ # 25.00 751 Gift to Customer
50
+ private def format_entry_with_split(entry)
51
+ output = format_entry_first_acct_amount(entry)
52
+ indent = ' ' * 12
53
+
54
+ entry.acct_amounts[1..-1].each do |acct_amount|
55
+ output << indent << format_acct_amount(acct_amount) << "\n"
56
+ end
57
+
58
+ if entry.description && entry.description.length > 0
59
+ output << entry.description
60
+ end
61
+ end
62
+
63
+
64
+ private def format_entry(entry)
65
+ if entry.acct_amounts.size > 2
66
+ format_entry_with_split(entry)
67
+ else
68
+ format_entry_no_split(entry)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,32 @@
1
+ require_relative '../documents/chart_of_accounts'
2
+ require_relative 'helpers/erb_helper'
3
+ require_relative 'helpers/reporter'
4
+ require_relative 'report_context'
5
+ require_relative 'data/multidoc_txn_by_account_data'
6
+
7
+ module RockBooks
8
+
9
+ class MultidocTransactionByAccountReport
10
+
11
+ include Reporter
12
+ include ErbHelper
13
+
14
+ attr_reader :context, :data
15
+
16
+
17
+ def initialize(data, report_context)
18
+ @data = data
19
+ @context = report_context
20
+ end
21
+
22
+ def account_total_line(account_code, account_total)
23
+ account_name = context.chart_of_accounts.name_for_code(account_code)
24
+ sprintf("%.2f Total for account: %s - %s", account_total, account_code, account_name)
25
+ end
26
+
27
+ def generate
28
+ presentation_context = template_presentation_context.merge({ fn_account_total_line: method(:account_total_line) })
29
+ ErbHelper.render_hashes('text/multidoc_txn_by_account_report.txt.erb', data, presentation_context)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ require_relative 'data/multidoc_txn_report_data'
2
+ require_relative '../documents/journal'
3
+ require_relative 'helpers/erb_helper'
4
+ require_relative 'helpers/reporter'
5
+ require_relative 'report_context'
6
+
7
+ module RockBooks
8
+
9
+ class MultidocTransactionReport
10
+
11
+ include Reporter
12
+ include ErbHelper
13
+
14
+ attr_reader :context, :data
15
+
16
+ def initialize(report_data, report_context)
17
+ @data = report_data
18
+ @context = report_context
19
+ end
20
+
21
+ def generate
22
+ ErbHelper.render_hashes('text/multidoc_txn_report.txt.erb', data, template_presentation_context)
23
+ end
24
+ end
25
+ end
@@ -6,65 +6,16 @@ class ReceiptsReport
6
6
 
7
7
  include Reporter
8
8
 
9
- attr_reader :context, :missing, :existing, :unused
9
+ attr_reader :context, :data
10
10
 
11
-
12
- def initialize(report_context, missing, existing, unused)
11
+ def initialize(report_context, data)
13
12
  @context = report_context
14
- @missing = missing
15
- @existing = existing
16
- @unused = unused
17
- end
18
-
19
-
20
- def generate_header
21
- lines = [banner_line]
22
- lines << center(context.entity || 'Unspecified Entity')
23
- lines << "#{center("Receipts Report")}"
24
- lines << banner_line
25
- lines.join("\n")
26
- end
27
-
28
-
29
- def receipt_info_line(info)
30
- "%-16.16s %s\n" % [info[:journal], info[:receipt]]
31
- end
32
-
33
-
34
- def column_headings
35
- format_string = "%-16.16s %s\n"
36
- (format_string % ['Journal', 'Receipt Filespec']) << (format_string % %w(------- ----------------)) << "\n"
37
- end
38
-
39
-
40
- def report_one_section(name, list)
41
- output = ''
42
- output << "\n\n\n#{name} Receipts:\n\n" << column_headings
43
- if list.empty?
44
- output << "[None]\n\n\n"
45
- else
46
- list.each { |receipt| output << receipt_info_line(receipt) }
47
- end
48
- output
13
+ @data = data
49
14
  end
50
15
 
51
16
 
52
- def generate_report
53
- output = generate_header
54
- output << report_one_section('Missing', missing)
55
-
56
- output << "\n\n\nUnused Receipts:\n\n"
57
- if unused.empty?
58
- output << "[None]\n\n\n"
59
- else
60
- unused.each { |filespec| output << filespec << "\n" }
61
- end
62
-
63
- output << report_one_section('Existing', existing)
64
- output
17
+ def generate
18
+ ErbHelper.render_hashes('text/receipts_report.txt.erb', data, template_presentation_context)
65
19
  end
66
-
67
- alias_method :to_s, :generate_report
68
- alias_method :call, :generate_report
69
20
  end
70
21
  end
@@ -0,0 +1,141 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+
5
+ <meta charset="utf-8">
6
+
7
+ <!--Bootstrap:-->
8
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
9
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
10
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
11
+
12
+ <style>
13
+ body {
14
+ padding: 36px;
15
+ background-color: #88c1f7;
16
+ color: #01182d;
17
+ }
18
+
19
+ h2 {
20
+ margin-top: 32px;
21
+ margin-bottom: 12px;
22
+ }
23
+
24
+ .this_page_style {
25
+ background-color: #88c1f7;
26
+ color: #01182d;
27
+ border: 0px;
28
+ }
29
+ </style>
30
+ </head>
31
+
32
+ <body>
33
+
34
+ <h1><%= chart_of_accounts.entity %></h1>
35
+ <p class="muted">Reports Generated at <%= DateTime.now.strftime('%Y-%m-%d %H:%M:%S') %> by RockBooks version <%=RockBooks::VERSION %></p>
36
+
37
+ <h2>Financial Statements</h2>
38
+ <div id="financial-statements">
39
+ <a href='balance_sheet.html' class="btn btn-primary">Balance Sheet</a>
40
+ <a href='income_statement.html' class="btn btn-primary">Income Statement</a>
41
+ </div>
42
+
43
+
44
+ <h2>Supporting Documents</h2>
45
+ <div id="supporting-documents" style="display: inline ">
46
+ <%
47
+ subdir_link = ->(name, caption) do
48
+ dir_name = File.expand_path(File.join(Dir.pwd, name))
49
+ if Dir.exist?(dir_name)
50
+ %Q{<a href=#{dir_name} class="btn btn-primary">#{caption}</a>}
51
+ end
52
+ end
53
+ %>
54
+ <%= subdir_link.('invoices', 'Invoices') %>
55
+ <%= subdir_link.('receipts', 'Receipts') %>
56
+ <%= subdir_link.('statements', 'Statements') %>
57
+ <%= subdir_link.('worksheets', 'Worksheets') %>
58
+ </div>
59
+
60
+
61
+ <h2>All Transactions Reports</h2>
62
+ <div id="all-transactions">
63
+ <a href="all_txns_by_acct.html" class="btn btn-primary">By Account</a>
64
+ <a href="all_txns_by_amount.html" class="btn btn-primary">By Amount</a>
65
+ <a href="all_txns_by_date.html" class="btn btn-primary">By Date</a>
66
+ </div>
67
+
68
+ <% collapsible_heading = ->(caption, href) do %Q{
69
+ <br /><br />
70
+ <div class="collapsible-heading">
71
+ <div class="container-fluid">
72
+ <div class="row">
73
+
74
+ <div class="col-sm2" style="margin-right: 12px;">
75
+ <a class="btn btn-primary" data-toggle="collapse" href="#{href}" role="button" aria-expanded="false" aria-controls="collapseExample">
76
+ +/-
77
+ </a>
78
+ </div>
79
+
80
+ <div class="col-sm10">
81
+ <h2 style="margin: 0px;">#{caption}</h2>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ } end %>
87
+
88
+ <%= collapsible_heading.('Journal Reports', '#journal-reports') %>
89
+
90
+ <div class="collapse" id="journal-reports">
91
+ <div class="card card-body this_page_style">
92
+ <ul>
93
+ <% journals.each do |journal|
94
+ filespec = journal.short_name + '.html' %>
95
+ <li><a href="<%= filespec %>" class="this_page_style"><%= journal.title %></a></li>
96
+ <% end %>
97
+ </ul>
98
+ </div>
99
+ </div>
100
+
101
+ <%= collapsible_heading.('Individual Accounts', '#individual-accounts') %>
102
+
103
+ <div class="collapse" id="individual-accounts">
104
+ <div class="card card-body this_page_style">
105
+ <ul>
106
+ <%
107
+ chart_of_accounts.accounts.each do |account|
108
+ filespec = File.join('single-account', "acct_#{account.code}.html")
109
+ caption = "#{account.name} (#{account.code})"
110
+ %>
111
+ <li><a href="<%= filespec %>" class="this_page_style"><%= caption %></a></li>
112
+ <% end %>
113
+ </ul>
114
+ </div>
115
+ </div>
116
+
117
+ <%= collapsible_heading.('Other', '#other') %>
118
+
119
+ <div class="collapse" id="other">
120
+ <div class="card card-body this_page_style">
121
+ <ul>
122
+ <% if run_options.do_receipts %>
123
+ <li><a href="receipts.html" class="this_page_style">Missing and Existing Receipts</a></li>
124
+ <% end %>
125
+ </ul>
126
+ </div>
127
+ </div>
128
+
129
+ <%= collapsible_heading.('Reports in PDF and Text Formats', '#other-formats') %>
130
+
131
+ <div class="collapse" id="other-formats">
132
+ <div class="card card-body this_page_style">
133
+ <ul>
134
+ <li><a href="../pdf" class="this_page_style">PDF Format</a></li>
135
+ <li><a href="../txt" class="this_page_style">Text Format</a></li>
136
+ </ul>
137
+ </div>
138
+ </div>
139
+
140
+ </body>
141
+ </html>
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title></title>
5
+ <meta name="generator" content="RockBooks Accounting"/>
6
+ </head>
7
+ <body>
8
+ <pre>
9
+ <%= report_body %>
10
+ </pre>
11
+ </body>
12
+ </html>
@@ -0,0 +1,17 @@
1
+ <% receipt_info_line = ->(info) { sprintf("%-16.16s %s", info[:journal], info[:receipt]) } -%>
2
+ <% format_heading_line = ->(str1, str2) { sprintf("%-16.16s %s", str1, str2) } -%>
3
+
4
+
5
+
6
+ <%= name %> Receipts:
7
+
8
+ <%= format_heading_line.('Journal', 'Receipt Filespec') %>
9
+ <%= format_heading_line.('-------', '----------------') %>
10
+
11
+ <% if list.empty? -%>
12
+ [None]
13
+ <% else -%>
14
+ <% list.each do |receipt| -%>
15
+ <%= receipt_info_line.(receipt) %>
16
+ <% end -%>
17
+ <% end -%>