|
#!/usr/bin/env bash |
|
# shellcheck disable=SC2016 |
|
set -e |
|
|
|
PROG=$(basename "$0") |
|
DEFTIMEACCT=0 |
|
DEFEXPACCT=0 |
|
|
|
function usage() { |
|
cat <<EOS |
|
-------------------------------------------------------------------------------- |
|
Make a md or pdf invoice for hledger-reported time and expenses last month, |
|
from a pandoc markdown template and similarly-named .css file. |
|
Requires awk, GNU date, envsubst, python3, sed, tail, pandoc, hledger 20210808+ |
|
Usage: |
|
|
|
$PROG [TEMPLATEFILE [TIMEACCT|HRS [EXPACCT|AMT]]] |
|
[-m|--markdown] [-p|--pdf] [-f|--force] [-c|--commit] |
|
|
|
With no arguments, show this help. |
|
|
|
With no flags, make a markdown invoice from TEMPLATEFILE on stdout for preview. |
|
Additional arguments set the time and expense accounts for hledger to |
|
query, or if numeric, the time and expense amounts directly. |
|
|
|
With flags, |
|
-m|--markdown save a markdown invoice if input files are newer |
|
-p|--pdf save a pdf if input files are newer, & open folder for preview |
|
-f|--force force invoice generation even if input files are older |
|
-c|--commit git commit any saved markdown/pdf invoices |
|
|
|
EOS |
|
} |
|
|
|
ARGS=() |
|
while [[ $# -gt 0 ]]; do |
|
key="$1" |
|
case $key in |
|
-h|--help) |
|
HELP=1 |
|
shift |
|
;; |
|
-m|--markdown) |
|
MD=1 |
|
shift |
|
;; |
|
-p|--pdf) |
|
PDF=1 |
|
shift |
|
;; |
|
-f|--force) |
|
FORCE=1 |
|
shift |
|
;; |
|
-c|--commit) |
|
COMMIT=1 |
|
shift |
|
;; |
|
*) |
|
if [[ "$1" != -* ]] |
|
then |
|
ARGS+=("$1") |
|
shift |
|
else |
|
echo "Error: unknown option $1" |
|
exit 1 |
|
fi |
|
;; |
|
esac |
|
done |
|
if [[ $HELP = 1 || ${#ARGS} -eq 0 ]]; then usage; exit; fi |
|
|
|
TEMPLATE="${ARGS[0]}" |
|
TIMEACCT="${ARGS[1]:-$DEFTIMEACCT}" |
|
EXPACCT="${ARGS[2]:-$DEFEXPACCT}" |
|
|
|
# when changing this, hledger and date may need different values |
|
HLEDGERPERIOD='last month' |
|
DATECMDPERIOD='last month' |
|
# HLEDGERPERIOD='2021-08' |
|
# DATECMDPERIOD='2021-08-01' |
|
|
|
NUMRE="^[0-9]+([.][0-9]+)?$" |
|
if [[ $TIMEACCT =~ $NUMRE ]] |
|
then |
|
HRS=$TIMEACCT |
|
else |
|
HRS=$(hledger -f~/adm/time.journal bal "$TIMEACCT" -1 "date:$HLEDGERPERIOD" -N | tail -1 | awk '{print $1}') |
|
fi |
|
if [[ $EXPACCT =~ $NUMRE ]] |
|
then |
|
EXP=$EXPACCT |
|
else |
|
EXP=$(hledger bal "$EXPACCT" "date:$HLEDGERPERIOD" amt:'>0' -N --commodity-column | tail -1 | awk '{print $1}') |
|
fi |
|
|
|
# on mac, use homebrew-installed GNU date |
|
if [ "$(builtin type -p gdate)" ]; then export date=gdate; else export date=date; fi |
|
|
|
# XXX FIXEDEXPS, RATE, other vars below, and printf widths must be kept synced with TEMPLATE |
|
|
|
FIXEDEXPS=$(python3 -c "print(sum([ 1111, 2222, 333 ]))") |
|
RATE=444 |
|
|
|
YEAR=$($date +%Y) |
|
MONTH=$($date +%B) |
|
DAY=$($date +%-d) |
|
LM=$($date +%b --date "$DATECMDPERIOD") |
|
LMM=$($date +%m --date "$DATECMDPERIOD") |
|
|
|
# shellcheck disable=SC2001 |
|
INVOICEBASE=$(basename "$TEMPLATE" | sed -e 's/\..*//') |
|
INVOICEDATED=$INVOICEBASE$YEAR$LMM |
|
INVOICEMD=$INVOICEDATED".md" |
|
INVOICEPDF=$INVOICEDATED".pdf" |
|
CSS=$INVOICEBASE".css" |
|
|
|
HRS="${HRS:-0}" |
|
HRS=$(printf %4s "$HRS") |
|
EXP=$(printf %5.0f "$EXP") |
|
AMT=$(python3 -c "print(round( $HRS * $RATE ))") |
|
AMT=$(printf %5s "$AMT") |
|
TOT=$(python3 -c "print(sum([ $FIXEDEXPS, $AMT, $EXP ]))") |
|
TOT=$(printf %5s "$TOT") |
|
export YEAR MONTH DAY LMM LM HRS EXP AMT TOT |
|
|
|
if [[ $MD != 1 && $PDF != 1 ]]; |
|
then |
|
envsubst '$YEAR:$MONTH:$DAY:$LMM:$LM:$HRS:$EXP:$AMT:$TOT' <"$TEMPLATE" |
|
|
|
else |
|
if [[ $MD = 1 ]]; |
|
then |
|
if [[ $FORCE = 1 || $TEMPLATE -nt $INVOICEMD ]] |
|
then |
|
envsubst '$YEAR:$MONTH:$DAY:$LMM:$LM:$HRS:$EXP:$AMT:$TOT' <"$TEMPLATE" >"$INVOICEMD" |
|
echo "wrote $INVOICEMD" |
|
fi |
|
fi |
|
|
|
if [[ $PDF = 1 ]]; |
|
then |
|
if [[ $FORCE = 1 || $TEMPLATE -nt $INVOICEMD || $CSS -nt $INVOICEMD ]] |
|
then |
|
envsubst '$YEAR:$MONTH:$DAY:$LMM:$LM:$HRS:$EXP:$AMT:$TOT' <"$TEMPLATE" \ |
|
| pandoc -t html5 --metadata title=" " --css "$CSS" -o "$INVOICEPDF" |
|
echo "wrote $INVOICEPDF" |
|
fi |
|
if [[ $COMMIT != 1 ]] |
|
then |
|
open . |
|
fi |
|
fi |
|
|
|
if [[ $COMMIT = 1 ]] |
|
then |
|
git add "$INVOICEMD" "$INVOICEPDF" && \ |
|
git commit -m "$INVOICEDATED" -- "$INVOICEMD" "$INVOICEPDF" && \ |
|
echo "committed:" && git show --stat |
|
fi |
|
fi |