2021-05-03 12:56:43 +02:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
# file: rechnung.sh
|
|
|
|
# date: 02.05.2021
|
|
|
|
# user: bernd@nr18.space
|
|
|
|
# desc: Liest verschiedene Kunden und Dienstleistungen aus der Datei
|
|
|
|
# rechnung.ini und erstellt daraus Rechnungen mit Hilfe eines
|
|
|
|
# Latex-Templates.
|
|
|
|
|
2021-05-03 14:21:39 +02:00
|
|
|
set -u
|
|
|
|
set -e
|
2021-05-03 12:56:43 +02:00
|
|
|
|
|
|
|
# Benötigte Programme
|
|
|
|
# -------------------
|
|
|
|
|
|
|
|
TR_BIN=$(which tr 2>/dev/null || echo "tr")
|
|
|
|
BC_BIN=$(which bc 2>/dev/null || echo "bc")
|
|
|
|
SED_BIN=$(which sed 2>/dev/null || echo "sed")
|
|
|
|
CUT_BIN=$(which cut 2>/dev/null || echo "cut")
|
|
|
|
DATE_BIN=$(which date 2>/dev/null || echo "date")
|
|
|
|
TPUT_BIN=$(which tput 2>/dev/null || echo "tput")
|
2021-05-03 19:19:25 +02:00
|
|
|
PDFLATEX_BIN=$(which pdflatex 2>/dev/null || echo "pdflatex")
|
2021-05-03 19:31:14 +02:00
|
|
|
RUBBER_BIN=$(which rubber 2>/dev/null || echo "rubber")
|
2021-05-03 23:07:45 +02:00
|
|
|
# Nicht auf rubber prüfen; Programm ist optional
|
|
|
|
EXECUTABLES_TO_CHECK="$BC_BIN $TR_BIN $SED_BIN $CUT_BIN $TPUT_BIN $DATE_BIN $PDFLATEX_BIN"
|
2021-05-03 19:31:14 +02:00
|
|
|
|
|
|
|
GENPDF=""
|
2021-05-03 21:49:13 +02:00
|
|
|
if [ -x "$RUBBER_BIN" ]; then
|
2021-05-03 19:31:14 +02:00
|
|
|
GENPDF="$RUBBER_BIN -d "
|
|
|
|
else
|
|
|
|
GENPDF="$PDFLATEX_BIN -halt-on-error "
|
|
|
|
fi
|
|
|
|
|
2021-05-03 12:56:43 +02:00
|
|
|
|
|
|
|
# Variablen definieren
|
|
|
|
# --------------------
|
|
|
|
|
|
|
|
PROGRAMM_NAME=$0
|
|
|
|
PROGRAMM_VERSION="0.0.1"
|
2021-05-03 22:57:06 +02:00
|
|
|
#VERBOSITY=0
|
2021-05-03 12:56:43 +02:00
|
|
|
RECHNUNGSFILE="rechnung.ini"
|
|
|
|
TEMPLATEFILE="template.ltx"
|
|
|
|
SEDFILE="sed.txt"
|
|
|
|
LINE_BUFFER=""
|
|
|
|
KEY_BUFFER=""
|
|
|
|
VALUE_BUFFER=""
|
|
|
|
ERROR=0
|
|
|
|
KUNDE=""
|
|
|
|
ADRESSE=""
|
|
|
|
ANREDE=""
|
|
|
|
ANZAHL=""
|
|
|
|
POSITION=""
|
|
|
|
SHORT=""
|
|
|
|
BETRAG=""
|
|
|
|
LFDNR=""
|
|
|
|
|
|
|
|
# Farben definieren
|
|
|
|
# -----------------
|
|
|
|
|
|
|
|
NUMBER_OF_COLORS=$($TPUT_BIN colors)
|
|
|
|
COLORED_OUTPUT=0
|
2021-05-03 22:44:03 +02:00
|
|
|
RED="$(tput bold)$(tput setaf 1)"
|
|
|
|
GREEN="$(tput bold)$(tput setaf 2)"
|
|
|
|
YELLOW="$(tput bold)$(tput setaf 3)"
|
|
|
|
BLUE="$(tput bold)$(tput setaf 4)"
|
|
|
|
NORMAL="$(tput bold)$(tput sgr0)"
|
2021-05-03 12:56:43 +02:00
|
|
|
|
|
|
|
|
|
|
|
# Diverse Checks
|
|
|
|
# --------------
|
|
|
|
|
|
|
|
check_readable() {
|
|
|
|
|
2021-05-03 22:43:20 +02:00
|
|
|
printf "\n[+] Datei %s ist lesbar ..." "$1"
|
2021-05-03 12:56:43 +02:00
|
|
|
if [ -f "$1" ] && [ -r "$1" ]
|
|
|
|
then
|
|
|
|
print_ok
|
|
|
|
else
|
|
|
|
print_failed
|
|
|
|
quit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
check_binaries() {
|
|
|
|
|
2021-05-03 21:41:53 +02:00
|
|
|
program=""
|
|
|
|
binaries=$*
|
2021-05-03 12:56:43 +02:00
|
|
|
|
|
|
|
for program in $binaries; do
|
2021-05-03 22:43:20 +02:00
|
|
|
printf "\n[+] Suche nach Programm %s ..." "$program"
|
2021-05-03 12:56:43 +02:00
|
|
|
if [ ! -x "$program" ]; then
|
|
|
|
print_failed
|
2021-05-03 22:43:20 +02:00
|
|
|
printf "\n[-] Das Programm \"%s\" wird benötigt, aber nicht gefunden." "$program"
|
2021-05-03 12:56:43 +02:00
|
|
|
quit 3
|
|
|
|
else
|
|
|
|
print_ok
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
is_option() (
|
|
|
|
|
2021-05-03 21:41:53 +02:00
|
|
|
line="$*"
|
2021-05-03 12:56:43 +02:00
|
|
|
|
|
|
|
if [ "${line#*=}" != "$line" ]; then
|
|
|
|
return 0
|
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
)
|
|
|
|
|
|
|
|
# Ausgaben im Terminal
|
|
|
|
# --------------------
|
|
|
|
|
|
|
|
print_failed() {
|
|
|
|
|
|
|
|
if [ "$COLORED_OUTPUT" -eq 1 ]; then
|
2021-05-03 22:43:20 +02:00
|
|
|
printf "%s Failed%s" "$RED" "$NORMAL"
|
2021-05-03 12:56:43 +02:00
|
|
|
else
|
|
|
|
printf " Failed"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
print_ok() {
|
|
|
|
|
|
|
|
if [ "$COLORED_OUTPUT" -eq 1 ]; then
|
2021-05-03 22:43:20 +02:00
|
|
|
printf "%s OK%s" "$GREEN" "$NORMAL"
|
2021-05-03 12:56:43 +02:00
|
|
|
else
|
|
|
|
printf " OK"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
print_warn() {
|
|
|
|
|
2021-05-03 21:41:53 +02:00
|
|
|
msg=$*
|
2021-05-03 12:56:43 +02:00
|
|
|
|
|
|
|
if [ "$COLORED_OUTPUT" -eq 1 ]; then
|
2021-05-03 22:57:47 +02:00
|
|
|
echo "${YELLOW}[-]$NORMAL $msg"
|
2021-05-03 12:56:43 +02:00
|
|
|
else
|
2021-05-03 22:43:20 +02:00
|
|
|
echo "[-] $msg"
|
2021-05-03 12:56:43 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Whitespaces entfernen
|
|
|
|
# ---------------------
|
|
|
|
|
|
|
|
trim_line() {
|
|
|
|
|
|
|
|
set -f
|
2021-05-03 21:51:45 +02:00
|
|
|
set -- "$*"
|
2021-05-03 12:56:43 +02:00
|
|
|
LINE_BUFFER=$(printf '%s' "$*")
|
|
|
|
set +f
|
|
|
|
}
|
|
|
|
|
|
|
|
trim_key() {
|
|
|
|
|
|
|
|
set -f
|
2021-05-03 21:51:45 +02:00
|
|
|
set -- "$*"
|
2021-05-03 12:56:43 +02:00
|
|
|
KEY_BUFFER=$(printf '%s' "$*")
|
|
|
|
set +f
|
|
|
|
}
|
|
|
|
|
|
|
|
trim_value() {
|
|
|
|
|
|
|
|
set -f
|
2021-05-03 21:51:45 +02:00
|
|
|
set -- "$*"
|
2021-05-03 12:56:43 +02:00
|
|
|
VALUE_BUFFER=$(printf '%s' "$*")
|
|
|
|
set +f
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
reset_values() {
|
|
|
|
|
2021-05-03 22:43:20 +02:00
|
|
|
printf "\n[+] Initialisiere Felder für Rechnung neu."
|
2021-05-03 12:56:43 +02:00
|
|
|
LINE_BUFFER=""
|
|
|
|
KEY_BUFFER=""
|
|
|
|
VALUE_BUFFER=""
|
|
|
|
ERROR=0
|
|
|
|
KUNDE=""
|
|
|
|
ADRESSE=""
|
|
|
|
ANREDE=""
|
|
|
|
ANZAHL=""
|
|
|
|
POSITION=""
|
|
|
|
SHORT=""
|
|
|
|
BETRAG=""
|
|
|
|
LFDNR=""
|
|
|
|
}
|
|
|
|
|
|
|
|
set_value() {
|
|
|
|
|
2021-05-03 21:41:53 +02:00
|
|
|
key=$(echo "$*" | $CUT_BIN -d "=" -f1)
|
|
|
|
value=$(echo "$*" | $CUT_BIN -d "=" -f2)
|
2021-05-03 12:56:43 +02:00
|
|
|
|
2021-05-03 21:51:45 +02:00
|
|
|
trim_key "$key"
|
|
|
|
trim_value "$value"
|
2021-05-03 12:56:43 +02:00
|
|
|
case $KEY_BUFFER in
|
|
|
|
kunde) KUNDE="$VALUE_BUFFER";;
|
|
|
|
adresse) ADRESSE="$VALUE_BUFFER";;
|
|
|
|
anrede) ANREDE="$VALUE_BUFFER";;
|
|
|
|
anzahl) ANZAHL="$VALUE_BUFFER";;
|
|
|
|
position) POSITION="$VALUE_BUFFER";;
|
|
|
|
betrag) BETRAG="$VALUE_BUFFER";;
|
|
|
|
lfdnr) LFDNR="$VALUE_BUFFER";;
|
|
|
|
short) SHORT="$VALUE_BUFFER";;
|
|
|
|
*) print_warn "Unbekanntes Feld: $KEY_BUFFER"; ERROR=1;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
make_invoice() {
|
|
|
|
|
2021-05-03 21:41:53 +02:00
|
|
|
dead_days="14"
|
2021-05-03 22:43:20 +02:00
|
|
|
if [ "$(date +%u)" -gt 5 ]; then
|
2021-05-03 19:49:57 +02:00
|
|
|
dead_days="16"
|
|
|
|
fi
|
|
|
|
|
2021-05-03 21:41:53 +02:00
|
|
|
month_ascii=$(date '+%B')
|
2021-05-03 22:57:06 +02:00
|
|
|
# inv_day=$(date '+%j')
|
2021-05-03 21:41:53 +02:00
|
|
|
inv_date=$(date '+%Y%m%d')
|
|
|
|
inv_dead=$(date -d "+${dead_days}days" '+%d.\\\\,%m.\\\\,%Y')
|
|
|
|
rechnungsnummer="$inv_date--$LFDNR"
|
|
|
|
subject="Rechnung zu $SHORT"
|
2021-05-03 23:18:47 +02:00
|
|
|
filename="$(date '+%Y%m%d')_Rechnung_${month_ascii}_$(echo "$KUNDE" | $TR_BIN " " "_").ltx"
|
2021-05-03 21:41:53 +02:00
|
|
|
buffer="$KUNDE; $ADRESSE"
|
|
|
|
anschrift="$(echo "$buffer" | sed 's/; /\\\\\\\\\\\\\\ /g')"
|
2021-05-03 12:56:43 +02:00
|
|
|
|
2021-05-03 23:20:44 +02:00
|
|
|
printf "\n[+] Erstelle Rechnung: %s" "$filename"
|
2021-05-03 23:17:35 +02:00
|
|
|
{
|
|
|
|
printf "s!#SUBJECT#!%s!\n" "$subject"
|
|
|
|
printf "s!#ANREDE#!%s!\n" "$ANREDE"
|
|
|
|
printf "s!#ANSCHRIFT#!%s!\n" "$anschrift"
|
|
|
|
printf "s!#RECHNUNGSNUMMER#!%s!\n" "$rechnungsnummer"
|
|
|
|
printf "s!#ANZAHL#!%s!\n" "$ANZAHL"
|
|
|
|
printf "s!#POSITION#!%s!\n" "$POSITION"
|
|
|
|
printf "s!#BETRAG#!%s!\n" "$BETRAG"
|
|
|
|
printf "s!#DEADLINE#!%s!\n" "$inv_dead"
|
|
|
|
} >>$SEDFILE
|
2021-05-03 21:49:13 +02:00
|
|
|
cp "$TEMPLATEFILE" "$filename"
|
|
|
|
$SED_BIN -i -f "$SEDFILE" "$filename"
|
2021-05-03 19:31:14 +02:00
|
|
|
|
2021-05-03 23:06:20 +02:00
|
|
|
if ! $GENPDF "$filename"; then
|
2021-05-03 12:56:43 +02:00
|
|
|
echo "[-] Rechnung fehlgeschlagen"
|
2021-05-03 23:06:20 +02:00
|
|
|
else
|
|
|
|
echo "[+] Rechnung erfolgreich erstellt"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -x "$RUBBER_BIN" ]; then
|
|
|
|
"$RUBBER_BIN" --clean "$filename"
|
2021-05-03 12:56:43 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
proced_ini_line() {
|
|
|
|
|
2021-05-03 21:41:53 +02:00
|
|
|
line=$*
|
|
|
|
first=$(echo "$line" | cut -c1-1)
|
2021-05-03 12:56:43 +02:00
|
|
|
|
|
|
|
# leerzeilen ignorieren
|
|
|
|
if [ "$line" = "" ]; then
|
|
|
|
return
|
|
|
|
|
|
|
|
# kommentarzeilen ignorieren
|
|
|
|
elif [ "$first" = "#" ]; then
|
|
|
|
return
|
|
|
|
|
|
|
|
# start einer neuen rechnung
|
|
|
|
elif [ "$line" = "[start]" ]; then
|
|
|
|
reset_values
|
|
|
|
|
|
|
|
# ende einer rechnung
|
|
|
|
elif [ "$line" = "[ende]" ]; then
|
|
|
|
if [ $ERROR -ne 0 ]; then
|
|
|
|
print_warn "Kunde \"$KUNDE\" enthält einen Fehler. Erstelle keine Rechung."
|
|
|
|
return
|
|
|
|
else
|
|
|
|
make_invoice
|
|
|
|
fi
|
|
|
|
|
|
|
|
# alle anderen zeilen
|
|
|
|
else
|
2021-05-03 23:06:20 +02:00
|
|
|
|
|
|
|
if is_option "$line"
|
2021-05-03 12:56:43 +02:00
|
|
|
then
|
2021-05-03 21:49:13 +02:00
|
|
|
set_value "$line"
|
2021-05-03 12:56:43 +02:00
|
|
|
else
|
|
|
|
print_warn "Invalid syntax: $line"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
quit() {
|
2021-05-03 22:43:20 +02:00
|
|
|
printf "\n"
|
2021-05-03 23:06:20 +02:00
|
|
|
printf "%s" "$BLUE"
|
2021-05-03 22:43:20 +02:00
|
|
|
printf "[-] Exit%s\n" "$NORMAL"
|
2021-05-03 21:49:13 +02:00
|
|
|
exit 1
|
2021-05-03 12:56:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# --- Programmstart --- #
|
|
|
|
# --------------------- #
|
|
|
|
echo "==================="
|
2021-05-03 22:55:50 +02:00
|
|
|
echo "= $PROGRAMM_NAME v$PROGRAMM_VERSION ="
|
2021-05-03 12:56:43 +02:00
|
|
|
echo "==================="
|
|
|
|
|
|
|
|
# Verschiedene Basic Checks
|
2021-05-03 21:49:13 +02:00
|
|
|
if [ -n "$NUMBER_OF_COLORS" ] && [ "$NUMBER_OF_COLORS" -ge 8 ]; then
|
2021-05-03 12:56:43 +02:00
|
|
|
COLORED_OUTPUT=1
|
|
|
|
fi
|
2021-05-03 14:24:49 +02:00
|
|
|
|
2021-05-03 21:51:45 +02:00
|
|
|
if [ "$(id -u)" -eq 0 ]; then
|
2021-05-03 14:08:07 +02:00
|
|
|
echo "$0: Das Skript darf nicht als Root ausgeführt werden."
|
2021-05-03 14:28:04 +02:00
|
|
|
exit 1
|
2021-05-03 12:56:43 +02:00
|
|
|
fi
|
2021-05-03 21:49:13 +02:00
|
|
|
check_binaries "$EXECUTABLES_TO_CHECK"
|
|
|
|
check_readable "$RECHNUNGSFILE"
|
|
|
|
check_readable "$TEMPLATEFILE"
|
2021-05-03 12:56:43 +02:00
|
|
|
printf "\n"
|
|
|
|
|
|
|
|
# Kundendatei einlesen und rechnungen erstellen
|
|
|
|
while IFS= read -r rawline
|
|
|
|
do
|
2021-05-03 21:49:13 +02:00
|
|
|
trim_line "$rawline"
|
|
|
|
proced_ini_line "$LINE_BUFFER"
|
|
|
|
done < "$RECHNUNGSFILE"
|
2021-05-03 12:56:43 +02:00
|
|
|
|
|
|
|
|