rock_books 0.1.6 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (262) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/LICENSE.txt +201 -21
  4. data/README.md +64 -142
  5. data/RELEASE_NOTES.md +38 -0
  6. data/lib/rock_books/cmd_line/command_line_interface.rb +30 -10
  7. data/lib/rock_books/documents/book_set.rb +5 -99
  8. data/lib/rock_books/documents/chart_of_accounts.rb +66 -29
  9. data/lib/rock_books/documents/journal.rb +45 -40
  10. data/lib/rock_books/documents/journal_entry_builder.rb +11 -5
  11. data/lib/rock_books/errors/date_range_error.rb +20 -0
  12. data/lib/rock_books/helpers/html_helper.rb +29 -0
  13. data/lib/rock_books/reports/balance_sheet.rb +2 -2
  14. data/lib/rock_books/reports/book_set_reporter.rb +201 -0
  15. data/lib/rock_books/reports/income_statement.rb +2 -2
  16. data/lib/rock_books/reports/index.html.erb +156 -0
  17. data/lib/rock_books/reports/receipts.html.erb +54 -0
  18. data/lib/rock_books/reports/receipts_report.rb +23 -10
  19. data/lib/rock_books/reports/report_context.rb +1 -6
  20. data/lib/rock_books/reports/reporter.rb +1 -1
  21. data/lib/rock_books/reports/transaction_report.rb +4 -2
  22. data/lib/rock_books/version.rb +1 -1
  23. data/manual.md +251 -0
  24. data/rock_books.gemspec +4 -3
  25. data/sample_data/minimal/receipts/01/2018-01-01-sample-receipt.jpg +0 -0
  26. data/sample_data/minimal/rockbooks-inputs/{2017-xyz-chart-of-accounts.txt → 2018-xyz-chart-of-accounts.txt} +3 -1
  27. data/sample_data/minimal/rockbooks-inputs/{2017-xyz-checking-journal.txt → 2018-xyz-checking-journal.txt} +3 -6
  28. data/sample_data/minimal/rockbooks-inputs/{2017-xyz-general-journal.txt → 2018-xyz-general-journal.txt} +3 -3
  29. data/sample_data/minimal/rockbooks-inputs/2018-xyz-visa-journal.txt +32 -0
  30. data/sample_data/minimal/rockbooks-reports/html/all_txns_by_acct.html +467 -454
  31. data/sample_data/minimal/rockbooks-reports/html/all_txns_by_amount.html +90 -84
  32. data/sample_data/minimal/rockbooks-reports/html/all_txns_by_date.html +89 -83
  33. data/sample_data/minimal/rockbooks-reports/html/balance_sheet.html +35 -35
  34. data/sample_data/minimal/rockbooks-reports/html/ck.hsbc.disb.html +27 -27
  35. data/sample_data/minimal/rockbooks-reports/html/ck_hsbc_disb.html +40 -0
  36. data/sample_data/minimal/rockbooks-reports/html/general.html +28 -28
  37. data/sample_data/minimal/rockbooks-reports/html/hsbc_visa.html +45 -40
  38. data/sample_data/minimal/rockbooks-reports/html/income_statement.html +33 -32
  39. data/sample_data/minimal/rockbooks-reports/html/index.html +271 -0
  40. data/sample_data/minimal/rockbooks-reports/html/receipts.html +28 -27
  41. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_accts.rec.html +14 -14
  42. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_accts_rec.html +27 -0
  43. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_bank.fees.html +14 -14
  44. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_bank_fees.html +27 -0
  45. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_books.refs.html +14 -14
  46. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_books_refs.html +27 -0
  47. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_cc.hsbc.visa.html +61 -54
  48. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_cc.proc.html +14 -14
  49. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_cc_hsbc_visa.html +74 -0
  50. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_cc_proc.html +27 -0
  51. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_ck.hsbc.html +32 -32
  52. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_ck_hsbc.html +45 -0
  53. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_conf.fees.html +23 -23
  54. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_conf_fees.html +36 -0
  55. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_cowork.fees.html +29 -29
  56. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_cowork_fees.html +42 -0
  57. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_govt.fees.html +14 -14
  58. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_govt_fees.html +27 -0
  59. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_inet.fees.html +14 -14
  60. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_inet_fees.html +27 -0
  61. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_insurance.html +23 -23
  62. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_int.exp.html +14 -14
  63. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_int_exp.html +27 -0
  64. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_loan.to.sh.html +34 -34
  65. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_loan_to_sh.html +47 -0
  66. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_meals.ent.html +14 -14
  67. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_meals_ent.html +27 -0
  68. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_misc.exp.html +14 -14
  69. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_misc_exp.html +27 -0
  70. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_mktng.exp.html +14 -14
  71. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_mktng_exp.html +27 -0
  72. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_own.equity.html +22 -22
  73. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_own_equity.html +35 -0
  74. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_paypal.html +14 -14
  75. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_prof.fees.html +14 -14
  76. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_prof_fees.html +27 -0
  77. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_repair.maint.html +14 -14
  78. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_repair_maint.html +27 -0
  79. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_ret.earn.html +14 -14
  80. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_ret_earn.html +27 -0
  81. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_ship.exp.html +14 -14
  82. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_ship_exp.html +27 -0
  83. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_sls.cons.html +22 -22
  84. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_sls_cons.html +35 -0
  85. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_supplies.html +23 -14
  86. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_sw.exp.html +14 -14
  87. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_sw_exp.html +27 -0
  88. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.airfare.html +22 -22
  89. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.autorent.html +14 -14
  90. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.gas.etc.html +14 -14
  91. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.govt.html +14 -14
  92. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.lodging.html +23 -23
  93. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.m.e.html +14 -14
  94. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.m.i.html +14 -14
  95. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.mileage.html +22 -22
  96. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.misc.html +14 -14
  97. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.parking.html +14 -14
  98. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.perdiem.mi.html +22 -22
  99. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.taxi.html +14 -14
  100. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.trainfare.html +14 -14
  101. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr.unclass.html +14 -14
  102. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_airfare.html +35 -0
  103. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_autorent.html +27 -0
  104. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_gas_etc.html +27 -0
  105. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_govt.html +27 -0
  106. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_lodging.html +36 -0
  107. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_m_e.html +27 -0
  108. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_m_i.html +27 -0
  109. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_mileage.html +35 -0
  110. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_misc.html +27 -0
  111. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_parking.html +27 -0
  112. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_perdiem_mi.html +35 -0
  113. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_taxi.html +27 -0
  114. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_trainfare.html +27 -0
  115. data/sample_data/minimal/rockbooks-reports/html/single-account/acct_tr_unclass.html +27 -0
  116. data/sample_data/minimal/rockbooks-reports/pdf/all_txns_by_acct.pdf +0 -0
  117. data/sample_data/minimal/rockbooks-reports/pdf/all_txns_by_amount.pdf +0 -0
  118. data/sample_data/minimal/rockbooks-reports/pdf/all_txns_by_date.pdf +0 -0
  119. data/sample_data/minimal/rockbooks-reports/pdf/balance_sheet.pdf +0 -0
  120. data/sample_data/minimal/rockbooks-reports/pdf/ck.hsbc.disb.pdf +0 -0
  121. data/sample_data/minimal/rockbooks-reports/pdf/ck_hsbc_disb.pdf +0 -0
  122. data/sample_data/minimal/rockbooks-reports/pdf/general.pdf +0 -0
  123. data/sample_data/minimal/rockbooks-reports/pdf/hsbc_visa.pdf +0 -0
  124. data/sample_data/minimal/rockbooks-reports/pdf/income_statement.pdf +0 -0
  125. data/sample_data/minimal/rockbooks-reports/pdf/receipts.pdf +0 -0
  126. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_accts.rec.pdf +0 -0
  127. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_accts_rec.pdf +0 -0
  128. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_bank.fees.pdf +0 -0
  129. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_bank_fees.pdf +0 -0
  130. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_books.refs.pdf +0 -0
  131. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_books_refs.pdf +0 -0
  132. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cc.hsbc.visa.pdf +0 -0
  133. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cc.proc.pdf +0 -0
  134. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cc_hsbc_visa.pdf +0 -0
  135. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cc_proc.pdf +0 -0
  136. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ck.hsbc.pdf +0 -0
  137. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ck_hsbc.pdf +0 -0
  138. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_conf.fees.pdf +0 -0
  139. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_conf_fees.pdf +0 -0
  140. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cowork.fees.pdf +0 -0
  141. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cowork_fees.pdf +0 -0
  142. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_govt.fees.pdf +0 -0
  143. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_govt_fees.pdf +0 -0
  144. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_inet.fees.pdf +0 -0
  145. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_inet_fees.pdf +0 -0
  146. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_insurance.pdf +0 -0
  147. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_int.exp.pdf +0 -0
  148. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_int_exp.pdf +0 -0
  149. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_loan.to.sh.pdf +0 -0
  150. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_loan_to_sh.pdf +0 -0
  151. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_meals.ent.pdf +0 -0
  152. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_meals_ent.pdf +0 -0
  153. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_misc.exp.pdf +0 -0
  154. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_misc_exp.pdf +0 -0
  155. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_mktng.exp.pdf +0 -0
  156. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_mktng_exp.pdf +0 -0
  157. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_own.equity.pdf +0 -0
  158. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_own_equity.pdf +0 -0
  159. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_paypal.pdf +0 -0
  160. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_prof.fees.pdf +0 -0
  161. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_prof_fees.pdf +0 -0
  162. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_repair.maint.pdf +0 -0
  163. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_repair_maint.pdf +0 -0
  164. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ret.earn.pdf +0 -0
  165. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ret_earn.pdf +0 -0
  166. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ship.exp.pdf +0 -0
  167. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ship_exp.pdf +0 -0
  168. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_sls.cons.pdf +0 -0
  169. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_sls_cons.pdf +0 -0
  170. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_supplies.pdf +0 -0
  171. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_sw.exp.pdf +0 -0
  172. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_sw_exp.pdf +0 -0
  173. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.airfare.pdf +0 -0
  174. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.autorent.pdf +0 -0
  175. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.gas.etc.pdf +0 -0
  176. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.govt.pdf +0 -0
  177. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.lodging.pdf +0 -0
  178. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.m.e.pdf +0 -0
  179. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.m.i.pdf +0 -0
  180. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.mileage.pdf +0 -0
  181. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.misc.pdf +0 -0
  182. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.parking.pdf +0 -0
  183. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.perdiem.mi.pdf +0 -0
  184. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.taxi.pdf +0 -0
  185. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.trainfare.pdf +0 -0
  186. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.unclass.pdf +0 -0
  187. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_airfare.pdf +0 -0
  188. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_autorent.pdf +0 -0
  189. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_gas_etc.pdf +0 -0
  190. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_govt.pdf +0 -0
  191. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_lodging.pdf +0 -0
  192. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_m_e.pdf +0 -0
  193. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_m_i.pdf +0 -0
  194. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_mileage.pdf +0 -0
  195. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_misc.pdf +0 -0
  196. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_parking.pdf +0 -0
  197. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_perdiem_mi.pdf +0 -0
  198. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_taxi.pdf +0 -0
  199. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_trainfare.pdf +0 -0
  200. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr_unclass.pdf +0 -0
  201. data/sample_data/minimal/rockbooks-reports/txt/all_txns_by_acct.txt +56 -43
  202. data/sample_data/minimal/rockbooks-reports/txt/all_txns_by_amount.txt +29 -23
  203. data/sample_data/minimal/rockbooks-reports/txt/all_txns_by_date.txt +29 -23
  204. data/sample_data/minimal/rockbooks-reports/txt/balance_sheet.txt +4 -4
  205. data/sample_data/minimal/rockbooks-reports/txt/ck.hsbc.disb.txt +5 -5
  206. data/sample_data/minimal/rockbooks-reports/txt/ck_hsbc_disb.txt +24 -0
  207. data/sample_data/minimal/rockbooks-reports/txt/general.txt +5 -5
  208. data/sample_data/minimal/rockbooks-reports/txt/hsbc_visa.txt +18 -13
  209. data/sample_data/minimal/rockbooks-reports/txt/income_statement.txt +4 -3
  210. data/sample_data/minimal/rockbooks-reports/txt/receipts.txt +6 -5
  211. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_accts_rec.txt +11 -0
  212. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_bank_fees.txt +11 -0
  213. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_books_refs.txt +11 -0
  214. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_cc.hsbc.visa.txt +21 -14
  215. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_cc_hsbc_visa.txt +58 -0
  216. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_cc_proc.txt +11 -0
  217. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_ck.hsbc.txt +4 -4
  218. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_ck_hsbc.txt +29 -0
  219. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_conf.fees.txt +2 -2
  220. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_conf_fees.txt +20 -0
  221. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_cowork.fees.txt +4 -4
  222. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_cowork_fees.txt +26 -0
  223. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_govt_fees.txt +11 -0
  224. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_inet_fees.txt +11 -0
  225. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_insurance.txt +3 -3
  226. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_int_exp.txt +11 -0
  227. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_loan.to.sh.txt +4 -4
  228. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_loan_to_sh.txt +31 -0
  229. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_meals_ent.txt +11 -0
  230. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_misc_exp.txt +11 -0
  231. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_mktng_exp.txt +11 -0
  232. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_own.equity.txt +1 -1
  233. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_own_equity.txt +19 -0
  234. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_prof_fees.txt +11 -0
  235. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_repair_maint.txt +11 -0
  236. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_ret_earn.txt +11 -0
  237. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_ship_exp.txt +11 -0
  238. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_sls.cons.txt +2 -2
  239. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_sls_cons.txt +19 -0
  240. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_supplies.txt +11 -2
  241. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_sw_exp.txt +11 -0
  242. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr.airfare.txt +1 -1
  243. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr.lodging.txt +2 -2
  244. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr.mileage.txt +2 -2
  245. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr.perdiem.mi.txt +1 -1
  246. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_airfare.txt +19 -0
  247. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_autorent.txt +11 -0
  248. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_gas_etc.txt +11 -0
  249. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_govt.txt +11 -0
  250. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_lodging.txt +20 -0
  251. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_m_e.txt +11 -0
  252. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_m_i.txt +11 -0
  253. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_mileage.txt +19 -0
  254. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_misc.txt +11 -0
  255. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_parking.txt +11 -0
  256. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_perdiem_mi.txt +19 -0
  257. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_taxi.txt +11 -0
  258. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_trainfare.txt +11 -0
  259. data/sample_data/minimal/rockbooks-reports/txt/single-account/acct_tr_unclass.txt +11 -0
  260. metadata +147 -15
  261. data/sample_data/minimal/receipts/01/2017-01-20-phoenix-hampton.pdf +0 -0
  262. data/sample_data/minimal/rockbooks-inputs/2017-xyz-visa-journal.txt +0 -27
@@ -1,3 +1,41 @@
1
+ ### v0.6.0
2
+
3
+ * Linux support added!
4
+
5
+ ### v0.5.0
6
+
7
+ * Add receipt hyperlinks to HTML output.
8
+
9
+
10
+ ## v0.4.0
11
+
12
+ * Sort unused receipts alphanumerically.
13
+ * Add 'x' receipts option for reporting both missing and unused receipts.
14
+ * Fix: journals were showing journal account instead of the other account in each transaction.
15
+ * Improve Receipts report.
16
+
17
+
18
+ ## v0.3.0
19
+
20
+ * Added ability to report unused receipts.
21
+ * Errors now include more context information.
22
+ * Improved chart of accounts validation.
23
+ * Change license from MIT to Apache 2.
24
+
25
+
26
+ ## v0.2.1
27
+
28
+ * Add help text to readme.
29
+
30
+
31
+ ## v0.2.0
32
+
33
+ * Add instruction manual, modify readme.
34
+ * Overhaul generated index.html.
35
+ * Add accounting period start and end date to configuration and reports.
36
+ * Add validation of transaction dates to ensure within configured date range.
37
+ * Make report hash / OpenStruct keys consistently symbols.
38
+
1
39
  ## v0.1.6
2
40
 
3
41
  * Fixed PDF output; PDF files were corrupt because cupsfilter starting sending
@@ -49,7 +49,7 @@ Command Line Switches: [rock-books version #{RockBooks::VERSI
49
49
 
50
50
  Commands:
51
51
 
52
- rec[eipts] - receipts: a/:a all, m/:m missing, e/:e existing
52
+ rec[eipts] - receipts: a/:a all, m/:m missing, e/:e existing, u/:u unused
53
53
  rep[orts] - return an OpenStruct containing all reports (interactive shell mode only)
54
54
  d[isplay_reports] - display all reports on stdout
55
55
  w[rite_reports] - write all reports to the output directory (see -o option)
@@ -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)`
@@ -310,17 +317,20 @@ When in interactive shell mode:
310
317
  raise Error.new("Receipt processing was requested but has been disabled with --no-receipts.")
311
318
  end
312
319
 
313
- missing, existing = book_set.missing_and_existing_receipts
320
+ missing, existing, unused = book_set.missing_existing_unused_receipts
314
321
 
315
- print_missing = -> { puts "Missing Receipts:"; ap missing }
316
- print_existing = -> { puts "Existing Receipts:"; ap existing }
322
+ print_missing = -> { puts "\n\nMissing Receipts:"; ap missing }
323
+ print_existing = -> { puts "\n\nExisting Receipts:"; ap existing }
324
+ print_unused = -> { puts "\n\nUnused Receipts:"; ap unused }
317
325
 
318
326
  case options.first.to_s
319
327
  when 'a' # all
320
328
  if run_options.interactive_mode
321
- { missing: missing, existing: existing }
329
+ { missing: missing, existing: existing, unused: unused }
322
330
  else
323
- print_missing.(); print_existing.()
331
+ print_missing.()
332
+ print_existing.()
333
+ print_unused.()
324
334
  end
325
335
 
326
336
  when 'm'
@@ -329,8 +339,16 @@ When in interactive shell mode:
329
339
  when 'e'
330
340
  run_options.interactive_mode ? existing : print_existing.()
331
341
 
342
+ when 'u'
343
+ run_options.interactive_mode ? unused : print_unused.()
344
+
345
+ when 'x'
346
+ run_options.interactive_mode ? missing : print_missing.()
347
+ run_options.interactive_mode ? unused : print_unused.()
348
+
332
349
  else
333
- message = "Invalid option for receipts. Must be 'a' for all, 'm' for missing, or 'e' for existing."
350
+ message = "Invalid option for receipts." + \
351
+ " Must be 'a' for all, 'm' for missing, 'e' for existing, 'u' for unused, or 'x' for errors (missing/unused)."
334
352
  if run_options.interactive_mode
335
353
  puts message
336
354
  else
@@ -340,7 +358,7 @@ When in interactive shell mode:
340
358
  end
341
359
 
342
360
  def cmd_w
343
- book_set.all_reports_to_files(run_options.output_dir, $filter)
361
+ BookSetReporter.new(book_set, run_options.output_dir, $filter).call
344
362
  nil
345
363
  end
346
364
 
@@ -368,6 +386,8 @@ When in interactive shell mode:
368
386
 
369
387
 
370
388
  def find_command_action(command_string)
389
+ return nil if command_string.nil?
390
+
371
391
  result = commands.detect do |cmd|
372
392
  cmd.max_string.start_with?(command_string) \
373
393
  && \
@@ -1,18 +1,14 @@
1
1
  require 'awesome_print'
2
+ require 'os'
2
3
 
3
4
  require_relative 'chart_of_accounts'
4
5
  require_relative 'journal'
5
6
  require_relative '../filters/journal_entry_filters' # for shell mode
7
+ require_relative '../helpers/html_helper'
6
8
  require_relative '../helpers/parse_helper'
7
- require_relative '../reports/balance_sheet'
8
- require_relative '../reports/income_statement'
9
- require_relative '../reports/multidoc_transaction_report'
10
- require_relative '../reports/receipts_report'
11
- require_relative '../reports/report_context'
12
- require_relative '../reports/transaction_report'
13
- require_relative '../reports/tx_by_account'
14
- require_relative '../reports/tx_one_account'
9
+ require_relative '../reports/book_set_reporter'
15
10
 
11
+ require 'erb'
16
12
  require 'open3'
17
13
 
18
14
  module RockBooks
@@ -27,80 +23,6 @@ module RockBooks
27
23
  end
28
24
 
29
25
 
30
- def report_context
31
- @report_context ||= ReportContext.new(chart_of_accounts, journals, nil, nil, 80)
32
- end
33
-
34
-
35
- def all_reports(filter = nil)
36
- context = report_context
37
- report_hash = context.journals.each_with_object({}) do |journal, report_hash|
38
- report_hash[journal.short_name] = TransactionReport.new(journal, context).call(filter)
39
- 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
-
46
- if run_options.do_receipts
47
- report_hash['receipts'] = ReceiptsReport.new(context, *missing_and_existing_receipts).call
48
- end
49
-
50
- chart_of_accounts.accounts.each do |account|
51
- key = 'acct_' + account.code
52
- report = TxOneAccount.new(context, account.code).call
53
- report_hash[key] = report
54
- end
55
- report_hash
56
- end
57
-
58
-
59
- def run_command(command)
60
- puts "\n----\nRunning command: #{command}"
61
- stdout, stderr, status = Open3.capture3(command)
62
- puts "Status was #{status}."
63
- unless stdout.size == 0
64
- puts "\nStdout was:\n\n#{stdout}"
65
- end
66
- unless stderr.size == 0
67
- puts "\nStderr was:\n\n#{stderr}"
68
- end
69
- puts
70
- stdout
71
- end
72
-
73
-
74
- def all_reports_to_files(directory = '.', filter = nil)
75
- reports = all_reports(filter)
76
-
77
- # "./pdf/short_name.pdf" or "./pdf/single_account/short_name.pdf"
78
- build_filespec = ->(short_name, file_format) do
79
- fragments = [directory, file_format, "#{short_name}.#{file_format}"]
80
- is_acct_report = /^acct_/.match(short_name)
81
- if is_acct_report
82
- fragments.insert(2, SINGLE_ACCT_SUBDIR)
83
- end
84
- File.join(*fragments)
85
- end
86
-
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')
91
-
92
- FileUtils.mkdir_p(File.dirname(txt_filespec))
93
- FileUtils.mkdir_p(File.dirname(html_filespec))
94
- FileUtils.mkdir_p(File.dirname(pdf_filespec))
95
-
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"
100
- end
101
- end
102
-
103
-
104
26
  def journal_names
105
27
  journals.map(&:short_name)
106
28
  end
@@ -117,22 +39,6 @@ module RockBooks
117
39
  @all_entries ||= Journal.entries_in_documents(journals)
118
40
  end
119
41
 
120
-
121
- def receipt_full_filespec(receipt_filespec)
122
- File.join(run_options.receipt_dir, receipt_filespec)
123
- end
124
-
125
-
126
- def missing_and_existing_receipts
127
- missing = []; existing = []
128
- all_entries.each do |entry|
129
- entry.receipts.each do |receipt|
130
- file_exists = File.file?(receipt_full_filespec(receipt))
131
- list = (file_exists ? existing : missing)
132
- list << { receipt: receipt, journal: entry.doc_short_name }
133
- end
134
- end
135
- [missing, existing]
136
- end
137
42
  end
138
43
  end
44
+
@@ -1,11 +1,13 @@
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
+ REQUIRED_FIELDS = %i(doc_type title accounts entity start_date end_date)
10
+ REQUIRED_FIELDS.each { |field| attr_reader(field) }
9
11
 
10
12
 
11
13
  def self.from_file(file)
@@ -21,36 +23,64 @@ class ChartOfAccounts
21
23
  def initialize(input_lines)
22
24
  @accounts = []
23
25
  input_lines.each { |line| parse_line(line) }
24
- end
26
+ # TODO: Add validation for required fields.
25
27
 
28
+ missing_fields = REQUIRED_FIELDS.select do |field|
29
+ instance_variable_get("@#{field}").nil?
30
+ end
26
31
 
27
- def parse_line(line)
28
- case line.strip
29
- when /^@doc_type:/
30
- @doc_type = line.split('@doc_type:').last.strip
31
- when /^@entity:/
32
- @entity ||= line.split('@entity:').last.strip
33
- when /^@title:/
34
- @title = line.split('@title:').last.strip
35
- when /^$/
36
- # ignore empty line
37
- when /^#/
38
- # ignore comment line
39
- else
40
- # this is an account line in the form: 101 Asset First National City Bank
41
- # The regex below gets everything before the first whitespace in token 1, and the rest in token 2.
42
- matcher = line.match(/^(\S+)\s+(.*)$/)
43
- code = matcher[1]
44
- rest = matcher[2]
32
+ unless missing_fields.empty?
33
+ raise Error.new("Chart of accounts lacks required fields: #{missing_fields.join(', ')}")
34
+ end
35
+ end
45
36
 
46
- matcher = rest.match(/^(\S+)\s+(.*)$/)
47
- account_type_token = matcher[1]
48
- account_type = AccountType.to_type(account_type_token).symbol
49
37
 
50
- name = matcher[2]
38
+ def parse_date(date_string)
39
+ # TODO: Add better handling for this error.
40
+ # begin
41
+ date = Date.iso8601(date_string)
42
+ # rescue ArgumentError
43
+ # ..
44
+ # end
45
+ end
51
46
 
52
- accounts << Account.new(code, account_type, name)
47
+ def parse_line(line)
48
+ begin
49
+ case line.strip
50
+ when /^@doc_type:/
51
+ @doc_type = line.split('@doc_type:').last.strip
52
+ when /^@entity:/
53
+ @entity ||= line.split('@entity:').last.strip
54
+ when /^@title:/
55
+ @title = line.split('@title:').last.strip
56
+ when /^@start_date:/
57
+ @start_date = parse_date(line.split('@start_date:').last.strip)
58
+ when /^@end_date:/
59
+ @end_date = parse_date(line.split('@end_date:').last.strip)
60
+ when /^$/
61
+ # ignore empty line
62
+ when /^#/
63
+ # ignore comment line
64
+ else
65
+ # this is an account line in the form: 101 Asset First National City Bank
66
+ # The regex below gets everything before the first whitespace in token 1, and the rest in token 2.
67
+ matcher = line.match(/^(\S+)\s+(.*)$/)
68
+ code = matcher[1]
69
+ rest = matcher[2]
70
+
71
+ matcher = rest.match(/^(\S+)\s+(.*)$/)
72
+ account_type_token = matcher[1]
73
+ account_type = AccountType.to_type(account_type_token).symbol
74
+
75
+ name = matcher[2]
76
+
77
+ accounts << Account.new(code, account_type, name)
78
+ end
79
+ rescue => e
80
+ puts "Error parsing chart of accounts. Line text is:\n#{line}\n\n"
81
+ raise
53
82
  end
83
+
54
84
  end
55
85
 
56
86
 
@@ -69,6 +99,11 @@ class ChartOfAccounts
69
99
  end
70
100
 
71
101
 
102
+ def included_in_period?(date)
103
+ (start_date..end_date).include?(date)
104
+ end
105
+
106
+
72
107
  def report_string
73
108
  result = ''
74
109
 
@@ -119,10 +154,12 @@ class ChartOfAccounts
119
154
 
120
155
 
121
156
  def ==(other)
122
- doc_type == other.doc_type && \
123
- title == other.title && \
124
- accounts == other.accounts && \
125
- entity == other.entity
157
+ doc_type == other.doc_type && \
158
+ title == other.title && \
159
+ accounts == other.accounts && \
160
+ entity == other.entity && \
161
+ start_date == other.start_date && \
162
+ end_date == other.end_date
126
163
  end
127
164
  end
128
165
  end
@@ -81,47 +81,52 @@ class Journal
81
81
 
82
82
 
83
83
  def parse_line(journal_entry_context)
84
- line = journal_entry_context.line
85
- case line.strip
86
- when /^@doc_type:/
87
- @doc_type = line.split(/^@doc_type:/).last.strip
88
- when /^@account_code:/
89
- @account_code = line.split(/^@account_code:/).last.strip
90
-
91
- unless chart_of_accounts.include?(@account_code)
92
- raise AccountNotFoundError.new(@account_code, journal_entry_context)
93
- end
94
-
95
- # if debit or credit has not yet been specified, inherit the setting from the account:
96
- unless @debit_or_credit
97
- @debit_or_credit = chart_of_accounts.debit_or_credit_for_code(@account_code)
98
- end
99
-
100
- when /^@title:/
101
- @title = line.split(/^@title:/).last.strip
102
- when /^@short_name:/
103
- @short_name = line.split(/^@short_name:/).last.strip
104
- when /^@date_prefix:/
105
- @date_prefix = line.split(/^@date_prefix:/).last.strip
106
- when /^@debit_or_credit:/
107
- data = line.split(/^@debit_or_credit:/).last.strip
108
- @debit_or_credit = data.to_sym
109
- when /^$/
110
- # ignore empty line
111
- when /^#/
112
- # ignore comment line
113
- when /^\d/ # a date/acct/amount line starting with a number
114
- entries << JournalEntryBuilder.new(journal_entry_context).build
115
- else # Text line(s) to be attached to the most recently parsed transaction
116
- unless entries.last
117
- raise Error.new("Entry for this description cannot be found: #{line}")
118
- end
119
- entries.last.description << line << "\n"
120
-
121
- if /^Receipt:/.match(line)
122
- receipt_spec = line.split(/^Receipt:/).last.strip
123
- entries.last.receipts << receipt_spec
84
+ begin
85
+ line = journal_entry_context.line
86
+ case line.strip
87
+ when /^@doc_type:/
88
+ @doc_type = line.split(/^@doc_type:/).last.strip
89
+ when /^@account_code:/
90
+ @account_code = line.split(/^@account_code:/).last.strip
91
+
92
+ unless chart_of_accounts.include?(@account_code)
93
+ raise AccountNotFoundError.new(@account_code, journal_entry_context)
94
+ end
95
+
96
+ # if debit or credit has not yet been specified, inherit the setting from the account:
97
+ unless @debit_or_credit
98
+ @debit_or_credit = chart_of_accounts.debit_or_credit_for_code(@account_code)
99
+ end
100
+
101
+ when /^@title:/
102
+ @title = line.split(/^@title:/).last.strip
103
+ when /^@short_name:/
104
+ @short_name = line.split(/^@short_name:/).last.strip
105
+ when /^@date_prefix:/
106
+ @date_prefix = line.split(/^@date_prefix:/).last.strip
107
+ when /^@debit_or_credit:/
108
+ data = line.split(/^@debit_or_credit:/).last.strip
109
+ @debit_or_credit = data.to_sym
110
+ when /^$/
111
+ # ignore empty line
112
+ when /^#/
113
+ # ignore comment line
114
+ when /^\d/ # a date/acct/amount line starting with a number
115
+ entries << JournalEntryBuilder.new(journal_entry_context).build
116
+ else # Text line(s) to be attached to the most recently parsed transaction
117
+ unless entries.last
118
+ raise Error.new("Entry for this description cannot be found: #{line}")
119
+ end
120
+ entries.last.description << line << "\n"
121
+
122
+ if /^Receipt:/.match(line)
123
+ receipt_spec = line.split(/^Receipt:/).last.strip
124
+ entries.last.receipts << receipt_spec
125
+ end
124
126
  end
127
+ rescue => e
128
+ puts "Error occurred parsing:\n#{journal_entry_context}\n\n"
129
+ raise
125
130
  end
126
131
  end
127
132