hackerbase/fio_splitter.sh

230 lines
5.3 KiB
Bash

#!/bin/sh
#
# fio_splitter.sh
#
# Batch splitter of yearly account statements into monthly ones.
#
# ISC License
#
# Copyright 2023 Brmlab, z.s.
# Jan Hrach
# Dominik Pantůček <dominik.pantucek@trustica.cz>
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# Configuration defaults - none
CONFIG_FILE="$HOME/.hackerbaserc"
CFG_BANK_DIR=
CFG_APIKEYS_FILE=
ARG_BANK_DIR=
ARG_APIKEYS_FILE=
# Argument parsing
while ! [ -z "$1" ] ; do
case "$1" in
-apikey)
ARG_APIKEYS_FILE="$2"
shift
shift
;;
-bankdir)
ARG_BANK_DIR="$2"
shift
shift
;;
-config)
CONFIG_FILE="$2"
shift
shift
;;
*)
echo "Usage: $0 [-config file] [-apikey file] [-bankdir dir]"
exit 1
;;
esac
done
# Configuration parsing - assumes "dumb" sed which cannot execute
# multiple statements
get_config_value() {
if [ -z "$1" ] ; then
echo "get_config_value() requires parameter name"
exit 1
fi
if [ -r "$CONFIG_FILE" ] ; then
cat "$CONFIG_FILE" \
| sed 's/#.*//' \
| sed 's/^[ \t]*//' \
| grep "^$1" \
| sed 's/^[^ \t]*//' \
| sed 's/^[ \t]*//' \
| sed 's/[ \t]*$//'
fi
}
CFG_BANK_DIR=`get_config_value bank-dir`
CFG_APIKEYS_FILE=`get_config_value apikeys-file`
# Configuration merging
if [ -z "$ARG_BANK_DIR" ] ; then
BANK_DIR="$CFG_BANK_DIR"
else
BANK_DIR="$ARG_BANK_DIR"
fi
if [ -z "$ARG_APIKEYS_FILE" ] ; then
APIKEYS_FILE="$CFG_APIKEYS_FILE"
else
APIKEYS_FILE="$ARG_APIKEYS_FILE"
fi
# Storage for partial account statements
BANK_DIR_PARTS="$BANK_DIR/parts"
if ! [ -d "$BANK_DIR_PARTS" ] ; then
mkdir -p "$BANK_DIR_PARTS"
fi
#
# Very simple "logging" function (stdout should be redirected to log anyway)
log() {
echo `date '+%Y-%m-%d %H:%M:%S'` "$@"
}
#
# Gets only given header
# $1 - path to file
# $2 - header name
get_header_field() {
egrep "^$2|^.$2" "$1"
}
#
# Returns the last day of given month in Fio format
end_of_month() {
YEAR="$1"
MONTH="$2"
case $MONTH in
01) DAY=31 ;;
02)
DAY=$(
if [ $YEAR = 2012 -o $YEAR = 2016 -o $YEAR = 2020 ] ; then
echo 29
else
echo 28
fi
)
;;
03) DAY=31 ;;
04) DAY=30 ;;
05) DAY=31 ;;
06) DAY=30 ;;
07) DAY=31 ;;
08) DAY=31 ;;
09) DAY=30 ;;
10) DAY=31 ;;
11) DAY=30 ;;
12) DAY=31 ;;
esac
echo "$DAY.$MONTH.$YEAR"
}
#
# Splits given file into twelve months
split_year() {
# Examine name
CSVNAME="$1"
bname=${CSVNAME##*/}
ACCNO=${bname%%-*}
rest=${bname##*-}
YEAR=${rest%%.*}
log Splitting "$CSVNAME" year "$YEAR" account "$ACCNO"
# Read header
accountId=`get_header_field $CSVNAME accountId`
bankId=`get_header_field $CSVNAME bankId`
currency=`get_header_field $CSVNAME currency`
iban=`get_header_field $CSVNAME iban`
openingBalance=`get_header_field $CSVNAME openingBalance`
closingBalance=`get_header_field $CSVNAME closingBalance`
dateStart=`get_header_field $CSVNAME dateStart`
dateEnd=`get_header_field $CSVNAME dateEnd`
idFrom=`get_header_field $CSVNAME idFrom`
idTo=`get_header_field $CSVNAME idTo`
# Emit months
for month in `seq 1 12` ; do
MONTH=$month
if [ $MONTH -lt 10 ] ; then
MONTH=0$MONTH
fi
MCSVNAME="$BANK_DIR_PARTS/$ACCNO-$YEAR-$MONTH.csv"
{
echo "$accountId"
echo "$bankId"
echo "$currency"
echo "$iban"
echo "$openingBalance"
echo "$closingBalance"
# echo "$dateStart"
echo "dateStart;01.$MONTH.$YEAR"
#echo "$dateEnd"
DATEEND=`end_of_month $YEAR $MONTH`
echo "dateEnd;$DATEEND"
if [ -z $idFrom ] ; then
# Empty year
echo
grep "^ID" "$CSVNAME"
else
# Non-empty year, maybe non-empty month
numrec=`grep -c "^[0-9]*;...$MONTH.$YEAR;" "$CSVNAME"`
if [ $numrec = 0 ] ; then
# Empty month
echo
grep "^ID" "$CSVNAME"
else
# Non-empty month
IDFROM=`grep "^[0-9]*;...$MONTH.$YEAR;" "$CSVNAME"|head -1|sed 's/;.*//'`
IDTO=`grep "^[0-9]*;...$MONTH.$YEAR;" "$CSVNAME"|sort -gr -t';'|head -1|sed 's/;.*//'`
echo "idFrom;$IDFROM"
echo "idTo;$IDTO"
echo
grep "^ID" "$CSVNAME"
grep "^[0-9]*;...$MONTH.$YEAR;" "$CSVNAME"
fi
fi
} >"$MCSVNAME"
done
}
# Current year (last in seq)
CYEAR=`date +%Y`
# Process all known accounts
log Started
while read accnt ; do
# Extract account number and starting year
ACCNO=${accnt%% *}
accrest=${accnt#* }
accrest2=${accrest#* }
YEAR=${accrest2%% *}
# Process the account
log ==== ACCNO=$ACCNO YEAR=$YEAR
# Iterate over years
for year in `seq $YEAR $CYEAR` ; do
CSVNAME="$BANK_DIR_PARTS/$ACCNO-$year.csv"
split_year $CSVNAME
done
done < "$APIKEYS_FILE"