transactions 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +11 -0
- data/LICENSE.md +21 -0
- data/README.md +245 -0
- data/bin/transactions +20 -0
- data/lib/transactions.rb +12 -0
- data/lib/transactions/main.rb +32 -0
- data/lib/transactions/options.rb +89 -0
- data/lib/transactions/parser.rb +162 -0
- data/lib/transactions/version.rb +4 -0
- metadata +56 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d1fb2dde0117abbbd982a133959573444cb4b0fd
|
4
|
+
data.tar.gz: 27fbf80ef838f35511f3a9337ac7746c159b811f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dfc5cc11724b32935bfb1b63936404109f9d384a3936dd28ab899e32ac0e11d55e51ef58491dfe9312d83ba62fcf6eb921bbd2f4d7091655e83c4e2d8b80d33c
|
7
|
+
data.tar.gz: e7d1c09de955ccde03a27024783c3eb9e5bd3ea7e6e4a875712da422ad03cd9ef30724ae6aa934d8b2437318762e242d326b9aa39b832ebb55b809c03c3298dc
|
data/CHANGELOG.md
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2013 Randy Schneck
|
2
|
+
|
3
|
+
The MIT License (MIT)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
9
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
10
|
+
so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
# [transactions](http://computercrayons.com/transactions)
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
transactions is a command line application for managing your finances using a
|
6
|
+
plain text format (yaml or json). All transactions are written to a text file
|
7
|
+
by hand similar to a checkbook register. This text file is your ledger and it
|
8
|
+
can handle most financial bookkeeping needs.
|
9
|
+
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
### Requirements
|
14
|
+
|
15
|
+
Before you can get started with *transaction*, the following must be installed
|
16
|
+
on your system. Note that RubyGems is included with Ruby since version 1.9.
|
17
|
+
|
18
|
+
* [Ruby](http://www.ruby-lang.org/en/downloads/)
|
19
|
+
* [RubyGems](http://rubygems.org/pages/download)
|
20
|
+
|
21
|
+
The best way to install transactions is via RubyGems. At the terminal prompt, run
|
22
|
+
the following command:
|
23
|
+
|
24
|
+
`gem install transactions`
|
25
|
+
|
26
|
+
|
27
|
+
## Additional Information
|
28
|
+
|
29
|
+
### Using the program
|
30
|
+
|
31
|
+
1. create a ledger file
|
32
|
+
* you can copy and paste the example ledger below into a text file named
|
33
|
+
"ledger.yaml" if you just want to try out the program. If this is your
|
34
|
+
style of bookkeeping, then just edit the file with your own info using
|
35
|
+
your favorite text editor.
|
36
|
+
* run this command `transactions bal` and see the output.
|
37
|
+
* by default, "transactions" looks in the current directory for a file
|
38
|
+
named "ledger.yaml".
|
39
|
+
* you can use the -f option to specify a different file (eg. `transactions
|
40
|
+
-f example.yaml bal`)
|
41
|
+
2. run `transactions reg`
|
42
|
+
* this is a register for all transactions
|
43
|
+
* notice that every transaction prints multiple times
|
44
|
+
* this happens because each transaction affects multiple accounts
|
45
|
+
3. to make the register more useful try `transactions reg assets:checking`
|
46
|
+
* this will limit the register to assets:checking (case is ignored)
|
47
|
+
* this would be equivalent to printing a checkbook register from
|
48
|
+
"ledger.yaml"
|
49
|
+
* more than one account can be included eg. assets:checking expenses:food
|
50
|
+
* this limit by string of text also works with the balance command.
|
51
|
+
4. see keeping a ledger below for information about general accounting
|
52
|
+
principles to help you with your own ledger.
|
53
|
+
|
54
|
+
|
55
|
+
### Sample Ledger File
|
56
|
+
|
57
|
+
# This is a sample ledger file
|
58
|
+
# this line and the one above are comments that will be ignored
|
59
|
+
# during processing! Comments can also be placed at the end of
|
60
|
+
# a line (see below for examples).
|
61
|
+
|
62
|
+
- date: 2013/01/01
|
63
|
+
transaction: Opening Balances
|
64
|
+
Assets:Checking: 251.0
|
65
|
+
Assets:Savings: 5005.3
|
66
|
+
Assets:IRA: 22510.92
|
67
|
+
Liabilities:CreditCard: -931.32
|
68
|
+
Liabilities:Salliemae: -10189.05
|
69
|
+
Equity:OpeningBalances: -16646.85
|
70
|
+
|
71
|
+
- date: 2013/01/07
|
72
|
+
transaction: Trader Joe's
|
73
|
+
Expenses:Food:Groceries: 58.77
|
74
|
+
Assets:Checking: -58.77
|
75
|
+
|
76
|
+
- date: 2013/01/09
|
77
|
+
transaction: Student Loan Payment
|
78
|
+
Liabilities:Salliemae: 103.3
|
79
|
+
Expenses:Interest:StudentLoan: 15.04
|
80
|
+
Assets:Checking: -118.34
|
81
|
+
|
82
|
+
- date: 2013/02/11
|
83
|
+
transaction: Deposit Paycheck
|
84
|
+
Assets:Checking: 1242.87
|
85
|
+
Income:JobName: -1242.87
|
86
|
+
|
87
|
+
- date: 2013/02/11
|
88
|
+
transaction: Visa Payment
|
89
|
+
Expenses:Interest:CreditCard: 10.0
|
90
|
+
Liabilities:CreditCard: 130.0
|
91
|
+
Assets:Checking: -140.0
|
92
|
+
|
93
|
+
- date: 2013/02/25
|
94
|
+
transaction: PG&E
|
95
|
+
Expenses:Utilities:Electric: 75
|
96
|
+
Assets:Checking: -75
|
97
|
+
|
98
|
+
- date: 2013/02/25
|
99
|
+
transaction: Verizon # Switch to Virgin Mobile
|
100
|
+
Expenses:Phone: 55.72
|
101
|
+
Assets:Checking: -55.72
|
102
|
+
|
103
|
+
- date: 2013/02/26
|
104
|
+
transaction: Ike's Lair # good sandwich
|
105
|
+
Expenses:Food:Dining: 22.31
|
106
|
+
Assets:Checking: -22.31
|
107
|
+
|
108
|
+
# a transaction requires only one space as a separator but can also be
|
109
|
+
# aligned as above. The choice is yours!
|
110
|
+
|
111
|
+
- date: 2013/02/26
|
112
|
+
transaction: Money Transfer
|
113
|
+
Assets:Savings: 494.7
|
114
|
+
Assets:Checking: -494.7
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
### Keeping a Ledger
|
119
|
+
|
120
|
+
Although the program doesn't limit you on naming your accounts, it is highly
|
121
|
+
recommended to use some standard conventions in order to facilitate easier
|
122
|
+
understanding of your finances by your accountant. The five base accounts that
|
123
|
+
you should use are:
|
124
|
+
|
125
|
+
+ Assets
|
126
|
+
* what you own
|
127
|
+
* a debit or withdrawal will be a negative number
|
128
|
+
* a deposit will be a positive number
|
129
|
+
+ Liabilities
|
130
|
+
* what you owe
|
131
|
+
* a payment towards a liability will be a positive number
|
132
|
+
* borrowing on a liability will be a negative number
|
133
|
+
+ Equity
|
134
|
+
* what you have accumulated over time
|
135
|
+
* Equity = Assets - Liabilities
|
136
|
+
+ Income
|
137
|
+
* your earnings from society
|
138
|
+
* this will always be a negative number (seems weird but you'll get used to
|
139
|
+
it)
|
140
|
+
* think of Income as a withdrawal from society and that is why it is
|
141
|
+
negative
|
142
|
+
+ Expenses
|
143
|
+
* things you spent your assets on or incurred liabilities for
|
144
|
+
* a purchase or expense will be a positive number
|
145
|
+
* a return or refund will be a negative number
|
146
|
+
|
147
|
+
Everything falls under one of these five categories but also belongs in a
|
148
|
+
sub-account. Sub-accounts are created by appending a colon and the name of the
|
149
|
+
sub-account after one of the main accounts. Some examples for account names
|
150
|
+
could then be `Assets:Savings`, `Income:My Job`, `Expenses:Food:Groceries`,
|
151
|
+
`Expenses:Food:Dining`, `Liabilities:Credit Card`.
|
152
|
+
|
153
|
+
See the example ledger above for the complete syntax.
|
154
|
+
|
155
|
+
|
156
|
+
### Start your own ledger
|
157
|
+
|
158
|
+
1. Create an empty text file named "ledger.yaml"
|
159
|
+
2. Enter your opening balances as the first transaction using the Equity
|
160
|
+
account (see example ledger above)
|
161
|
+
* The accounting equation that makes this work is `Equity = Assets -
|
162
|
+
Liabilities`
|
163
|
+
* Your Assets are positive numbers (unless your checking account is in the
|
164
|
+
negative == BAD!)
|
165
|
+
* Your Liabilities are negative since they bring down your net worth
|
166
|
+
* The difference of your Assets and Liabilities is balanced to zero with
|
167
|
+
the equity account.
|
168
|
+
* A negative equity in our ledger means a positive net worth (your assets
|
169
|
+
are greater than your liabilities).
|
170
|
+
* A positive equity in our ledger means a negative net worth (your
|
171
|
+
liabilities are greater than your assets).
|
172
|
+
3. Enter transactions (be consistent with your account naming).
|
173
|
+
4. The best way to be consistent is to run `transactions bal` to see all your
|
174
|
+
accounts before creating your new entry.
|
175
|
+
5. Transaction names can be whatever you want to help remind you of the
|
176
|
+
transaction.
|
177
|
+
6. The date is formatted as `YYYY/MM/DD` (this is important for the date
|
178
|
+
limiting options to function)
|
179
|
+
|
180
|
+
|
181
|
+
### Some (hopefully) Helpful Notes
|
182
|
+
|
183
|
+
* Assets, Liabilities, and Equity accounts are called "Real" accounts since
|
184
|
+
their balances are not zeroed out at the end of an accounting period.
|
185
|
+
* While this is unfortunate in the case of your Liabilities, it is
|
186
|
+
beneficial to your Assets.
|
187
|
+
* Income and Expense accounts are called "Nominal" accounts since they begin at
|
188
|
+
zero at the start of a new accounting period.
|
189
|
+
* Income is used for expenses, to pay liabilities, or put into an asset
|
190
|
+
account as it comes in from society and thus starts at zero every
|
191
|
+
accounting period
|
192
|
+
* Expenses start over every accounting period (you can't claim already
|
193
|
+
claimed Expenses
|
194
|
+
|
195
|
+
|
196
|
+
### Examples
|
197
|
+
|
198
|
+
Trial Balance - list of all accounts in the ledger and their balances
|
199
|
+
|
200
|
+
transactions balance
|
201
|
+
|
202
|
+
Balance Sheet - What you own and owe
|
203
|
+
|
204
|
+
transactions balance assets liabilities
|
205
|
+
|
206
|
+
Income Statement - measures cash flow / profitability (income vs expenses)
|
207
|
+
|
208
|
+
transactions balance income expenses
|
209
|
+
|
210
|
+
Limit by date
|
211
|
+
|
212
|
+
transactions -b 2013/01/01 -e 2013/12/31 balance
|
213
|
+
|
214
|
+
* this will show the entire year of 2013 inclusive of the dates used as
|
215
|
+
arguments.
|
216
|
+
* the date limits work for balance, register, and print commands.
|
217
|
+
* the totals for income and expenses will be accurate with date limits since
|
218
|
+
they are nominal accounts that reset at the beginning of a new accounting
|
219
|
+
period.
|
220
|
+
* the totals for assets and liabilities are the amounts that the accounts
|
221
|
+
changed during the accounting period. To see the totals that you actually
|
222
|
+
have in your assets or liabilities the date limits must be left out.
|
223
|
+
|
224
|
+
|
225
|
+
## Contributing
|
226
|
+
|
227
|
+
How to get your work merged into the project?
|
228
|
+
|
229
|
+
* Fork the project.
|
230
|
+
* Clone your fork ( git clone git@github.com:<username>/transactions.git ).
|
231
|
+
* Create a topic branch for your change ( git checkout -b my_new_feature ).
|
232
|
+
* Hack away, add tests. Not necessarily in that order.
|
233
|
+
* Make sure everything still passes by running rake.
|
234
|
+
* If necessary, rebase your commits into logical chunks, without errors.
|
235
|
+
* Push the branch up ( git push origin my_new_feature ).
|
236
|
+
* Create a pull request against randyschneck/transactions and describe what
|
237
|
+
your change does and the why you think it should be merged.
|
238
|
+
|
239
|
+
|
240
|
+
## Credits
|
241
|
+
|
242
|
+
Written by Randy A. Schneck (rasch@computercrayons.com)
|
243
|
+
|
244
|
+
see [LICENSE.md](https://github.com/randyschneck/transactions/blob/master/LICENSE.md)
|
245
|
+
|
data/bin/transactions
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib") # For use/testing when not installed
|
4
|
+
|
5
|
+
require 'transactions'
|
6
|
+
|
7
|
+
t = Transaction::Parser.new
|
8
|
+
|
9
|
+
if ARGV[0]
|
10
|
+
command = ARGV[0]
|
11
|
+
unless %w(balance bal register reg print).include? command
|
12
|
+
puts "That's not an option. Type 'transactions --help' for more info."
|
13
|
+
end
|
14
|
+
t.send(:parse, "balance") if %w(balance bal).include? command
|
15
|
+
t.send(:parse, "register") if %w(register reg).include? command
|
16
|
+
t.send(:parse, "print") if 'print' == command
|
17
|
+
else
|
18
|
+
puts "At least one command is required. Type 'transactions --help' for more info."
|
19
|
+
end
|
20
|
+
|
data/lib/transactions.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) # For use/testing when not installed
|
2
|
+
|
3
|
+
# stdlib
|
4
|
+
require 'yaml'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
# internal requires
|
8
|
+
require 'transactions/version'
|
9
|
+
require 'transactions/options'
|
10
|
+
require 'transactions/main'
|
11
|
+
require 'transactions/parser'
|
12
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Transaction
|
2
|
+
|
3
|
+
class Parser
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@options = Options.new.options
|
7
|
+
@default_ledger = 'ledger.yaml'
|
8
|
+
if @options[:file]
|
9
|
+
ledger = File.read @options[:file]
|
10
|
+
else
|
11
|
+
if File.exists? File.expand_path(@default_ledger)
|
12
|
+
ledger = File.read(File.expand_path(@default_ledger))
|
13
|
+
else
|
14
|
+
abort "There is no 'ledger.yaml' file in the current directory."
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@ledger = YAML::load ledger if ledger != ""
|
18
|
+
@ledger = [] if ledger == ""
|
19
|
+
@date = Time.now.strftime "%Y/%m/%d"
|
20
|
+
if @options[:sort] == 'tran' # sort by transaction
|
21
|
+
@ledger.sort_by! { |h| h['transaction'] }
|
22
|
+
elsif @options[:sort] == 'date' # sort by date
|
23
|
+
@ledger.sort_by! { |h| h['date'] }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
include Transaction
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Transaction
|
2
|
+
|
3
|
+
class Options
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@options = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def options
|
10
|
+
OptionParser.new do |opts|
|
11
|
+
|
12
|
+
opts.banner = "Usage: transactions [options] COMMAND [ARGS] ..."
|
13
|
+
|
14
|
+
opts.on("-f", "--file PATH", "PATH to yaml file to parse") do |x|
|
15
|
+
@options[:file] = x
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on("-c", "--current",
|
19
|
+
"don't include entries with future dates") do |x|
|
20
|
+
@options[:current] = x
|
21
|
+
end
|
22
|
+
|
23
|
+
opts.on("-b", "--begin DATE", "set begin date, DATE: YYYY/MM/DD") do |x|
|
24
|
+
@options[:begin] = x
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on("-e", "--end DATE", "set end date, DATE: YYYY/MM/DD") do |x|
|
28
|
+
@options[:end] = x
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on("-s", "--subtotal", "show sub-totals for balance") do |x|
|
32
|
+
@options[:subtotal] = x
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on("-E", "--empty", "show accounts with zero balance") do |x|
|
36
|
+
@options[:empty] = x
|
37
|
+
end
|
38
|
+
|
39
|
+
opts.on("-S", "--sort ARG", "sort by field, ARG can be date or tran") do |x|
|
40
|
+
@options[:sort] = x
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on("-w", "--wide", "print 132 columns wide for register") do |x|
|
44
|
+
@options[:wide] = x
|
45
|
+
end
|
46
|
+
|
47
|
+
#opts.on("-C", "--cleared", "only include cleared transactions") do |x|
|
48
|
+
# @options[:cleared] = x
|
49
|
+
#end
|
50
|
+
|
51
|
+
#opts.on("-U", "--uncleared", "only include uncleared transactions") do |x|
|
52
|
+
# @options[:uncleared] = x
|
53
|
+
#end
|
54
|
+
|
55
|
+
opts.on_tail("-h", "--help", "show this help message") do
|
56
|
+
puts opts
|
57
|
+
abort self.commands_help
|
58
|
+
end
|
59
|
+
|
60
|
+
opts.on_tail("-v", "--version", "show version") do
|
61
|
+
abort "#{Transaction::VERSION}"
|
62
|
+
end
|
63
|
+
|
64
|
+
end.parse!
|
65
|
+
|
66
|
+
@options
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def commands_help
|
72
|
+
<<-COMMANDHELP
|
73
|
+
|
74
|
+
COMMANDS
|
75
|
+
--------
|
76
|
+
balance [ACCOUNT].. Prints account balances, limited to ACCOUNTS.
|
77
|
+
'bal' can be used as a shortcut.
|
78
|
+
register [ACCOUNT].. Prints account register, limited to ACCOUNTS.
|
79
|
+
'reg' can be used as a shortcut.
|
80
|
+
print Prints transactions formatted for export to ledger.
|
81
|
+
Can be limited by date but not ACCOUNT.
|
82
|
+
COMMANDHELP
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
@@ -0,0 +1,162 @@
|
|
1
|
+
module Transaction
|
2
|
+
|
3
|
+
def parse(cmd)
|
4
|
+
|
5
|
+
@accounts = {}
|
6
|
+
@running_total = 0
|
7
|
+
|
8
|
+
def transaction_print(x)
|
9
|
+
puts "#{x['date']} #{x['transaction']}"
|
10
|
+
x.each do |k, v |
|
11
|
+
puts sprintf(" %-30.30s % .2f", k, v) if v.is_a? Numeric
|
12
|
+
end
|
13
|
+
puts ""
|
14
|
+
end
|
15
|
+
|
16
|
+
def transaction_balance(k, v)
|
17
|
+
@accounts[k] += v if v.is_a? Numeric
|
18
|
+
end
|
19
|
+
|
20
|
+
def transaction_register(x, k, v, running_total)
|
21
|
+
if v.is_a? Numeric
|
22
|
+
if @options[:wide] # for printing 132 columns wide
|
23
|
+
t = "%10s %-44s %-44s %15.2f %15.2f"
|
24
|
+
puts sprintf(t, x['date'], x['transaction'][0..42],
|
25
|
+
k[0..42], v, running_total)
|
26
|
+
else # for printing 78 columns wide (default)
|
27
|
+
t = "%10s %-20s %-24s %10.2f %10.2f"
|
28
|
+
puts sprintf(t, x['date'], x['transaction'][0..18],
|
29
|
+
k[0..22], v, running_total)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def transaction_command(cmd, x, k, v)
|
35
|
+
ARGV.map! { |z| z.downcase }
|
36
|
+
if ARGV[1..-1].any? { |arg| k.downcase.include? arg }
|
37
|
+
@running_total += v if v.is_a? Numeric
|
38
|
+
if cmd == 'print'
|
39
|
+
transaction_print(x)
|
40
|
+
elsif cmd == 'balance'
|
41
|
+
transaction_balance(k, v)
|
42
|
+
elsif cmd == 'register'
|
43
|
+
transaction_register(x, k, v, @running_total)
|
44
|
+
end
|
45
|
+
elsif !ARGV[1]
|
46
|
+
@running_total += v if v.is_a? Numeric
|
47
|
+
if cmd == 'print'
|
48
|
+
transaction_print(x)
|
49
|
+
elsif cmd == 'balance'
|
50
|
+
transaction_balance(k, v)
|
51
|
+
elsif cmd == 'register'
|
52
|
+
transaction_register(x, k, v, @running_total)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
@ledger.each do |x|
|
58
|
+
total = 0
|
59
|
+
x.each do |k, v|
|
60
|
+
total += v if v.is_a? Numeric
|
61
|
+
@accounts[k] ||= 0 if v.is_a? Numeric
|
62
|
+
|
63
|
+
if @options[:current]
|
64
|
+
if @options[:begin]
|
65
|
+
if x['date'] <= @date && x['date'] >= @options[:begin]
|
66
|
+
transaction_command(cmd, x, k, v); break if cmd == 'print'
|
67
|
+
end
|
68
|
+
else
|
69
|
+
if x['date'] <= @date
|
70
|
+
transaction_command(cmd, x, k, v); break if cmd == 'print'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
elsif @options[:begin] || @options[:end]
|
74
|
+
if @options[:begin] && @options[:end]
|
75
|
+
if @options[:begin] <= x['date'] and x['date'] <= @options[:end]
|
76
|
+
transaction_command(cmd, x, k, v); break if cmd == 'print'
|
77
|
+
end
|
78
|
+
elsif @options[:begin]
|
79
|
+
if x['date'] >= @options[:begin]
|
80
|
+
transaction_command(cmd, x, k, v); break if cmd == 'print'
|
81
|
+
end
|
82
|
+
elsif @options[:end]
|
83
|
+
if x['date'] <= @options[:end]
|
84
|
+
transaction_command(cmd, x, k, v); break if cmd == 'print'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
else
|
88
|
+
transaction_command(cmd, x, k, v); break if cmd == 'print'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
if total.round(2) != 0
|
92
|
+
abort <<-EOF
|
93
|
+
You have an UNBALANCED Transaction
|
94
|
+
#{x}
|
95
|
+
Your total is off by #{sprintf("%.2f", -total)}
|
96
|
+
EOF
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
if cmd == 'balance'
|
102
|
+
accounts_total = 0
|
103
|
+
main_accounts = {}
|
104
|
+
|
105
|
+
if ARGV[1] && !@options[:subtotal]
|
106
|
+
ARGV[1..-1].each do |arg|
|
107
|
+
@accounts.sort.each do |k, v|
|
108
|
+
if k.downcase.include? arg
|
109
|
+
accounts_total += v
|
110
|
+
v = v.round(2)
|
111
|
+
if @options[:empty]
|
112
|
+
puts sprintf("%16.2f %s", v, k)
|
113
|
+
else
|
114
|
+
puts sprintf("%16.2f %s", v, k) if v != 0
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
puts "#{'-' * 16}"
|
120
|
+
puts sprintf("%16.2f", accounts_total)
|
121
|
+
|
122
|
+
elsif @options[:subtotal]
|
123
|
+
summary_total = 0
|
124
|
+
@accounts.each do |k, v|
|
125
|
+
x = k.split(':')
|
126
|
+
main_accounts[x[0].to_sym] ||= 0
|
127
|
+
main_accounts[x[0].to_sym] += v
|
128
|
+
main_accounts.each do |account, value|
|
129
|
+
main_accounts[account] = value.round(2)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
main_accounts.sort.each do |k, v|
|
133
|
+
if ARGV[1]
|
134
|
+
ARGV.map! { |x| x.downcase }
|
135
|
+
ARGV[1..-1].each do |arg|
|
136
|
+
puts "#{sprintf("%16.2f %s", v, k)}" if k.to_s.downcase.include? arg
|
137
|
+
summary_total += v if k.to_s.downcase.include? arg
|
138
|
+
end
|
139
|
+
else
|
140
|
+
puts "#{sprintf("%16.2f %s", v, k)}"
|
141
|
+
summary_total += v
|
142
|
+
end
|
143
|
+
end
|
144
|
+
puts "#{"-" * 16}"
|
145
|
+
puts "#{sprintf("%16.2f", summary_total.round(2))}"
|
146
|
+
|
147
|
+
else
|
148
|
+
@accounts.sort.each do |k, v|
|
149
|
+
v = v.round(2)
|
150
|
+
if @options[:empty]
|
151
|
+
puts sprintf("%16.2f %s", v, k)
|
152
|
+
else
|
153
|
+
puts sprintf("%16.2f %s", v, k) if v != 0
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: transactions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Randy Schneck
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-06-27 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |2
|
14
|
+
A small but powerful command line application to help manage finances.
|
15
|
+
Transactions are entered into a text file using yaml and reports are
|
16
|
+
generated by parsing this data.
|
17
|
+
email: rasch@computercrayons.com
|
18
|
+
executables:
|
19
|
+
- transactions
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- bin/transactions
|
24
|
+
- lib/transactions/main.rb
|
25
|
+
- lib/transactions/options.rb
|
26
|
+
- lib/transactions/parser.rb
|
27
|
+
- lib/transactions/version.rb
|
28
|
+
- lib/transactions.rb
|
29
|
+
- LICENSE.md
|
30
|
+
- README.md
|
31
|
+
- CHANGELOG.md
|
32
|
+
homepage: https://github.com/randyschneck/transactions
|
33
|
+
licenses:
|
34
|
+
- MIT
|
35
|
+
metadata: {}
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 2.0.2
|
53
|
+
signing_key:
|
54
|
+
specification_version: 4
|
55
|
+
summary: A bookkeeping application to help manage your finances.
|
56
|
+
test_files: []
|