Merge branch 'test' of ../kivitendo-erp_20220811
[kivitendo-erp.git] / templates / print / marei / kiviletter.sty
1 \NeedsTeXFormat{LaTeX2e}
2 \ProvidesPackage{kiviletter}[2022/04/23 Letter Layouts for Kivitendo]
3
4 \RequirePackage{l3keys2e}
5
6 %Optionen vor den eigenen Paketoptionen hinzufügen, damit spätere diese ggf. überschreiben
7 \PassOptionsToPackage{
8   fromlogo,
9   fromalign=right,
10   firstfoot=false,%Für einheitliche Randeinstellungen
11   refline=nodate,
12 }{scrletter}
13
14 \ExplSyntaxOn
15 \newif\if@kivi@infobox
16 \newif\if@kivi@footer
17 \keys_define:nn {kiviletter} {
18   infobox .choices:nn = {true,false} {\use:c {@kivi@infobox\l_keys_choice_tl}},
19   infobox .default:n = true,
20   infobox .initial:n = true,
21   reffields .meta:n = {infobox=false},
22   footer .choices:nn = {true,false} {\use:c {@kivi@footer\l_keys_choice_tl}},
23   footer .default:n = true,
24   footer .initial:n = true,
25   nofooter .meta:n = {footer=false},
26   unknown .code:n = \PassOptionsToPackage{\l_keys_key_str=#1}{scrletter},
27 }
28 \ExplSyntaxOff
29
30 \ProcessKeysOptions{kiviletter}
31
32 \RequirePackage{xparse}
33 \RequirePackage{iftex}
34
35 % Schriftart, Eingabelayout der Tastatur
36 \ifPDFTeX
37   \RequirePackage[utf8]{inputenc}% Nur notwendig, wenn Basis älter als TL2018
38   \RequirePackage[T1]{fontenc}
39   \RequirePackage{lmodern}
40
41   \RequirePackage{eurosym}
42   \DeclareUnicodeCharacter{20AC}{\euro}
43 \else
44   \RequirePackage{fontspec}
45 \fi
46
47 \RequirePackage{xltabular}
48 \RequirePackage{booktabs}
49 \RequirePackage{graphicx}
50
51 \RequirePackage{scrletter}
52 \LoadLetterOption{DIN}
53
54 \newkomavar{taxpoint}
55 \newkomavar{transaction}
56 \newkomavar[\lieferschein{}~\nr]{delivery}
57 \newkomavar[\angebot{}~\nr]{quote}
58 \newkomavar[\auftragsnummer]{orderID}
59 \newkomavar[\projektnummer]{projectID}
60 \setkomavar*{fromphone}{\textTelefon}
61 \setkomavar*{fromemail}{\textEmail}
62 \setkomavar*{fromfax}{\textFax}
63 \setkomavar*{customer}{\kundennummer}
64
65
66 \usepackage{geometry}
67
68 \ExplSyntaxOn
69 \dim_new:N \g_kivi_margin_dim
70 \dim_gset:Nn \g_kivi_margin_dim {\useplength{toaddrhpos}}
71 \geometry{a4paper,margin=\g_kivi_margin_dim,heightrounded}
72 %Scratch variables
73 \int_new:N \l_kivi_tmp_int
74 \bool_new:N \l_kivi_tmp_bool
75 \bool_new:N  \g_kivi_TableFoot_bool
76 \dim_new:N \g_kivi_orig@textheight_dim
77 \ExplSyntaxOff
78
79 \newsavebox{\shippingAddressBox}
80
81
82 \DeclareNewLayer[
83   foreground,
84   hoffset=\useplength{toaddrhpos},
85   voffset=\dimexpr\useplength{toaddrvpos}+\useplength{toaddrheight}+4\baselineskip,%sep to shippingaddressbox
86   contents={\usebox\shippingAddressBox}
87 ]{kivitendo.shippingaddress}
88
89 \newpairofpagestyles{kivitendo.letter}{}
90
91 \renewcommand*{\letterpagestyle}{kivitendo.letter}
92
93 \DeclareNewPageStyleByLayers{kivitendo.letter.first}{
94   kivitendo.shippingaddress,
95   plain.kivitendo.letter.head.odd,plain.kivitendo.letter.head.even,plain.kivitendo.letter.head.oneside,%
96   plain.kivitendo.letter.foot.odd,plain.kivitendo.letter.foot.even,plain.kivitendo.letter.foot.oneside,%
97 }
98
99 \setkomavar{backaddress}{\firma\ $\cdot$ \strasse\ $\cdot$ \ort}
100
101 \setkomavar{firsthead}{
102   \if@logo
103     \rlap{\usekomavar{fromlogo}}%
104   \fi
105 }
106
107 \@setplength{locwidth}{6cm}
108
109 \ExplSyntaxOn
110 \dim_new:N \l_kivi_tab_desc_leftskip_dim
111
112
113
114 \cs_new:Nn \__kivi_set_colwidth:nn  {
115   \dim_set:cn {l_kivi_tab_#1_dim} {#2}
116 }
117
118
119 \cs_new:Nn \__kivi_initialize_columns: {
120   \clist_map_inline:Nn \g_kivi_pricingtable_col_clist {
121     \bool_if_exist:cF {l_kivi_col_##1_bool}
122     {
123       \bool_new:c {l_kivi_col_##1_bool}
124       \dim_new:c {l_kivi_tab_##1_dim}
125       \keys_define:nn {kivi/PricingTable} {
126         ##1 .choice:,
127         ##1 / true .code:n = \bool_set_true:c {l_kivi_col_##1_bool},
128         ##1 / false .code:n = \bool_set_false:c {l_kivi_col_##1_bool},
129         ##1 / unknown .code:n = {
130             \bool_set_true:c {l_kivi_col_##1_bool}
131             \dim_set:cn {l_kivi_tab_##1_dim} {####1}
132           },
133         ##1 .default:n = true,
134         ##1 .initial:n = true,
135         ##1 / header .prop_put:c = {l_kivi_col_##1_prop},
136         ##1 / colspec .prop_put:c = {l_kivi_col_##1_prop},
137       }
138     }
139   }
140 }
141
142 \clist_new:N \g_kivi_pricingtable_col_clist
143
144 \keys_define:nn {kivi/PricingTable} {
145   columns .code:n =
146   \clist_gset:Nn \g_kivi_pricingtable_col_clist {#1}
147   \__kivi_initialize_columns:,
148   columns .initial:n = {pos, id, desc, amount, price, pricetotal},
149   unknown .code:n = \keys_set:no {kivi/Tabular} {\l_keys_key_str=#1}
150 }
151
152 % set default values for colwidth
153 \keys_set:nn {kivi/PricingTable} {
154   pos=5ex,
155   id=4em,
156   amount=5em,
157   price=7em,
158   pricetotal=7em,
159   %  desc=auto,
160   pos/header=\position,
161   id/header=\artikelnummer,
162   desc/header=\bezeichnung,
163   amount/header=\menge,
164   price/header=\einzelpreis,
165   pricetotal/header=\gesamtpreis,
166   price / colspec = Price,
167   pricetotal / colspec = Price ,
168 }
169
170 \dim_new:N \g_kivi_tabcolsep_dim
171 \dim_gset:Nn \g_kivi_tabcolsep_dim {.5\tabcolsep}
172 \setlength\tabcolsep{.5\tabcolsep}
173
174 \prg_new_conditional:Nnn \kivi_if_Price_col:n {T} {
175   \prop_get:cnN {l_kivi_col_#1_prop} {colspec} \l_tmpa_tl
176   \exp_args:NV \tl_if_eq:nnTF \l_tmpa_tl {Price}
177   {\prg_return_true:}
178   {\prg_return_false:}
179 }
180
181
182 \cs_new:Nn \__kivi_calc_desc_column: {
183   \bool_if:NTF \g__kivi_Tabular_rowcolor_bool
184   {\dim_set:Nn \l_kivi_tab_desc_leftskip_dim {2\g_kivi_tabcolsep_dim}}
185   {\dim_zero:N \l_kivi_tab_desc_leftskip_dim}
186   \dim_zero:N \l_kivi_tab_desc_dim
187   \bool_set_false:N \l_tmpa_bool
188   \tl_gclear:N \g_kivi_Pricing_colspec_tl
189   \clist_map_inline:Nn \g_kivi_pricingtable_col_clist {
190     \tl_if_eq:nnTF {##1} {desc}  {
191       \dim_set:Nn \l_kivi_tab_desc_dim {
192         \textwidth-\l_kivi_tab_desc_leftskip_dim
193       }
194       \bool_set_true:N \l_tmpa_bool
195       \tl_gput_right:Nn \g_kivi_Pricing_colspec_tl {p{\l_kivi_tab_desc_dim}}
196     }{
197       \bool_if:cT {l_kivi_col_##1_bool} {
198         \bool_if:NTF \l_tmpa_bool {
199           \dim_sub:Nn \l_kivi_tab_desc_dim {
200             \dim_use:c {l_kivi_tab_##1_dim}+2\g_kivi_tabcolsep_dim
201           }
202         }{
203           \dim_add:Nn \l_kivi_tab_desc_leftskip_dim {
204             \dim_use:c {l_kivi_tab_##1_dim}+2\g_kivi_tabcolsep_dim
205           }
206         }
207         \tl_gput_right:Nn \g_kivi_Pricing_colspec_tl {K{\dim_use:c {l_kivi_tab_##1_dim}}}
208         \kivi_if_Price_col:nT {##1} {\tl_gput_right:Nn \g_kivi_Pricing_colspec_tl {<{\__kivi_tab_column_currency:}}}
209       }
210     }
211   }
212   \bool_if:NF \g__kivi_Tabular_rowcolor_bool {
213     \tl_gput_left:Nn \g_kivi_Pricing_colspec_tl {@{}}
214     \tl_gput_right:Nn \g_kivi_Pricing_colspec_tl {@{}}
215   }
216 }
217
218 \newcolumntype{K}[1]{>{\raggedleft\arraybackslash}p{#1}}
219 \newcolumntype{P}[1]{K{#1}<{\__kivi_tab_column_currency:}}
220
221 \RequirePackage{tcolorbox}
222 \tcbuselibrary{breakable, skins}
223
224 \tcb@new@skin{kivi@LT}{base@unbroken,%
225   frame~engine=empty,interior~titled~engine=empty,interior~engine=empty,segmentation~engine=empty,title~engine=empty,%
226   skin~first=kivi@LT@first,skin~middle=kivi@LT@middle,skin~last=kivi@LT@last,
227   underlay~first~and~middle={
228     \node[anchor=north]  at (interior.north)  {\csname box_use:c\endcsname  {g_kivi_LT@head_box}};
229     \node[anchor=south]  at (interior.south)  {\csname box_use:c\endcsname  {g_kivi_LT@foot_box}};
230 },
231   underlay~unbroken~and~last={
232     \node[anchor=north]  at (interior.north)  {\csname box_use:c\endcsname  {g_kivi_LT@head_box}};
233     \node[anchor=south]  at (interior.south)  {\csname box_use:c\endcsname  {g_kivi_LT@lastfoot_box}};
234   },
235   boxsep=0pt,
236   boxrule=0pt,
237   left=0pt,
238   right=0pt,
239   bottom=\box_ht:N  \g_kivi_LT@foot_box+\box_dp:N  \g_kivi_LT@foot_box + \aboverulesep,
240   top=\box_ht:N  \g_kivi_LT@head_box+\box_dp:N  \g_kivi_LT@head_box +\belowrulesep,
241   parbox=false,
242 }
243
244 \tcb@new@skin{kivi@LT@first}{base@first,%
245   frame~engine=empty,interior~titled~engine=empty,interior~engine=empty,segmentation~engine=empty,title~engine=empty,%
246   skin~first=kivi@LT@first,skin~middle=kivi@LT@middle,skin~last=kivi@LT@middle,
247 }
248
249 \tcb@new@skin{kivi@LT@middle}{base@middle,%
250   frame~engine=empty,interior~titled~engine=empty,interior~engine=empty,segmentation~engine=empty,title~engine=empty,%
251   skin~first=kivi@LT@middle,skin~middle=kivi@LT@middle,skin~last=kivi@LT@middle,
252 }
253
254 \tcb@new@skin{kivi@LT@last}{base@last,%
255   frame~engine=empty,interior~titled~engine=empty,interior~engine=empty,segmentation~engine=empty,title~engine=empty,%
256   skin~first=kivi@LT@middle,skin~middle=kivi@LT@middle,skin~last=kivi@LT@last,
257 }
258
259 \tcbset{kivi@LT/.style={skin=kivi@LT}}%
260
261 \seq_new:N \l_kivi_PricingTable_seq
262 \seq_new:N \l_kivi_columns_seq
263 \seq_new:N \g_kivi_extraDescription_seq
264
265 \int_new:N \g__kivi_PricingTable_rowcolor_int
266 \dim_new:N \l__kivi_fboxsep_dim
267 \dim_set:Nn \l__kivi_fboxsep_dim {\g_kivi_tabcolsep_dim}
268
269 %colorbox variant to only add vertical spacing
270 %based on colorbox definition from xcolor.sty
271 %% ----------------------------------------------------------------
272 %% Copyright (C) 2003-2016 by Dr. Uwe Kern <xcolor at ukern dot de>
273 %% ----------------------------------------------------------------
274 %% This variant of colorbox adds a space of \l__kivi_fboxsep_dim along the vertical axes but no horizontal space
275 \def\kivi@tabcolorbox#1#{\protect\kivi@tabcolor@box{#1}}
276
277 \def\kivi@tabcolor@box#1#2{
278   \tl_if_empty:oTF {#2}
279   \kivi@nocolor@b@x
280   \kivi@color@b@x
281   \relax{\color#1{#2}}
282 }
283 \long\def\kivi@color@b@x#1#2#3%
284 {\leavevmode
285   \setbox\z@\hbox{{\set@color#3}}%
286   \dimen@\ht\z@\advance\dimen@\l__kivi_fboxsep_dim\ht\z@\dimen@
287   \dimen@\dp\z@\advance\dimen@\l__kivi_fboxsep_dim\dp\z@\dimen@
288   {#1{#2\color@block{\wd\z@}{\ht\z@}{\dp\z@}\box\z@}}}
289
290 \long\def\kivi@nocolor@b@x#1#2#3%
291 {\leavevmode
292   \setbox\z@\hbox{#3}%
293   \dimen@\ht\z@\advance\dimen@\l__kivi_fboxsep_dim\ht\z@\dimen@
294   \dimen@\dp\z@\advance\dimen@\l__kivi_fboxsep_dim\dp\z@\dimen@
295   {\box\z@}}
296
297 %%%
298
299
300 \newcommand{\FakeTable}[1]{
301   \par
302   \seq_set_split:Nnn \l_kivi_PricingTable_seq {\tabularnewline} {#1}
303   \seq_remove_all:Nn \l_kivi_PricingTable_seq {}
304   \begingroup
305   \setlength{\parskip}{\c_zero_dim}
306   \let\ExtraDescription\__kivi_addExtraDescription:n
307   \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
308   \seq_map_inline:Nn \l_kivi_PricingTable_seq {
309     \if_mode_horizontal: \par \fi
310     \bool_if:NT \g__kivi_Tabular_rowcolor_bool {
311       \int_gincr:N \g__kivi_PricingTable_rowcolor_int
312       \int_if_odd:nTF {\g__kivi_PricingTable_rowcolor_int}
313       {\nointerlineskip\kivi@tabcolorbox{\g__kivi_Tabular_rowcolor_odd_tl}}
314       {\nointerlineskip\kivi@tabcolorbox{\g__kivi_Tabular_rowcolor_even_tl}}
315     }
316     {\parbox{\linewidth}{
317         \seq_set_split:Nnn  \l_kivi_columns_seq {&} {##1}
318         \seq_gclear:N \g_kivi_extraDescription_seq
319         \exp_args:Nnx \use:n {\tabular[t]}\g_kivi_Pricing_colspec_tl
320         \seq_pop_left:NN \__l_FakeTable_columns_seq \l_tmpa_tl
321         \seq_item:Nn \l_kivi_columns_seq {\l_tmpa_tl}
322         \seq_map_inline:Nn \__l_FakeTable_columns_seq {
323           &\seq_item:Nn \l_kivi_columns_seq {####1}
324         }
325         \endtabular
326         \seq_if_empty:NTF \g_kivi_extraDescription_seq
327         {\par}
328         {\par\nopagebreak
329           \begingroup
330           \setlength{\leftskip}{\dim_eval:n {\bool_if:NT \g__kivi_Tabular_rowcolor_bool {-\tabcolsep} +\l_kivi_tab_desc_leftskip_dim}}
331           \setlength{\hsize}{\dim_eval:n {\l_kivi_tab_desc_dim+\leftskip}}
332           \usekomafont{extraDescription}
333           \seq_use:Nn \g_kivi_extraDescription_seq {\\}
334           \par
335           \endgroup
336         }
337       }}
338   }
339   \endgroup\par
340   \l__kivi_Tabular_rowsep_tl
341 }
342
343
344 \seq_new:N  \__l_FakeTable_columns_seq
345 \cs_new:Nn \__kivi_setup_FakeTable: {
346   \seq_clear:N \__l_FakeTable_columns_seq
347   \int_zero:N \l_tmpa_int
348   \clist_map_inline:Nn \g_kivi_pricingtable_col_clist {
349     \int_incr:N \l_tmpa_int
350     \bool_if:cT {l_kivi_col_##1_bool} {\seq_put_right:Nx \__l_FakeTable_columns_seq {\int_use:N \l_tmpa_int}}
351   }
352 }
353
354 \tl_new:N \g_kivi_Pricing_colspec_tl
355 \tl_gset:Nn \g_kivi_Pricing_colspec_tl {
356   \bool_if:NF \g__kivi_Tabular_rowcolor_bool {@{}}
357   \bool_if:NT \l_kivi_col_pos_bool {p{\l_kivi_tab_pos_dim}}
358   \bool_if:NT \l_kivi_col_id_bool {p{\l_kivi_tab_id_dim}}
359   p{\l_kivi_tab_desc_dim}
360   \bool_if:NT \l_kivi_col_amount_bool {\exp_not:n {>{\raggedleft\arraybackslash}p{\l_kivi_tab_amount_dim}}}
361   \bool_if:NT \l_kivi_col_price_bool {\exp_not:n {>{\raggedleft\arraybackslash}p{\l_kivi_tab_price_dim}<{\__kivi_tab_column_currency:}}}
362   \bool_if:NT \l_kivi_col_pricetotal_bool {\exp_not:n {>{\raggedleft\arraybackslash}p{\l_kivi_tab_pricetotal_dim}<{\__kivi_tab_column_currency:}}}
363   \bool_if:NF \g__kivi_Tabular_rowcolor_bool {@{}}
364 }
365
366 \cs_new_protected:Nn \__kivi_tab_column_currency: {\,\currency}
367 \def\tabcurrency{\__kivi_tab_column_currency:}
368 \cs_set:Nn \__kivi_tab_column_header_currency: {}
369 \cs_set_eq:NN \__kivi_tab_column_body_currency:  \__kivi_tab_column_currency:
370
371 \clist_map_inline:nn {head, foot, firsthead, lastfoot} {%TODO reduce
372   \box_new:c {g_kivi_LT@#1_box}
373 }
374
375 \newkomafont{PricingTableHeader}{\bfseries}
376
377 \cs_new:Nn \__kivi_setup_LT_boxes: {
378   \__kivi_calc_desc_column:
379   \hbox_gset:Nn \g_kivi_LT@head_box {
380     \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
381     \bool_if:NT \g__kivi_Tabular_rowcolor_bool {\kivi@tabcolorbox{\g__kivi_Tabular_rowcolor_header_tl}}%
382     {
383       \exp_args:Nnx \use:n {\tabular[b]}\g_kivi_Pricing_colspec_tl
384       \__kivi_PricingTabular_header:
385       \endtabular
386     }
387   }
388   \hbox_gset:Nn \g_kivi_LT@foot_box {
389     \begin{tabular*}{\textwidth}[t]{@{\extracolsep{\fill}}r@{\bool_if:NT \g__kivi_Tabular_rowcolor_bool {\hskip\tabcolsep}}}
390       \bool_if:NTF \g__kivi_Tabular_rowcolor_bool
391       {\hline\noalign{\vskip1pt}}
392       \midrule
393       \strut\weiteraufnaechsterseite
394     \end{tabular*}
395   }
396   \hbox_gset:Nn \g_kivi_LT@lastfoot_box {
397     \raisebox{\dimexpr\depth+\baselineskip}[0pt][0pt]{
398       \begin{tabular*}{\textwidth}{@{\bool_if:NT \g__kivi_Tabular_rowcolor_bool {\hskip\tabcolsep}\extracolsep{\fill}}r@{\bool_if:NT \g__kivi_Tabular_rowcolor_bool {\hskip\tabcolsep}}}
399         \bool_if:NF \g__kivi_Tabular_rowcolor_bool \bottomrule
400       \end{tabular*}
401     }
402   }
403 }
404
405
406 %Macht es sinn hier eine Variante zu machen, in der alle Spalten Belegbar sind?
407 \NewDocumentEnvironment{PricingTotal}{+b}{
408   \par\nointerlineskip
409 }{
410   \bool_if:NT \g__kivi_Tabular_rowcolor_bool   {\nointerlineskip\kivi@tabcolorbox{\g__kivi_Tabular_rowcolor_PricingTotal_tl}}
411   {
412     \tabular[t]{
413       @{\bool_if:NT \g__kivi_Tabular_rowcolor_bool {\hskip\tabcolsep}}
414       p{\dim_eval:n {\linewidth-\l_kivi_tab_pricetotal_dim-\bool_if:NTF \g__kivi_Tabular_rowcolor_bool {4}{2}\tabcolsep}}P{\l_kivi_tab_pricetotal_dim}@{\bool_if:NT \g__kivi_Tabular_rowcolor_bool {\hskip\tabcolsep}}
415     }
416     \l__kivi_Tabular_PricingTotal_topsep_tl
417     #1
418     \endtabular
419   }
420 }
421
422 \tl_new:N \l__kivi_Tabular_PricingTotal_topsep_tl
423 %TODO
424 \tl_set:Nn \l__kivi_Tabular_PricingTotal_topsep_tl {\bool_if:NF \g__kivi_Tabular_rowcolor_bool \midrule}
425
426 \newcommand*\ExtraDescription{
427   \PackageError{kiviletter}{The~command~\string\ExtraDescription\space~may~be~only~used~inside~the~\string\FakeTable\space~environment.}{See~documentation~for~details}
428 }
429
430
431 \cs_new:Nn \__kivi_addExtraDescription:n {\seq_gput_right:Nn \g_kivi_extraDescription_seq {#1}}
432
433 \newenvironment{PricingTabular}[1][]{
434   \begingroup
435   \dim_set:Nn \parskip {\c_zero_dim}
436   \tl_if_empty:nF {#1} {\keys_set:nn {kivi/PricingTable} {#1}}
437   \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
438   \__kivi_calc_desc_column:
439   \exp_args:Nx \longtable \g_kivi_Pricing_colspec_tl
440   % Tabellenkopf
441   \__kivi_PricingTabular_header:
442   \endhead
443   \midrule
444   \rlap{\makebox[\textwidth][r]{\weiteraufnaechsterseite}}\\
445   \endfoot
446   \bool_if:NF \g__kivi_Tabular_rowcolor_bool \bottomrule
447   \endlastfoot
448 }{
449   \endlongtable
450   \endgroup
451 }
452
453 \cs_set:Nn \__kivi_PricingTabular_header: {
454   \bool_if:NTF \g__kivi_Tabular_rowcolor_bool {\noalign{\skip_vertical:n {\dp\strutbox}}}\toprule
455   \cs_gset_eq:NN \__kivi_tab_column_currency: \__kivi_tab_column_header_currency:
456   \bool_set_false:N \l_tmpa_bool
457   \clist_map_inline:Nn \g_kivi_pricingtable_col_clist  {
458     \bool_if:cT {l_kivi_col_##1_bool} {
459       \bool_if:NT \l_tmpa_bool {&}
460       \bool_set_true:N \l_tmpa_bool
461       \usekomafont{PricingTableHeader}
462       \prop_item:cn {l_kivi_col_##1_prop} {header}
463     }
464   }
465   \cs_gset_eq:NN \__kivi_tab_column_currency: \__kivi_tab_column_body_currency:
466   \\
467   \bool_if:NF \g__kivi_Tabular_rowcolor_bool \midrule
468 }
469
470 \newkomafont{tablehead}{\bfseries}
471
472 \keys_define:nn {kivi/SimpleTabular} {
473   colspec .tl_set:N =\l_kivi_SimpleTabular_colspec_tl,
474   colspec .initial:n = {rrX},
475   headline .tl_set:N = \l_kivi_SimpleTabular_headline_tl,
476   headline .initial:n = {\usekomafont{tablehead}\position & \usekomafont{tablehead}\menge & \usekomafont{tablehead}\bezeichnung},
477 }
478
479 \keys_define:nn {kivi/Tabular} {
480   color-rows .bool_gset:N =  \g__kivi_Tabular_rowcolor_bool ,
481   color-rows .initial:n = false,
482   color-rows .default:n = true,
483   rowcolor-odd .tl_gset:N = \g__kivi_Tabular_rowcolor_odd_tl,
484   rowcolor-odd .initial:n = black!10,
485   rowcolor-even .tl_gset:N = \g__kivi_Tabular_rowcolor_even_tl,
486   rowcolor-even .initial:n =,
487   rowcolor-header .tl_gset:N = \g__kivi_Tabular_rowcolor_header_tl,
488   rowcolor-header .initial:n = black!35,
489   rowcolor-total .tl_gset:N = \g__kivi_Tabular_rowcolor_PricingTotal_tl,
490   rowcolor-total .initial:n = black!35,
491   rowsep .tl_set:N =\l__kivi_Tabular_rowsep_tl,
492   rowsep .initial:n = ,
493   hrule .meta:n = {
494     rowsep={
495       \vskip\aboverulesep
496       \leavevmode\hrule\@height\lightrulewidth
497       \vskip\belowrulesep}},
498 }
499
500 \newcommand*{\SetupSimpleTabular}[1]{\keys_set:nn {kivi/SimpleTabular} {#1}}
501 \newcommand*{\SetupPricingTabular}[1]{\keys_set:nn {kivi/PricingTable} {#1}}
502
503 \newenvironment{SimpleTabular}[1][]
504 {
505   \tl_if_in:nnTF {#1} {=} {\keys_set:nn {kivi/SimpleTabular} {#1}} {\tl_if_empty:nF {#1} {\tl_set:Nn \l_kivi_SimpleTabular_headline_tl {#1}}}
506   \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
507   \dim_set:Nn \parskip {\c_zero_dim}
508   \bool_if:NF \g__kivi_Tabular_rowcolor_bool {
509     \tl_put_right:Nn \l_kivi_SimpleTabular_colspec_tl {@{}}
510     \tl_put_left:Nn \l_kivi_SimpleTabular_colspec_tl {@{}}
511   }
512   \exp_args:NnV \xltabular{\linewidth}\l_kivi_SimpleTabular_colspec_tl
513   \toprule
514   \cs_gset_eq:NN \__kivi_tab_column_currency: \__kivi_tab_column_header_currency:
515   \l_kivi_SimpleTabular_headline_tl
516   \\
517   \noalign{\cs_gset_eq:NN \__kivi_tab_column_currency: \__kivi_tab_column_body_currency:}
518   \midrule
519   \endhead
520   \midrule
521   \rlap{\makebox[\textwidth][r]{\weiteraufnaechsterseite}}\\
522   \endfoot
523   \bool_if:NF \g__kivi_Tabular_rowcolor_bool \bottomrule
524   \endlastfoot
525   \ignorespaces
526 }{
527   \def\@currenvir{tabularx}
528   \endxltabular
529 }
530
531 %PricingTabular* kann automatisch spalten ignorieren
532 % \begin{PricingTabular*}[id=false]
533 % deaktiviert damit die Spalte der Produktnummer
534 % analog ist dies für pos, amount, price, pricetotal möglich.
535 % Die Spalte der Bezeichnung ist nicht deaktivierbar
536 \newenvironment{PricingTabular*}[1][]{
537   \int_gzero:N \g__kivi_PricingTable_rowcolor_int
538   \tl_if_empty:nF {#1} {\keys_set:nn {kivi/PricingTable} {#1}}
539   \__kivi_setup_LT_boxes:
540   \__kivi_setup_FakeTable:
541   \dim_set:Nn \parskip {\c_zero_dim}
542   \PricingTabularBox\ignorespaces
543 }{\endPricingTabularBox
544   %compensate footer spacing
545   \skip_vertical:n {-\box_ht:N  \g_kivi_LT@foot_box-\box_dp:N  \g_kivi_LT@foot_box}
546 }
547
548 \newtcolorbox{PricingTabularBox}{breakable,skin=kivi@LT}
549
550 \if@kivi@infobox
551
552   \def\locationsep{:}
553
554   \NewDocumentCommand{\locationentry}{som}{
555     \Ifkomavarempty{#3}{}{
556       \IfBooleanTF {#1} {
557         \strut
558         \IfNoValueTF {#2}
559         {\usekomavar*{#3}}
560         {#2}
561         \locationsep
562         \hfill\strut\space
563         \hbox_set:Nn \l_tmpa_box {\usekomavar{#3}}
564         \dim_compare:nTF {\box_wd:N \l_tmpa_box>\linewidth}
565         {\newline\hspace*{\fill}\llap}
566         {\hspace*{\fill}}
567         {\box_use:N \l_tmpa_box\strut}
568       }{
569         \@hangfrom{\strut
570           \IfNoValueTF {#2}
571           {\usekomavar*{#3}}
572           {#2}\locationsep~
573         }{
574           \parbox[t]{\dimexpr\linewidth-\hangindent}{
575             \raggedleft
576             \usekomavar{#3}\strut
577           }
578         }
579       }
580     }
581     \par
582   }
583
584   \newkomafont{transaction}{\bfseries}
585
586   \setkomavar{location}{
587     \Ifkomavarempty{transaction}{}{{
588           \usekomafont{transaction}
589           \usekomavar{transaction}
590         }
591     }
592     \par
593     \medskip
594     \parbox{\useplength{locwidth}}{
595       \locationentry{date}
596       \locationentry{myref}
597       \locationentry{customer}
598       \locationentry{yourref}
599       \locationentry{delivery}
600       \locationentry{quote}
601       \locationentry{orderID}
602       \locationentry{projectID}
603       \locationentry{taxpoint}
604       \locationentry[\ansprechpartner]{fromname}
605       \locationentry{fromphone}
606       \locationentry*{fromemail}
607     }
608   }
609   \removereffields
610   \AtBeginLetter{
611     \ifdim\ht\shippingAddressBox>\z@
612       \@addtoplength{refvpos}{\dimexpr\ht\shippingAddressBox+\dp\shippingAddressBox}
613       \@addtoplength{refvpos}{4\baselineskip}%sep between address boxes
614     \fi
615   }
616
617 \fi
618
619 %Fallback for older KOMA-Script-Versions
620 \cs_if_exist:NF \Ifstr {\let\Ifstr\ifstr}
621 \cs_if_exist:NF \Ifkomavarempty {\let\Ifkomavarempty\ifkomavarempty}
622
623 %Definitionen für die insettings.tex
624
625 \newcommand*{\setupIdentpath}[1]{
626   \int_set:Nn \l_kivi_tmp_int {1}
627   \bool_set_true:N \l_kivi_tmp_bool
628   \bool_while_do:Nn \l_kivi_tmp_bool {
629     \file_if_exist:nTF {firma\int_use:N \l_kivi_tmp_int/ident.tex}
630     {
631       \exp_args:Nf \str_if_in:nnTF {#1} {Firma\int_use:N \l_kivi_tmp_int}
632       {
633         \newcommand*{\identpath}{firma\int_use:N \l_kivi_tmpa_int}
634         \bool_set_false:N \l_kivi_tmp_bool
635       }
636       {\int_incr:N \l_kivi_tmp_int}
637     }
638     {
639       \bool_set_false:N \l_kivi_tmp_bool
640       \newcommand*{\identpath}{firma}
641     }
642   }
643 }
644
645 \newcommand*{\setupCurrencyConfig}[3][euro]{
646   \tl_new:N \g_kivi_currency_tl
647   \exp_args:Nf \str_if_in:nnT {#3} {USD} {\tl_gset:Nn \g_kivi_currency_tl {usd}}
648   \exp_args:Nf \str_if_in:nnT {#3} {CHF} {\tl_gset:Nn \g_kivi_currency_tl {chf}}
649   \exp_args:Nf \str_if_in:nnT {#3} {EUR} {\tl_gset:Nn \g_kivi_currency_tl {euro}}
650   \tl_if_empty:NT  \g_kivi_currency_tl {
651     \tl_if_empty:oTF {#3} {
652       \tl_gset:Nn \g_kivi_currency_tl {#1}
653     } {
654       \tl_gset:Nn \g_kivi_currency_tl {#3}
655     }
656   }
657   \input{#2/\g_kivi_currency_tl _account.tex}
658   \let\setupCurrencyConfig\_kivi_currency_already_configured:w
659 }
660
661 \newcommand*{\_kivi_currency_already_configured:w}[3][euro]{
662   \msg_error:nnx {kiviletter} {currency-already-configured} {\g_kivi_currency_tl}
663 }
664
665 \msg_new:nnn {kiviletter} {currency-already-configured} {
666   The~currency~configuration~is~a~global~setting~for~each~document.\\
667   It's~already~set~to~#1,~please~remove~the~second~call~of~\string\setupCurrencyConfig.
668 }
669 \ExplSyntaxOff
670
671
672 \renewcommand*{\raggedsignature}{\raggedright}
673
674 \newkomafont{extraDescription}{}
675 \newkomafont{subtotal}{}
676 \newkomafont{total}{}
677
678 \endinput