1 \NeedsTeXFormat{LaTeX2e}
2 \ProvidesPackage{kiviletter}[2020/04/24 Letter Layouts for Kivitendo]
6 \DeclareOption{reffields}{\@kivi@infoboxfalse}
7 \DeclareOption{infobox}{\@kivi@infoboxtrue}
13 \RequirePackage{expl3}
14 \RequirePackage{iftex}
15 \KOMAoptions{fontsize=12pt}
16 % Schriftart, Eingabelayout der Tastatur
18 \RequirePackage[utf8]{inputenc}% Nur notwendig, wenn Basis älter als TL2018
19 \RequirePackage[T1]{fontenc}
20 \RequirePackage{lmodern}
22 \RequirePackage{fontspec}
25 %\RequirePackage{xltabular}
26 \RequirePackage{tabularx}
27 \RequirePackage{longtable}
28 \RequirePackage{booktabs}
29 \PassOptionsToPackage{table}{xcolor}
31 \RequirePackage{xcolor}
32 \RequirePackage{graphicx}
35 \RequirePackage{eurosym}
36 \DeclareUnicodeCharacter{20AC}{\euro}
39 \RequirePackage[fromlogo,fromalign=right,
40 firstfoot=false,%Für einheitliche Randeinstellungen
43 \LoadLetterOption{DIN}
45 \newkomavar{transaction}
46 \newkomavar[\lieferschein{}~\nr]{delivery}
47 \newkomavar[\angebot{}~\nr]{quote}
49 \newkomavar{projectID}
54 \dim_new:N \g_kivi_margin_dim
55 \dim_gset:Nn \g_kivi_margin_dim {\useplength{toaddrhpos}}
56 \geometry{a4paper,margin=\g_kivi_margin_dim,heightrounded}
57 \savegeometry{kivi.letter@default}
59 \int_new:N \l_kivi_tmp_int
60 \bool_new:N \l_kivi_tmp_bool
61 \bool_new:N \g_kivi_TableFoot_bool
62 \dim_new:N \g_kivi_orig@textheight_dim
63 \int_new:N \g_PricingTabular_firstpage_int
66 \newsavebox{\shippingAddressBox}
71 hoffset=\useplength{toaddrhpos},
72 voffset=\dimexpr\useplength{toaddrvpos}+\useplength{toaddrheight}+4\baselineskip,
73 contents={\usebox\shippingAddressBox}
74 ]{kivitendo.shippingaddress}
81 hoffset=\g_kivi_margin_dim,
82 voffset=\g_kivi_margin_dim,
84 height=\box_ht:N \g_kivi_LT@head_box,
85 contents={\box_use:N \g_kivi_LT@head_box},
86 ]{kivitendo.TableHead}
93 voffset=\dim_eval:n {\paperheight-\g_kivi_margin_dim},
94 height=\box_ht:N \g_kivi_LT@foot_box,
95 contents=\bool_if:NT \g_kivi_TableFoot_bool {\box_use:N \g_kivi_LT@foot_box},
97 ]{kivitendo.TableFoot}
99 \AtBeginLetter{\dim_gset:Nn \g_kivi_orig@textheight_dim {\textheight}}
102 \newpairofpagestyles{kivitendo.letter}{}
103 \renewcommand*{\letterpagestyle}{kivitendo.letter}
105 \DeclareNewPageStyleByLayers{kivitendo.letter.PricingTable}{
108 kivitendo.letter.head.odd,kivitendo.letter.head.even,kivitendo.letter.head.oneside,%
109 kivitendo.letter.foot.odd,kivitendo.letter.foot.even,kivitendo.letter.foot.oneside,%
111 \DeclareNewPageStyleByLayers{kivitendo.letter.first}{
112 kivitendo.shippingaddress,
114 kivitendo.letter.head.odd,kivitendo.letter.head.even,kivitendo.letter.head.oneside,%
115 kivitendo.letter.foot.odd,kivitendo.letter.foot.even,kivitendo.letter.foot.oneside,%
118 \setkomavar{backaddress}{\firma\ $\cdot$ \strasse\ $\cdot$ \ort}
120 \setkomavar{firsthead}{
122 \rlap{\usekomavar{fromlogo}}%
126 \@setplength{locwidth}{6cm}
129 \dim_new:N \g_kivi_tab_pos_dim
130 \dim_gset:Nn \g_kivi_tab_pos_dim {3.5ex}
131 \dim_new:N \g_kivi_tab_id_dim
132 \dim_gset:Nn \g_kivi_tab_id_dim {4em}
133 \dim_new:N \g_kivi_tab_num_dim
134 \dim_gset:Nn \g_kivi_tab_num_dim {5em}
135 \dim_new:N \g_kivi_tab_price_dim
136 \dim_gset:Nn \g_kivi_tab_price_dim {7em}
137 \dim_new:N \g_kivi_tab_desc_dim
139 \dim_new:N \g_kivi_tabcolsep_dim
140 \dim_gset:Nn \g_kivi_tabcolsep_dim {.5\tabcolsep}
141 \newcommand*{\CalcTabCols}{
142 \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}
145 \newcolumntype{P}{>{\raggedleft\arraybackslash}p{\g_kivi_tab_price_dim}<{\,\currency}}
148 \RequirePackage{tcolorbox}
149 \tcbuselibrary{breakable, skins}
150 \seq_new:N \l_kivi_PricingTable_seq
151 \seq_new:N \g_kivi_extraDescription_seq
152 \newcommand{\FakeTable}[1]{
155 \seq_set_split:Nnn \l_kivi_PricingTable_seq {\tabularnewline} {#1}
157 \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
158 \seq_map_inline:Nn \l_kivi_PricingTable_seq {
159 \seq_gclear:N \g_kivi_extraDescription_seq
160 \exp_args:NnV \use:n {\tabular[t]}\g_kivi_Pricing_colspec_tl
163 \seq_if_empty:NTF \g_kivi_extraDescription_seq
164 {\par\nointerlineskip}
165 {\par\nointerlineskip
168 left=\dim_eval:n {\g_kivi_tab_pos_dim+ \g_kivi_tab_id_dim +4\g_kivi_tabcolsep_dim},
169 right=\dim_eval:n {\g_kivi_tab_num_dim+ 2\g_kivi_tab_price_dim +6\g_kivi_tabcolsep_dim},top=0pt,bottom=0pt,
172 lines~before~break=1,
174 \seq_use:Nn \g_kivi_extraDescription_seq {\\}
183 \tl_new:N \g_kivi_Pricing_colspec_tl
184 \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}@{}}
187 \clist_map_inline:nn {head, foot, firsthead, lastfoot} {%TODO reduce
188 \box_new:c {g_kivi_LT@#1_box}
192 \csname kivi_setup_LT_boxes:\endcsname
194 hmargin=\g_kivi_margin_dim,
195 top=\dim_eval:n {\g_kivi_margin_dim + \box_ht:N \g_kivi_LT@head_box},
196 bottom=\dim_eval:n {\g_kivi_margin_dim + \box_ht:N \g_kivi_LT@foot_box},
198 \savegeometry{kivi.letter@table}
199 \loadgeometry{kivi.letter@default}
202 \cs_new:Nn \kivi_setup_LT_boxes: {
204 \hbox_gset:Nn \g_kivi_LT@head_box {
205 \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
206 \exp_args:NnV \use:n {\tabular[b]}\g_kivi_Pricing_colspec_tl
208 \bfseries\position & \bfseries\artikelnummer & \bfseries\bezeichnung & \bfseries\menge &\multicolumn{1}{P}{\bfseries\einzelpreis}&\multicolumn{1}{P@{}}{\bfseries\gesamtpreis}\\
212 \hbox_gset:Nn \g_kivi_LT@foot_box {
214 \begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}r@{}}
216 \strut\weiteraufnaechsterseite
223 %Macht es sinn hier eine Variante zu machen, in der alle Spalten Belegbar sind?
224 \newenvironment{PricingTotal}{
225 \tabular[t]{@{}p{\dim_eval:n {\linewidth-\g_kivi_tab_price_dim-2\tabcolsep}}P@{}}
228 \bottomrule\endtabular
231 \newcommand{\ExtraDescription}[1]{\seq_gput_right:Nn \g_kivi_extraDescription_seq {#1}}
233 \newenvironment{PricingTabular}[1][]{
235 \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
237 \exp_args:NV \longtable \g_kivi_Pricing_colspec_tl
240 \bfseries\position & \bfseries\artikelnummer & \bfseries\bezeichnung & \bfseries\menge &\multicolumn{1}{P}{\bfseries\einzelpreis}&\multicolumn{1}{P@{}}{\bfseries\gesamtpreis}\\
244 \multicolumn{6}{@{}r@{}}{\weiteraufnaechsterseite}\\
251 \RequirePackage{xltabular}
254 \newenvironment{SimpleTabular}[1][\bfseries\position & \bfseries\menge & \bfseries\bezeichnung]
256 \setlength{\tabcolsep}{\g_kivi_tabcolsep_dim}
257 \xltabular{\linewidth}{@{}rrX@{}}
262 \multicolumn{3}{@{}>{\raggedright}p{\linewidth}@{}}{\weiteraufnaechsterseite}\\
268 \def\@currenvir{tabularx}
273 \usepackage{afterpage}
275 \cs_new:cpn {PricingTabular*}{
276 \bool_gset_true:N \g_kivi_inTable_bool
278 \@nameuse{Gm@restore@@kivi.letter@table}%
281 \def \@currenvir {PricingTabular*}\edef \@currenvline {\on@line }
282 \int_gset:Nn \g_PricingTabular_firstpage_int {\c@page}
283 \addtolength{\vsize}{-\box_ht:N \g_kivi_LT@foot_box}
287 \bool_gset_true:N \g_kivi_TableFoot_bool
288 \pagestyle{kivitendo.letter.PricingTable}
289 \leavevmode\box_use:N \g_kivi_LT@head_box
290 \par\nointerlineskip\ignorespaces
293 \cs_new:cpn {endPricingTabular*} {
294 \int_compare:nNnF \g_PricingTabular_firstpage_int = \c@page {\thispagestyle{kivitendo.letter.PricingTable}}
295 \bool_gset_false:N \g_kivi_TableFoot_bool
296 \@nameuse{Gm@restore@@kivi.letter@default}
298 \bool_gset_true:N \g_kivi_restore_geometry_bool
300 \kivi_conditional_restore_geometry:
304 \cs_new:Nn \kivi_conditional_restore_geometry: {
305 \bool_if:NT \g_kivi_restore_geometry_bool
307 \@nameuse{Gm@restore@@kivi.letter@default}
310 \bool_gset_false:N \g_kivi_restore_geometry_bool
316 \setkomavar{location}{
317 \ifkomavarempty{transaction}{}{
319 \usekomavar{transaction}
323 \begin{tabularx}{\useplength{locwidth}}{@{}l<{:}>{\raggedleft\arraybackslash}X@{}}
324 \usekomavar*{date}&\usekomavar{date}\\
325 \ifkomavarempty{myref}{}{
326 \usekomavar*{myref}&\usekomavar{myref}\\
328 \kundennummer&\usekomavar{customer}\\
329 \ifkomavarempty{yourref}{}{
330 \usekomavar*{yourref}&\usekomavar{yourref}\\
332 \ifkomavarempty{delivery}{}{
333 \usekomavar*{delivery}&\usekomavar{delivery}\\
335 \ifkomavarempty{quote}{}{
336 \usekomavar*{quote}&\usekomavar{quote}\\
338 \ifkomavarempty{orderID}{}{\auftragsnummer&\usekomavar{orderID}\\}
339 \ifkomavarempty{projectID}{}{\projektnummer&\usekomavar{projectID}\\}
340 \ansprechpartner&\usekomavar{fromname}
341 \ifkomavarempty{fromphone}{}{\\\textTelefon&\usekomavar{fromphone}}
342 \ifkomavarempty{fromemail}{}{\\\textEmail&\usekomavar{fromemail}}
347 \ifdim\ht\shippingAddressBox>\z@
348 \addtoplength{refvpos}{\ht\shippingAddressBox}
349 \addtoplength{refvpos}{4\baselineskip}
357 \renewcommand*{\raggedsignature}{\raggedright}