diff --git a/bin/ft b/bin/ft new file mode 100755 index 00000000000..3ecad36be1a --- /dev/null +++ b/bin/ft @@ -0,0 +1,161 @@ +#!/usr/bin/env bash +# * ft - financial scripts, see below +# ** PREAMBLE +# shellcheck shell=bash disable=SC2317 +# Customise as needed; consider keeping as a git checkout for merging updates. + +set -e + +rg="rg -IN --sort=path" +date=$(if [ "$(builtin type -p gdate)" ]; then echo gdate; else echo date; fi) +sed=$(if [ "$(builtin type -p gsed)" ]; then echo gsed; else echo sed; fi) + +help() { # show this help + cat < paypal.csv +} + +import-dry() { # import new downloaded transactions to the journal, dry run + hledger -f "$JOURNAL" import "${IMPORTFILES[@]}" --dry-run +} + +import() { # import new downloaded transactions to the journal, logging and not printing errors + date >>import.log + hledger -f "$JOURNAL" import "${IMPORTFILES[@]}" 2>>import.log || echo "Failed, check import.log" + echo "Use ledger-mode's M-q to align entries." +} + +# ** IMPORT PRICES ------------------------------------------------------------ + +get-prices() { # [PRICEHISTFETCHOPTS] - download prices for main commodities (default: today's) + (pricehist fetch -o ledger -s "$TODAY" alphavantage EUR/USD "$@" | $sed -E 's/EUR/€/') & + (pricehist fetch -o ledger -s "$TODAY" alphavantage GBP/USD "$@" | $sed -E 's/GBP/£/') & + (pricehist fetch -o ledger -s "$TODAY" alphavantage JPY/USD "$@" | $sed -E 's/JPY/¥/') + # Parallelised for speed; do slowest last. + # Output order varies, can be sorted with LC_COLLATE=C.UTF-8 sort or hledger -f- prices. +} + +# ** REPORTS ------------------------------------------------------------ +# **** general ------------------------------------------------------------ + +bs() { # show balance sheet + hledger -f "$JOURNAL" bs --layout bare --pretty --drop 1 -p "$PERIOD" -E -5 "$@" +} + +is() { # show income statement + hledger -f "$JOURNAL" is --layout bare --pretty --drop 1 -p "$PERIOD" -S "$@" +} + +a() { # show assets + hledger -f "$JOURNAL" bal type:al -H --layout bare --pretty --drop 1 -p "$PERIOD" -E "$@" +} + +r() { # show revenues + hledger -f "$JOURNAL" bal type:r --layout bare --pretty --drop 1 -p "$PERIOD" -S --invert "$@" +} + +x() { # show expenses + hledger -f "$JOURNAL" bal type:x --layout bare --pretty --drop 1 -p "$PERIOD" -S --invert "$@" +} + +ab() { # show assets bar chart + echo "Quarterly net worth:" + hledger-bar -v 200 -f "$JOURNAL" -Q type:al -H "$@" +} + +rb() { # show revenues bar chart + echo "Quarterly revenues:" + hledger-bar -v 40 -f "$JOURNAL" -Q type:r --invert "$@" +} + +xb() { # show expenses bar chart + echo "Quarterly expenses:" + hledger-bar -v 40 -f "$JOURNAL" -Q type:x --invert "$@" +} + +# XXX with partial workaround for https://github.com/gooofy/drawilleplot/issues/4 +al() { # show assets line chart + hledger -f "$JOURNAL" plot -- bal --depth=1 ^assets --historical --terminal --rcParams '{"figure.figsize":[8,3]}' --no-today -q --title "hledger assets" "$@" | $sed 's/⠀/ /g' +} + +rl() { # show revenues line chart + hledger -f "$JOURNAL" plot -- bal --depth=1 ^revenues --monthly --invert --terminal --rcParams '{"figure.figsize":[8,3]}' --drawstyle 'steps-mid' --no-today -q --title "hledger monthly revenues" "$@" | $sed 's/⠀/ /g' +} + +xl() { # show expenses line chart + hledger -f "$JOURNAL" plot -- bal --depth=1 ^expenses --monthly --terminal --rcParams '{"figure.figsize":[8,3]}' --drawstyle 'steps-mid' --no-today -q --title "hledger monthly expenses" "$@" | $sed 's/⠀/ /g' +} + +forecast() { # print transactions predicted by forecast rules from last week on + hledger print --auto --forecast=lastweek.. -I tag:_generated "$@" +} + +household() { # show a draft month-end household adjustment transaction for last month + env household "$($date -v-1m +%b)" +} + +# **** tax ------------------------------------------------------------ + +# estimated-tax: +# @echo "Federal estimated tax due for this year" +# $(HLEDGER) register liabilities:personal:tax:federal:$(YEAR) --width=130 +# @echo State estimated tax due for this year: +# @$(HLEDGER) register liabilities:personal:tax:state:$(YEAR) --width=130 +# @echo + +# **** business ------------------------------------------------------------ + +consulting() { # show consulting revenue + hledger -f "$JOURNAL" reg --invert 'revenues:(client1|client2)' -p "$PERIOD" "$@" +} + +# **** other ------------------------------------------------------------ + +bin() { # [PAT] show all scripts in $DIR/bin/[bashrc] (default: ~/finance/) + env bin "$@" +} + +# ** END + +if [[ $# -eq 0 ]]; then help # no args shows help +elif declare -f "$1" > /dev/null; then "$@"; # arg 1 selects a function above +else hledger -f "$JOURNAL" "$@"; fi # or fall through to hledger +exit diff --git a/bin/tt b/bin/tt new file mode 100755 index 00000000000..c15490c4aff --- /dev/null +++ b/bin/tt @@ -0,0 +1,180 @@ +#!/usr/bin/env bash +# * tt - time scripts, see below +# ** PREAMBLE +# Customise as needed; consider keeping as a git checkout for merging updates. +# Uses hledger, bash, python, a few other unix tools. +# wakelog is a script grepping system logs for sleep/wake events; provide it or comment it. + +## #!/usr/bin/env -S osh # -*- sh -*- # or osh - more powerful, less tool support +## shopt -s -errexit strict:all 2>/dev/null || set -e + +# shellcheck shell=bash disable=SC2096 disable=SC2317 + +set -e + +rg="rg -IN --sort=path" +date=$(if [ "$(builtin type -p gdate)" ]; then echo gdate; else echo date; fi) +sed=$(if [ "$(builtin type -p gsed)" ]; then echo gsed; else echo sed; fi) +stat=$(if [ "$(builtin type -p gstat)" ]; then echo gstat; else echo stat; fi) + +help() { # show this help + line + cat <>"$TIMELOG" +} + +hours() { # show a bar chart of daily hours + hledger-bar -v 1 -f "$TIMELOG" -D "$@" +} + +# ** END + +if [[ $# -eq 0 ]]; then help # no args shows help +elif declare -f "$1" > /dev/null; then "$@"; # arg 1 selects a function above +else hledger -f "$TIMELOG" "$@"; fi # or fall through to hledger +exit