#! /bin/bash

# This applications takes an text input file $FILE
# and converts it into a gnucash account scheme with a random name.
# The input file is read line by line where each line
# should be formatted as
#  number name (no leading spaces)
# or
#  category name (one leading space)
# .
# Empty lines are not allowed, number is expected to have 4 digits.
# The output is a two layer structure
# of all accounts. Whenever the first
# digit of number changes, a new source group is created.
# Whenever a new category line is passed, all following
# accounts are put below.
#
# Example:
# input:
#   1234 A
#   2000 B
#    Type B1
#   2001 B1a
#   2002 B1b
#    Type B2
#   2010 B2a
#   2011 B2b
# output:
#   Class 0
#   Class 1
#    \- 1234 A
#   Class 2
#    \- 2000 B
#    \- Type B1
#       \- 2001 B1a
#       \- 2002 B1b
#    \- Type B2
#       \- 2010 B2a
#       \- 2011 B2b
#
# (C) 2009, Michael Braun, michael-developer@fami-braun.de
# Distributed under GPL v3.0 or newer.
# see http://www.gnu.org/licenses/gpl.html for details

echo "start"

FILE="Art.-Nr.11180.txt"

if [ ! -f "$FILE" ]; then 
 echo "no such file $FILE"
 exit 1;
fi

getuid()
{
 dd if=/dev/urandom bs=1 count=32  2>/dev/null | md5sum | awk -F' ' '{print $1}';
}

OUT="$(getuid).gnucash"

ROOT=$(getuid);
NUM=$(cat $FILE | wc -l)
NUM=$(expr $NUM + 1);
ID=0

echo -n > $OUT;

cat >> "$OUT" <<EOF
<?xml version="1.0" encoding="utf-8" ?>
<gnc-v2
     xmlns:gnc="http://www.gnucash.org/XML/gnc"
     xmlns:act="http://www.gnucash.org/XML/act"
     xmlns:book="http://www.gnucash.org/XML/book"
     xmlns:cd="http://www.gnucash.org/XML/cd"
     xmlns:cmdty="http://www.gnucash.org/XML/cmdty"
     xmlns:price="http://www.gnucash.org/XML/price"
     xmlns:slot="http://www.gnucash.org/XML/slot"
     xmlns:split="http://www.gnucash.org/XML/split"
     xmlns:sx="http://www.gnucash.org/XML/sx"
     xmlns:trn="http://www.gnucash.org/XML/trn"
     xmlns:ts="http://www.gnucash.org/XML/ts"
     xmlns:fs="http://www.gnucash.org/XML/fs"
     xmlns:bgt="http://www.gnucash.org/XML/bgt"
     xmlns:recurrence="http://www.gnucash.org/XML/recurrence"
     xmlns:lot="http://www.gnucash.org/XML/lot"
     xmlns:cust="http://www.gnucash.org/XML/cust"
     xmlns:job="http://www.gnucash.org/XML/job"
     xmlns:addr="http://www.gnucash.org/XML/addr"
     xmlns:owner="http://www.gnucash.org/XML/owner"
     xmlns:taxtable="http://www.gnucash.org/XML/taxtable"
     xmlns:tte="http://www.gnucash.org/XML/tte"
     xmlns:employee="http://www.gnucash.org/XML/employee"
     xmlns:order="http://www.gnucash.org/XML/order"
     xmlns:billterm="http://www.gnucash.org/XML/billterm"
     xmlns:bt-days="http://www.gnucash.org/XML/bt-days"
     xmlns:bt-prox="http://www.gnucash.org/XML/bt-prox"
     xmlns:invoice="http://www.gnucash.org/XML/invoice"
     xmlns:entry="http://www.gnucash.org/XML/entry"
     xmlns:vendor="http://www.gnucash.org/XML/vendor">
<gnc:count-data cd:type="account">$NUM</gnc:count-data>
<gnc:account version="2.0.0">
  <act:name>Root Account</act:name>
  <act:id type="guid">$ROOT</act:id>
  <act:type>ROOT</act:type>
  <act:commodity-scu>0</act:commodity-scu>
</gnc:account>
EOF
LAST=0
CURR=$(getuid);
CURRSUB=$CURR;

addkontenklasse() {
echo
echo -n "add kontenklasse $LAST";
cat >>"$OUT" <<EOF
<gnc:account version="2.0.0">
  <act:name>Kontenklasse $LAST</act:name>
  <act:id type="guid">$CURR</act:id>
  <act:type>ASSET</act:type>
  <act:commodity>
    <cmdty:space>ISO4217</cmdty:space>
    <cmdty:id>EUR</cmdty:id>
  </act:commodity>
  <act:commodity-scu>100</act:commodity-scu>
  <act:description>Erträge</act:description>
  <act:slots>
    <slot>
      <slot:key>placeholder</slot:key>
      <slot:value type="string">true</slot:value>
    </slot>
  </act:slots>
  <act:parent type="guid">$ROOT</act:parent>
</gnc:account>
EOF
echo " done";
}

addkontenklasse;

addkontengruppe() {
echo
echo -n "add kontengruppe $1";
cat >>"$OUT" <<EOF
<gnc:account version="2.0.0">
  <act:name>$ID $1</act:name>
  <act:id type="guid">$CURRSUB</act:id>
  <act:type>ASSET</act:type>
  <act:commodity>
    <cmdty:space>ISO4217</cmdty:space>
    <cmdty:id>EUR</cmdty:id>
  </act:commodity>
  <act:commodity-scu>100</act:commodity-scu>
  <act:description>$1</act:description>
  <act:slots>
    <slot>
      <slot:key>placeholder</slot:key>
      <slot:value type="string">true</slot:value>
    </slot>
  </act:slots>
  <act:parent type="guid">$CURR</act:parent>
</gnc:account>
EOF
echo " done";
}

addkonto() {
cat >>"$OUT" <<EOF
<gnc:account version="2.0.0">
  <act:name>$1 $2</act:name>
  <act:id type="guid">$(getuid)</act:id>
  <act:type>ASSET</act:type>
  <act:commodity>
    <cmdty:space>ISO4217</cmdty:space>
    <cmdty:id>EUR</cmdty:id>
  </act:commodity>
  <act:commodity-scu>100</act:commodity-scu>
  <act:description>$2</act:description>
  <act:code>$1</act:code>
  <act:parent type="guid">$CURRSUB</act:parent>
</gnc:account>
EOF
}

while (true); do
 LL=$REPLY
 read
 if [ "x$REPLY" = "x" ]; then
   echo
   echo "end of file after $LL";
   break;
 fi
 REPLY=$(echo "$REPLY" | sed 's/\s\+/ /g');
 KTOID=$(echo "$REPLY" | sed 's/ .*//');
 NAME=$(echo "$REPLY" | sed 's/^[0-9]\+ \+//');
 if [ -z "$NAME" ]; then
   NAME="dummy";
 fi
 #echo "$REPLY => $KTOID | $NAME";
 echo -n "$KTOID "
 if [ -z "$KTOID" ]; then
   CURRSUB=$(getuid);
   ID=$(expr $ID + 1);
   addkontengruppe "$NAME";
 else 
  if [ $KTOID -gt "$LAST"999 ]; then
   # new cat
   LAST=$(echo $KTOID | sed 's/\(.\).*/\1/');
   CURR=$(getuid);
   CURRSUB=$CURR;
   ID=0
   addkontenklasse;
  fi
  addkonto "$KTOID" "$NAME"; 
 fi
done < "$FILE"

echo "</gnc-v2>" >> "$OUT";
echo "done: written to $OUT"

