summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/zugferd/zugferd.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/zugferd/zugferd.dtx')
-rw-r--r--Master/texmf-dist/source/latex/zugferd/zugferd.dtx169
1 files changed, 106 insertions, 63 deletions
diff --git a/Master/texmf-dist/source/latex/zugferd/zugferd.dtx b/Master/texmf-dist/source/latex/zugferd/zugferd.dtx
index 83b080e77c6..53ad030fad0 100644
--- a/Master/texmf-dist/source/latex/zugferd/zugferd.dtx
+++ b/Master/texmf-dist/source/latex/zugferd/zugferd.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2021–2024 Marei Peischl <marei@peitex.de>
+% Copyright (C) 2021–2025 Marei Peischl <marei@peitex.de>
% ---------------------------------------------------------
%
% This file may be distributed and/or modified under the
@@ -16,14 +16,14 @@
% \fi
% \iffalse
%<*driver>
-\ProvidesFile{zugferd.dtx}[2024-12-08 v0.9c ZUGFerd Invoice and Faktur-X]
+\ProvidesFile{zugferd.dtx}[2025-01-02 v0.9d ZUGFerd Invoice and Faktur-X]
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[2023-11-01]
-%<package>\ProvidesExplPackage{zugferd}{2024-12-08}{0.9c}{Create ZUGFerd invoices using LaTeX}
+%<package>\ProvidesExplPackage{zugferd}{2025-01-02}{0.9d}{Create ZUGFerd invoices using LaTeX}
%<*driver>
\DocumentMetadata{pdfstandard=a-3b,lang=en}
\documentclass[lm-default=false,cs-break-nohyphen]{l3doc}
-\usepackage{zugferd}[2024-12-08]
+\usepackage{zugferd}[2025-01-02]
\EnableCrossrefs
%\CodelineIndex
\RecordChanges
@@ -220,6 +220,15 @@
author={Peischl, Marei},
url={https://github.com/TeXhackse/LaTeX-ZUGFeRD}
}
+@online{hyperref,
+ title = {CTAN: Package hyperref},
+ urldate = {2025-01-02},
+ language = {english},
+ author={Rahtz, Sebastian and Oberdiek, Heiko and {The \LaTeX{} Project}},
+ date={2024-11-05},
+ url = {https://ctan.org/pkg/hyperref},
+ documentation = {ctan://macros/latex/contrib/hyperref/doc/hyperref-doc.pdf}
+}
\end{filecontents}
\addbibresource{zugferd.bib}
\nocite{cl-recommendations}
@@ -384,16 +393,10 @@
%
% The option \option{xrechnung} is only used internally to set the global parameters for all |xrechnung| variants.
%
-% \DescribeKeyOption{auto-exemption=\meta{boolean}}{true}
-% \pkg{zugferd} tries to automatically add an exemption-reason for the most common VAT categories.
-% In case a more specific reason is required this setting can be disabled and everything should be configured manually.
-% See \autoref{sec:tax-category} for more explanation of this feature and the categories this applies to.
-%
% \end{documentation}
% \begin{implementation}
-% \begin{optionenv}{format,xrechnung,write-xml,zugferd,xml-file,auto-exemption}
+% \begin{optionenv}{format,xrechnung,write-xml,zugferd,xml-file}
% \changes{v0.9a}{2024-11-07}{Add support for format=minimum}
-% \changes{v0.7}{2024-09-10}{Added auto-exemption option}
% \begin{macrocode}
\char_set_catcode_other:N \#%
\keys_define:nn {zugferd} {
@@ -452,25 +455,59 @@
xml-file .tl_gset:N = \g_@@_xml_file_tl,
xml-file .initial:n = \jobname _zugferd.xml,
xml-file .usage:n = load,
+% \end{macrocode}
+% \end{optionenv}
+% \end{implementation}
+% \begin{documentation}
+% \DescribeKeyOption{auto-exemption=\meta{boolean}}{true}
+% \pkg{zugferd} tries to automatically add an exemption-reason for the most common VAT categories.
+% In case a more specific reason is required this setting can be disabled and everything should be configured manually.
+% See \autoref{sec:tax-category} for more explanation of this feature and the categories this applies to.
+%
+% \end{documentation}
+% \begin{implementation}
+% \changes{v0.7}{2024-09-10}{Added auto-exemption option}
+% \begin{optionenv}{auto-exemption}
+% \begin{macrocode}
auto-exemption .bool_gset:N = \g_@@_auto_exemption_bool,
auto-exemption .initial:n = true,
auto-exemption .default:n = true,
- auto-exemption .usage:n =load,
+ auto-exemption .usage:n = load,
+% \end{macrocode}
+% \end{optionenv}
+% \end{implementation}
+% \begin{documentation}
+% \DescribeKeyOption{unknown-value-warning=\meta{boolean}}{true}
+% There are predefined values for units, tax categories and payment-means.
+% Since there are a lot of options \pkg{zugferd} does not define all of them.
+% In case you want to use another one as the predefined options you there will a warning to make you aware of the fact, that the package does not know if that's a valid selection.
+% This is to help you avoiding typos.
+% In case you are sure about your selection and don't want to define an own value for this you can also disable the warning by setting \option{unknown-value-warning} to false.
+%
+% \end{documentation}
+% \begin{implementation}
+% \changes{v0.9d}{2025-01-02}{Added unknown-value-warning option}
+% \begin{optionenv}{unknown-value-warning}
+% \begin{macrocode}
+ unknown-value-warning .bool_gset:N = \g_@@_unknown_value_warning_bool,
+ unknown-value-warning .initial:n = true,
+% \end{macrocode}
+% \end{optionenv}
+% \begin{macrocode}
}
\char_set_catcode_parameter:N \#%
\ProcessKeyOptions[zugferd]
% \end{macrocode}
-% \end{optionenv}
% \subsection{Preparation to write the \file{.xml} file}
% \begin{variable}{\_@@_xml_writer_iow}
% \begin{macrocode}
\iow_new:N \_@@_xml_writer_iow
% \end{macrocode}
% \end{variable}
-% To adjust the metadata it is necessary to use the \pkg{pdfmanagement-testphase} by \citeauthor{pdfmanagement-testphase}.
+% To adjust the metadata it is necessary to use the \pkg{pdfmanagement-testphase} by Ulrike Fischer from the \LaTeX{} Project Team.
% She had prepared some experiment files for the PDF attachment in the experiments of the repository.
-% We use these to embed the \XML file.
+% We use these to embed the \XML file \issue{7}.
%
% This part prepares the XMP metadata according to the required scheme.
% \changes{v0.8a}{2024-09-17}{Use the new public interface for l3pdfmeta.}
@@ -558,8 +595,9 @@
% \end{syntax}
% \DescribeMacro{\SetZUGFeRDData}
% \DescribeMacro[noindex]{\SetZugferdData}
-% The two modes of \cs[no-index]{SetZUGFeRDData} control if the argument is expanded before the fields are set.
+% The two modes of \cs[no-index]{SetZUGFeRDData} control if the argument is expanded before the data is processed.
% Depending on the source of the data this might be necessary.
+% In that case activate the expansion by using the star argument.
% Fields which are involved in the calculation will be expanded anyway, but the text fields will not, to support special characters.
%
% \end{documentation}
@@ -613,12 +651,15 @@
% To simplify the usage in letters we also add fields to be able to use the zugferd data within \LaTeX{} output.
% Country is still missing.
% \begin{macrocode}
+\NewExpandableDocumentCommand{\UseZUGFeRDElement}{m}{
+ \tl_use:c {l_@@_#1_tl}
+}
\NewDocumentCommand{\InsertZUGFeRDData}{om}{
\str_case:nnF {#1} {
% \end{macrocode}
% \begin{macrocode}
{AddressData} {
- \clist_map_inline:nn {name, lineone, linetwo} {
+ \clist_map_inline:nn {name, lineone, linetwo,linethree} {
\prop_if_in:cnT {g_@@_#2_AddressData_prop } {##1} {
\prop_item:cn {g_@@_#2_AddressData_prop } {##1}\\
}
@@ -820,7 +861,7 @@
% \DescribeMacro{\zugferd_write_Item:ennnnnn}
% This is grouping the command and adding an argument in front to add additional options.
% \begin{syntax}
-% \cs[no-index]{zugferd_write_Item:nnnnn}
+% \cs[no-index]{zugferd_write_Item:nnnnnnn}
% \marg{additional local options}
% \marg{LineID}\marg{optional: item id (\enquote{SellerAssignedID})}\marg{item name}
% \marg{NetPriceProductTradePrice}
@@ -1396,7 +1437,9 @@
}
{\keys_set:nx { zugferd } {unit= {\str_uppercase:f {#1}}}}
{
- \msg_warning:nnn { zugferd } {unknown-value} {currency} {#1}
+ \bool_if:NT \g_@@_unknown_value_warning_bool {
+ \msg_warning:nnn { zugferd } {unknown-value} {currency} {#1}
+ }
\tl_set:Ne \l_@@_currency_tl {\str_uppercase:f {#1}}
}
},
@@ -1467,6 +1510,8 @@
% \DescribeKeyOption{add-note=\meta{Tokenlist}}{}*
% The ZUGFeRD example files\cite{zugferd-download} use all visible data to add them to the \XML as a note.
% \option{subject} and \option{fromaddress} are used to support this.
+% \changes{v0.9d}{2025-01-02}{Add note on subject not being the same as subject-code \issue{35}.}%
+% Please be aware that \option{subject-code} is not the same as \option{subject} even if some viewers might display it like that, \issue{35}.
% The data should not be too relevant but \pkg{zugferd} want's to support adding additional data to the \XML using the note element.
% So these fields can be left out but in case they are not empty, they will also be written to the \XML.
%
@@ -1620,25 +1665,25 @@
\seq_set_split:Nnn \l_tmpa_seq {\\} {##1}
%TODO error if more than 2 lines or only 1
\keys_set:nx {zugferd / #1} {
- lineone=\seq_item:Nn \l_tmpa_seq {1},
- linetwo=\seq_item:Nn \l_tmpa_seq {2},
- linethree=\seq_item:Nn \l_tmpa_seq {3}
+ lineone={\seq_item:Nn \l_tmpa_seq {1}},
+ linetwo={\seq_item:Nn \l_tmpa_seq {2}},
+ linethree={\seq_item:Nn \l_tmpa_seq {3}}
}
},
contact .code:n = {
\seq_set_split:Nnn \l_tmpa_seq {\\} {##1}
\int_compare:nNnTF {\seq_count:N \l_tmpa_seq} > {3} {
\keys_set:ne {zugferd/#1} {
- contact-name = \seq_item:Nn \l_tmpa_seq {1},
- contact-department = \seq_item:Nn \l_tmpa_seq {2},
- contact-phone = \seq_item:Nn \l_tmpa_seq {3},
- contact-email= \seq_item:Nn \l_tmpa_seq {4}
+ contact-name = {\seq_item:Nn \l_tmpa_seq {1}},
+ contact-department = {\seq_item:Nn \l_tmpa_seq {2}},
+ contact-phone = {\seq_item:Nn \l_tmpa_seq {3}},
+ contact-email= {\seq_item:Nn \l_tmpa_seq {4}},
}
}{
\keys_set:ne {zugferd/#1} {
- contact-name = \seq_item:Nn \l_tmpa_seq {1},
- contact-phone = \seq_item:Nn \l_tmpa_seq {2},
- contact-email= \seq_item:Nn \l_tmpa_seq {3}
+ contact-name = {\seq_item:Nn \l_tmpa_seq {1}},
+ contact-phone = {\seq_item:Nn \l_tmpa_seq {2}},
+ contact-email= {\seq_item:Nn \l_tmpa_seq {3}},
}
}
},
@@ -1727,23 +1772,15 @@
\_@@_define_xml_content:Nn \_@@_PostalTradeAddress:nnnnnnn {%
<ram:PostalTradeAddress>
\bool_if:NF \g_@@_minimum_bool {%
- \_@@_indent: <ram:PostcodeCode>#1</ram:PostcodeCode>
- \tl_if_blank:nF {#2} {%
- \_@@_indent: <ram:LineOne>#2</ram:LineOne>
- }%
- \tl_if_blank:nF {#3} {%
- \_@@_indent: <ram:LineTwo>#3</ram:LineTwo>
- }%
- \tl_if_blank:nF {#4} {%
- \_@@_indent: <ram:LineThree>#4</ram:LineThree>
- }%
- \_@@_indent: <ram:CityName>#5</ram:CityName>
+ \_@@_write_inline_i:nn {ram:PostcodeCode} {#1}
+ \_@@_write_inline_i:nn {ram:LineOne} {#2}
+ \_@@_write_inline_i:nn {ram:LineTwo} {#3}
+ \_@@_write_inline_i:nn {ram:LineThree} {#4}
+ \_@@_write_inline_i:nn {ram:CityName} {#5}
}%
\_@@_indent: <ram:CountryID>#6</ram:CountryID>
\bool_if:NF \g_@@_minimum_bool {%
- \tl_if_blank:nF {#7} {%
- \_@@_indent: <ram:CountrySubDivisionName>#7</ram:CountrySubDivisionName>
- }%
+ \_@@_write_inline_i:nn {ram:CountrySubDivisionName} {#7}
}%
</ram:PostalTradeAddress>%
}%
@@ -1780,19 +1817,9 @@
\bool_if:NT \g_@@_writeTradeContact_bool {%
<ram:DefinedTradeContact>
\_@@_indent: <ram:PersonName>#1</ram:PersonName>
- \tl_if_blank:nF {#2} {%
- \_@@_indent: <ram:DepartmentName>#2</ram:DepartmentName>
- }%
- \tl_if_blank:nF {#3} {%
- \_@@_indent: <ram:TelephoneUniversalCommunication>
- \_@@_indent:n {2} <ram:CompleteNumber>#3</ram:CompleteNumber>
- \_@@_indent: </ram:TelephoneUniversalCommunication>
- }%
- \tl_if_blank:nF {#4} {%
- \_@@_indent: <ram:EmailURIUniversalCommunication>
- \_@@_indent:n {2} <ram:URIID>#4</ram:URIID>
- \_@@_indent: </ram:EmailURIUniversalCommunication>
- }%
+ \_@@_write_inline_i:nn {ram:DepartmentName} {#2}
+ \_@@_write_inline_wrapped_i:nnn {ram:TelephoneUniversalCommunication} {ram:CompleteNumber} {#3}
+ \_@@_write_inline_wrapped_i:nnn {ram:EmailURIUniversalCommunication} {ram:URIID} {#4}
</ram:DefinedTradeContact>%
}%
}%
@@ -1917,10 +1944,10 @@
\clist_new:N \g_@@_buyer_document_references_clist
\keys_define:nn {zugferd} {
contract-reference .prop_gput:N = \g_@@_document_references_prop,
- purchaseorder-reference .prop_gput:N = \g_@@_document_references_prop,
- purchase-order-reference .meta:n = {purchaseorder-reference=#1},
- salesorder-reference .prop_gput:N = \g_@@_document_references_prop,
- sales-order-reference .meta:n = {salesorder-reference=#1},
+ buyerorder-reference .prop_gput:N = \g_@@_document_references_prop,
+ purchase-order-reference .meta:n = {buyerorder-reference=#1},
+ sellerorder-reference .prop_gput:N = \g_@@_document_references_prop,
+ sales-order-reference .meta:n = {sellerorder-reference=#1},
}
\cctab_begin:N \g_@@_xml_cctab%
\_@@_define_xml_writer:Nn \_@@_write_ReferencedDocument:n {%
@@ -1999,7 +2026,9 @@
\tl_gset_eq:NN \g_@@_payment_means_tl \l_keys_choice_tl
},
payment-means / unknown .code:n = {
- \msg_warning:nnn { zugferd } {unknown-value} {payment-means} {#1}
+ \bool_if:NT \g_@@_unknown_value_warning_bool {
+ \msg_warning:nnn { zugferd } {unknown-value} {payment-means} {#1}
+ }
\tl_gset:Nn \g_@@_payment_means_tl {\int_eval:n {#1}}
}
}
@@ -2073,7 +2102,9 @@
{
\keys_set:ne { zugferd } {unit= {\l_tmpa_tl}}
} {
- \msg_warning:nnn { zugferd } {unknown-unit} {#1}
+ \bool_if:NT \g_@@_unknown_value_warning_bool {
+ \msg_warning:nnn { zugferd } {unknown-unit} {#1}
+ }
\tl_set_eq:NN \l_@@_unit_code_tl \l_tmpa_tl
}
},
@@ -2223,7 +2254,10 @@
{
\keys_set:nx { zugferd } {category= {\str_uppercase:f {#1}}}
} {
- \msg_warning:nnn { zugferd } {unknown-tax-category} {#1}
+ \tl_set:Ne \l_@@_tax_category_code_tl {\str_uppercase:f {#1}}
+ \bool_if:NT \g_@@_unknown_value_warning_bool {
+ \msg_warning:nnn { zugferd } {unknown-tax-category} {#1}
+ }
}
},
category .initial:n = S,
@@ -2279,6 +2313,15 @@
<#1#2>#3</#1>
}
}
+\_@@_define_xml_content:Nn \_@@_write_inline_wrapped:nnnn {
+ \_@@_indent:n {#1} <#2>\_@@_xml_newline_indent:
+ \_@@_indent:n {#1+1} <#3>#4</#3>\_@@_xml_newline_indent:
+ \_@@_indent:n {#1} </#2>
+}
+\_@@_define_xml_content:Nn \_@@_write_inline_wrapped_i:nnn {
+ \_@@_write_inline_wrapped:nnnn {1} {#1} {#2} {#3}
+}
+
\cs_generate_variant:Nn \_@@_write_inline:nn {ne}
\_@@_define_xml_content:Nn \_@@_write_inline_i:nnn {
\_@@_indent: \_@@_write_inline:nnn {#1} {#2} {#3}