rock_books 0.6.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -3
  3. data/RELEASE_NOTES.md +49 -10
  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 -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 +115 -98
  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 +47 -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 +13 -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/rock_books.gemspec +1 -0
  47. metadata +43 -10
  48. data/lib/rock_books/helpers/html_helper.rb +0 -29
  49. data/lib/rock_books/reports/index.html.erb +0 -156
  50. data/lib/rock_books/reports/multidoc_transaction_report.rb +0 -66
  51. data/lib/rock_books/reports/receipts.html.erb +0 -54
  52. data/lib/rock_books/reports/reporter.rb +0 -118
  53. data/lib/rock_books/reports/transaction_report.rb +0 -105
  54. data/lib/rock_books/reports/tx_by_account.rb +0 -82
@@ -0,0 +1,16 @@
1
+ <% create_section = ->(name, list) do
2
+ fn_erb_render_hashes.('text/_receipt_section.txt.erb', { name: name, list: list }, {})
3
+ end -%>
4
+ <%= banner_line %>
5
+ <%= fn_center.(entity || 'Unspecified Entity') %>
6
+ <%= fn_center.('Receipts Report') %>
7
+ <%= fn_center.(accounting_period) %>
8
+
9
+ <%= fn_center.(generated) %>
10
+ <%= banner_line %>
11
+
12
+ <% # Unlike existing and missing, which arrays of hashes with keys :receipt and :journal, unused is an array of receipt filespecs %>
13
+
14
+ <%= create_section.('Missing', missing) %>
15
+ <%= create_section.('Unused', unused.map { |receipt| { receipt: receipt, journal: nil } }) %>
16
+ <%= create_section.('Existing', existing) %>
@@ -0,0 +1,21 @@
1
+ <%= banner_line %>
2
+ <%= fn_center.(entity || 'Unspecified Entity') %>
3
+ <%= fn_center.("Transactions for Account #{account_string}") %>
4
+ <%= fn_center.(sprintf("Total: %.2f", total)) %>
5
+ <%= fn_center.(accounting_period) %>
6
+
7
+ <%= fn_center.(generated) %>
8
+ <%= banner_line %>
9
+
10
+
11
+ <% if entries.empty? %>
12
+ There were no transactions for this account.
13
+
14
+
15
+ <% else -%>
16
+ <% entries.each do |entry| -%>
17
+ <%= fn_format_multidoc_entry.(entry) %>
18
+ <% end -%>
19
+
20
+ <%= fn_erb_render_binding.('text/_totals.txt.erb', binding) %>
21
+ <% end %>
@@ -1,63 +1,28 @@
1
+ require_relative 'data/tx_one_account_data'
1
2
  require_relative '../documents/chart_of_accounts'
2
3
  require_relative '../documents/journal'
3
- require_relative 'reporter'
4
+ require_relative 'helpers/erb_helper'
5
+ require_relative 'helpers/text_report_helper'
4
6
  require_relative 'report_context'
5
7
 
6
8
  module RockBooks
7
9
 
8
10
  class TxOneAccount
9
11
 
10
- include Reporter
12
+ include TextReportHelper
13
+ include ErbHelper
11
14
 
12
- attr_reader :context, :account_code, :account
15
+ attr_reader :context, :account_code, :data
13
16
 
14
17
 
15
- def initialize(report_context, account_code)
18
+ def initialize(data, report_context)
19
+ @data = data
16
20
  @context = report_context
17
- @account_code = account_code
18
- @account = context.chart_of_accounts.account_for_code(account_code)
19
21
  end
20
22
 
21
23
 
22
- def generate_header(account_total)
23
- lines = [banner_line]
24
- lines << center(context.entity || 'Unspecified Entity')
25
- lines << center("Transactions for Account #{account_code_name_type_string(account)}")
26
- lines << center("Total: %.2f" % account_total)
27
- lines << banner_line
28
- lines << ''
29
- lines << ''
30
- lines << ''
31
- lines.join("\n")
24
+ def generate
25
+ ErbHelper.render_hashes('text/tx_one_account.txt.erb', data, template_presentation_context)
32
26
  end
33
-
34
-
35
- def process_account(entries)
36
- entries.each_with_object('') do |entry, output|
37
- output << format_multidoc_entry(entry) << "\n"
38
- output << "\n" if entry.description && entry.description.length > 0
39
- end
40
- end
41
-
42
-
43
- def generate_report
44
- entries = Journal.entries_in_documents(context.journals, JournalEntryFilters.account_code(account_code))
45
- account_total = JournalEntry.total_for_code(entries, account_code)
46
- output = generate_header(account_total)
47
-
48
- if entries.empty?
49
- output << "There were no transactions for this account.\n\n\n\n"
50
- else
51
- output << process_account(entries)
52
- totals = AcctAmount.aggregate_amounts_by_account(JournalEntry.entries_acct_amounts(entries))
53
- output << generate_and_format_totals('Totals', totals)
54
- end
55
-
56
- output
57
- end
58
-
59
- alias_method :to_s, :generate_report
60
- alias_method :call, :generate_report
61
27
  end
62
-
63
28
  end
@@ -2,6 +2,18 @@ module RockBooks
2
2
 
3
3
  # The ChartOfAccount holds the set of all these accounts for the entity.
4
4
  class Account < Struct.new(:code, :type, :name)
5
- end
6
5
 
6
+ PERMITTED_CODE_CHAR_REGEX = /[\w\-\.]$/ # word chars (letters, numbers, underscores), hyphens, periods
7
+
8
+ def validate_code(code)
9
+ unless PERMITTED_CODE_CHAR_REGEX.match(code)
10
+ raise "Code {#{code}} may only contain letters, numbers, underscores, hyphens, and periods."
11
+ end
12
+ end
13
+
14
+ def initialize(code, type, name)
15
+ validate_code(code)
16
+ super
17
+ end
18
+ end
7
19
  end
@@ -12,7 +12,7 @@ module RockBooks
12
12
 
13
13
  ALL_TYPES = [ASSET, LIABILITY, EQUITY, INCOME, EXPENSE]
14
14
 
15
- TYPE_HASH = {
15
+ LETTER_TO_TYPE = {
16
16
  'A' => ASSET,
17
17
  'L' => LIABILITY,
18
18
  'O' => EQUITY,
@@ -20,14 +20,25 @@ module RockBooks
20
20
  'E' => EXPENSE
21
21
  }
22
22
 
23
- # Converts strings
24
- def self.to_type(string)
25
- type = TYPE_HASH[string[0].upcase]
26
- if type.nil?
23
+ SYMBOL_TO_TYPE = {
24
+ :asset => ASSET,
25
+ :liability => LIABILITY,
26
+ :equity => EQUITY,
27
+ :income => INCOME,
28
+ :expense => EXPENSE
29
+ }
30
+
31
+ # Converts type upper case letter representation to a type object (e.g. 'A' => ASSET)
32
+ def self.letter_to_type(string)
33
+ key = string[0].upcase
34
+ LETTER_TO_TYPE.fetch(key) do
27
35
  raise Error.new("Account type of #{string} not valid. " +
28
- "Must be one of #{TYPE_HASH.keys} (#{ALL_TYPES.map(&:singular_name)})")
36
+ "Must be one of #{LETTER_TO_TYPE.keys} (#{ALL_TYPES.map(&:singular_name)})")
29
37
  end
30
- type
38
+ end
39
+
40
+ def self.symbol_to_type(symbol)
41
+ SYMBOL_TO_TYPE[symbol]
31
42
  end
32
43
  end
33
44
  end
@@ -1,3 +1,4 @@
1
1
  module RockBooks
2
- VERSION = "0.6.0"
2
+ VERSION = '0.9.0'
3
+ PROJECT_URL = 'https://github.com/keithrbennett/rock_books'
3
4
  end
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
33
33
  spec.add_dependency 'amazing_print', '> 0'
34
34
  spec.add_dependency 'os', '> 1.0.0'
35
35
  spec.add_dependency 'pry', '> 0.0.0'
36
+ spec.add_dependency 'prawn', '>= 2.1'
36
37
 
37
38
  spec.add_development_dependency "bundler", "~> 2.0"
38
39
  spec.add_development_dependency "rake", ">= 12.3.3"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rock_books
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Bennett
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-30 00:00:00.000000000 Z
11
+ date: 2021-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: amazing_print
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: prawn
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '2.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '2.1'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -111,6 +125,7 @@ files:
111
125
  - README.md
112
126
  - RELEASE_NOTES.md
113
127
  - Rakefile
128
+ - assets/fonts/JetBrainsMono-Medium.ttf
114
129
  - bin/console
115
130
  - bin/setup
116
131
  - exe/rock_books
@@ -130,19 +145,37 @@ files:
130
145
  - lib/rock_books/filters/acct_amount_filters.rb
131
146
  - lib/rock_books/filters/journal_entry_filters.rb
132
147
  - lib/rock_books/helpers/book_set_loader.rb
133
- - lib/rock_books/helpers/html_helper.rb
134
148
  - lib/rock_books/helpers/parse_helper.rb
135
149
  - lib/rock_books/reports/balance_sheet.rb
136
150
  - lib/rock_books/reports/book_set_reporter.rb
151
+ - lib/rock_books/reports/data/bs_is_data.rb
152
+ - lib/rock_books/reports/data/bs_is_section_data.rb
153
+ - lib/rock_books/reports/data/journal_data.rb
154
+ - lib/rock_books/reports/data/multidoc_txn_by_account_data.rb
155
+ - lib/rock_books/reports/data/multidoc_txn_report_data.rb
156
+ - lib/rock_books/reports/data/receipts_report_data.rb
157
+ - lib/rock_books/reports/data/tx_one_account_data.rb
158
+ - lib/rock_books/reports/helpers/erb_helper.rb
159
+ - lib/rock_books/reports/helpers/receipts_hyperlink_converter.rb
160
+ - lib/rock_books/reports/helpers/text_report_helper.rb
137
161
  - lib/rock_books/reports/income_statement.rb
138
- - lib/rock_books/reports/index.html.erb
139
- - lib/rock_books/reports/multidoc_transaction_report.rb
140
- - lib/rock_books/reports/receipts.html.erb
162
+ - lib/rock_books/reports/index_html_page.rb
163
+ - lib/rock_books/reports/journal_report.rb
164
+ - lib/rock_books/reports/multidoc_txn_by_account_report.rb
165
+ - lib/rock_books/reports/multidoc_txn_report.rb
141
166
  - lib/rock_books/reports/receipts_report.rb
142
167
  - lib/rock_books/reports/report_context.rb
143
- - lib/rock_books/reports/reporter.rb
144
- - lib/rock_books/reports/transaction_report.rb
145
- - lib/rock_books/reports/tx_by_account.rb
168
+ - lib/rock_books/reports/templates/html/index.html.erb
169
+ - lib/rock_books/reports/templates/html/report_page.html.erb
170
+ - lib/rock_books/reports/templates/text/_receipt_section.txt.erb
171
+ - lib/rock_books/reports/templates/text/_totals.txt.erb
172
+ - lib/rock_books/reports/templates/text/balance_sheet.txt.erb
173
+ - lib/rock_books/reports/templates/text/income_statement.txt.erb
174
+ - lib/rock_books/reports/templates/text/journal.txt.erb
175
+ - lib/rock_books/reports/templates/text/multidoc_txn_by_account_report.txt.erb
176
+ - lib/rock_books/reports/templates/text/multidoc_txn_report.txt.erb
177
+ - lib/rock_books/reports/templates/text/receipts_report.txt.erb
178
+ - lib/rock_books/reports/templates/text/tx_one_account.txt.erb
146
179
  - lib/rock_books/reports/tx_one_account.rb
147
180
  - lib/rock_books/types/account.rb
148
181
  - lib/rock_books/types/account_type.rb
@@ -431,7 +464,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
431
464
  - !ruby/object:Gem::Version
432
465
  version: '0'
433
466
  requirements: []
434
- rubygems_version: 3.1.4
467
+ rubygems_version: 3.2.3
435
468
  signing_key:
436
469
  specification_version: 4
437
470
  summary: Very basic accounting package.
@@ -1,29 +0,0 @@
1
- module RockBooks
2
- module HtmlHelper
3
-
4
- module_function
5
-
6
- def self.convert_receipts_to_hyperlinks(html_text)
7
- html_lines = html_text.split("\n")
8
- replacements_made = false
9
-
10
- html_lines.each_with_index do |line, index|
11
- matches = /Receipt:\s*(.*?)</.match(line)
12
- if matches
13
- receipt_filespec = matches[1]
14
- line_with_hyperlink = line.gsub( \
15
- /Receipt:\s*#{receipt_filespec}/, \
16
- %Q{Receipt: <a href="../../../receipts/#{receipt_filespec}">#{receipt_filespec}</a>})
17
- html_lines[index] = line_with_hyperlink
18
- replacements_made = true
19
- end
20
- end
21
-
22
- if replacements_made
23
- html_text = html_lines.join("\n")
24
- end
25
-
26
- [html_text, replacements_made]
27
- end
28
- end
29
- end
@@ -1,156 +0,0 @@
1
- <!DOCTYPE html>
2
-
3
-
4
- <html>
5
-
6
- <head>
7
-
8
- <!--Bootstrap:-->
9
- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
10
-
11
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
12
- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
13
-
14
- <style>
15
- body {
16
- padding: 18px;
17
- background-color: #e7f7cd;
18
- color: darkgreen;
19
- }
20
-
21
- h2 {
22
- margin-top: 32px;
23
- margin-bottom: 12px;
24
- }
25
-
26
- .this_page_style {
27
- background-color: #e7f7cd;
28
- color: darkgreen;
29
- border: 0px;
30
- }
31
-
32
-
33
-
34
- </style>
35
-
36
- </head>
37
-
38
- <body>
39
-
40
- <h1><%= chart_of_accounts.entity %></h1>
41
- <p class="muted">Reports Generated at <%= DateTime.now.strftime('%Y-%m-%d %H:%M:%S') %> by RockBooks version <%=RockBooks::VERSION %></p>
42
-
43
-
44
- <h2>Financial Statements</h2>
45
- <div id="financial-statements">
46
- <a href='balance_sheet.html' class="btn btn-success">Balance Sheet</a>
47
- <a href='income_statement.html' class="btn btn-success">Income Statement</a>
48
- </div>
49
-
50
-
51
- <h2>Supporting Documents</h2>
52
- <div id="supporting-documents" style="display: inline ">
53
- <%
54
- subdir_link = ->(name, caption) do
55
- dir_name = File.expand_path(File.join(Dir.pwd, name))
56
- if Dir.exist?(dir_name)
57
- %Q{<a href=#{dir_name} class="btn btn-success">#{caption}</a>}
58
- end
59
- end
60
- %>
61
- <%= subdir_link.('invoices', 'Invoices') %>
62
- <%= subdir_link.('receipts', 'Receipts') %>
63
- <%= subdir_link.('statements', 'Statements') %>
64
- <%= subdir_link.('worksheets', 'Worksheets') %>
65
- </div>
66
-
67
-
68
- <h2>All Transactions Reports</h2>
69
- <div id="all-transactions">
70
- <a href="all_txns_by_acct.html" class="btn btn-success">By Account</a>
71
- <a href="all_txns_by_amount.html" class="btn btn-success">By Amount</a>
72
- <a href="all_txns_by_date.html" class="btn btn-success">By Date</a>
73
- </div>
74
-
75
- <% collapsible_heading = ->(caption, href) do
76
- %Q{<br /><br />
77
- <div class="collapsible-heading">
78
- <div class="container-fluid">
79
- <div class="row">
80
-
81
- <div class="col-sm2" style="margin-right: 12px;">
82
- <a class="btn btn-success" data-toggle="collapse" href="#{href}" role="button" aria-expanded="false" aria-controls="collapseExample">
83
- +/-
84
- </a>
85
- </div>
86
-
87
- <div class="col-sm10">
88
- <h2 style="margin: 0px;">#{caption}</h2>
89
- </div>
90
- </div>
91
- </div>
92
- </div>
93
- }
94
- end
95
- %>
96
-
97
- <%= collapsible_heading.('Journal Reports', '#journal-reports') %>
98
-
99
- </div>
100
- <div class="collapse" id="journal-reports">
101
- <div class="card card-body this_page_style">
102
- <ul>
103
- <% journals.each do |journal|
104
- filespec = journal.short_name + '.html'
105
- caption = "#{journal.title} -- #{journal.short_name} -- #{journal.account_code}"%>
106
- <li><a href="<%= filespec %>" class="this_page_style" target="_blank"><%= caption %></a></li>
107
- <% end %>
108
- </ul>
109
- </div>
110
- </div>
111
-
112
-
113
- <%= collapsible_heading.('Individual Accounts', '#individual-accounts') %>
114
-
115
- <div class="collapse" id="individual-accounts">
116
- <div class="card card-body this_page_style">
117
- <ul>
118
-
119
- <%
120
- chart_of_accounts.accounts.each do |account|
121
- filespec = File.join('single-account', "acct_#{account.code}.html")
122
- caption = "#{account.name} (#{account.code})"
123
- %>
124
- <li><a href="<%= filespec %>" class="this_page_style"><%= caption %></a></li>
125
- <% end %>
126
- </ul>
127
- </div>
128
- </div>
129
- </div>
130
-
131
-
132
- <%= collapsible_heading.('Other', '#other') %>
133
-
134
- <div class="collapse" id="other">
135
- <div class="card card-body this_page_style">
136
- <ul>
137
- <% if run_options.do_receipts %>
138
- <li><a href="receipts.html" class="this_page_style">Missing and Existing Receipts</a></li>
139
- <% end %>
140
- </ul>
141
- </div>
142
- </div>
143
-
144
- <%= collapsible_heading.('Reports in PDF and Text Formats', '#other-formats') %>
145
-
146
- <div class="collapse" id="other-formats">
147
- <div class="card card-body this_page_style">
148
- <ul>
149
- <li><a href="../pdf" class="this_page_style" target="_blank">PDF Format</a></li>
150
- <li><a href="../txt" class="this_page_style" target="_blank">Text Format</a></li>
151
- </ul>
152
- </div>
153
- </div>
154
-
155
- </body>
156
- </html>