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
@@ -136,17 +136,23 @@ class JournalEntryBuilder < Struct.new(:journal_entry_context)
136
136
  tokens = line.split
137
137
  acct_amount_tokens = tokens[1..-1]
138
138
  date_string = journal.date_prefix + tokens[0]
139
- raise_error = -> do
140
- raise Error.new("In journal '#{journal.short_name}', date string was '#{date_string}'" +
141
- " but should be a valid date in the form YYYY-MM-DD.")
139
+
140
+ raise_date_format_error = -> do
141
+ raise Error.new("Date string was '#{date_string}' but should be a valid date in the form YYYY-MM-DD in " + \
142
+ "journal '#{journal_entry_context[:journal].title}', line #{journal_entry_context[:linenum]}.")
142
143
  end
143
144
 
144
- raise_error.() if date_string.length != 10
145
+ raise_date_format_error.() if date_string.length != 10
145
146
 
146
147
  begin
147
148
  date = Date.iso8601(date_string)
148
149
  rescue ArgumentError
149
- raise_error.()
150
+ raise_date_format_error.()
151
+ end
152
+
153
+ unless chart_of_accounts.included_in_period?(date)
154
+ raise DateRangeError.new(date, chart_of_accounts.start_date,
155
+ chart_of_accounts.end_date, journal_entry_context)
150
156
  end
151
157
 
152
158
  acct_amounts = build_acct_amount_array(date, acct_amount_tokens)
@@ -0,0 +1,20 @@
1
+ module RockBooks
2
+ class DateRangeError < RuntimeError
3
+
4
+ attr_reader :date, :start_date, :end_date, :extra_string
5
+
6
+ def initialize(date, start_date, end_date, extra_string = nil)
7
+ @date = date
8
+ @start_date = start_date
9
+ @end_date = end_date
10
+ @extra_string = extra_string
11
+ end
12
+
13
+ def to_s
14
+ s = "#{date} is not within this data set's period of #{start_date} to #{end_date}"
15
+ s << " (#{extra_string})" if extra_string
16
+ s << '.'
17
+ s
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
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
@@ -19,14 +19,14 @@ class BalanceSheet
19
19
 
20
20
 
21
21
  def end_date
22
- context.end_date || Time.new.to_date
22
+ context.chart_of_accounts.end_date
23
23
  end
24
24
 
25
25
 
26
26
  def generate_header
27
27
  lines = [banner_line]
28
28
  lines << center(context.entity || 'Unspecified Entity')
29
- lines << center("Balance Sheet -- #{end_date}")
29
+ lines << center("Balance Sheet for Period Ending #{end_date}")
30
30
  lines << banner_line
31
31
  lines << ''
32
32
  lines << ''
@@ -0,0 +1,201 @@
1
+ require_relative '../documents/book_set'
2
+
3
+ require_relative 'balance_sheet'
4
+ require_relative 'income_statement'
5
+ require_relative 'multidoc_transaction_report'
6
+ require_relative 'receipts_report'
7
+ require_relative 'report_context'
8
+ require_relative 'transaction_report'
9
+ require_relative 'tx_by_account'
10
+ require_relative 'tx_one_account'
11
+
12
+ module RockBooks
13
+ class BookSetReporter
14
+
15
+ extend Forwardable
16
+
17
+ attr_reader :book_set, :output_dir, :filter, :context
18
+
19
+ def_delegator :book_set, :all_entries
20
+ def_delegator :book_set, :journals
21
+ def_delegator :book_set, :chart_of_accounts
22
+ def_delegator :book_set, :run_options
23
+
24
+
25
+ def initialize(book_set, output_dir, filter = nil)
26
+ @book_set = book_set
27
+ @output_dir = output_dir
28
+ @filter = filter
29
+ @context = ReportContext.new(book_set.chart_of_accounts, book_set.journals, 80)
30
+ end
31
+
32
+
33
+ def call
34
+ check_prequisite_executables
35
+ reports = all_reports(filter)
36
+ create_directories
37
+ create_index_html
38
+ write_reports(reports)
39
+ end
40
+
41
+
42
+ # All methods after this point are private.
43
+
44
+ private def all_reports(filter = nil)
45
+
46
+ report_hash = journals.each_with_object({}) do |journal, report_hash|
47
+ key = journal.short_name.to_sym
48
+ report_hash[key] = TransactionReport.new(journal, context).call(filter)
49
+ end
50
+
51
+ report_hash[:all_txns_by_date] = MultidocTransactionReport.new(context).call(filter)
52
+ report_hash[:all_txns_by_amount] = MultidocTransactionReport.new(context).call(filter, :amount)
53
+ report_hash[:all_txns_by_acct] = TxByAccount.new(context).call
54
+ report_hash[:balance_sheet] = BalanceSheet.new(context).call
55
+ report_hash[:income_statement] = IncomeStatement.new(context).call
56
+
57
+ if run_options.do_receipts
58
+ report_hash[:receipts] = ReceiptsReport.new(context, *missing_existing_unused_receipts).call
59
+ end
60
+
61
+ chart_of_accounts.accounts.each do |account|
62
+ key = ('acct_' + account.code).to_sym
63
+ report = TxOneAccount.new(context, account.code).call
64
+ report_hash[key] = report
65
+ end
66
+
67
+ report_hash
68
+ end
69
+
70
+
71
+ private def run_command(command)
72
+ puts "\n----\nRunning command: #{command}"
73
+ stdout, stderr, status = Open3.capture3(command)
74
+ puts "Status was #{status}."
75
+ unless stdout.size == 0
76
+ puts "\nStdout was:\n\n#{stdout}"
77
+ end
78
+ unless stderr.size == 0
79
+ puts "\nStderr was:\n\n#{stderr}"
80
+ end
81
+ puts
82
+ stdout
83
+ end
84
+
85
+
86
+ private def executable_exists?(name)
87
+ `which #{name}`
88
+ $?.success?
89
+ end
90
+
91
+
92
+ private def check_prequisite_executables
93
+ raise "Report generation is not currently supported in Windows." if OS.windows?
94
+ required_exes = OS.mac? ? %w(textutil cupsfilter) : %w(txt2html cupsfilter)
95
+ missing_exes = required_exes.reject { |exe| executable_exists?(exe) }
96
+ if missing_exes.any?
97
+ raise "Missing required report generation executable(s): #{missing_exes.join(', ')}"
98
+ end
99
+ end
100
+
101
+
102
+ private def create_directories
103
+ %w(txt pdf html).each do |format|
104
+ dir = File.join(output_dir, format, SINGLE_ACCT_SUBDIR)
105
+ FileUtils.mkdir_p(dir)
106
+ end
107
+ end
108
+
109
+
110
+ # "./pdf/short_name.pdf" or "./pdf/single_account/short_name.pdf"
111
+ private def build_filespec(directory, short_name, file_format)
112
+ fragments = [directory, file_format, "#{short_name}.#{file_format}"]
113
+ is_acct_report = /^acct_/.match(short_name)
114
+ if is_acct_report
115
+ fragments.insert(2, SINGLE_ACCT_SUBDIR)
116
+ end
117
+ File.join(*fragments)
118
+ end
119
+
120
+
121
+ private def create_index_html
122
+ filespec = build_filespec(output_dir, 'index', 'html')
123
+ File.write(filespec, index_html_content)
124
+ puts "Created index.html"
125
+ end
126
+
127
+
128
+ private def write_reports(reports)
129
+
130
+ reports.each do |short_name, report_text|
131
+ txt_filespec = build_filespec(output_dir, short_name, 'txt')
132
+ html_filespec = build_filespec(output_dir, short_name, 'html')
133
+ pdf_filespec = build_filespec(output_dir, short_name, 'pdf')
134
+
135
+ File.write(txt_filespec, report_text)
136
+
137
+ # Linux & Mac OS
138
+ cupsfilter = -> { run_command("cupsfilter #{txt_filespec} > #{pdf_filespec}") }
139
+
140
+ # Mac OS
141
+ textutil = ->(font_size) do
142
+ run_command("textutil -convert html -font 'Courier New Bold' -fontsize #{font_size} #{txt_filespec} -output #{html_filespec}")
143
+ end
144
+
145
+ # Linux
146
+ txt2html = -> { run_command("txt2html --preformat_trigger_lines 0 #{txt_filespec} > #{html_filespec}") }
147
+
148
+ # Use smaller size for the PDF but larger size for the web pages:
149
+ if OS.mac?
150
+ textutil.(11)
151
+ cupsfilter.()
152
+ textutil.(14)
153
+ else
154
+ txt2html.()
155
+ cupsfilter.()
156
+ end
157
+
158
+ hyperlinkized_text, replacements_made = HtmlHelper.convert_receipts_to_hyperlinks(File.read(html_filespec))
159
+ if replacements_made
160
+ File.write(html_filespec, hyperlinkized_text)
161
+ end
162
+
163
+ puts "Created reports in txt, html, and pdf for #{"%-20s" % short_name} at #{File.dirname(txt_filespec)}.\n\n\n"
164
+ end
165
+ end
166
+
167
+
168
+ private def receipt_full_filespec(receipt_filespec)
169
+ File.join(run_options.receipt_dir, receipt_filespec)
170
+ end
171
+
172
+
173
+ private def missing_existing_unused_receipts
174
+ missing = []
175
+ existing = []
176
+ unused = Dir['receipts/**/*'].select { |s| File.file?(s) }.sort # Remove files as they are found
177
+ unused.map! { |s| "./" + s } # Prepend './' to match the data
178
+
179
+ all_entries.each do |entry|
180
+ entry.receipts.each do |receipt|
181
+ filespec = receipt_full_filespec(receipt)
182
+ unused.delete(filespec)
183
+ file_exists = File.file?(filespec)
184
+ list = (file_exists ? existing : missing)
185
+ list << { receipt: receipt, journal: entry.doc_short_name }
186
+ end
187
+ end
188
+ [missing, existing, unused]
189
+ end
190
+
191
+
192
+ private def index_html_content
193
+ erb_filespec = File.join(File.dirname(__FILE__), 'index.html.erb')
194
+ erb = ERB.new(File.read(erb_filespec))
195
+ erb.result_with_hash(
196
+ journals: journals,
197
+ chart_of_accounts: chart_of_accounts,
198
+ run_options: run_options)
199
+ end
200
+ end
201
+ end
@@ -17,12 +17,12 @@ module RockBooks
17
17
 
18
18
 
19
19
  def start_date
20
- context.start_date || Date.new(1900, 1, 1)
20
+ context.chart_of_accounts.start_date
21
21
  end
22
22
 
23
23
 
24
24
  def end_date
25
- context.end_date || Date.new(2100, 1, 1)
25
+ context.chart_of_accounts.end_date
26
26
  end
27
27
 
28
28
 
@@ -0,0 +1,156 @@
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>