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