initialer commit
This commit is contained in:
commit
3714984af5
|
@ -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.
|
||||
|
|
@ -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}
|
|
@ -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.
|
||||
|
|
@ -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]
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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)
|
|
@ -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 New Issue