initialer commit
This commit is contained in:
commit
3714984af5
11
TODO.txt
Normal file
11
TODO.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
TODO
|
||||||
|
----
|
||||||
|
|
||||||
|
* Ausgabe (besonders farbige) im Terminal verbessern.
|
||||||
|
* Parameterübergabe um einzelne Kunden zu bearbeiten.
|
||||||
|
* Parameter für den Versand der Rechnung.
|
||||||
|
* Parameterübergabe für ein Ausgabeverzeichnis.
|
||||||
|
* Ansonsten vielleicht PDF verschieben
|
||||||
|
* Nicht mehr benötigte Dateien (*.log, *.aux, etc.) der Rechnung löschen.
|
||||||
|
* Den Begleittext dürch eine Variable ersetzen.
|
||||||
|
|
9
octorech.lco
Normal file
9
octorech.lco
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
\setkomavar{fromname}{OctoPi.Consulting}
|
||||||
|
\setkomavar{fromaddress}{Zitzmannstr.\,15\\07743 Jena}
|
||||||
|
\setkomavar{frommobilephone}[\faMobilePhone~]{01\,63 / 615 61 98}
|
||||||
|
\setkomavar{fromurl}{https://octopi.consulting/}
|
||||||
|
\setkomavar{fromemail}[\faEnvelopeO~]{rechnung@octopi.consulting}
|
||||||
|
\setkomavar{place}{Jena}
|
||||||
|
\setkomavar{placeseparator}{, }
|
||||||
|
\setkomavar{signature}{Jens Kubieziel}
|
||||||
|
\setkomavar{frombank}{Commerzbank AG Jena}
|
21
readme.txt
Normal file
21
readme.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
rechnung.sh
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Erstellt aus einer Kundendatei Rechnungen.
|
||||||
|
|
||||||
|
Beschreibung
|
||||||
|
------------
|
||||||
|
|
||||||
|
Aus einer Kundendatei (rechnung.ini) werden blockweise Kundendaten gelesen
|
||||||
|
und in Variablen gespeichert. Am Ende des Blocks wird eine Kopie des
|
||||||
|
Templates (template.ltx) erstellt und die Platzhalter in der Kopie durch die
|
||||||
|
entsprechenden Variablen erstellt. Diese Kopie wird zweimal mittels pdflatex
|
||||||
|
übersetzt.
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
Kopieren Sie die Dateien template.ltx, octorech.lco, rechnung.ini und
|
||||||
|
rechnung.sh in ein Verzeichnis Ihrer Wahl. Passen Sie die Dateien
|
||||||
|
rechnung.ini und octorech.lco an Ihre Bedürfnisse an.
|
||||||
|
|
36
rechnung.ini
Normal file
36
rechnung.ini
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# file: rechnung.ini
|
||||||
|
#
|
||||||
|
|
||||||
|
[start]
|
||||||
|
kunde=Firma A
|
||||||
|
adresse1= Strasse A; 012345 Stadt A
|
||||||
|
anrede=Sehr geehrte Damen und Herren,
|
||||||
|
anzahl=1
|
||||||
|
position=Dienstleistung A mit etwas mehr Text
|
||||||
|
short=Leistung A
|
||||||
|
betrag=100
|
||||||
|
lfdnr=1
|
||||||
|
[ende]
|
||||||
|
|
||||||
|
[start]
|
||||||
|
kunde=Firma B
|
||||||
|
adresse=Personalabteilung; Frau B; Strasse B; 01234 Stadt B
|
||||||
|
anrede=Sehr geehrte Frau B,
|
||||||
|
anzahl=1
|
||||||
|
position=Dienstleistung B mit mehr noch viel Text
|
||||||
|
short=Leistung B
|
||||||
|
betrag=99
|
||||||
|
lfdnr=1
|
||||||
|
[ende]
|
||||||
|
|
||||||
|
[start]
|
||||||
|
kunde=Herr C
|
||||||
|
adresse=Strasse C; 12345 Stadt C
|
||||||
|
anrede=Sehr geehrter Herr C,
|
||||||
|
anzahl=1
|
||||||
|
position=Dienstleistung C
|
||||||
|
short=Leistung C
|
||||||
|
betrag=110
|
||||||
|
lfdnr=1
|
||||||
|
[ende]
|
||||||
|
|
302
rechnung.sh
Executable file
302
rechnung.sh
Executable file
|
@ -0,0 +1,302 @@
|
||||||
|
#!/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 -o posix
|
||||||
|
|
||||||
|
# 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")
|
||||||
|
LATEX_BIN=$(which pdflatex 2>/dev/null || echo "pdflatex")
|
||||||
|
EXECUTABLES_TO_CHECK="$BC_BIN $TR_BIN $SED_BIN $CUT_BIN $TPUT_BIN $DATE_BIN $LATEX_BIN"
|
||||||
|
|
||||||
|
# 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 month_ascii=$(date '+%B')
|
||||||
|
local inv_day=$(date '+%j')
|
||||||
|
local inv_date=$(date '+%Y%m%d')
|
||||||
|
local inv_dead=$(date -d '+14days' +%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
|
||||||
|
$LATEX_BIN -halt-on-error $filename
|
||||||
|
$LATEX_BIN -halt-on-error $filename
|
||||||
|
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 [ "$EUID" -eq 0 ]; then
|
||||||
|
echo "$0: Das Skript muss nicht als Root ausfegührt werden."
|
||||||
|
quit 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
|
||||||
|
|
||||||
|
|
15
requirements.txt
Normal file
15
requirements.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
Abhängigkeiten von rechnung.sh:
|
||||||
|
|
||||||
|
a) rechnung.sh
|
||||||
|
|
||||||
|
1.) bc
|
||||||
|
2.) tr
|
||||||
|
3.) sed
|
||||||
|
4.) date
|
||||||
|
5.) pdflatex
|
||||||
|
6.) optional tput für farbe im terminal
|
||||||
|
|
||||||
|
b) pdflatex
|
||||||
|
|
||||||
|
1.) fontawesome.sty
|
||||||
|
2.) rechnung.sty (https://github.com/tomka/rechnung)
|
78
template.ltx
Normal file
78
template.ltx
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
\documentclass[ngerman,headsepline=off,%
|
||||||
|
parskip=half,%
|
||||||
|
%DIV=calc,%
|
||||||
|
% Was kommt in den Briefkopf und in die Anschrift
|
||||||
|
fromalign=right,%% Plazierung des Briefkopfs
|
||||||
|
frommobilephone=on,%% Telefonnummer im Absender
|
||||||
|
fromrule=aftername,%% Linie im Absender (aftername, afteraddress)
|
||||||
|
fromfax=off,%% Faxnummer
|
||||||
|
fromemail=on,%% Emailadresse
|
||||||
|
fromurl=off,%% Homepage
|
||||||
|
fromlogo=off,%% Firmenlogo
|
||||||
|
addrfield=on,%% Adressfeld fuer Fensterkuverts
|
||||||
|
backaddress=on,%% ...und Absender im Fenster
|
||||||
|
subject=beforeopening,%% Plazierung der Betreffzeile
|
||||||
|
locfield=narrow,%% zusaetzliches Feld fuer Absender
|
||||||
|
foldmarks=on,%% Faltmarken setzen
|
||||||
|
numericaldate=off,%% Datum numerisch ausgeben
|
||||||
|
refline=narrow,%% Geschaeftszeile im Satzspiegel
|
||||||
|
firstfoot=on,%% Footerbereich
|
||||||
|
octorech]{scrlttr2}
|
||||||
|
\usepackage[ngerman]{babel}
|
||||||
|
\usepackage[utf8]{inputenc}
|
||||||
|
\usepackage[T1]{fontenc}
|
||||||
|
\usepackage{lmodern}
|
||||||
|
\usepackage{charter}
|
||||||
|
\usepackage{eurosym}
|
||||||
|
\usepackage{tabularx}
|
||||||
|
\usepackage{fontawesome}
|
||||||
|
\usepackage{rechnung}
|
||||||
|
\usepackage{csquotes}
|
||||||
|
\let\raggedsignature=\raggedright
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\LoadLetterOption{DIN}
|
||||||
|
\makeatletter
|
||||||
|
\@addtoplength[-]{firstfootvpos}{.75cm} % Fuß ein Stück nach oben
|
||||||
|
\makeatother
|
||||||
|
\setkomavar{firstfoot}{\footnotesize%
|
||||||
|
\rule[3pt]{\textwidth}{.4pt} \\
|
||||||
|
\begin{tabularx}{\textwidth}{XXl}
|
||||||
|
OctoPi.Consulting & Amtsgericht Jena & \textbf{Bankverbindung}\\
|
||||||
|
Jens Kubieziel & USt.-IdNr.: & IBAN: DE50 8204 0000\\
|
||||||
|
Zitzmannstr.\,15 & DE298453137 & \hfill{}0264 3955 00\\
|
||||||
|
07743 Jena & & Commerzbank AG Jena
|
||||||
|
\end{tabularx}%
|
||||||
|
}
|
||||||
|
|
||||||
|
\begin{letter}{#ANSCHRIFT#}
|
||||||
|
|
||||||
|
%% Rechnungsnummer im Format YYYYMMDD--LFDNR
|
||||||
|
\setkomavar{invoice}{#RECHNUNGSNUMMER#}
|
||||||
|
%% Betreff der Rechnung
|
||||||
|
\setkomavar{subject}{#SUBJECT#}
|
||||||
|
%% Anrede
|
||||||
|
\opening{#ANREDE#}
|
||||||
|
|
||||||
|
wie besprochen, stelle ich für die Durchführung des Seminars
|
||||||
|
folgende Rechnung.
|
||||||
|
|
||||||
|
|
||||||
|
\begin{Rechnung}[B]
|
||||||
|
\TrennerAus
|
||||||
|
\Waehrung{\euro}
|
||||||
|
\Artikel{#ANZAHL#}{#POSITION#}{#BETRAG#}
|
||||||
|
\end{Rechnung}
|
||||||
|
|
||||||
|
Ich bitte Sie, den
|
||||||
|
Rechnungsbetrag bis zum #DEADLINE# auf das unten genannte Konto
|
||||||
|
zu überweisen.
|
||||||
|
|
||||||
|
Ich danke Ihnen für diesen Auftrag und würde mich freuen, bald wieder
|
||||||
|
für Sie tätig zu werden.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\closing{Mit freundlichen Grüßen}
|
||||||
|
\end{letter}
|
||||||
|
\end{document}
|
Loading…
Reference in a new issue