feramhq / transity
- четверг, 7 июня 2018 г. в 00:14:21
PureScript
Keep track of your 💵 , 🕘 , 🐖 , 🐄 , 🍻 on your command line
The plain text accounting tool of the future.
Keep track of your
npm install --global transity
git clone https://github.com/feramhq/transity
cd transity
npm link
$ transity balance examples/journal.yaml
anna 1 evil-machine
-49978.02 €
ben -50 $
-1.432592 BTC
-100 €
evil-corp -1 evil-machine
50015 €
good-inc -100 €
grocery-shop 11.97 €
john:giro 50 $
1.432592 BTC
85 €
john:wallet 66.05 €
If linked modules aren't exposed in your path you can also run
cli/main.js balance examples/journal.yaml
List complete usage manual by simply calling transity
without any arguments.
$ transity
Usage: transity <command> <path/to/journal.yaml>
Command Description
------------------ ------------------------------------------------------------
balance Simple balance of all accounts
transactions All transcations and their transfers
entries All individual deposits & withdrawals
entries-by-account All individual deposits & withdrawals grouped by account
gplot Code and data for gnuplot impulse diagram
to visualize transfers of all accounts
gplot-cumul Code and data for cumuluative gnuplot step chart
to visualize balance of all accounts
A minimal journal file is a YAML file with following format:
owner: anna
commodities:
- id: €
name: Euro
alias:
- EUR
note: Currency used in the European Union
utc: 2017-04-02 19:33:53
entities:
- id: anna
name: Anna Smith
utc: 2017-04-02 19:33:28
tags:
- person
accounts:
- id: wallet
name: Wallet
note: Anna's black wallet
utc: 2017-04-02 19:33:28
tags:
- wallet
- id: evil-corp
name: Evil Corporation
utc: 2017-04-02 19:33:28
note: The Evil Corporation in the United States of Evil
tags:
- company
transactions:
- title: Purchase of evil machine
transfers:
- utc: 2017-02-17
from: anna
to: evil-corp
amount: 50000 €
- utc: 2017-02-17
from: evil-corp
to: anna
amount: 1 evil-machine
Per default all accounts are plotted.
To limit it to only a subsection use awk
to filter the output.
For example all transactions of Euro accounts:
transity gplot examples/journal.yaml \
| awk '/^$/ || /(EOD|^set terminal)/ || /€/' \
| gnuplot \
| imgcat
Or all account balances of Euro accounts over time:
transity gplot-cumul examples/journal.yaml \
| awk '/^$/ || /(EOD|^set terminal)/ || /€/' \
| gnuplot \
| imgcat
Update the ledger filepath in following command, copy it into your CLI and execute it.
bash -c '{ \
echo date,id,from,to,amount,note,tags; \
ledger \
--file ledgers/main.ledger \
--csv-format \'%(
format_date(date,"%Y-%m-%d")),%(
quoted(code)),%(
quoted("")),%(
quoted(payee)),%(quoted(display_amount)),%(
quoted(join(trim(xact.note | "{{PLACEHOLDER}}")))),%(
quoted("- " + display_account + "\\\\n- " +
join(trim(note | "{{PLACEHOLDER}}")))
)\n\' \
--sort date \
csv; \
} \
| sed "s/{{PLACEHOLDER}}//g" \
| sed \'s/\\\\"/""/g\' \
> transactions.csv'
(The ugly {{PLACEHOLDER}}
workaround is necessary to make it work
if no note is specified for a transaction,
the second sed
command fixes escaping of "
in CSV)
Convert transactions.csv
to YAML with e.g. browserling.com/tools/csv-to-yaml
Attention:
from
and to
).
(For expenses basically copy the ledger-account from the second entry
into the from
field of the first entry)from
and to
might reversed for income
(depending on how the payee
field was used)tags
field.
There is no way to get only the tags in Ledger-CLI Existing accounting tools are historically based on the notion of an account. You add money (debit) and you remove money (credit). (If this sounds backwards to you, read this explanation)
For example you get 50 € from your mum and buy some food for 20 €.
Account | Debit | Credit
--------|---------|--------
Wallet | 50.00 € |
Wallet | | 20.00 €
---------------------------
Simple, but also incomplete. Where did the money come from, where did it go? This led to double entry bookkeeping. Whenever you add some money to an account you have to remove the same amount from another.
Account | Debit | Credit
--------|---------|--------
Wallet | 50.00 € |
Mum | | 50.00 €
Wallet | | 20.00 €
Food | 20.00 € |
---------------------------
But you must never forget a posting, because otherwise your account won't balance.
Account | Debit | Credit
--------|---------|--------
Wallet | 50.00 € |
Mum | | 50.00 €
Wallet | | 20.00 €
---------------------------
Oops, where did the money go? 🤷
If this looks (and sounds) confusing or too complicated, you're not alone! It made sense in former times as this layout makes it easier to add up the amounts by hand, but not in times of computers.
So how can we simplify it? It's actually quite easy: We just have to model it in terms of transactions, and not accounts.
Amount | From | To
-------|--------|--------
50 € | Mum | Wallet
20 € | Wallet | Food
-------------------------
Together with some further changes it yields a easier understandable, more robust and more complete representation of accounting!
PureScript leverages strong static typing and can therefore give more guarantees about the functionality of the code than weakly typed or untyped languages (like JavaScript).
You wouldn't want your money get lost in rounding errors or
be turned to undefined
, would you?
PureScript can also easily be used in the browser or get deployed as a cloud function as it simply compiles to JavaScript. With Haskell you'd have to use another language for a web frontend or quarrel with experimental stuff like GHCJS.
Checkout the files hledger.journal and journal.yaml for similar transactions modeled in Hledger and in Transity.
hledger --file examples/hledger.journal balance
# vs
transity balance examples/journal.yaml
hledger --file examples/hledger.journal register
# vs
transity transactions examples/journal.yaml
hledger --file examples/hledger.journal register --output-format=csv
# vs
transity entries examples/journal.yaml
There are no separate fields for entry or value dates necessary. Simply use ISO 8601 time intervals to specify the duration of a transfer.
transactions:
- id: '123456789'
note: Deposit of savings
transfers:
- utc: 2018-01-04T12:00--05T22:10
from: john
to: bank
amount: 100 €
This is a first concept for an alternative syntax for the YAML journal file:
2016-04-16 18:50:28
#20135604
1 year registration of domain "example.org"
john -> paypal : 9.95 €
paypal -> namecheap : 10.69 $
paypal -> icann : 0.18 $
namecheap -> john : 1 Domain