rock_books 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +62 -144
  4. data/RELEASE_NOTES.md +8 -0
  5. data/lib/rock_books/cmd_line/command_line_interface.rb +11 -2
  6. data/lib/rock_books/documents/book_set.rb +53 -21
  7. data/lib/rock_books/documents/chart_of_accounts.rb +27 -5
  8. data/lib/rock_books/documents/index.html.erb +156 -0
  9. data/lib/rock_books/documents/journal_entry_builder.rb +11 -5
  10. data/lib/rock_books/documents/receipts.html.erb +54 -0
  11. data/lib/rock_books/errors/date_range_error.rb +20 -0
  12. data/lib/rock_books/reports/balance_sheet.rb +2 -2
  13. data/lib/rock_books/reports/income_statement.rb +2 -2
  14. data/lib/rock_books/reports/report_context.rb +0 -2
  15. data/lib/rock_books/version.rb +1 -1
  16. data/manual.md +251 -0
  17. data/sample_data/minimal/receipts/01/2018-01-01-sample-receipt.jpg +0 -0
  18. data/sample_data/minimal/rockbooks-inputs/{2017-xyz-chart-of-accounts.txt → 2018-xyz-chart-of-accounts.txt} +3 -1
  19. data/sample_data/minimal/rockbooks-inputs/{2017-xyz-checking-journal.txt → 2018-xyz-checking-journal.txt} +3 -6
  20. data/sample_data/minimal/rockbooks-inputs/{2017-xyz-general-journal.txt → 2018-xyz-general-journal.txt} +3 -3
  21. data/sample_data/minimal/rockbooks-inputs/2018-xyz-visa-journal.txt +32 -0
  22. data/sample_data/minimal/rockbooks-reports/html/all_txns_by_acct.html +467 -454
  23. data/sample_data/minimal/rockbooks-reports/html/all_txns_by_amount.html +90 -84
  24. data/sample_data/minimal/rockbooks-reports/html/all_txns_by_date.html +89 -83
  25. data/sample_data/minimal/rockbooks-reports/html/balance_sheet.html +35 -35
  26. data/sample_data/minimal/rockbooks-reports/html/ck.hsbc.disb.html +27 -27
  27. data/sample_data/minimal/rockbooks-reports/html/general.html +28 -28
  28. data/sample_data/minimal/rockbooks-reports/html/hsbc_visa.html +45 -40
  29. data/sample_data/minimal/rockbooks-reports/html/income_statement.html +33 -32
  30. data/sample_data/minimal/rockbooks-reports/html/receipts.html +28 -27
  31. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_accts.rec.html +14 -14
  32. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_bank.fees.html +14 -14
  33. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_books.refs.html +14 -14
  34. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_cc.hsbc.visa.html +61 -54
  35. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_cc.proc.html +14 -14
  36. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_ck.hsbc.html +32 -32
  37. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_conf.fees.html +23 -23
  38. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_cowork.fees.html +29 -29
  39. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_govt.fees.html +14 -14
  40. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_inet.fees.html +14 -14
  41. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_insurance.html +23 -23
  42. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_int.exp.html +14 -14
  43. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_loan.to.sh.html +34 -34
  44. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_meals.ent.html +14 -14
  45. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_misc.exp.html +14 -14
  46. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_mktng.exp.html +14 -14
  47. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_own.equity.html +22 -22
  48. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_paypal.html +14 -14
  49. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_prof.fees.html +14 -14
  50. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_repair.maint.html +14 -14
  51. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_ret.earn.html +14 -14
  52. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_ship.exp.html +14 -14
  53. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_sls.cons.html +22 -22
  54. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_supplies.html +23 -14
  55. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_sw.exp.html +14 -14
  56. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.airfare.html +22 -22
  57. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.autorent.html +14 -14
  58. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.gas.etc.html +14 -14
  59. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.govt.html +14 -14
  60. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.lodging.html +23 -23
  61. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.m.e.html +14 -14
  62. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.m.i.html +14 -14
  63. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.mileage.html +22 -22
  64. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.misc.html +14 -14
  65. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.parking.html +14 -14
  66. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.perdiem.mi.html +22 -22
  67. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.taxi.html +14 -14
  68. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.trainfare.html +14 -14
  69. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.unclass.html +14 -14
  70. data/sample_data/minimal/rockbooks-reports/pdf/all_txns_by_acct.pdf +0 -0
  71. data/sample_data/minimal/rockbooks-reports/pdf/all_txns_by_amount.pdf +0 -0
  72. data/sample_data/minimal/rockbooks-reports/pdf/all_txns_by_date.pdf +0 -0
  73. data/sample_data/minimal/rockbooks-reports/pdf/balance_sheet.pdf +0 -0
  74. data/sample_data/minimal/rockbooks-reports/pdf/ck.hsbc.disb.pdf +0 -0
  75. data/sample_data/minimal/rockbooks-reports/pdf/general.pdf +0 -0
  76. data/sample_data/minimal/rockbooks-reports/pdf/hsbc_visa.pdf +0 -0
  77. data/sample_data/minimal/rockbooks-reports/pdf/income_statement.pdf +0 -0
  78. data/sample_data/minimal/rockbooks-reports/pdf/receipts.pdf +0 -0
  79. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_accts.rec.pdf +0 -0
  80. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_bank.fees.pdf +0 -0
  81. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_books.refs.pdf +0 -0
  82. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cc.hsbc.visa.pdf +0 -0
  83. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cc.proc.pdf +0 -0
  84. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ck.hsbc.pdf +0 -0
  85. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_conf.fees.pdf +0 -0
  86. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cowork.fees.pdf +0 -0
  87. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_govt.fees.pdf +0 -0
  88. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_inet.fees.pdf +0 -0
  89. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_insurance.pdf +0 -0
  90. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_int.exp.pdf +0 -0
  91. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_loan.to.sh.pdf +0 -0
  92. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_meals.ent.pdf +0 -0
  93. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_misc.exp.pdf +0 -0
  94. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_mktng.exp.pdf +0 -0
  95. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_own.equity.pdf +0 -0
  96. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_paypal.pdf +0 -0
  97. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_prof.fees.pdf +0 -0
  98. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_repair.maint.pdf +0 -0
  99. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ret.earn.pdf +0 -0
  100. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ship.exp.pdf +0 -0
  101. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_sls.cons.pdf +0 -0
  102. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_supplies.pdf +0 -0
  103. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_sw.exp.pdf +0 -0
  104. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.airfare.pdf +0 -0
  105. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.autorent.pdf +0 -0
  106. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.gas.etc.pdf +0 -0
  107. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.govt.pdf +0 -0
  108. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.lodging.pdf +0 -0
  109. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.m.e.pdf +0 -0
  110. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.m.i.pdf +0 -0
  111. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.mileage.pdf +0 -0
  112. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.misc.pdf +0 -0
  113. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.parking.pdf +0 -0
  114. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.perdiem.mi.pdf +0 -0
  115. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.taxi.pdf +0 -0
  116. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.trainfare.pdf +0 -0
  117. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.unclass.pdf +0 -0
  118. data/sample_data/minimal/rockbooks-reports/txt/all_txns_by_acct.txt +56 -43
  119. data/sample_data/minimal/rockbooks-reports/txt/all_txns_by_amount.txt +29 -23
  120. data/sample_data/minimal/rockbooks-reports/txt/all_txns_by_date.txt +29 -23
  121. data/sample_data/minimal/rockbooks-reports/txt/balance_sheet.txt +4 -4
  122. data/sample_data/minimal/rockbooks-reports/txt/ck.hsbc.disb.txt +5 -5
  123. data/sample_data/minimal/rockbooks-reports/txt/general.txt +5 -5
  124. data/sample_data/minimal/rockbooks-reports/txt/hsbc_visa.txt +18 -13
  125. data/sample_data/minimal/rockbooks-reports/txt/income_statement.txt +4 -3
  126. data/sample_data/minimal/rockbooks-reports/txt/receipts.txt +6 -5
  127. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_cc.hsbc.visa.txt +21 -14
  128. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_ck.hsbc.txt +4 -4
  129. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_conf.fees.txt +2 -2
  130. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_cowork.fees.txt +4 -4
  131. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_insurance.txt +3 -3
  132. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_loan.to.sh.txt +4 -4
  133. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_own.equity.txt +1 -1
  134. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_sls.cons.txt +2 -2
  135. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_supplies.txt +11 -2
  136. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr.airfare.txt +1 -1
  137. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr.lodging.txt +2 -2
  138. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr.mileage.txt +2 -2
  139. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr.perdiem.mi.txt +1 -1
  140. metadata +11 -7
  141. data/sample_data/minimal/receipts/01/2017-01-20-phoenix-hampton.pdf +0 -0
  142. data/sample_data/minimal/rockbooks-inputs/2017-xyz-visa-journal.txt +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80a8729354ab4814e6703e459d4a95ef1d2ce537cd71ab3d87c976ed45ec4b8c
4
- data.tar.gz: aa7ac7d7ddbf5cc913631085c769e212460e5e317f884e4e847577a057c9ecc4
3
+ metadata.gz: 9e4e92f78b312267260f444d6650180bea2a9b248177b91d28cbb12db63e97b6
4
+ data.tar.gz: ed88d2eda1870d85d972e8e0e56ae141aa4cdef67b7a09e254af812c1435b7c1
5
5
  SHA512:
6
- metadata.gz: b1d621b011fc393ce025cdd0729674eb52dcb09b8e106407a35547115a44a8af21453e1159c921b9604785d27e174af84bbf6819e3b61896db0821d89e7fbe87
7
- data.tar.gz: b73f51018ef14b8db92d2e96d72ee5d08419ec119d9da753cd91861b7df827acfd922b70930f02a2fa51e3287b1c025935dc5605c2997f65ae1b9c6ea812b7ac
6
+ metadata.gz: 1c08cce1a4ed26f2dd2caeda2857e0443cfbb31c83952d172819c134b9d5ff6c7457dbac258142052f19baef55b19f352cf05988921e23f0c008b30895db48f8
7
+ data.tar.gz: 0665fe1fa4ccadb3fe420174c2cd13efc4e3c18f676f96f86877dc5eea30d59d3315e02b492ef0e2ffad0d8c80f56fed79ad14ec1e4345c53d581e846cca19d8
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  /.idea/
10
+ .DS_Store
10
11
 
11
12
  # rspec failure tracking
12
13
  .rspec_status
data/README.md CHANGED
@@ -1,183 +1,101 @@
1
1
  # RockBooks
2
2
 
3
- A super primitive bookkeeping system using text files as input documents and console output
4
- for reporting.
3
+ | Note: |
4
+ | ---- |
5
+ | The [manual.md file](manual.md) has more detailed information about RockBooks usage. |
5
6
 
6
- A supreme goal of this project is to give _you_ control over your data.
7
- Want to serialize it to YAML, JSON, CSV, or manipulate it in your custom code?
8
- No problem!
7
+ **A simple but useful accounting software application for very small entities.**
9
8
 
10
- It assumes the traditional double entry bookkeeping system, with debits and credits.
11
- In general, assets and expenses are debit balance accounts, and income, liabilities and equity
12
- are credit balance accounts.
9
+ A supreme goal of this project is to give _you_ control over your data. Want to serialize it to YAML, JSON, CSV, or manipulate it in your custom code? No problem!
13
10
 
14
- So, to really have this software make sense to you, you should probably understand
15
- the double entry bookkeeping paradigm pretty well.
11
+ After entering the data in input files, there is a processing step (a single command) that is done to validate the input and generate the reports and home page. (This could be automated using `guard`, etc.) An `index.html` is generated that links to the reports, input documents, receipts, invoices, statements, worksheets, etc., in a unified interface. This `index.html` can be opened locally using a `file:///` URL but the directory tree can easily be copied to a web server for shared and/or remote access.
16
12
 
17
- # Terminology Usage
13
+ #### How RockBooks Is Different
18
14
 
19
- * document - a RockBooks logical document such as a chart of accounts, a journal, etc.,
20
- usually containing information parsed from a data file
15
+ Mainstream accounting packages like QuickBooks have lots of bells and whistles, but are opinionated and not customizable; if you want to use your data _your_ way, or do something differently, you're out of luck.
21
16
 
22
- * data file - a RockBooks data file, which is a text file with the extension `.txt`
17
+ RockBooks is different in many ways.
23
18
 
19
+ The software is in the form of Ruby classes and objects that can be incorporated into your own code for your own customizations. The data is available to programmers as Ruby objects (and therefore JSON, YAML, etc.) In addition, RockBooks could be used as an engine with alternate pluggable UI's. Feel free to write a web app for inputting the data!
24
20
 
25
- ## Data File Format
21
+ Rather than hiding accounting concepts from the user, RockBooks embraces and exposes them. There is no attempt to hide the traditional double entry bookkeeping system, with debits and credits. Accounting terminology is used throughout (e.g. "chart of accounts", "journals"). Some understanding of accounting or bookkeeping principles is helpful but not absolutely necessary.
26
22
 
27
- Lines beginning with `#` will be ignored.
23
+ To simplify its implementation, RockBooks assumes some conventions:
28
24
 
29
- Data lines that contain the value of document properties,
30
- as opposed to transactions, etc., will be expressed as lines beginning with `@`:
25
+ * Input documents (chart of accounts, journals) are assumed to be in the `rockbooks-inputs` directory.
31
26
 
32
- ```
33
- @doc_type: journal
34
- @title: "ABC Bank Checking Account Disbursements Journal"
35
- @account: ck_abc
36
- ```
37
-
38
- Repeating data types such as entries in journals, and accounts in the chart of accounts,
39
- should in general be input after the properties.
27
+ * The following directories are assumed to contain the appropriate content, or nothing at all. They are simply presented on the reports web page as directories in the filesystem, so you can feel free to organize files in subdirectories as you see fit:
40
28
 
41
- Data lines will contain fields that an be separated with an arbitrary number of spaces, e.g.:
42
-
43
- ```
44
- 2018-05-18 123.45 703
45
- ```
46
-
47
- In journals, all entries will begin with dates, and all dates begin with numerals, so the
48
- presence of a numeral in the first column will be interpreted as the beginning of a new
49
- transaction (entry). Any lines following it not beginning with a `#` or number will be
50
- assumed to be the textual description of the transaction, and will be saved along with
51
- its other data.
52
-
53
- In order to make the entry of dates more convenient, many documents will support
54
- a `@date_prefix` property that will be prepended to dates. For example, if this prefix
55
- contains `2018-`, then subsequent dates must exclude that prefix since it will be
56
- automatically prepended. So, for example, a journal might contain the following lines:
57
-
58
- ```
59
- @date_prefix: 2018-
60
- # ...more lines...
61
- 05-29 37.50 ofc.spls
62
- 05-30 22.20 tr.taxi
63
- ```
64
-
65
- All date strings must use the format `YYYY-MM-DD`, because that's what will be expected
66
- by the application when it converts the date strings into numeric dates.
67
-
68
-
69
-
70
- ### Chart of Accounts
71
-
72
- Pretty much everything in this application assumes the presence of a chart of accounts
73
- listing the accounts, including their codes, types, and names.
74
-
75
- You'll need to provide a chart of accounts file that includes the following line in the header:
76
-
77
- `@document_type: chart_of_accounts`
78
-
79
- This file should contain the accounts
80
- that will be used. Each account should contain the following fields:
81
-
82
- | Property Name | Description |
83
- | ------------- | ------------- |
84
- | code | a short string with which to identify an account, e.g. `ret.earn` for retained earnings
85
- | type | 'A' for asset, 'L' for liability, 'O' for (owners) equity, 'I' for income, and 'E' for expenses.
86
- | name | a longer more descriptive name, used in reports, so no more than 30 or so characters long is recommended
29
+ * `receipts` - receipts documenting expenses & other transactions
30
+ * `invoices` - sales/services invoices
31
+ * `statements` - statements from banks, etc.
32
+ * `worksheets` - spreadsheets, etc., e.g. mileage and per diem calculations
87
33
 
34
+
35
+ #### Text Files as Input
88
36
 
89
- So, the chart of accounts data might include something like this:
90
-
91
- ```
92
- ck.xyz A XYZ Bank Checking Account
93
- loan.owner L Loan Payable to Owner
94
- o.equity O Owner's Equity
95
- sls.cons I Consulting Sales
96
- tr.airfare E Travel - Air Fare
97
- ```
98
-
99
- Although hyphens and underscores are typically used to logically separate string fragments,
100
- we recommend periods; they're much easier to type, and you'll be doing a lot of that.
101
-
102
- There is no maximum length for account codes, and reports will automatically align based
103
- on the longest account code. However, keep in mind that you will need to type these codes,
104
- and they will consume space in reports.
37
+ Instead of a web interface, data input is done in plain text files. This isn't as fancy but has the following advantages:
105
38
 
106
- ### Journals
39
+ * Data can be tracked in git or other version control software, offering a readable and easily accessible audit trail, manageable collaboration, with free cloud backup including history with Github, Gitlab, Bitbucket, etc.
107
40
 
108
- Journals (also referred to as _documents_ by this application)
109
- are used to record transactions of, for example:
41
+ * Text notes of arbitrary length can be included in input files, and included or excluded in reports. This can be useful, for example, in explaining the context of a transaction more thoroughly than could be done in a conventional accounting application. This can be helpful to accountants, auditors, etc., saving the time, and you money, and can demonstrate your helpfulness and transparency.
110
42
 
111
- * cash disbursements (expenditures for a single checking account)
112
- * cash receipts (funds coming into a single checking account)
113
- * combined cash disbursements and receipts
114
- * a credit card account
115
- * a Paypal account
116
- * sales
43
+ * Data will be longer lived, as it is readable and printable without any special software.
117
44
 
118
- Each journal data file needs to contain:
45
+ * Users can use their favorite text editors.
119
46
 
120
- `@doc_type: journal`
47
+ * All data entry can be done without moving the hands away from the keyboard.
121
48
 
122
- Also, it needs to identify the code of the account the journal is representing.
123
- So for example, if it is a journal of a PayPal account, and the PayPal
124
- account's code is `paypal`, then you'll need a line like this in your journal file:
125
49
 
126
- `@account_code: paypal`
50
+ #### The Accounting Period
127
51
 
128
- For your convenience, when entering transactions in a journal (but _not_ a _general_ journal),
129
- you may enter all numbers going in the direction natural for that journal as positive numbers.
52
+ There is no handling of end of year closings or the like; the entire set of data in the input files is considered included in the reporting period when generating the reports. Therefore, the best approach is to create a new data set for each year. The chart of accounts and journal files can be copied and modified as necessary.
130
53
 
131
- For example, a _Cash Disbursements Journal_ (something like a
132
- check register) may contain a transaction like this:
54
+ #### RockBooks Help Text
133
55
 
134
56
  ```
135
- 05-29 37.50 ofc.spls
57
+ Command Line Switches: [rock-books version 0.2.0 at https://github.com/keithrbennett/rock_books]
58
+
59
+ -i input directory specification, default: './rockbooks-inputs'
60
+ -o output (reports) directory specification, default: './rockbooks-reports'
61
+ -r receipts directory, default: './receipts'
62
+ -s run in shell mode
63
+
64
+ Commands:
65
+
66
+ rec[eipts] - receipts: a/:a all, m/:m missing, e/:e existing
67
+ rep[orts] - return an OpenStruct containing all reports (interactive shell mode only)
68
+ d[isplay_reports] - display all reports on stdout
69
+ w[rite_reports] - write all reports to the output directory (see -o option)
70
+ c[hart_of_accounts] - chart of accounts
71
+ h[elp] - prints this help
72
+ jo[urnals] - list of the journals' short names
73
+ proj[ect_page] - open the RockBooks Github project page in a browser
74
+ rel[oad_data] - reload data from input files
75
+ q[uit] - exits this program (interactive shell mode only) (see also 'x')
76
+ x[it] - exits this program (interactive shell mode only) (see also 'q')
77
+
78
+ When in interactive shell mode:
79
+ * use quotes for string parameters such as method names.
80
+ * for pry commands, use prefix `%`.
81
+ * you can use the global variable $filter to filter reports
136
82
  ```
137
83
 
138
- There may be many transactions in your journal, and it would be cumbersome to have to
139
- type minus signs in front of all of them if they were credits.
84
+ ----
140
85
 
141
- Because of this, the program allows you to configure each journal as to the direction
142
- (debit or credit) of the transaction. This is done with the `@debit_or_credit` property.
86
+ ## What RockBooks Is Not
143
87
 
144
- For an asset journal whose numbers will be crediting the main account
145
- (e.g. a cash disbursements journal whose entries will primarily be crediting
146
- the cash account), you would set the property to `debit`:
147
-
148
- ```
149
- @debit_or_credit: debit
150
- ```
151
-
152
-
153
- #### General Journal
154
-
155
- The general journal is a special form of journal that does not have a primary account.
156
-
157
- In this journal, debits and credits need to be specified literally as account code/amount
158
- pairs, where positive numbers will result in debits, and negative numbers will result in credits, e.g.:
159
-
160
- ```
161
- 03-10 tr.perdiem.mi 495.00 loan.to.sh -495.00
162
- Per Diem allowance for conference trip
163
- ```
88
+ As a product written by a single developer in his spare time, RockBooks lacks some conveniences of traditional accounting software programs, such as:
164
89
 
90
+ * Import of data from financial institutions
91
+ * On the fly data validation
92
+ * Data entry conveniences such as drop down selection lists for data such as accounts
93
+ * Fancy reporting and graphing -- however, RockBooks' bringing links to all the entity's documentation and output into a single web page may well be more useful
94
+ * At this time, RockBooks is only tested on Macs. The input files are plain text files and could be created on any OS, but the validation and report generation might not work. Get in touch with me if you are using a different OS and want to use RockBooks, and are willing and available to test my changes. Linux in particular should be an easy port.
165
95
 
166
96
 
167
97
  ## Installation
168
98
 
169
- Add this line to your application's Gemfile:
170
-
171
- ```ruby
172
- gem 'rock_books'
173
- ```
174
-
175
- And then execute:
176
-
177
- $ bundle
178
-
179
- Or install it yourself as:
180
-
181
99
  $ gem install rock_books
182
100
 
183
101
  ## Contributing
data/RELEASE_NOTES.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## v0.2.0
2
+
3
+ * Add instruction manual, modify readme.
4
+ * Overhaul generated index.html.
5
+ * Add accounting period start and end date to configuration and reports.
6
+ * Add validation of transaction dates to ensure within configured date range.
7
+ * Make report hash / OpenStruct keys consistently symbols.
8
+
1
9
  ## v0.1.6
2
10
 
3
11
  * Fixed PDF output; PDF files were corrupt because cupsfilter starting sending
@@ -80,7 +80,14 @@ When in interactive shell mode:
80
80
 
81
81
  def validate_run_options(options)
82
82
 
83
- return if options.suppress_command_line_validation
83
+ if [
84
+ # the command requested was to show the project page
85
+ find_command_action(ARGV[0]) == find_command_action('proj'),
86
+
87
+ options.suppress_command_line_validation,
88
+ ].any?
89
+ return # do not validate
90
+ end
84
91
 
85
92
  validate_input_dir = -> do
86
93
  File.directory?(options.input_dir) ? nil : "Input directory '#{options.input_dir}' does not exist. "
@@ -280,7 +287,7 @@ When in interactive shell mode:
280
287
  os = OpenStruct.new(book_set.all_reports($filter))
281
288
 
282
289
  # add hash methods for convenience
283
- def os.keys; to_h.keys.map(&:to_s); end
290
+ def os.keys; to_h.keys; end
284
291
  def os.values; to_h.values; end
285
292
 
286
293
  # to access as array, e.g. `a.at(1)`
@@ -368,6 +375,8 @@ When in interactive shell mode:
368
375
 
369
376
 
370
377
  def find_command_action(command_string)
378
+ return nil if command_string.nil?
379
+
371
380
  result = commands.detect do |cmd|
372
381
  cmd.max_string.start_with?(command_string) \
373
382
  && \
@@ -13,6 +13,7 @@ require_relative '../reports/transaction_report'
13
13
  require_relative '../reports/tx_by_account'
14
14
  require_relative '../reports/tx_one_account'
15
15
 
16
+ require 'erb'
16
17
  require 'open3'
17
18
 
18
19
  module RockBooks
@@ -28,27 +29,31 @@ module RockBooks
28
29
 
29
30
 
30
31
  def report_context
31
- @report_context ||= ReportContext.new(chart_of_accounts, journals, nil, nil, 80)
32
+ @report_context ||= ReportContext.new(chart_of_accounts, journals, 80)
32
33
  end
33
34
 
34
35
 
35
36
  def all_reports(filter = nil)
37
+
38
+ periods_to_underscores = ->(string) { string.gsub('.', '_') }
39
+
36
40
  context = report_context
37
41
  report_hash = context.journals.each_with_object({}) do |journal, report_hash|
38
- report_hash[journal.short_name] = TransactionReport.new(journal, context).call(filter)
42
+ key = periods_to_underscores.(journal.short_name).to_sym
43
+ report_hash[key] = TransactionReport.new(journal, context).call(filter)
39
44
  end
40
- report_hash['all_txns_by_date'] = MultidocTransactionReport.new(context).call(filter)
41
- report_hash['all_txns_by_amount'] = MultidocTransactionReport.new(context).call(filter, :amount)
42
- report_hash['all_txns_by_acct'] = TxByAccount.new(context).call
43
- report_hash['balance_sheet'] = BalanceSheet.new(context).call
44
- report_hash['income_statement'] = IncomeStatement.new(context).call
45
+ report_hash[:all_txns_by_date] = MultidocTransactionReport.new(context).call(filter)
46
+ report_hash[:all_txns_by_amount] = MultidocTransactionReport.new(context).call(filter, :amount)
47
+ report_hash[:all_txns_by_acct] = TxByAccount.new(context).call
48
+ report_hash[:balance_sheet] = BalanceSheet.new(context).call
49
+ report_hash[:income_statement] = IncomeStatement.new(context).call
45
50
 
46
51
  if run_options.do_receipts
47
- report_hash['receipts'] = ReceiptsReport.new(context, *missing_and_existing_receipts).call
52
+ report_hash[:receipts] = ReceiptsReport.new(context, *missing_and_existing_receipts).call
48
53
  end
49
54
 
50
55
  chart_of_accounts.accounts.each do |account|
51
- key = 'acct_' + account.code
56
+ key = ('acct_' + periods_to_underscores.(account.code)).to_sym
52
57
  report = TxOneAccount.new(context, account.code).call
53
58
  report_hash[key] = report
54
59
  end
@@ -74,8 +79,15 @@ module RockBooks
74
79
  def all_reports_to_files(directory = '.', filter = nil)
75
80
  reports = all_reports(filter)
76
81
 
82
+ create_directories = -> do
83
+ %w(txt pdf html).each do |format|
84
+ dir = File.join(directory, format, SINGLE_ACCT_SUBDIR)
85
+ FileUtils.mkdir_p(dir)
86
+ end
87
+ end
88
+
77
89
  # "./pdf/short_name.pdf" or "./pdf/single_account/short_name.pdf"
78
- build_filespec = ->(short_name, file_format) do
90
+ build_filespec = ->(directory, short_name, file_format) do
79
91
  fragments = [directory, file_format, "#{short_name}.#{file_format}"]
80
92
  is_acct_report = /^acct_/.match(short_name)
81
93
  if is_acct_report
@@ -84,20 +96,31 @@ module RockBooks
84
96
  File.join(*fragments)
85
97
  end
86
98
 
87
- reports.each do |short_name, report_text|
88
- txt_filespec = build_filespec.(short_name, 'txt')
89
- html_filespec = build_filespec.(short_name, 'html')
90
- pdf_filespec = build_filespec.(short_name, 'pdf')
99
+ create_index_html = -> do
100
+ filespec = build_filespec.(directory, 'index', 'html')
101
+ File.write(filespec, index_html_content)
102
+ puts "Created index.html"
103
+ end
91
104
 
92
- FileUtils.mkdir_p(File.dirname(txt_filespec))
93
- FileUtils.mkdir_p(File.dirname(html_filespec))
94
- FileUtils.mkdir_p(File.dirname(pdf_filespec))
105
+ write_reports = ->do
95
106
 
96
- File.write(txt_filespec, report_text)
97
- run_command("textutil -convert html -font 'Menlo Regular' -fontsize 10 #{txt_filespec} -output #{html_filespec}")
98
- run_command("cupsfilter #{html_filespec} > #{pdf_filespec}")
99
- puts "Created reports in txt, html, and pdf for #{"%-20s" % short_name} at #{File.dirname(txt_filespec)}.\n\n\n"
107
+ reports.each do |short_name, report_text|
108
+ txt_filespec = build_filespec.(directory, short_name, 'txt')
109
+ html_filespec = build_filespec.(directory, short_name, 'html')
110
+ pdf_filespec = build_filespec.(directory, short_name, 'pdf')
111
+
112
+ File.write(txt_filespec, report_text)
113
+ # Use smaller size for the PDF but larger size for the web pages:
114
+ run_command("textutil -convert html -font 'Courier New Bold' -fontsize 11 #{txt_filespec} -output #{html_filespec}")
115
+ run_command("cupsfilter #{html_filespec} > #{pdf_filespec}")
116
+ run_command("textutil -convert html -font 'Courier New Bold' -fontsize 14 #{txt_filespec} -output #{html_filespec}")
117
+ puts "Created reports in txt, html, and pdf for #{"%-20s" % short_name} at #{File.dirname(txt_filespec)}.\n\n\n"
118
+ end
100
119
  end
120
+
121
+ create_directories.()
122
+ create_index_html.()
123
+ write_reports.()
101
124
  end
102
125
 
103
126
 
@@ -134,5 +157,14 @@ module RockBooks
134
157
  end
135
158
  [missing, existing]
136
159
  end
160
+
161
+ def index_html_content
162
+ erb_filespec = File.join(File.dirname(__FILE__), 'index.html.erb')
163
+ erb = ERB.new(File.read(erb_filespec))
164
+ erb.result_with_hash(
165
+ journals: journals,
166
+ chart_of_accounts: chart_of_accounts,
167
+ run_options: run_options)
168
+ end
137
169
  end
138
170
  end
@@ -1,11 +1,12 @@
1
1
  require_relative '../types/account'
2
2
  require_relative '../types/account_type'
3
3
  require_relative '../errors/error'
4
+ require_relative '../errors/date_range_error'
4
5
 
5
6
  module RockBooks
6
7
  class ChartOfAccounts
7
8
 
8
- attr_reader :doc_type, :title, :accounts, :entity
9
+ attr_reader :doc_type, :title, :accounts, :entity, :start_date, :end_date
9
10
 
10
11
 
11
12
  def self.from_file(file)
@@ -21,9 +22,19 @@ class ChartOfAccounts
21
22
  def initialize(input_lines)
22
23
  @accounts = []
23
24
  input_lines.each { |line| parse_line(line) }
25
+ # TODO: Add validation for required fields.
24
26
  end
25
27
 
26
28
 
29
+ def parse_date(date_string)
30
+ # TODO: Add better handling for this error.
31
+ # begin
32
+ date = Date.iso8601(date_string)
33
+ # rescue ArgumentError
34
+ # ..
35
+ # end
36
+ end
37
+
27
38
  def parse_line(line)
28
39
  case line.strip
29
40
  when /^@doc_type:/
@@ -32,6 +43,10 @@ class ChartOfAccounts
32
43
  @entity ||= line.split('@entity:').last.strip
33
44
  when /^@title:/
34
45
  @title = line.split('@title:').last.strip
46
+ when /^@start_date:/
47
+ @start_date = parse_date(line.split('@start_date:').last.strip)
48
+ when /^@end_date:/
49
+ @end_date = parse_date(line.split('@end_date:').last.strip)
35
50
  when /^$/
36
51
  # ignore empty line
37
52
  when /^#/
@@ -69,6 +84,11 @@ class ChartOfAccounts
69
84
  end
70
85
 
71
86
 
87
+ def included_in_period?(date)
88
+ (start_date..end_date).include?(date)
89
+ end
90
+
91
+
72
92
  def report_string
73
93
  result = ''
74
94
 
@@ -119,10 +139,12 @@ class ChartOfAccounts
119
139
 
120
140
 
121
141
  def ==(other)
122
- doc_type == other.doc_type && \
123
- title == other.title && \
124
- accounts == other.accounts && \
125
- entity == other.entity
142
+ doc_type == other.doc_type && \
143
+ title == other.title && \
144
+ accounts == other.accounts && \
145
+ entity == other.entity && \
146
+ start_date == other.start_date && \
147
+ end_date == other.end_date
126
148
  end
127
149
  end
128
150
  end