forked from berhsi/rechnung
qbi
df4a20e623
Das Zahlungsziel darf nicht an einem Wochenende liegen. Der Code prüft jetzt, ob es ein Wochenendtag ist und verlängert das Datum um zwei Tage.
321 lines
6.7 KiB
Bash
Executable file
321 lines
6.7 KiB
Bash
Executable file
#!/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.
|
|
|
|
set -u
|
|
set -e
|
|
|
|
# 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")
|
|
PDFLATEX_BIN=$(which pdflatex 2>/dev/null || echo "pdflatex")
|
|
RUBBER_BIN=$(which rubber 2>/dev/null || echo "rubber")
|
|
EXECUTABLES_TO_CHECK="$BC_BIN $TR_BIN $SED_BIN $CUT_BIN $TPUT_BIN $DATE_BIN $PDFLATEX_BIN $RUBBER_BIN"
|
|
|
|
GENPDF=""
|
|
if [ -x $RUBBER_BIN ]; then
|
|
GENPDF="$RUBBER_BIN -d "
|
|
else
|
|
GENPDF="$PDFLATEX_BIN -halt-on-error "
|
|
fi
|
|
|
|
|
|
# Variablen definieren
|
|
# --------------------
|
|
|
|
PROGRAMM_NAME=$0
|
|
PROGRAMM_VERSION="0.0.1"
|
|
VERBOSITY=0
|
|
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
|
|
RED="\\033[1;31m"
|
|
GREEN="\\033[1;32m"
|
|
YELLOW="\\033[1;33m"
|
|
BLUE="\\033[1;34m"
|
|
NORMAL="\\033[0;39m"
|
|
|
|
|
|
# Diverse Checks
|
|
# --------------
|
|
|
|
check_readable() {
|
|
|
|
printf "\n[+] Datei \"$1\" ist lesbar ..."
|
|
if [ -f "$1" ] && [ -r "$1" ]
|
|
then
|
|
print_ok
|
|
else
|
|
print_failed
|
|
quit 1
|
|
fi
|
|
}
|
|
|
|
check_binaries() {
|
|
|
|
local program=""
|
|
local binaries=$*
|
|
|
|
for program in $binaries; do
|
|
printf "\n[+] Suche nach Programm $program ..."
|
|
if [ ! -x "$program" ]; then
|
|
print_failed
|
|
printf "\n[-] Das Programm \"$program\" wird benötigt, aber nicht gefunden."
|
|
quit 3
|
|
else
|
|
print_ok
|
|
fi
|
|
done
|
|
}
|
|
|
|
is_option() (
|
|
|
|
local line="$*"
|
|
|
|
if [ "${line#*=}" != "$line" ]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
)
|
|
|
|
# Ausgaben im Terminal
|
|
# --------------------
|
|
|
|
print_failed() {
|
|
|
|
if [ "$COLORED_OUTPUT" -eq 1 ]; then
|
|
printf "$RED Failed$NORMAL"
|
|
else
|
|
printf " Failed"
|
|
fi
|
|
}
|
|
|
|
print_ok() {
|
|
|
|
if [ "$COLORED_OUTPUT" -eq 1 ]; then
|
|
printf "$GREEN OK$NORMAL"
|
|
else
|
|
printf " OK"
|
|
fi
|
|
}
|
|
|
|
print_warn() {
|
|
|
|
local msg=$*
|
|
|
|
if [ "$COLORED_OUTPUT" -eq 1 ]; then
|
|
echo -e "$YELLOW[-]$NORMAL $msg"
|
|
else
|
|
echo -e "[-] $msg"
|
|
fi
|
|
}
|
|
|
|
# Whitespaces entfernen
|
|
# ---------------------
|
|
|
|
trim_line() {
|
|
|
|
set -f
|
|
set -- $*
|
|
LINE_BUFFER=$(printf '%s' "$*")
|
|
set +f
|
|
}
|
|
|
|
trim_key() {
|
|
|
|
set -f
|
|
set -- $*
|
|
KEY_BUFFER=$(printf '%s' "$*")
|
|
set +f
|
|
}
|
|
|
|
trim_value() {
|
|
|
|
set -f
|
|
set -- $*
|
|
VALUE_BUFFER=$(printf '%s' "$*")
|
|
set +f
|
|
}
|
|
|
|
|
|
reset_values() {
|
|
|
|
echo -e "\n[+] Initialisiere Felder für Rechnung neu."
|
|
LINE_BUFFER=""
|
|
KEY_BUFFER=""
|
|
VALUE_BUFFER=""
|
|
ERROR=0
|
|
KUNDE=""
|
|
ADRESSE=""
|
|
ANREDE=""
|
|
ANZAHL=""
|
|
POSITION=""
|
|
SHORT=""
|
|
BETRAG=""
|
|
LFDNR=""
|
|
}
|
|
|
|
set_value() {
|
|
|
|
local key=$(echo "$*" | $CUT_BIN -d "=" -f1)
|
|
local value=$(echo "$*" | $CUT_BIN -d "=" -f2)
|
|
|
|
trim_key $key
|
|
trim_value $value
|
|
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() {
|
|
|
|
local dead_days="14"
|
|
if [ $(date +%u) -gt 5 ]; then
|
|
dead_days="16"
|
|
fi
|
|
|
|
local month_ascii=$(date '+%B')
|
|
local inv_day=$(date '+%j')
|
|
local inv_date=$(date '+%Y%m%d')
|
|
local inv_dead=$(date -d "+${dead_days}days" +%d.%m.%Y)
|
|
local rechnungsnummer="$inv_date-$LFDNR"
|
|
local subject="Rechnung zu $SHORT"
|
|
local filename="$(date '+%Y%m%d')_Rechnung_$(echo "$month_ascii")_$(echo "$KUNDE" | $TR_BIN " " "_").ltx"
|
|
local buffer="$KUNDE; $ADRESSE"
|
|
local anschrift="$(echo "$buffer" | sed 's/; /\\\\\\\\\\\\\\ /g')"
|
|
|
|
echo "[+] Erstelle Rechnung: $filename"
|
|
echo -n "s!#SUBJECT#!" >$SEDFILE; echo "$subject!" >>$SEDFILE
|
|
echo -n "s!#ANREDE#!" >>$SEDFILE; echo "$ANREDE!" >>$SEDFILE
|
|
echo -n "s!#ANSCHRIFT#!" >>$SEDFILE; echo "$anschrift!" >>$SEDFILE
|
|
echo -n "s!#RECHNUNGSNUMMER#!" >>$SEDFILE; echo "$rechnungsnummer!" >>$SEDFILE
|
|
echo -n "s!#ANZAHL#!" >>$SEDFILE; echo "$ANZAHL!" >>$SEDFILE
|
|
echo -n "s!#POSITION#!" >>$SEDFILE; echo "$POSITION!" >>$SEDFILE
|
|
echo -n "s!#BETRAG#!" >>$SEDFILE; echo "$BETRAG!" >>$SEDFILE
|
|
echo -n "s!#DEADLINE#!" >>$SEDFILE; echo "$inv_dead!" >>$SEDFILE
|
|
cp $TEMPLATEFILE $filename
|
|
$SED_BIN -i -f $SEDFILE $filename
|
|
$GENPDF $filename
|
|
if [ -x $RUBBER_BIN ]; then
|
|
$RUBBER_BIN --clean $filename
|
|
fi
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "[+] Rechnung erfolgreich erstellt"
|
|
else
|
|
echo "[-] Rechnung fehlgeschlagen"
|
|
fi
|
|
}
|
|
|
|
proced_ini_line() {
|
|
|
|
local line=$*
|
|
local first=$(echo "$line" | cut -c1-1)
|
|
|
|
# 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
|
|
is_option $line
|
|
if [ $? -eq 0 ]
|
|
then
|
|
set_value $line
|
|
else
|
|
print_warn "Invalid syntax: $line"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
quit() {
|
|
printf "\n$BLUE"
|
|
printf "[-] Exit$NORMAL\n"
|
|
exit $1
|
|
}
|
|
|
|
|
|
# --- Programmstart --- #
|
|
# --------------------- #
|
|
echo "==================="
|
|
echo "= Rechnung v$PROGRAMM_VERSION ="
|
|
echo "==================="
|
|
|
|
# Verschiedene Basic Checks
|
|
if [ -n $NUMBER_OF_COLORS ] && [ "$NUMBER_OF_COLORS" -ge 8 ]; then
|
|
COLORED_OUTPUT=1
|
|
fi
|
|
|
|
if [ $(id -u) -eq 0 ]; then
|
|
echo "$0: Das Skript darf nicht als Root ausgeführt werden."
|
|
exit 1
|
|
fi
|
|
check_binaries $EXECUTABLES_TO_CHECK
|
|
check_readable $RECHNUNGSFILE
|
|
check_readable $TEMPLATEFILE
|
|
printf "\n"
|
|
|
|
# Kundendatei einlesen und rechnungen erstellen
|
|
while IFS= read -r rawline
|
|
do
|
|
trim_line $rawline
|
|
proced_ini_line $LINE_BUFFER
|
|
done <$RECHNUNGSFILE
|
|
|
|
|