initialer commit

This commit is contained in:
bernd 2021-05-03 12:56:43 +02:00
commit 3714984af5
7 changed files with 472 additions and 0 deletions

11
TODO.txt Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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}