]> wagnertech.de Git - mfinanz.git/blob - kiviletter.sty
scrlayer-scrpage compat
[mfinanz.git] / kiviletter.sty
1 \NeedsTeXFormat{LaTeX2e}
2 \ProvidesPackage{kiviletter}[2019/10/10 Letter Layouts for Kivitendo]
3
4 \newif\if@kivi@infobox
5 \DeclareOption{reffields}{\@kivi@infoboxfalse}
6 \DeclareOption{infobox}{\@kivi@infoboxtrue}
7 \@kivi@infoboxtrue
8
9 \newif\if@kivi@faketable
10 \DeclareOption{faketable}{\@kivi@faketabletrue}
11
12 \ProcessOptions\relax
13
14
15 \RequirePackage{expl3}
16 \RequirePackage{iftex}
17 % Schriftart, Eingabelayout der Tastatur
18 \ifPDFTeX
19 \RequirePackage[utf8]{inputenc}% Nur notwendig, wenn Basis älter als TL2018
20 \RequirePackage[T1]{fontenc}
21 \else
22 \RequirePackage{fontspec}
23 \fi
24
25 %\RequirePackage{xltabular}
26 \RequirePackage{tabularx}
27 \RequirePackage{longtable}
28 \RequirePackage{booktabs}
29 \PassOptionsToPackage{table}{xcolor}
30
31 \RequirePackage{xcolor}
32 \RequirePackage{graphicx}
33
34 \ifPDFTeX
35 \RequirePackage{eurosym}
36 \DeclareUnicodeCharacter{20AC}{\euro}
37 \fi
38
39 \RequirePackage[fromlogo,fromalign=right,
40         firstfoot=false,%Für einheitliche Randeinstellungen
41         ]{scrletter}
42 \LoadLetterOption{DIN}
43
44 \usepackage{geometry}
45
46 \ExplSyntaxOn
47 \dim_new:N \g_kivi_margin_dim
48 \dim_gset:Nn \g_kivi_margin_dim {\useplength{toaddrhpos}}
49 \geometry{a4paper,margin=\g_kivi_margin_dim,heightrounded}
50 \savegeometry{kivi.letter@default}
51 %Scratch variables
52 \int_new:N \l_kivi_tmp_int
53 \bool_new:N \l_kivi_tmp_bool
54 \bool_new:N  \g_kivi_TableFoot_bool
55 \dim_new:N \g_kivi_orig@textheight_dim
56 \int_new:N \g_PricingTabular_firstpage_int
57 \ExplSyntaxOff
58
59 \newsavebox{\shippingAddressBox}
60
61
62 \DeclareNewLayer[
63 foreground,
64 hoffset=\useplength{toaddrhpos},
65 voffset=\dimexpr\useplength{toaddrvpos}+\useplength{toaddrheight}+2\baselineskip,
66 contents={\usebox\shippingAddressBox}
67 ]{kivitendo.shippingaddress}
68
69
70 \ExplSyntaxOn
71 \DeclareNewLayer[
72 foreground,
73 mode=picture,
74 hoffset=\g_kivi_margin_dim,
75 voffset=\g_kivi_margin_dim,
76 align=tl,
77 height=\box_ht:N \g_kivi_LT@head_box,
78 contents={\box_use:N \g_kivi_LT@head_box},
79 ]{kivitendo.TableHead}
80
81
82 \DeclareNewLayer[
83 foreground,
84 textarea,
85 mode=picture,
86 voffset=\dim_eval:n {\paperheight-\g_kivi_margin_dim},
87 height=\box_ht:N \g_kivi_LT@foot_box,
88 contents=\bool_if:NT \g_kivi_TableFoot_bool {\box_use:N \g_kivi_LT@foot_box},
89 align=bl,
90 ]{kivitendo.TableFoot}
91
92 \AtBeginLetter{\dim_gset:Nn \g_kivi_orig@textheight_dim {\textheight}}
93 \ExplSyntaxOff
94
95 \newpairofpagestyles{kivitendo.letter}{}
96 \renewcommand*{\letterpagestyle}{kivitendo.letter}
97
98 \DeclareNewPageStyleByLayers{kivitendo.letter.PricingTable}{
99         kivitendo.TableHead,
100         kivitendo.TableFoot
101         kivitendo.letter.head.odd,kivitendo.letter.head.even,kivitendo.letter.head.oneside,%
102         kivitendo.letter.foot.odd,kivitendo.letter.foot.even,kivitendo.letter.foot.oneside,%
103 }
104 \DeclareNewPageStyleByLayers{kivitendo.letter.first}{
105         kivitendo.shippingaddress,
106         kivitendo.TableFoot,
107         kivitendo.letter.head.odd,kivitendo.letter.head.even,kivitendo.letter.head.oneside,%
108         kivitendo.letter.foot.odd,kivitendo.letter.foot.even,kivitendo.letter.foot.oneside,%
109 }
110
111 \setkomavar{backaddress}{\firma\ $\cdot$ \strasse\ $\cdot$ \ort}
112 \@setplength{locwidth}{6cm}
113
114 \ExplSyntaxOn
115 \dim_new:N \g_kivi_tab_pos_dim
116 \dim_gset:Nn \g_kivi_tab_pos_dim {3.5ex}
117 \dim_new:N \g_kivi_tab_id_dim
118 \dim_gset:Nn \g_kivi_tab_id_dim {4em}
119 \dim_new:N \g_kivi_tab_num_dim
120 \dim_gset:Nn \g_kivi_tab_num_dim {5em}
121 \dim_new:N \g_kivi_tab_price_dim
122 \dim_gset:Nn \g_kivi_tab_price_dim {7em}
123 \dim_new:N \g_kivi_tab_desc_dim
124
125 \dim_new:N \g_kivi_tabcolsep_dim
126 \dim_gset:Nn \g_kivi_tabcolsep_dim {.5\tabcolsep}
127 \newcommand*{\CalcTabCols}{
128         \dim_gset:Nn \g_kivi_tab_desc_dim {\textwidth-\g_kivi_tab_pos_dim -\g_kivi_tab_id_dim-\g_kivi_tab_num_dim - 2\g_kivi_tab_price_dim - 10\g_kivi_tabcolsep_dim}
129 }
130
131 \newcolumntype{P}{>{\raggedleft\arraybackslash}p{\g_kivi_tab_price_dim}<{\,\currency}}
132
133 %\if@kivi@faketable
134 \RequirePackage{tcolorbox}
135 \tcbuselibrary{breakable, skins}
136 \seq_new:N \l_kivi_PricingTable_seq
137 \seq_new:N \g_kivi_extraDescription_seq
138 \newcommand{\FakeTable}[1]{
139         \par
140         \CalcTabCols
141         \seq_set_split:Nnn \l_kivi_PricingTable_seq {\tabularnewline} {#1}
142         \begingroup
143         \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
144         \seq_map_inline:Nn \l_kivi_PricingTable_seq {
145         \seq_gclear:N \g_kivi_extraDescription_seq
146         \exp_args:NnV \use:n {\tabular[t]}\g_kivi_Pricing_colspec_tl
147         ##1
148         \endtabular
149         \seq_if_empty:NTF \g_kivi_extraDescription_seq
150         {\par\nointerlineskip}
151         {\par\nointerlineskip
152         \begin{tcolorbox}[
153                 empty,
154                 left=\dim_eval:n {\g_kivi_tab_pos_dim+ \g_kivi_tab_id_dim +4\g_kivi_tabcolsep_dim},
155                 right=\dim_eval:n {\g_kivi_tab_num_dim+ 2\g_kivi_tab_price_dim +6\g_kivi_tabcolsep_dim},top=0pt,bottom=0pt,
156                 boxsep=0pt,
157                 breakable,
158                 lines~before~break=1,
159         ]
160         \seq_use:Nn \g_kivi_extraDescription_seq {\\}
161         \end{tcolorbox}
162         \nointerlineskip
163         }
164         }
165         \endgroup
166 }
167
168
169 \tl_new:N \g_kivi_Pricing_colspec_tl
170 \tl_gset:Nn \g_kivi_Pricing_colspec_tl {@{}p{\g_kivi_tab_pos_dim}p{\g_kivi_tab_id_dim}p{\g_kivi_tab_desc_dim}>{\raggedleft\arraybackslash}p{\g_kivi_tab_num_dim}*2{P}@{}}
171
172
173 \clist_map_inline:nn {head, foot, firsthead, lastfoot} {%TODO reduce
174         \box_new:c {g_kivi_LT@#1_box}
175 }
176
177 \AtBeginDocument{
178         \csname kivi_setup_LT_boxes:\endcsname
179         \geometry{a4paper,
180                 hmargin=\g_kivi_margin_dim,
181                 top=\dim_eval:n {\g_kivi_margin_dim + \box_ht:N \g_kivi_LT@head_box},
182                 bottom=\dim_eval:n {\g_kivi_margin_dim + \box_ht:N \g_kivi_LT@foot_box},
183                 heightrounded}
184         \savegeometry{kivi.letter@table}
185         \loadgeometry{kivi.letter@default}
186 }
187
188 \cs_new:Nn \kivi_setup_LT_boxes: {
189         \CalcTabCols
190         \hbox_gset:Nn \g_kivi_LT@head_box {
191         \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
192         \exp_args:NnV \use:n {\tabular[b]}\g_kivi_Pricing_colspec_tl
193         \toprule
194         \bfseries\position & \bfseries\artikelnummer & \bfseries\bezeichnung & \bfseries\menge &\multicolumn{1}{P}{\bfseries\einzelpreis}&\multicolumn{1}{P@{}}{\bfseries\gesamtpreis}\\
195         \midrule
196         \endtabular
197         }
198         \hbox_gset:Nn \g_kivi_LT@foot_box {
199         \raisebox{\depth}{
200         \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}r@{}}
201         \midrule
202         \strut\weiteraufnaechsterseite
203         \end{tabular*}
204         }
205         }
206 }
207
208
209 %Macht es sinn hier eine Variante zu machen, in der alle Spalten Belegbar sind?
210 \newenvironment{PricingTotal}{
211         \tabular[t]{@{}p{\dim_eval:n {\linewidth-\g_kivi_tab_price_dim-2\tabcolsep}}P@{}}
212         \midrule
213 }{
214         \bottomrule\endtabular
215 }
216
217 \newcommand{\ExtraDescription}[1]{\seq_gput_right:Nn \g_kivi_extraDescription_seq {#1}}
218 %\else
219 \newenvironment{PricingTabular}[1][]{
220         \begingroup
221         \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
222         \CalcTabCols
223         \exp_args:NV \longtable \g_kivi_Pricing_colspec_tl
224         % Tabellenkopf
225         \toprule
226         \bfseries\position & \bfseries\artikelnummer & \bfseries\bezeichnung & \bfseries\menge &\multicolumn{1}{P}{\bfseries\einzelpreis}&\multicolumn{1}{P@{}}{\bfseries\gesamtpreis}\\
227         \midrule
228         \endhead
229         \midrule
230         \multicolumn{6}{@{}r@{}}{\weiteraufnaechsterseite}\\
231         \endfoot
232 }{
233         \endlongtable
234         \endgroup
235 }
236
237 \usepackage{afterpage}
238
239 \cs_new:cpn {PricingTabular*}{
240         \bool_gset_true:N \g_kivi_inTable_bool
241         \endgroup
242         \@nameuse{Gm@restore@@kivi.letter@table}%
243         \Gm@changelayout
244         \begingroup
245         \def \@currenvir {PricingTabular*}\edef \@currenvline {\on@line }
246         \int_gset:Nn \g_PricingTabular_firstpage_int {\c@page}
247         \addtolength{\vsize}{-\box_ht:N \g_kivi_LT@foot_box}
248         \pagegoal\vsize
249         \widowpenalty0
250         \clubpenalty0
251         \bool_gset_true:N \g_kivi_TableFoot_bool
252         \pagestyle{kivitendo.letter.PricingTable}
253         \leavevmode\box_use:N \g_kivi_LT@head_box
254         \par\nointerlineskip\ignorespaces
255 }
256
257 \cs_new:cpn {endPricingTabular*} {
258         \int_compare:nNnF \g_PricingTabular_firstpage_int = \c@page {\thispagestyle{kivitendo.letter.PricingTable}}
259         \bool_gset_false:N \g_kivi_TableFoot_bool
260         \@nameuse{Gm@restore@@kivi.letter@default}
261         \Gm@changelayout
262         \bool_gset_true:N \g_kivi_restore_geometry_bool
263         \afterpage{
264                 \kivi_conditional_restore_geometry:
265         }
266 }
267
268 \cs_new:Nn \kivi_conditional_restore_geometry: {
269         \bool_if:NT \g_kivi_restore_geometry_bool
270         {
271         \@nameuse{Gm@restore@@kivi.letter@default}
272         \Gm@changelayout
273         }
274         \bool_gset_false:N \g_kivi_restore_geometry_bool
275 }
276 %\ExplSyntaxOff
277
278 \if@kivi@infobox
279 \newkomavar{locationtitle}
280 \setkomavar{location}{
281         \begin{flushright}
282                 \bfseries
283                 \LARGE
284                 \usekomavar{locationtitle}
285         \end{flushright}
286         \par
287         \medskip
288         \begin{tabularx}{\linewidth}{@{}l<{:}>{\raggedright\arraybackslash}X@{}}
289                 \datum&\usekomavar{date}\\
290                 \kundennummer&\usekomavar{customer}\\
291                 \ansprechpartner&\usekomavar{fromname}
292                 \ifkomavarempty{fromphone}{}{\\\textTelefon&\usekomavar{fromphone}}
293                 \ifkomavarempty{fromemail}{}{\\\textEmail&\usekomavar{fromemail}}
294         \end{tabularx}
295 }
296 \removereffields
297
298 %\ExplSyntaxOn
299 \AtBeginLetter{
300         \ifkomavarempty{title}{}{
301                 \exp_args:Nno\setkomavar{locationtitle}{\scr@title@var}
302                 \setkomavar{title}{}
303         }
304         \ifdim\ht\shippingAddressBox>\z@
305         \addtoplength{refvpos}{\ht\shippingAddressBox}
306         \addtoplength{refvpos}{2\baselineskip}
307         \fi
308 }
309 \ExplSyntaxOff
310 \fi
311
312
313
314 \renewcommand*{\raggedsignature}{\raggedright}
315
316 \endinput