rock_books 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/README.md +3 -13
  4. data/RELEASE_NOTES.md +15 -1
  5. data/lib/rock_books/cmd_line/command_line_interface.rb +19 -9
  6. data/lib/rock_books/cmd_line/main.rb +9 -2
  7. data/lib/rock_books/documents/book_set.rb +20 -5
  8. data/lib/rock_books/documents/chart_of_accounts.rb +19 -4
  9. data/lib/rock_books/documents/journal.rb +29 -7
  10. data/lib/rock_books/documents/journal_entry_builder.rb +23 -14
  11. data/lib/rock_books/errors/account_not_found_error.rb +9 -8
  12. data/lib/rock_books/errors/incorrect_sequence_error.rb +21 -0
  13. data/lib/rock_books/errors/transaction_not_balanced_error.rb +21 -0
  14. data/lib/rock_books/filters/journal_entry_filters.rb +6 -1
  15. data/lib/rock_books/helpers/book_set_loader.rb +2 -2
  16. data/lib/rock_books/helpers/parse_helper.rb +1 -1
  17. data/lib/rock_books/reports/tx_by_account.rb +1 -1
  18. data/lib/rock_books/reports/tx_one_account.rb +1 -1
  19. data/lib/rock_books/types/acct_amount.rb +4 -4
  20. data/lib/rock_books/types/journal_entry_context.rb +14 -0
  21. data/lib/rock_books/version.rb +1 -1
  22. data/sample_data/minimal/rockbooks-inputs/{2017-xyz-chart-of-accounts.rbt → 2017-xyz-chart-of-accounts.txt} +62 -62
  23. data/sample_data/minimal/rockbooks-inputs/{2017-xyz-checking-journal.rbt → 2017-xyz-checking-journal.txt} +17 -17
  24. data/sample_data/minimal/rockbooks-inputs/{2017-xyz-general-journal.rbt → 2017-xyz-general-journal.txt} +14 -14
  25. data/sample_data/minimal/rockbooks-inputs/{2017-xyz-visa-journal.rbt → 2017-xyz-visa-journal.txt} +27 -23
  26. data/sample_data/minimal/rockbooks-reports/{all_txns_by_acct.html → html/all_txns_by_acct.html} +63 -51
  27. data/sample_data/minimal/rockbooks-reports/{all_txns_by_amount.html → html/all_txns_by_amount.html} +13 -8
  28. data/sample_data/minimal/rockbooks-reports/{all_txns_by_date.html → html/all_txns_by_date.html} +13 -8
  29. data/sample_data/minimal/rockbooks-reports/{balance_sheet.html → html/balance_sheet.html} +6 -6
  30. data/sample_data/minimal/rockbooks-reports/{ck.hsbc.html → html/ck.hsbc.disb.html} +2 -2
  31. data/sample_data/minimal/rockbooks-reports/{general.html → html/general.html} +2 -2
  32. data/sample_data/minimal/rockbooks-reports/{hsbc_visa.html → html/hsbc_visa.html} +8 -4
  33. data/sample_data/minimal/rockbooks-reports/{income_statement.html → html/income_statement.html} +5 -5
  34. data/sample_data/minimal/rockbooks-reports/{receipts.html → html/receipts.html} +3 -2
  35. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_accts.rec.html +2 -2
  36. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_bank.fees.html +2 -2
  37. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_books.refs.html +2 -2
  38. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_cc.hsbc.visa.html +12 -6
  39. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_cc.proc.html +2 -2
  40. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_ck.hsbc.html +5 -5
  41. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_conf.fees.html +2 -2
  42. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_cowork.fees.html +11 -5
  43. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_govt.fees.html +2 -2
  44. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_inet.fees.html +2 -2
  45. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_insurance.html +2 -2
  46. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_int.exp.html +2 -2
  47. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_loan.to.sh.html +2 -2
  48. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_meals.ent.html +2 -2
  49. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_misc.exp.html +2 -2
  50. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_mktng.exp.html +2 -2
  51. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_own.equity.html +3 -3
  52. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_paypal.html +2 -2
  53. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_prof.fees.html +2 -2
  54. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_repair.maint.html +2 -2
  55. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_ret.earn.html +2 -2
  56. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_ship.exp.html +2 -2
  57. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_sls.cons.html +3 -3
  58. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_supplies.html +2 -2
  59. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_sw.exp.html +2 -2
  60. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.airfare.html +2 -2
  61. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.autorent.html +2 -2
  62. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.gas.etc.html +2 -2
  63. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.govt.html +2 -2
  64. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.lodging.html +2 -2
  65. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.m.e.html +2 -2
  66. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.m.i.html +2 -2
  67. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.mileage.html +2 -2
  68. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.misc.html +2 -2
  69. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.parking.html +2 -2
  70. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.perdiem.mi.html +2 -2
  71. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.taxi.html +2 -2
  72. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.trainfare.html +2 -2
  73. data/sample_data/minimal/rockbooks-reports/{single-account → html/single-account}/acct_tr.unclass.html +2 -2
  74. data/sample_data/minimal/rockbooks-reports/pdf/all_txns_by_acct.pdf +0 -0
  75. data/sample_data/minimal/rockbooks-reports/pdf/all_txns_by_amount.pdf +0 -0
  76. data/sample_data/minimal/rockbooks-reports/pdf/all_txns_by_date.pdf +0 -0
  77. data/sample_data/minimal/rockbooks-reports/pdf/balance_sheet.pdf +0 -0
  78. data/sample_data/minimal/rockbooks-reports/pdf/ck.hsbc.disb.pdf +0 -0
  79. data/sample_data/minimal/rockbooks-reports/pdf/general.pdf +0 -0
  80. data/sample_data/minimal/rockbooks-reports/pdf/hsbc_visa.pdf +0 -0
  81. data/sample_data/minimal/rockbooks-reports/pdf/income_statement.pdf +0 -0
  82. data/sample_data/minimal/rockbooks-reports/pdf/receipts.pdf +0 -0
  83. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_accts.rec.pdf +0 -0
  84. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_bank.fees.pdf +0 -0
  85. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_books.refs.pdf +0 -0
  86. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cc.hsbc.visa.pdf +0 -0
  87. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cc.proc.pdf +0 -0
  88. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ck.hsbc.pdf +0 -0
  89. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_conf.fees.pdf +0 -0
  90. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_cowork.fees.pdf +0 -0
  91. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_govt.fees.pdf +0 -0
  92. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_inet.fees.pdf +0 -0
  93. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_insurance.pdf +0 -0
  94. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_int.exp.pdf +0 -0
  95. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_loan.to.sh.pdf +0 -0
  96. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_meals.ent.pdf +0 -0
  97. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_misc.exp.pdf +0 -0
  98. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_mktng.exp.pdf +0 -0
  99. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_own.equity.pdf +0 -0
  100. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_paypal.pdf +0 -0
  101. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_prof.fees.pdf +0 -0
  102. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_repair.maint.pdf +0 -0
  103. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ret.earn.pdf +0 -0
  104. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_ship.exp.pdf +0 -0
  105. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_sls.cons.pdf +0 -0
  106. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_supplies.pdf +0 -0
  107. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_sw.exp.pdf +0 -0
  108. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.airfare.pdf +0 -0
  109. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.autorent.pdf +0 -0
  110. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.gas.etc.pdf +0 -0
  111. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.govt.pdf +0 -0
  112. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.lodging.pdf +0 -0
  113. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.m.e.pdf +0 -0
  114. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.m.i.pdf +0 -0
  115. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.mileage.pdf +0 -0
  116. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.misc.pdf +0 -0
  117. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.parking.pdf +0 -0
  118. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.perdiem.mi.pdf +0 -0
  119. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.taxi.pdf +0 -0
  120. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.trainfare.pdf +0 -0
  121. data/sample_data/minimal/rockbooks-reports/pdf/single-account/acct_tr.unclass.pdf +0 -0
  122. data/sample_data/minimal/rockbooks-reports/{all_txns_by_acct.txt → txt/all_txns_by_acct.txt} +61 -49
  123. data/sample_data/minimal/rockbooks-reports/{all_txns_by_amount.txt → txt/all_txns_by_amount.txt} +11 -6
  124. data/sample_data/minimal/rockbooks-reports/{all_txns_by_date.txt → txt/all_txns_by_date.txt} +11 -6
  125. data/sample_data/minimal/rockbooks-reports/{balance_sheet.txt → txt/balance_sheet.txt} +4 -4
  126. data/sample_data/minimal/rockbooks-reports/{ck.hsbc.txt → txt/ck.hsbc.disb.txt} +0 -0
  127. data/sample_data/minimal/rockbooks-reports/{general.txt → txt/general.txt} +0 -0
  128. data/sample_data/minimal/rockbooks-reports/{hsbc_visa.txt → txt/hsbc_visa.txt} +6 -2
  129. data/sample_data/minimal/rockbooks-reports/{income_statement.txt → txt/income_statement.txt} +3 -3
  130. data/sample_data/minimal/rockbooks-reports/{receipts.txt → txt/receipts.txt} +1 -0
  131. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_accts.rec.txt +0 -0
  132. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_bank.fees.txt +0 -0
  133. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_books.refs.txt +0 -0
  134. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_cc.hsbc.visa.txt +10 -4
  135. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_cc.proc.txt +0 -0
  136. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_ck.hsbc.txt +3 -3
  137. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_conf.fees.txt +0 -0
  138. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_cowork.fees.txt +9 -3
  139. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_govt.fees.txt +0 -0
  140. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_inet.fees.txt +0 -0
  141. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_insurance.txt +0 -0
  142. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_int.exp.txt +0 -0
  143. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_loan.to.sh.txt +0 -0
  144. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_meals.ent.txt +0 -0
  145. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_misc.exp.txt +0 -0
  146. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_mktng.exp.txt +0 -0
  147. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_own.equity.txt +1 -1
  148. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_paypal.txt +0 -0
  149. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_prof.fees.txt +0 -0
  150. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_repair.maint.txt +0 -0
  151. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_ret.earn.txt +0 -0
  152. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_ship.exp.txt +0 -0
  153. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_sls.cons.txt +1 -1
  154. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_supplies.txt +0 -0
  155. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_sw.exp.txt +0 -0
  156. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.airfare.txt +0 -0
  157. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.autorent.txt +0 -0
  158. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.gas.etc.txt +0 -0
  159. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.govt.txt +0 -0
  160. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.lodging.txt +0 -0
  161. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.m.e.txt +0 -0
  162. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.m.i.txt +0 -0
  163. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.mileage.txt +0 -0
  164. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.misc.txt +0 -0
  165. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.parking.txt +0 -0
  166. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.perdiem.mi.txt +0 -0
  167. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.taxi.txt +0 -0
  168. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.trainfare.txt +0 -0
  169. data/sample_data/minimal/rockbooks-reports/{single-account → txt/single-account}/acct_tr.unclass.txt +0 -0
  170. metadata +155 -151
  171. data/sample_data/minimal/rockbooks-reports/all_txns_by_acct.pdf +0 -0
  172. data/sample_data/minimal/rockbooks-reports/all_txns_by_amount.pdf +0 -0
  173. data/sample_data/minimal/rockbooks-reports/all_txns_by_date.pdf +0 -0
  174. data/sample_data/minimal/rockbooks-reports/balance_sheet.pdf +0 -0
  175. data/sample_data/minimal/rockbooks-reports/ck.hsbc.pdf +0 -0
  176. data/sample_data/minimal/rockbooks-reports/general.pdf +0 -0
  177. data/sample_data/minimal/rockbooks-reports/hsbc_visa.pdf +0 -0
  178. data/sample_data/minimal/rockbooks-reports/income_statement.pdf +0 -0
  179. data/sample_data/minimal/rockbooks-reports/receipts.pdf +0 -0
  180. data/sample_data/minimal/rockbooks-reports/single-account/acct_accts.rec.pdf +0 -0
  181. data/sample_data/minimal/rockbooks-reports/single-account/acct_bank.fees.pdf +0 -0
  182. data/sample_data/minimal/rockbooks-reports/single-account/acct_books.refs.pdf +0 -0
  183. data/sample_data/minimal/rockbooks-reports/single-account/acct_cc.hsbc.visa.pdf +0 -0
  184. data/sample_data/minimal/rockbooks-reports/single-account/acct_cc.proc.pdf +0 -0
  185. data/sample_data/minimal/rockbooks-reports/single-account/acct_ck.hsbc.pdf +0 -0
  186. data/sample_data/minimal/rockbooks-reports/single-account/acct_conf.fees.pdf +0 -0
  187. data/sample_data/minimal/rockbooks-reports/single-account/acct_cowork.fees.pdf +0 -0
  188. data/sample_data/minimal/rockbooks-reports/single-account/acct_govt.fees.pdf +0 -0
  189. data/sample_data/minimal/rockbooks-reports/single-account/acct_inet.fees.pdf +0 -0
  190. data/sample_data/minimal/rockbooks-reports/single-account/acct_insurance.pdf +0 -0
  191. data/sample_data/minimal/rockbooks-reports/single-account/acct_int.exp.pdf +0 -0
  192. data/sample_data/minimal/rockbooks-reports/single-account/acct_loan.to.sh.pdf +0 -0
  193. data/sample_data/minimal/rockbooks-reports/single-account/acct_meals.ent.pdf +0 -0
  194. data/sample_data/minimal/rockbooks-reports/single-account/acct_misc.exp.pdf +0 -0
  195. data/sample_data/minimal/rockbooks-reports/single-account/acct_mktng.exp.pdf +0 -0
  196. data/sample_data/minimal/rockbooks-reports/single-account/acct_own.equity.pdf +0 -0
  197. data/sample_data/minimal/rockbooks-reports/single-account/acct_paypal.pdf +0 -0
  198. data/sample_data/minimal/rockbooks-reports/single-account/acct_prof.fees.pdf +0 -0
  199. data/sample_data/minimal/rockbooks-reports/single-account/acct_repair.maint.pdf +0 -0
  200. data/sample_data/minimal/rockbooks-reports/single-account/acct_ret.earn.pdf +0 -0
  201. data/sample_data/minimal/rockbooks-reports/single-account/acct_ship.exp.pdf +0 -0
  202. data/sample_data/minimal/rockbooks-reports/single-account/acct_sls.cons.pdf +0 -0
  203. data/sample_data/minimal/rockbooks-reports/single-account/acct_supplies.pdf +0 -0
  204. data/sample_data/minimal/rockbooks-reports/single-account/acct_sw.exp.pdf +0 -0
  205. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.airfare.pdf +0 -0
  206. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.autorent.pdf +0 -0
  207. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.gas.etc.pdf +0 -0
  208. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.govt.pdf +0 -0
  209. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.lodging.pdf +0 -0
  210. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.m.e.pdf +0 -0
  211. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.m.i.pdf +0 -0
  212. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.mileage.pdf +0 -0
  213. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.misc.pdf +0 -0
  214. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.parking.pdf +0 -0
  215. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.perdiem.mi.pdf +0 -0
  216. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.taxi.pdf +0 -0
  217. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.trainfare.pdf +0 -0
  218. data/sample_data/minimal/rockbooks-reports/single-account/acct_tr.unclass.pdf +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb5e28caf47f966b9793cef3f45eafde78895029034d25256864c1035f16e3a5
4
- data.tar.gz: 3c5c3d288454789332a4395c57ee362d933e5d141294a22951ef38401556606a
3
+ metadata.gz: 748869c04031f76ba911a05c45f954290f0d364c5cb4cd08c725238398542075
4
+ data.tar.gz: a926e2ec2498a2312b5e765ac8511f8f62ffbbcafc016c03752b4c1934cf4eb8
5
5
  SHA512:
6
- metadata.gz: f8e890585583e9331567371567cd483ea9ac4d8a11999bfaf443094fd896e04343ef2cbbdddf26a1a823cf98301254d9c1a66338a53abab8fd3a4c322066919d
7
- data.tar.gz: 39d6ed81e515fc38db7f8b116388cb8e0cf5025e8f2d9adcc307cb0fb03e4bdc6dc40b0477d6adab6857753c7418dcf9c32967dc1fac63d541ae4a92157b602f
6
+ metadata.gz: 40f17cf379eddd8a675c2aa427f4faf32471e6d95252a5f77a12727f0949efc5e46947cc9e11a08e0d7d00d4cbb1a42f6219d0b4a880c0fcdba53eccf736d47c
7
+ data.tar.gz: 47eaf0e7d59c26efe53718a965cd09bfd00ba72385e634a3928d096a6909be67354a474e1cb927aa4b57fe1f7f77a0f82794682b755c30f073c7dc7d8f1b4f66
data/.gitattributes ADDED
@@ -0,0 +1 @@
1
+ sample_data/minimal/rockbooks-reports/* linguist-vendored
data/README.md CHANGED
@@ -19,8 +19,7 @@ the double entry bookkeeping paradigm pretty well.
19
19
  * document - a RockBooks logical document such as a chart of accounts, a journal, etc.,
20
20
  usually containing information parsed from a data file
21
21
 
22
- * data file - a RockBooks data file, which is a text file, which
23
- by convention has the extension `.rbt`
22
+ * data file - a RockBooks data file, which is a text file with the extension `.txt`
24
23
 
25
24
 
26
25
  ## Data File Format
@@ -181,19 +180,10 @@ Or install it yourself as:
181
180
 
182
181
  $ gem install rock_books
183
182
 
184
- ## Usage
185
-
186
- TODO: Write usage instructions here
187
-
188
- ## Development
189
-
190
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
191
-
192
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
193
-
194
183
  ## Contributing
195
184
 
196
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rock_books.
185
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/keithrbennett/rock_books](https://github.com/keithrbennett/rock_books).
186
+
197
187
 
198
188
  ## License
199
189
 
data/RELEASE_NOTES.md CHANGED
@@ -1,6 +1,20 @@
1
+ ## v0.1.3
2
+
3
+ * Report output now goes to separate txt, html, and pdf subdirectories.
4
+ * Add vendor.yml to exclude generated report files from language reporting.
5
+ * Use .gitattributes instead of vendor.yml to specify vendored code.
6
+ * Add == methods to ChartOfAccounts and Journal classes.
7
+ * Rename input files from .rbt to .txt.
8
+ * Convert sample input files to DOS line endings.
9
+ * Add validation that transaction is balanced.
10
+ * Fix so that requesting help shows correct help text, and that passing no args on cmd line triggers help.
11
+ * Implement more helpful error messages, with document short name, line number, and line text.
12
+ * Add JournalEntryContext and TransactionNotBalancedError classes.
13
+ * Add 'from_string' methods to Journal and ChartOfAccounts.
14
+
1
15
  ## v0.1.2
2
16
 
3
- Improve error emssage when the needed directories do not exist.
17
+ * Improve error message when the needed directories do not exist.
4
18
 
5
19
  ## v0.1.1
6
20
 
@@ -24,7 +24,7 @@ class CommandLineInterface
24
24
  class BadCommandError < RuntimeError; end
25
25
 
26
26
 
27
- # Enable use of some BookSet methods in shell with long and short names aaa, ae:
27
+ # Enable use of some BookSet methods in shell with long and short aliases:
28
28
 
29
29
  def_delegator :book_set, :all_acct_amounts
30
30
  def_delegator :book_set, :all_acct_amounts, :aaa
@@ -56,6 +56,7 @@ w[rite_reports] - write all reports to the output directory (see -o op
56
56
  c[hart_of_accounts] - chart of accounts
57
57
  h[elp] - prints this help
58
58
  jo[urnals] - list of the journals' short names
59
+ proj[ect_page] - open the RockBooks Github project page in a browser
59
60
  rel[oad_data] - reload data from input files
60
61
  q[uit] - exits this program (interactive shell mode only) (see also 'x')
61
62
  x[it] - exits this program (interactive shell mode only) (see also 'q')
@@ -79,18 +80,22 @@ When in interactive shell mode:
79
80
 
80
81
  def validate_run_options(options)
81
82
 
83
+ return if options.suppress_command_line_validation
84
+
82
85
  validate_input_dir = -> do
83
86
  File.directory?(options.input_dir) ? nil : "Input directory '#{options.input_dir}' does not exist. "
84
87
  end
85
88
 
86
89
  validate_output_dir = -> do
87
- dir = options.output_dir
88
- subdir = File.join(dir, SINGLE_ACCT_SUBDIR)
89
90
 
90
- # We need to create the reports directory and its single-account subdirectory.
91
- # We can accomplish both by creating just the subdirectory.
92
- FileUtils.mkdir_p(subdir) ? nil : \
93
- "Output directory '#{dir}' and/or #{subdir} does not exist and could not be created. "
91
+ # We need to create the reports directory if it does not already exist.
92
+ # mkdir_p silently returns if the directory already exists.
93
+ begin
94
+ FileUtils.mkdir_p(options.output_dir)
95
+ nil
96
+ rescue Errno::EACCES => error
97
+ "Output directory '#{options.output_dir}' does not exist and could not be created. "
98
+ end
94
99
  end
95
100
 
96
101
  validate_receipts_dir = -> do
@@ -273,9 +278,14 @@ When in interactive shell mode:
273
278
  end
274
279
 
275
280
  os = OpenStruct.new(book_set.all_reports($filter))
276
- def os.keys; to_h.keys.map(&:to_s); end # add hash methods for convenience
281
+
282
+ # add hash methods for convenience
283
+ def os.keys; to_h.keys.map(&:to_s); end
277
284
  def os.values; to_h.values; end
278
- def os.at(index); self.public_send(keys[index]); end # to access as array, e.g. `a.at(1)`
285
+
286
+ # to access as array, e.g. `a.at(1)`
287
+ def os.at(index); self.public_send(keys[index]); end
288
+
279
289
  os
280
290
  end
281
291
 
@@ -39,6 +39,11 @@ class Main
39
39
 
40
40
  OptionParser.new do |parser|
41
41
 
42
+ parser.on("-h", "--help", "Show help") do |_help_requested|
43
+ ARGV << 'h' # pass on the request to the command processor
44
+ options.suppress_command_line_validation = true
45
+ end
46
+
42
47
  parser.on('-i', '--input_dir DIR',
43
48
  "Input directory containing source data files, default: '#{DEFAULT_INPUT_DIR}'") do |v|
44
49
  options.input_dir = File.expand_path(v)
@@ -80,10 +85,9 @@ class Main
80
85
  end
81
86
 
82
87
 
83
- # Arg is a directory containing 'chart_of_accounts.rbd' and '*journal*.rbd' for input,
84
- # and reports (*.rpt) will be output to this directory as well.
85
88
  def call
86
89
  begin
90
+ ARGV << '-h' if ARGV.empty?
87
91
  run_options = parse_command_line
88
92
  CommandLineInterface.new(run_options).call
89
93
  rescue => error
@@ -91,7 +95,10 @@ class Main
91
95
  <<~HEREDOC
92
96
  #{error.backtrace.join("\n")}
93
97
 
98
+ #{'-' * 79}
94
99
  #{error}
100
+ #{'-' * 79}
101
+
95
102
  HEREDOC
96
103
 
97
104
  if run_options.say
@@ -63,13 +63,28 @@ module RockBooks
63
63
 
64
64
  def all_reports_to_files(directory = '.', filter = nil)
65
65
  reports = all_reports(filter)
66
+
67
+ # "./pdf/short_name.pdf" or "./pdf/single_account/short_name.pdf"
68
+ build_filespec = ->(short_name, file_format) do
69
+ fragments = [directory, file_format, "#{short_name}.#{file_format}"]
70
+ is_acct_report = /^acct_/.match(short_name)
71
+ if is_acct_report
72
+ fragments.insert(2, SINGLE_ACCT_SUBDIR)
73
+ end
74
+ File.join(*fragments)
75
+ end
76
+
66
77
  reports.each do |short_name, report_text|
67
- report_directory = /^acct_/.match(short_name) ? File.join(directory, SINGLE_ACCT_SUBDIR) : directory
68
- txt_filespec = File.join(report_directory, "#{short_name}.txt")
69
- html_filespec = File.join(report_directory, "#{short_name}.html")
70
- pdf_filespec = File.join(report_directory, "#{short_name}.pdf")
78
+ txt_filespec = build_filespec.(short_name, 'txt')
79
+ html_filespec = build_filespec.(short_name, 'html')
80
+ pdf_filespec = build_filespec.(short_name, 'pdf')
81
+
82
+ FileUtils.mkdir_p(File.dirname(txt_filespec))
83
+ FileUtils.mkdir_p(File.dirname(html_filespec))
84
+ FileUtils.mkdir_p(File.dirname(pdf_filespec))
85
+
71
86
  File.write(txt_filespec, report_text)
72
- run_command("textutil -convert html -font 'Menlo Regular' #{txt_filespec} -output #{html_filespec}")
87
+ run_command("textutil -convert html -font 'Menlo Regular' -fontsize 10 #{txt_filespec} -output #{html_filespec}")
73
88
  run_command("cupsfilter #{html_filespec} > #{pdf_filespec}")
74
89
  puts "Created reports in txt, html, and pdf for #{"%-20s" % short_name} at #{File.dirname(txt_filespec)}.\n\n\n"
75
90
  end
@@ -9,14 +9,18 @@ class ChartOfAccounts
9
9
 
10
10
 
11
11
  def self.from_file(file)
12
- self.new(File.read(file))
12
+ self.new(File.readlines(file).map(&:chomp))
13
13
  end
14
14
 
15
15
 
16
- def initialize(input_string)
16
+ def self.from_string(string)
17
+ self.new(string.split("\n"))
18
+ end
19
+
20
+
21
+ def initialize(input_lines)
17
22
  @accounts = []
18
- lines = input_string.split("\n")
19
- lines.each { |line| parse_line(line) }
23
+ input_lines.each { |line| parse_line(line) }
20
24
  end
21
25
 
22
26
 
@@ -49,10 +53,12 @@ class ChartOfAccounts
49
53
  end
50
54
  end
51
55
 
56
+
52
57
  def accounts_of_type(type)
53
58
  accounts.select { |account| account.type == type }
54
59
  end
55
60
 
61
+
56
62
  def account_codes_of_type(type)
57
63
  accounts_of_type(type).map(&:code)
58
64
  end
@@ -88,6 +94,7 @@ class ChartOfAccounts
88
94
  found ? found.type : nil
89
95
  end
90
96
 
97
+
91
98
  def name_for_code(code)
92
99
  found = account_for_code(code)
93
100
  found ? found.name : nil
@@ -109,5 +116,13 @@ class ChartOfAccounts
109
116
  raise "Unexpected type #{type} for code #{code}."
110
117
  end
111
118
  end
119
+
120
+
121
+ def ==(other)
122
+ doc_type == other.doc_type && \
123
+ title == other.title && \
124
+ accounts == other.accounts && \
125
+ entity == other.entity
126
+ end
112
127
  end
113
128
  end
@@ -4,6 +4,7 @@ require 'yaml'
4
4
 
5
5
  require_relative '../errors/account_not_found_error'
6
6
  require_relative '../types/acct_amount'
7
+ require_relative '../types/journal_entry_context'
7
8
  require_relative 'journal_entry'
8
9
  require_relative 'journal_entry_builder'
9
10
  require_relative '../reports/reporter'
@@ -18,7 +19,12 @@ module RockBooks
18
19
  class Journal
19
20
 
20
21
  def self.from_file(chart_of_accounts, file)
21
- self.new(chart_of_accounts, File.read(file))
22
+ self.new(chart_of_accounts, File.readlines(file).map(&:chomp))
23
+ end
24
+
25
+
26
+ def self.from_string(chart_of_accounts, string)
27
+ self.new(chart_of_accounts, string.split("\n"))
22
28
  end
23
29
 
24
30
 
@@ -61,18 +67,21 @@ class Journal
61
67
  attr_reader :short_name, :account_code, :chart_of_accounts, :date_prefix, :debit_or_credit, :doc_type, :title, :entries
62
68
 
63
69
  # short_name is a name that will appear on reports identifying the journal from which a transaction comes
64
- def initialize(chart_of_accounts, input_string, short_name = nil)
70
+ def initialize(chart_of_accounts, input_lines, short_name = nil)
65
71
  @chart_of_accounts = chart_of_accounts
66
72
  @short_name = short_name
67
73
  @entries = []
68
74
  @date_prefix = ''
69
75
  @title = ''
70
- lines = input_string.split("\n")
71
- lines.each { |line| parse_line(line) }
76
+ input_lines.each_with_index do |line, linenum|
77
+ context = JournalEntryContext.new(self, linenum + 1, line)
78
+ parse_line(context)
79
+ end
72
80
  end
73
81
 
74
82
 
75
- def parse_line(line)
83
+ def parse_line(journal_entry_context)
84
+ line = journal_entry_context.line
76
85
  case line.strip
77
86
  when /^@doc_type:/
78
87
  @doc_type = line.split(/^@doc_type:/).last.strip
@@ -80,7 +89,7 @@ class Journal
80
89
  @account_code = line.split(/^@account_code:/).last.strip
81
90
 
82
91
  unless chart_of_accounts.include?(@account_code)
83
- raise AccountNotFoundError.new(@account_code)
92
+ raise AccountNotFoundError.new(@account_code, journal_entry_context)
84
93
  end
85
94
 
86
95
  # if debit or credit has not yet been specified, inherit the setting from the account:
@@ -102,7 +111,7 @@ class Journal
102
111
  when /^#/
103
112
  # ignore comment line
104
113
  when /^\d/ # a date/acct/amount line starting with a number
105
- entries << JournalEntryBuilder.new(line, self).build
114
+ entries << JournalEntryBuilder.new(journal_entry_context).build
106
115
  else # Text line(s) to be attached to the most recently parsed transaction
107
116
  unless entries.last
108
117
  raise Error.new("Entry for this description cannot be found: #{line}")
@@ -157,5 +166,18 @@ class Journal
157
166
 
158
167
  def to_json; to_h.to_json; end
159
168
  def to_yaml; to_h.to_yaml; end
169
+
170
+
171
+ def ==(other)
172
+ # excluding date_prefix from this test intentionally because it does not
173
+ # affect the parsed data.
174
+ short_name == other.short_name && \
175
+ account_code == other.account_code && \
176
+ chart_of_accounts == other.chart_of_accounts && \
177
+ debit_or_credit == other.debit_or_credit && \
178
+ doc_type == other.doc_type && \
179
+ title == other.title && \
180
+ entries == other.entries
181
+ end
160
182
  end
161
183
  end
@@ -1,23 +1,24 @@
1
+ require_relative '../errors/incorrect_sequence_error'
2
+ require_relative '../errors/transaction_not_balanced_error'
1
3
  require_relative '../types/acct_amount'
4
+ require_relative '../types/journal_entry_context'
2
5
  require_relative 'chart_of_accounts'
3
6
  require_relative 'journal'
4
7
 
5
8
  module RockBooks
6
- class JournalEntryBuilder < Struct.new(:line, :journal)
9
+ class JournalEntryBuilder < Struct.new(:journal_entry_context)
7
10
 
8
- def acct_amounts_from_tokens(tokens, date, chart_of_accounts)
11
+ def journal; journal_entry_context.journal; end
12
+ def linenum; journal_entry_context.linenum; end
13
+ def line; journal_entry_context.line; end
14
+ def chart_of_accounts; journal_entry_context.chart_of_accounts; end
15
+
16
+
17
+ def acct_amounts_from_tokens(tokens, date)
9
18
  acct_amounts = []
10
19
 
11
20
  tokens[0..-1].each_slice(2).each do |(account_code, amount)|
12
- begin
13
- acct_amount = AcctAmount.create_with_chart_validation(date, account_code, amount, chart_of_accounts)
14
- rescue AccountNotFoundError => error
15
- error.document_name = journal.short_name
16
- error.line = line
17
- raise
18
- end
19
-
20
- acct_amounts << acct_amount
21
+ acct_amounts << AcctAmount.create_with_chart_validation(date, account_code, amount, journal_entry_context)
21
22
  end
22
23
 
23
24
  acct_amounts
@@ -26,7 +27,7 @@ class JournalEntryBuilder < Struct.new(:line, :journal)
26
27
 
27
28
  def validate_acct_amount_token_array_size(tokens)
28
29
  if tokens.size.odd?
29
- raise Error.new("Incorrect sequence of account codes and amounts: #{tokens}")
30
+ raise IncorrectSequenceError.new(tokens, journal_entry_context)
30
31
  end
31
32
  end
32
33
 
@@ -118,7 +119,15 @@ class JournalEntryBuilder < Struct.new(:line, :journal)
118
119
  convert_signs_for_debit_credit(tokens)
119
120
  end
120
121
 
121
- acct_amounts_from_tokens(tokens, date, journal.chart_of_accounts)
122
+ acct_amounts_from_tokens(tokens, date)
123
+ end
124
+
125
+
126
+ def validate_transaction_is_balanced(acct_amounts)
127
+ sum = acct_amounts.map(&:amount).sum.round(4)
128
+ unless sum == 0.0
129
+ raise TransactionNotBalancedError.new(sum, journal_entry_context)
130
+ end
122
131
  end
123
132
 
124
133
 
@@ -141,8 +150,8 @@ class JournalEntryBuilder < Struct.new(:line, :journal)
141
150
  end
142
151
 
143
152
  acct_amounts = build_acct_amount_array(date, acct_amount_tokens)
153
+ validate_transaction_is_balanced(acct_amounts)
144
154
  JournalEntry.new(date, acct_amounts, journal.short_name)
145
155
  end
146
-
147
156
  end
148
157
  end
@@ -1,20 +1,21 @@
1
+ require_relative '../types/journal_entry_context'
2
+
3
+
1
4
  module RockBooks
2
5
  class AccountNotFoundError < RuntimeError
3
6
 
4
- attr_accessor :bad_account_code, :document_name, :line
7
+ attr_accessor :code, :journal_entry_context
5
8
 
6
- def initialize(bad_account_code, document_name = nil, line = nil)
7
- self.bad_account_code = bad_account_code
9
+ def initialize(code, journal_entry_context)
10
+ self.code = code
11
+ self.journal_entry_context = journal_entry_context
8
12
  super(to_s)
9
13
  end
10
14
 
11
15
 
12
16
  def to_s
13
- s = "Account code not found in chart of accounts: #{bad_account_code}"
14
- if document_name && line
15
- s << ", document: #{document_name}, line: #{line}"
16
- end
17
- s
17
+ ctx = journal_entry_context
18
+ "Account code '#{code}' in journal '#{ctx.journal.short_name}', line ##{ctx.linenum} not found in chart of accounts. Line: '#{ctx.line}'"
18
19
  end
19
20
  end
20
21
  end
@@ -0,0 +1,21 @@
1
+ require_relative '../types/journal_entry_context'
2
+
3
+
4
+ module RockBooks
5
+ class IncorrectSequenceError < RuntimeError
6
+
7
+ attr_accessor :tokens, :journal_entry_context
8
+
9
+ def initialize(tokens, journal_entry_context)
10
+ self.tokens = tokens
11
+ self.journal_entry_context = journal_entry_context
12
+ super(to_s)
13
+ end
14
+
15
+
16
+ def to_s
17
+ ctx = journal_entry_context
18
+ "Incorrect token sequence in journal '#{ctx.journal.short_name}', line ##{ctx.linenum}: #{tokens.inspect}"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require_relative '../errors/transaction_not_balanced_error'
2
+
3
+ module RockBooks
4
+
5
+ class TransactionNotBalancedError < RuntimeError
6
+
7
+ attr_reader :discrepancy, :journal_entry_context
8
+
9
+ def initialize(discrepancy, journal_entry_context)
10
+ @discrepancy = discrepancy
11
+ @journal_entry_context = journal_entry_context
12
+ super(to_s)
13
+ end
14
+
15
+ def to_s
16
+ amount_string = "%0.2f" % discrepancy
17
+ "Transaction not balanced; discrepancy is #{amount_string}. Context: #{journal_entry_context}"
18
+ end
19
+ end
20
+
21
+ end
@@ -6,6 +6,11 @@ module JournalEntryFilters
6
6
  module_function
7
7
 
8
8
 
9
+ def filter(entries, entry_filter)
10
+ entries.select { |entry| entry_filter.(entry) }
11
+ end
12
+
13
+
9
14
  # Dates can be provided as a Ruby Date object, or as a string that will be converted to date (yyyy-mm-dd).
10
15
  def to_date(string_or_date_object)
11
16
  if string_or_date_object.is_a?(String)
@@ -40,7 +45,7 @@ module JournalEntryFilters
40
45
  end
41
46
 
42
47
 
43
- def account_code_filter(account_code)
48
+ def account_code(account_code)
44
49
  ->(entry) do
45
50
  entry.acct_amounts.map(&:code).detect { |code| code == account_code }
46
51
  end
@@ -8,7 +8,7 @@ module RockBooks
8
8
  module_function
9
9
 
10
10
  def get_files_with_types(directory)
11
- files = Dir[File.join(directory, '*.rbt')]
11
+ files = Dir[File.join(directory, '*.txt')]
12
12
  files.each_with_object({}) do |filespec, files_with_types|
13
13
  files_with_types[filespec] = ParseHelper.find_document_type_in_file(filespec)
14
14
  end
@@ -40,7 +40,7 @@ module RockBooks
40
40
  end
41
41
 
42
42
 
43
- # Uses all *.rbt files in the specified directory; uses @doc_type to determine which
43
+ # Uses all *.txt files in the specified directory; uses @doc_type to determine which
44
44
  # is the chart of accounts and which are journals.
45
45
  # To exclude a file, make the extension other than .rdt.
46
46
  def load(run_options)
@@ -16,7 +16,7 @@ module RockBooks
16
16
 
17
17
 
18
18
  def find_document_type_in_file(filespec)
19
- find_document_type(File.readlines(filespec))
19
+ find_document_type(File.readlines(filespec).map(&:chomp))
20
20
  end
21
21
  end
22
22
  end
@@ -31,7 +31,7 @@ class TxByAccount
31
31
 
32
32
  def account_header(account, account_total)
33
33
  total_string = "%.2f" % account_total
34
- title = "Total: #{total_string} -- #{account_code_name_type_string(account)})"
34
+ title = "Total: #{total_string} -- #{account_code_name_type_string(account)}"
35
35
 
36
36
  <<~HEREDOC
37
37
  #{banner_line}
@@ -41,7 +41,7 @@ module RockBooks
41
41
 
42
42
 
43
43
  def generate_report
44
- entries = Journal.entries_in_documents(context.journals, JournalEntryFilters.account_code_filter(account_code))
44
+ entries = Journal.entries_in_documents(context.journals, JournalEntryFilters.account_code(account_code))
45
45
  account_total = JournalEntry.total_for_code(entries, account_code)
46
46
  output = generate_header(account_total)
47
47
 
@@ -2,13 +2,13 @@ module RockBooks
2
2
 
3
3
  # This class represents an account code and an amount.
4
4
  # Journal entries will have multiple instances of these.
5
- class AcctAmount < Struct.new(:date, :code, :amount)
5
+ class AcctAmount < Struct.new(:date, :code, :amount, :journal_entry_context)
6
6
 
7
7
 
8
8
  # Same as constructor except it raises an error if the account code is not in the chart of accounts.
9
- def self.create_with_chart_validation(date, code, amount, chart_of_accounts)
10
- unless chart_of_accounts.include?(code)
11
- raise AccountNotFoundError.new(code)
9
+ def self.create_with_chart_validation(date, code, amount, journal_entry_context)
10
+ unless journal_entry_context.chart_of_accounts.include?(code)
11
+ raise AccountNotFoundError.new(code, journal_entry_context)
12
12
  end
13
13
  self.new(date, code, amount)
14
14
  end
@@ -0,0 +1,14 @@
1
+ module RockBooks
2
+
3
+ class JournalEntryContext < Struct.new(:journal, :linenum, :line)
4
+
5
+ def chart_of_accounts
6
+ journal.chart_of_accounts
7
+ end
8
+
9
+ def to_s
10
+ "Journal '#{journal.short_name}', line ##{linenum}, text: #{line}"
11
+ end
12
+ end
13
+
14
+ end
@@ -1,3 +1,3 @@
1
1
  module RockBooks
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end