add Teckids utility suite, by request from Natureshadow
[shellsnippets/shellsnippets.git] / mksh / teckids / mkrechnung
1 # -*- mode: sh -*-
2 #-
3 # Copyright © 2014, 2016, 2017
4 #       Dominik George <dominik.george@teckids.org>
5 # Copyright © 2014, 2015, 2016, 2017
6 #       Thorsten Glaser <thorsten.glaser@teckids.org>
7 # Copyright © 2016
8 #       Niklas Bildhauer <niklas.bildhauer@teckids.org>
9 #
10 # Provided that these terms and disclaimer and all copyright notices
11 # are retained or reproduced in an accompanying document, permission
12 # is granted to deal in this work without restriction, including un‐
13 # limited rights to use, publicly perform, distribute, sell, modify,
14 # merge, give away, or sublicence.
15 #
16 # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
17 # the utmost extent permitted by applicable law, neither express nor
18 # implied; without malicious intent or gross negligence. In no event
19 # may a licensor, author or contributor be held liable for indirect,
20 # direct, other damage, loss, or other issues arising in any way out
21 # of dealing in the work, even if advised of the possibility of such
22 # damage or existence of a defect, except proven that it results out
23 # of said person’s immediate fault when using the work as intended.
24
25 teckids_sourcing_wrapper=1
26 . "$(dirname "$0")/teckids"
27
28 function split_addr {
29         local a=$addr s=$1
30
31         while [[ $a = *', '* ]]; do
32                 print -r -- "${a%%, *}$s"
33                 a=${a#*, }
34         done
35         [[ -n $a ]] && print -r -- "$a"
36 }
37
38 cd "$ROOT/finance/rechnungen"
39
40
41 rg=$(<rgnr.txt)
42 if [[ $rg != +([0-9]) ]]; then
43         print -ru2 "E: rgnr '$rg' ungültig!"
44         exit 1
45 fi
46 # Führende Nullen nicht oktal interpretieren. POSIX will das… ☹
47 rg=$((10#$rg))
48
49 # 1. Volle Anschrift des Empfängers (kann auch unvolständig sein) einlesen
50
51 reqanschrift=1
52 [[ -s $TECKIDS_CACHE_DIR/last_whois ]] || reqanschrift=2
53 #"${VISUAL:-${EDITOR:-vi}}"
54 dopersonenkonto=1
55 while (( reqanschrift )); do
56         case $reqanschrift {
57         (4)
58                 split_addr "" >"$ROOT"/.tmp/mkrechnung
59                 "${VISUAL:-${EDITOR:-vi}}" "$ROOT"/.tmp/mkrechnung
60                 addr=
61                 while IFS= read -r line; do
62                         addr+=", $line"
63                 done <"$ROOT"/.tmp/mkrechnung
64                 rm -f "$ROOT"/.tmp/mkrechnung
65                 addr=${addr#, }
66                 reqanschrift=3
67                 ;;
68         (3)
69                 print -u2 Bitte bestätigen, 0 für Neueingabe
70                 select x in "$addr" "(im Texteditor bearbeiten)"; do
71                         if [[ $REPLY = 0 ]]; then
72                                 reqanschrift=2
73                                 break
74                         fi
75                         if [[ $REPLY = 1 ]]; then
76                                 reqanschrift=0
77                                 break
78                         fi
79                         if [[ $REPLY = 2 ]]; then
80                                 reqanschrift=4
81                                 break
82                         fi
83                 done
84                 ;;
85         (2)
86                 dopersonenkonto=0
87                 print -u2 "Rechnungsempfänger eingeben, Ende mit leerer Zeile"
88                 print -u2
89
90                 addr=
91                 while IFS= read -r line && [[ -n $line ]]; do
92                         addr+=", $line"
93                 done
94                 addr=${addr#, }
95                 reqanschrift=3
96                 ;;
97         (1)
98                 $MKSH "$ROOT"/util/getpost |&
99                 set -A askanschrift
100                 naskanschrift=0
101                 addr=
102                 while IFS= read -pr line; do
103                         if [[ -n $line ]]; then
104                                 addr+=", $line"
105                         else
106                                 askanschrift[naskanschrift++]=${addr#, }
107                                 addr=
108                         fi
109                 done
110                 print -u2 Bitte Rechnungsempfänger-Basisadresse auswählen, 0 für Neueingabe
111                 select addr in "${askanschrift[@]}"; do
112                         if [[ $REPLY = 0 ]]; then
113                                 reqanschrift=2
114                                 break
115                         fi
116                         if [[ -n $addr ]]; then
117                                 reqanschrift=3
118                                 break
119                         fi
120                 done
121                 ;;
122         }
123 done
124
125 addr=$(split_addr "\\\\")
126
127 # Personenkontonummer finden
128 if (( dopersonenkonto )); then
129         asso_setldap_sasl users -- -b "$(cat "$TECKIDS_CACHE_DIR"/last_whois)" -s base
130         asso_loadk users "$(cat "$TECKIDS_CACHE_DIR"/last_whois)"
131         employeeNumber=$(asso_getv users "$(cat "$TECKIDS_CACHE_DIR"/last_whois)" employeeNumber 0)
132         cashAccount=$(asso_getv users "$(cat "$TECKIDS_CACHE_DIR"/last_whois)" teckidsCashAccount 0)
133 fi
134 kontostand=$("$ROOT/util/not_teckidscmd/gnc_balance" ${employeeNumber:-$cashAccount})
135 [[ -z $kontostand ]] && kontostand=0.00
136
137 # 2. Beliebig viele Artikel aus artikel.lst auswählen
138 # 3. Artikelpreise summieren
139
140 sepa=
141 while [[ $sepa != @(j|y|n) ]]; do
142         print -n 'SEPA-Lastschriftmandat? '
143         read sepa
144 done
145
146 art=
147 sum_0=000
148 sum_7=000
149 sum_19=000
150 while cat artikel.lst; IFS= read -r \
151     artnr?"Artikelnummer (0 für Sonderposten, leer für Ende): "; do
152         [[ -n $artnr ]] || break
153         if [[ $artnr != +([0-9]) ]]; then
154                 print -u2 "E: Artikelnummern sind Zahlen!"
155                 sleep 2
156                 continue
157         fi
158         if [[ $artnr = +(0) ]]; then
159                 line=
160                 while [[ -z $line ]]; do
161                         IFS= read -r line?"Artikelbezeichnung Sonderposten: "
162                 done
163                 dasfeld=
164                 while [[ $dasfeld != ?(-)+([0-9]).[0-9][0-9] ]]; do
165                         IFS= read -r dasfeld?"Preis in Euro (xxxx.xx): "
166                 done
167                 ssatz=
168                 while [[ $ssatz != 0 && $ssatz != 7 && $ssatz != 19 ]]; do
169                         IFS= read -r ssatz?"USt-Satz in % (0, 7 oder 19): "
170                 done
171                 bereich=
172                 while [[ $bereich != IB && $bereich != ZB && $bereich != GB ]]; do
173                         IFS= read -r bereich?"Bereich (IB/ZB/GB): "
174                 done
175                 line="          ${line//[&      ]/ }    $dasfeld        $ssatz  $bereich"
176         else
177                 line=$(grep "^$artnr    " artikel.lst)
178         fi
179         if [[ -z $line ]]; then
180                 print -u2 "E: Unbekannter Artikel $artnr!"
181                 sleep 2
182                 continue
183         fi
184
185         sIFS=$IFS; IFS=$'\t'
186         set -A felder -- $line
187         IFS=$sIFS
188
189         brutto=$(echo "scale=2; ${felder[2]} * (100 + ${felder[3]}) / 100" | bc -q)
190
191         art="$art${art:+\\\\\\hline$nl}${felder[0]} & ${felder[1]} & ${felder[3]}~\\% & ${felder[4]} & ${felder[2]}~€ & ${brutto}~€"
192
193         case ${felder[3]} in
194         0) (( sum_0 += ${felder[2]/.} )) ;;
195         7) (( sum_7 += ${felder[2]/.} )) ;;
196         19) (( sum_19 += ${felder[2]/.} )) ;;
197         esac
198 done
199
200 st_0=000
201 st_7=000 ; [[ $sum_7 != 000 ]] && st_7=$(echo "scale=2; $sum_7 / 100 * 0.07" | bc -q) ; st_7=${st_7/.}
202 st_19=000 ; [[ $sum_19 != 000 ]] && st_19=$(echo "scale=2; $sum_19 / 100 * 0.19" | bc -q) ; st_19=${st_19/.}
203
204 rblk=
205
206 print "Kontostand: $kontostand"
207 kontostand=${kontostand/.}
208 if (( kontostand < 0 )); then
209         verr=
210         while [[ $verr != @(j|y|n) ]]; do
211                 print -n 'Verrechnen? '
212                 read verr
213         done
214
215         if [[ $verr != n ]]; then
216                 rblk+='\textbf{Das Personenkonto weist einen Betrag von '${kontostand::${#kontostand}-2}.${kontostand: -2}'~€ auf. '
217                 (( rsum = sum + kontostand ))
218                 if (( rsum <= 0 )); then
219                         rblk+='Es ist keine Zahlung notwendig!}'
220                 else
221                         rblk+='Bitte zahlen Sie nur den Restbetrag von '${sum::${#sum}-2}.${sum: -2}'~€.}
222
223 '
224                 fi
225         fi
226 fi
227
228 # 4. template-rechnung.tex kopieren und folgendes ersetzen:
229 #      --Anschrift-- durch  Zeile 1\\
230 #                           Zeile 2\\
231 #                           ...
232 #                           Zeile 4
233 #      --RgNr--      durch  Zahl in rgnr.txt
234 #      --Pos--       durch  Artikelnummer & Bezeichnung & Preis\\\hline
235 #                           Artikelnummer # Bezeichnung # Preis\\\hline
236 #                           ...
237 #      --Summe--     durch  Summe der Preise
238
239 # Name aus erster Zeile von $addr, sanitised
240 name=${addr%%*(\\)$'\n'*}
241 name=${name//@([/ ])/-}
242
243 if [[ -z $rsum ]] || (( rsum > 0 )); then
244         if [[ $sepa = n ]]; then
245                 rblk+='Bitte leisten Sie die Zahlung bis spätestens \AdvanceDate[7]\today{}
246         bei einem Vorstandsmitglied oder per Überweisung auf folgendes Konto:
247
248         \begin{tabular}{ l l }
249          Kontoinhaber:   & Teckids e.V.\\
250          IBAN:           & DE31 3705 0198 1933 0485 46\\
251          BIC:            & COLSDE33XXX\\
252          Kreditinstitut: & Sparkasse KölnBonn
253         \end{tabular}'
254         else
255                 sman=TECKIDS$(date +'%Y%m%d')RG$rg
256                 sgid="DE70ZZZ00001497650"
257                 rblk+='Der Betrag wird frühestens am \AdvanceDate[5]\today{} mit der Mandatsreferenz \textbf{'"$sman"'} und der
258         Gläubiger-ID \textbf{'$sgid'} entsprechend dem erteilten SEPA-Lastschriftmandat eingezogen.'
259         fi
260 fi
261
262 file=$(<template-rechnung.tex)
263 file=${file//--Konto--/"${employeeNumber:-$cashAccount}"}
264 file=${file//--RBLK--/"$rblk"}
265 file=${file//--Anschrift--/"$addr"}
266 file=${file//--RgNr--/"$rg"}
267 file=${file//--Pos--/"$art"}
268 sum=$(( sum_0 + sum_7 + sum_19 ))
269 sumtext=${sum::${#sum}-2}.${sum: -2}    # LP: #1453827
270 file=${file//--Summe--/$sumtext}
271 sum=$(( sum + st_7 + st_19 ))
272 sumtext=${sum::${#sum}-2}.${sum: -2}    # LP: #1453827
273 file=${file//--BruttoSumme--/$sumtext}
274 file=${file//--St7--/${st_7::${#st_7}-2}.${st_7: -2}}
275 file=${file//--St19--/${st_19::${#st_19}-2}.${st_19: -2}}
276
277 print -r -- "$file" >"rechnung_${rg}_$name.tex"
278
279 # 5. rgnr.txt erhöhen
280 print -- $((rg + 1)) >rgnr.txt
281
282 set -e
283 make "rechnung_${rg}_$name.pdf"
284 if [[ -n $DISPLAY ]]; then
285         for x in xdg-open mupdf okular atril; do
286                 if whence -p $x >/dev/null; then
287                         $x "rechnung_${rg}_$name.pdf"
288                         exit 0
289                 fi
290         done
291 fi