texlive[73081] Master/texmf-dist: zugferd (9dec24)
commits+karl at tug.org
commits+karl at tug.org
Mon Dec 9 22:13:34 CET 2024
Revision: 73081
https://tug.org/svn/texlive?view=revision&revision=73081
Author: karl
Date: 2024-12-09 22:13:34 +0100 (Mon, 09 Dec 2024)
Log Message:
-----------
zugferd (9dec24)
Modified Paths:
--------------
trunk/Master/texmf-dist/doc/latex/zugferd/DEMO-rechnung-zugferd.pdf
trunk/Master/texmf-dist/doc/latex/zugferd/DEMO-rechnung-zugferd.tex
trunk/Master/texmf-dist/doc/latex/zugferd/README.md
trunk/Master/texmf-dist/doc/latex/zugferd/zugferd.pdf
trunk/Master/texmf-dist/source/latex/zugferd/zugferd.dtx
trunk/Master/texmf-dist/tex/latex/zugferd/zugferd-invoice.sty
trunk/Master/texmf-dist/tex/latex/zugferd/zugferd.sty
Modified: trunk/Master/texmf-dist/doc/latex/zugferd/DEMO-rechnung-zugferd.pdf
===================================================================
(Binary files differ)
Modified: trunk/Master/texmf-dist/doc/latex/zugferd/DEMO-rechnung-zugferd.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zugferd/DEMO-rechnung-zugferd.tex 2024-12-09 21:13:19 UTC (rev 73080)
+++ trunk/Master/texmf-dist/doc/latex/zugferd/DEMO-rechnung-zugferd.tex 2024-12-09 21:13:34 UTC (rev 73081)
@@ -1,7 +1,7 @@
% !TeX Program=lualatex
%
% Demo file for the LaTeX-ZUGFeRD project
-% This file corresponds to version 0.9b (2024-11-17)
+% This file corresponds to version 0.9c (2024-12-08)
%
% Copyright (C) 2024 Marei Peischl <marei at peitex.de>
% ---------------------------------------------------------
Modified: trunk/Master/texmf-dist/doc/latex/zugferd/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/zugferd/README.md 2024-12-09 21:13:19 UTC (rev 73080)
+++ trunk/Master/texmf-dist/doc/latex/zugferd/README.md 2024-12-09 21:13:34 UTC (rev 73081)
@@ -2,7 +2,7 @@
Copyright (C) 2023–2024 by Marei Peischl (peiTeX) <marei at peitex.de>
-zugferd version 0.9b (2024-11-17)
+zugferd version 0.9c (2024-12-08)
***************************************************************************
@@ -23,6 +23,10 @@
## Version History
+* 0.9c (2024-12-08)
+ - extend address interface
+ - add document reference fields
+ - fix bug adding the PDF attachment entry twice
* 0.9b (2024-11-17)
- Rename embedded xml-file if xrechnung is used
- Fix bug leaving an unescaped `\n` in the output
Modified: trunk/Master/texmf-dist/doc/latex/zugferd/zugferd.pdf
===================================================================
(Binary files differ)
Modified: trunk/Master/texmf-dist/source/latex/zugferd/zugferd.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/zugferd/zugferd.dtx 2024-12-09 21:13:19 UTC (rev 73080)
+++ trunk/Master/texmf-dist/source/latex/zugferd/zugferd.dtx 2024-12-09 21:13:34 UTC (rev 73081)
@@ -16,14 +16,14 @@
% \fi
% \iffalse
%<*driver>
-\ProvidesFile{zugferd.dtx}[2024-11-17 v0.9b ZUGFerd Invoice and Faktur-X]
+\ProvidesFile{zugferd.dtx}[2024-12-08 v0.9c ZUGFerd Invoice and Faktur-X]
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[2023-11-01]
-%<package>\ProvidesExplPackage{zugferd}{2024-11-17}{0.9b}{Create ZUGFerd invoices using LaTeX}
+%<package>\ProvidesExplPackage{zugferd}{2024-12-08}{0.9c}{Create ZUGFerd invoices using LaTeX}
%<*driver>
\DocumentMetadata{pdfstandard=a-3b,lang=en}
\documentclass[lm-default=false,cs-break-nohyphen]{l3doc}
-\usepackage{zugferd}[2024-11-17]
+\usepackage{zugferd}[2024-12-08]
\EnableCrossrefs
%\CodelineIndex
\RecordChanges
@@ -228,7 +228,7 @@
\newcommand*{\XML}{XML\xspace}
\newcommand*{\XMLfile}{\XML file}
-\newcommand*{\issue}[1]{%
+\DeclareRobustCommand{\issue}[1]{%
{\DeclareFieldFormat{citeurlpostfix}{\href{##1/issues/#1}{\##1}}\citefield{LaTeX-ZUGFeRD-GitHub}[citeurlpostfix]{url}}%
}
\newcommand*{\version}[1]{v#1}
@@ -487,8 +487,9 @@
}
% \end{macrocode}
% \changes{v0.9a}{2024-11-07}{Add error message if pdfmanagement is outdated.}
+% \changes{v0.9c}{2024-12-08}{Compatbility to show the error message in older formats versions.}
% \begin{macrocode}
- \IfPackageAtLeastF{pdfmanagement-testphase}{2024/09/13}{
+ \IfPackageAtLeastTF{pdfmanagement-testphase}{2024/09/13}{}{
\msg_new:nnn {zugferd} {PDFmanagement-too-old} {
Your~version~of~\LaTeX's~PDF~management~is~too~old.
You~need~to~update~your~LaTeX~distribution~to~be~able~to~use~the~zugferd~package~correctly.
@@ -753,20 +754,17 @@
\pdfdict_put:nnn {l_pdffile/Filespec} {Desc}{(Factur-X/ZUGFeRD-Rechnung)}
\exp_args:NnV \pdffile_embed_file:nnn {\g_@@_xml_file_tl} \g_@@_xml_embedded_file_tl
{zugferd/rechnung}
+ \group_end:
% \end{macrocode}
% Since some tools require the Catalog entry to match the file name of the embedded file this this has to be set separately (\issue{26}).
% \changes{v0.9b}{2024-11-17}{Fix file name of embedded file for the zugferd profile.}
+% \changes{v0.9c}{2024-12–08}{Remove second catalog entry linking to xml \issue{32}}
% \begin{macrocode}
- \pdfmanagement_add:nee
- {Catalog/Names/EmbeddedFiles}
- {\g_@@_xml_embedded_file_tl}
- {\pdf_object_ref:n{zugferd/rechnung}}
- \group_end:
- \pdfmanagement_add:nnx
- {Catalog/Names}
- {EmbeddedFiles}
+ \pdfmanagement_add:nee
+ {Catalog/Names/EmbeddedFiles}
+ {\g_@@_xml_embedded_file_tl}
{\pdf_object_ref:n{zugferd/rechnung}}
- % steht in der docu ist aber pdf 2.0 ....
+ % steht in der doku ist aber pdf 2.0 ....
\pdfmanagement_add:nnx{Catalog}{AF}{\pdf_object_ref:n{zugferd/rechnung}}
}
}
@@ -844,6 +842,8 @@
% And this will also print the \enquote{SpecifiedTradeSettlementPaymentMeans}, see \autoref{sec:PaymentMeans}.
%
% \DescribeMacro{\zugferd_write_TaxEntry:nnnn}
+% \DescribeMacro{\zugferd_write_TaxEntry:ennn}
+% \changes{v0.9c}{2024-12-08}{Added \cs{zugferd_write_TaxEntry:ennn} variant}
% This command is writing the sum over a tax rate. This command has to be used once per rate applied to the items.
% \begin{syntax}
% \cs[no-index]{zugferd_write_TaxEntry:nnnn} \marg{tax category code} \marg{tax rate in \%} \marg{basis amount the tax applies to} \marg{tax amount}
@@ -933,7 +933,7 @@
% \end{macrocode}
% \end{function}
% \changes{v0.9}{2024-10-23}{Add interface using an argument for the keyval options locally per item}
-% \begin{function}{\_@@_write_Item:nnnnnnn}
+% \begin{function}{\zugferd_write_Item:nnnnnnn}
% \begin{macrocode}
\cs_new:Nn \zugferd_write_Item:nnnnnnn {
\group_begin:
@@ -944,6 +944,11 @@
\cs_generate_variant:Nn \zugferd_write_Item:nnnnnnn {ennnnnn}
% \end{macrocode}
% \end{function}
+% \begin{function}{\zugferd_write_TaxEntry:ennn}
+% \begin{macrocode}
+\cs_generate_variant:Nn \zugferd_write_TaxEntry:nnnn {ennn}
+% \end{macrocode}
+% \end{function}
% \begin{function}{\_@@_write_xml:n,\_@@_define_xml_writer:Nn,\_@@_define_xml_content:Nn}
% These commands are used to toggle the writing of the \XMLfile. This corresponds to the option \option{write-xml}.
% \begin{macrocode}
@@ -1069,22 +1074,25 @@
% \fi
% \begin{macrocode}
\cs_new:Nn \zugferd_disable_macros: {
- \let\{\textbraceleft
- \let\}\textbraceright
- \let\\\textbackslash
- \let\#\textnumbersign
- \let\$\textdollar
+ \let\{\c_left_brace_str
+ \let\textbraceleft\c_left_brace_str
+ \let\}\c_right_brace_str
+ \let\textbraceright\c_right_brace_str
+ \let\#\c_hash_str
% \end{macrocode}
% This only is a part of the list.
% There is no real use of printing the whole list, it's inside \file{zugferd.sty} anyway.
% \comment
% \begin{macrocode}
- \let\%\textpercent
- \let\&\textampersand
- \let\_\textunderscore
- \let\P\textparagraph
- \let\ldots\textellipsis
- \let\dots\textellipsis
+ \let\textnumbersign\c_hash_str
+ \let\$\c_dollar_str
+ \let\textdollar\c_dollar_str
+ \let\%\c_percent_str
+ \let\&\c_ampersand_str
+ \let\_\c_underscore_str
+ \def\P{§}
+ \def\ldots{…}
+ \def\dots{…}
\def\\{\space}%
\def\newline{\space}%
\def\TeX{TeX}%
@@ -1188,6 +1196,55 @@
% \end{function}
% \end{implementation}
% \begin{documentation}
+% \DescribeMacro{\zugferd_tl_set_escaped_xml:Nn}
+% \DescribeMacro{\zugferd_tl_gset_escaped_xml:Nn}
+% \changes{v0.9c}{2024-12-08}{Added mechanism to escape XML special characters.}
+% As described before and also in \issue{9} there are characters which are special in \XML but not within \LaTeX.
+% Additionally there also are characters which aren't special in \LaTeX{} but within \XML.
+% In version \version{0.9c} \pkg{zugferd} added some auxiliary commands to support users escaping those.
+% This mechanism involves turning the category codes of characters like |"<>'&| to active and might have side effects.
+% It is an experimental feature and should be handled with care!
+% \end{documentation}
+% \begin{implementation}
+% \begin{macrocode}
+\tl_new:N \g_@@_tmp_tl
+\cs_new:Nn \zugferd_tl_gset_escaped_xml:Nn {
+ \group_begin:
+ \zugferd_disable_macros:
+ \_@@_escape_xml_aux:
+ \tl_gset_rescan:Nnn #1 {
+ \cctab_select:N \c_str_cctab
+ \_@@_escape_xml_activate:
+ } {#2}
+ \tl_gset:Ne #1 {#1}
+ \group_end:
+}
+\cs_new:Nn \zugferd_tl_set_escaped_xml:Nn {
+ \zugferd_tl_gset_escaped_xml:Nn \g_@@_tmp_tl {#2}
+ \tl_set_eq:NN #1 \g_@@_tmp_tl
+}
+\cs_new:Nn \_@@_escape_xml_aux: {
+ \edef\&{\tl_to_str:n {&}}
+ \edef\textgreater{\tl_to_str:n {>}}
+ \edef\textless{\tl_to_str:n {<}}
+ \edef\textquotedbl{\tl_to_str:n {"}}
+ \edef\textquotesingle{\tl_to_str:n {'}}
+ \char_set_active_eq:NN > \textgreater
+ \char_set_active_eq:NN < \textless
+ \char_set_active_eq:NN " \textquotedbl
+ \char_set_active_eq:NN ' \textquotesingle
+ \char_set_active_eq:NN & \&
+}
+\cs_new:Nn \_@@_escape_xml_activate: {
+ \char_set_catcode_active:N >
+ \char_set_catcode_active:N <
+ \char_set_catcode_active:N "
+ \char_set_catcode_active:N '
+ \char_set_catcode_active:N &
+}
+% \end{macrocode}
+% \end{implementation}
+% \begin{documentation}
% \subsection{Rounding Interface}
% \label{sec:rounding-interface}
% \changes{v0.9a}{2024-11-07}{Add public interface for the rounding mechanism.}
@@ -1268,8 +1325,19 @@
% \end{macrocode}
% \end{implementation}
% \begin{documentation}
-% \DescribeKeyOption{document-type=commercial-invoice}{commercial-invoice}
-% Select the document type. The only supported value currently is |commercial-invoice|. This will select the corresponding type code, which is 380.
+% \DescribeKeyOption{document-type=\meta{type}}{commercial-invoice}
+% Select the document type. Since \version{0.9c} \pkg{zugferd} supports the following types:
+% \changes{v0.9c}{2024-12-08}{Add support for other invoice types.}
+% \begin{valuelist}
+% \item[commercial-invoice] 380
+% \item[partial-invoice] 326
+% \item[corrected-invoice] 384
+% \item[self-billed-invoice] 389
+% \item[credit-note] 381
+% \item[partial-construction-invoice] 875
+% \item[partial-final-construction-invoice] 876
+% \item[final-construction-invoice] 877
+% \end{valuelist}
% \end{documentation}
% \begin{implementation}
% \begin{optionenv}{id, document-type}
@@ -1277,6 +1345,20 @@
document-type .choice:,
document-type / commercial-invoice .code:n =
\tl_gset:Nn \g_@@_DocumentTypeCode_tl {380},
+ document-type / partial-invoice .code:n =
+ \tl_gset:Nn \g_@@_DocumentTypeCode_tl {326},
+ document-type / corrected-invoice .code:n =
+ \tl_gset:Nn \g_@@_DocumentTypeCode_tl {384},
+ document-type / self-billed-invoice .code:n =
+ \tl_gset:Nn \g_@@_DocumentTypeCode_tl {389},
+ document-type / credit-note .code:n =
+ \tl_gset:Nn \g_@@_DocumentTypeCode_tl {381},
+ document-type / partial-construction-invoice .code:n =
+ \tl_gset:Nn \g_@@_DocumentTypeCode_tl {875},
+ document-type / partial-final-construction-invoice .code:n =
+ \tl_gset:Nn \g_@@_DocumentTypeCode_tl {876},
+ document-type / final-construction-invoice .code:n =
+ \tl_gset:Nn \g_@@_DocumentTypeCode_tl {877},
document-type .initial:n = commercial-invoice,
% \end{macrocode}
% \end{optionenv}
@@ -1443,13 +1525,18 @@
% As this also depends on the selected scheme and version we will not list the details.
% All fields for a trade party can be set using the \enquote{group} named by the party.
% For example setting all the seller data is done in the following listing:
+% \changes{v0.9c}{2024-12-08}{Add support for extended Addresses including additionl legal data.}
% \begin{examplecode}
% \SetZUGFeRDData{
+% seller/id = {ID – usually internal ID provided by buyer},
% seller/name = {peiTeX (Marei Peischl)},
+% seller/legal-description = {Additional legal information},
+% seller/legal-id = {legal registration ID},
+% seller/trading-name = {trading name},
% seller/email = {invoicing at peitex.de},
% seller/vatid = {DE123456789},
% seller/contact= {Marei\\+4900000000\\marei at peitex.de},
-% seller/address = {Address Line 1\\Address Line 2},
+% seller/address = {Address Line 1\\Address Line 2\\Address Line 3},
% seller/postcode = {20253},
% seller/city ={Hamburg},
% seller/country = {DE},
@@ -1465,16 +1552,21 @@
% \DescribeKeyOption*{\meta{party}/name=\meta{name}}{}*
% \DescribeKeyOption*{\meta{party}/email=\meta{email address}}{}*
% \DescribeKeyOption*{\meta{party}/vatid=\meta{VAT ID}}{}*
+% \DescribeKeyOption*{\meta{party}/taxid=\meta{VAT ID}}{}*
+% \changes{v0.9c}{2024-12-08}{Add support for taxid.}
%
% \DescribeKeyOption*{\meta{party}/address=\meta{address}}{}*
-% As shown in the example \option{address} can use two lines separted by |\\|.
+% \changes{v0.9c}{2024-12-08}{Add support for third address line.}
+% As shown in the example \option{address} can use three lines separted by |\\|.
% It's possble to set all fields for all trade contacts, but e.\,g. for the |shipto|-party email and vatid will not be used in the \XML.
%
-% Alternatively it's also possible to use \option{\meta{party}/lineone} and \option{\meta{party/linetwo}} separately.
+% Alternatively it's also possible to use \option{\meta{party}/lineone}, \option{\meta{party}/linetwo} and \option{\meta{party}/linethree} separately.
% This may be helpful if you use a custom input format. In any way you should ensure that all macros used within the data either are expandable or disabled using \cs[no-index]{zugferd_disable_macros:}.
%
% \DescribeKeyOption*{\meta{party}/postcode=\meta{postal code}}{}*
% \DescribeKeyOption*{\meta{party}/city=\meta{city}}{}*
+% \DescribeKeyOption*{\meta{party}/subdivision=\meta{subdivision}}{}*
+% \changes{v0.9c}{2024-12-08}{Add support for subdivision.}
% \DescribeKeyOption*{\meta{party}/country=\meta{country code}}{}*
% The two letter country codes allowed here can be found in \cite{country-codes}.
%
@@ -1529,7 +1621,8 @@
%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}
+ linetwo=\seq_item:Nn \l_tmpa_seq {2},
+ linethree=\seq_item:Nn \l_tmpa_seq {3}
}
},
contact .code:n = {
@@ -1558,18 +1651,29 @@
% \end{macrocode}
% \end{variable}
% \end{optionenv}
-% \begin{function}{\_@@_PostalTradeAddress:N,\_@@_DefinedTradeContact:N}
+% \begin{function}{\_@@_TradePartyIdentity:N \_@@_PostalTradeAddress:N,\_@@_DefinedTradeContact:N}
% Wrappers to map the property list items to the writing macro.
+% \changes{v0.9c}{2024-12-08}{Add TradePartyName to support additional legal information.}
% \begin{macrocode}
+\cs_new:Nn \_@@_TradePartyIdentity:N {
+ \_@@_TradePartyIdentity:eeeee
+ {\prop_item:Nn #1 {id}}
+ {\prop_item:Nn #1 {name}}
+ {\prop_item:Nn #1 {legal-description}}
+ {\prop_item:Nn #1 {legal-id}}
+ {\prop_item:Nn #1 {trading-name}}
+}
\cs_new:Nn \_@@_PostalTradeAddress_short:N {
\exp_args:Ne \tl_if_blank:nF {\prop_item:Nn #1 {name}}
{<ram:Name>\prop_item:Nn #1 {name}</ram:Name>\iow_newline:\_@@_xml_auto_indent:}
- \_@@_PostalTradeAddress:eeeee
+ \_@@_PostalTradeAddress:eeeeeee
{\prop_item:Nn #1 {postcode}}
{\prop_item:Nn #1 {lineone}}
{\prop_item:Nn #1 {linetwo}}
+ {\prop_item:Nn #1 {linethree}}
{\prop_item:Nn #1 {city}}
{\prop_item:Nn #1 {country}}
+ {\prop_item:Nn #1 {subdivision}}
}
\cs_new:Nn \_@@_PostalTradeAddress:N {%
\_@@_PostalTradeAddress:eeeeeee
@@ -1576,10 +1680,12 @@
{\prop_item:Nn #1 {postcode}}
{\prop_item:Nn #1 {lineone}}
{\prop_item:Nn #1 {linetwo}}
+ {\prop_item:Nn #1 {linethree}}
{\prop_item:Nn #1 {city}}
{\prop_item:Nn #1 {country}}
- {\prop_item:Nn #1 {email}}
- {\prop_item:Nn #1 {vatid}}
+ {\prop_item:Nn #1 {subdivision}}
+ \_@@_UniversalCommunication:n {\prop_item:Nn #1 {email}}
+ \_@@_TaxRegistration:nn {\prop_item:Nn #1 {vatid}} {\prop_item:Nn #1 {taxid}}
}%
\cs_new:Nn \_@@_DefinedTradeContact:N {%
\_@@_DefinedTradeContact:eeee
@@ -1594,10 +1700,31 @@
\cctab_begin:N \g_@@_xml_cctab%
% \end{macrocode}
% \iffalse
-% \_@@_PostalTradeAddress:nnnnnnn Name/Firma PLZ Zeile1 Zeile2 Ort Ländercode Email UID
+% \_@@_TradePartyIdentity:eeeee ID Name description legal-id trading-name
% \fi
% \begin{macrocode}
-\_@@_define_xml_content:Nn \_@@_PostalTradeAddress:nnnnn {%
+\_@@_define_xml_content:Nn \_@@_TradePartyIdentity:nnnnn {%
+ %%<!-- BT-29 -->
+ \_@@_write_inline:nn {ram:ID} {#1}
+ %%<!-- BT-27 -->
+ \_@@_write_inline:nn {ram:Name} {#2}
+ %%<!-- BT-33 -->
+ \_@@_write_inline:nn {ram:Description} {#3}
+ \tl_if_blank:eF {#4#5} {%
+ <ram:SpecifiedLegalOrganization>
+ %%%<!-- BT-30 -->
+ \_@@_write_inline_i:nnn {ram:ID} {~schemeID="0088"} {#4}
+ %%<!-- BT-28 -->
+ \_@@_write_inline_i:nn {ram:TradingBusinessName} {#5}
+ </ram:SpecifiedLegalOrganization>
+ }%
+}%
+% \end{macrocode}
+% \iffalse
+% \_@@_PostalTradeAddress:nnnnnnn Name/Firma PLZ Zeile1 Zeile2 Zeile3 Ort Ländercode Bundesland/Bezirk
+% \fi
+% \begin{macrocode}
+\_@@_define_xml_content:Nn \_@@_PostalTradeAddress:nnnnnnn {%
<ram:PostalTradeAddress>
\bool_if:NF \g_@@_minimum_bool {%
\_@@_indent: <ram:PostcodeCode>#1</ram:PostcodeCode>
@@ -1607,27 +1734,43 @@
\tl_if_blank:nF {#3} {%
\_@@_indent: <ram:LineTwo>#3</ram:LineTwo>
}%
- \_@@_indent: <ram:CityName>#4</ram:CityName>
+ \tl_if_blank:nF {#4} {%
+ \_@@_indent: <ram:LineThree>#4</ram:LineThree>
+ }%
+ \_@@_indent: <ram:CityName>#5</ram:CityName>
}%
- \_@@_indent: <ram:CountryID>#5</ram:CountryID>
+ \_@@_indent: <ram:CountryID>#6</ram:CountryID>
+ \bool_if:NF \g_@@_minimum_bool {%
+ \tl_if_blank:nF {#7} {%
+ \_@@_indent: <ram:CountrySubDivisionName>#7</ram:CountrySubDivisionName>
+ }%
+ }%
</ram:PostalTradeAddress>%
-}
-\_@@_define_xml_content:Nn \_@@_PostalTradeAddress:nnnnnnn {%
- \_@@_PostalTradeAddress:nnnnn {#1} {#2} {#3} {#4} {#5}%
- \bool_lazy_or:nnF {\g_@@_minimum_bool}%
- {\tl_if_blank_p:n {#6}}%
- {%
- \_@@_xml_newline_indent:%
+}%
+\bool_if:NTF \g_@@_minimum_bool {%
+ \cs_set_eq:NN \_@@_UniversalCommunication:n \use_none:n%
+} {%
+ \_@@_define_xml_content:Nn \_@@_UniversalCommunication:n {%
+ \tl_if_blank:eF {#1} {
<ram:URIUniversalCommunication>
- \_@@_indent: <ram:URIID~schemeID="EM">#6</ram:URIID>
+ \_@@_indent: <ram:URIID~schemeID="EM">#1</ram:URIID>
</ram:URIUniversalCommunication>%
}%
- % TODO add support local tax id: schemaID="FC"
- \tl_if_empty:nF {#7} {
+ }%
+}%
+\_@@_define_xml_content:Nn \_@@_TaxRegistration:nn {%
+ %%%<!-- BT-34 -->
+ \tl_if_blank:eF {#1} {
<ram:SpecifiedTaxRegistration>
- \_@@_indent: <ram:ID~schemeID="VA">#7</ram:ID>
+ \_@@_indent: <ram:ID~schemeID="VA">#1</ram:ID>
</ram:SpecifiedTaxRegistration>%
}%
+ %%%<!-- BT-32 -->
+ \tl_if_blank:eF {#2} {
+ <ram:SpecifiedTaxRegistration>
+ \_@@_indent: <ram:ID~schemeID="FC">#2</ram:ID>
+ </ram:SpecifiedTaxRegistration>%
+ }%
}%
%
% Contact data phone/email to a specific contact person
@@ -1668,7 +1811,7 @@
\_@@_write_xml:n {<ram:SellerTradeParty>}%
\int_gincr:N \g_@@_indent_int%
\_@@_write_xml:e {%
- <ram:Name>\prop_item:Nn \g_@@_seller_AddressData_prop {name}</ram:Name>
+ \_@@_TradePartyIdentity:N \g_@@_seller_AddressData_prop
\_@@_DefinedTradeContact:N \g_@@_seller_AddressData_prop%
\_@@_PostalTradeAddress:N \g_@@_seller_AddressData_prop%
}%
@@ -1679,7 +1822,7 @@
}%
\int_gincr:N \g_@@_indent_int%
\_@@_write_xml:e {%
- <ram:Name>\prop_item:Nn \g_@@_buyer_AddressData_prop {name}</ram:Name>%
+ \_@@_TradePartyIdentity:N \g_@@_buyer_AddressData_prop
\bool_if:NF \g_@@_minimum_bool {
\_@@_DefinedTradeContact:N \g_@@_buyer_AddressData_prop%
\_@@_PostalTradeAddress:N \g_@@_buyer_AddressData_prop%
@@ -1687,6 +1830,9 @@
}%
\int_gdecr:N \g_@@_indent_int%
\_@@_write_xml:n {</ram:BuyerTradeParty>}%
+ \clist_map_inline:nn {SellerOrder,BuyerOrder,Contract} {%
+ \_@@_write_ReferencedDocument:n {##1}%
+ }%
\int_gdecr:N \g_@@_indent_int%
\_@@_write_xml:n {</ram:ApplicableHeaderTradeAgreement>}%
\bool_if:NTF \g_@@_minimum_bool%
@@ -1726,8 +1872,8 @@
}%
%
\cctab_end:
+\cs_generate_variant:Nn \_@@_TradePartyIdentity:nnnnn {eeeee}
\cs_generate_variant:Nn \_@@_DefinedTradeContact:nnnn {eeee}
-\cs_generate_variant:Nn \_@@_PostalTradeAddress:nnnnn {eeeee}%
\cs_generate_variant:Nn \_@@_PostalTradeAddress:nnnnnnn {eeeeeee}
\cs_generate_variant:Nn \_@@_ApplicableHeaderTradeDelivery:n {V}
% \end{macrocode}
@@ -1760,6 +1906,36 @@
% \end{optionenv}
% \end{implementation}
% \begin{documentation}
+% \subsubsection{Document references}
+% Additionally to the general buyer reference there may be additional data used by the buyer a reference.
+% These fields are technically optional, but the buyer may enforce them to be used.
+% These were not supported before \version{0.9c}.
+% \end{documentation}
+% \begin{implementation}
+% \begin{macrocode}
+\prop_new:N \g_@@_document_references_prop
+\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},
+}
+\cctab_begin:N \g_@@_xml_cctab%
+\_@@_define_xml_writer:Nn \_@@_write_ReferencedDocument:n {%
+ \prop_if_in:NeT \g_@@_document_references_prop {\str_lowercase:n {#1}-reference} {%
+ \_@@_write_xml:e {%
+ <ram:#1ReferencedDocument>
+ \_@@_indent:<ram:IssuerAssignedID>\prop_item:Ne \g_@@_document_references_prop {\str_lowercase:n {#1}-reference}</ram:IssuerAssignedID>
+ </ram:#1ReferencedDocument>%
+ }%
+ }%
+}%
+\cctab_end:
+% \end{macrocode}
+% \end{implementation}
+% \begin{documentation}
% \subsubsection{Payment Means}
% \label{sec:PaymentMeans}
% The payment means are selected by numeric codes.
@@ -2095,15 +2271,21 @@
% \end{macrocode}
% \endoptionenv
% \begin{macrocode}
-\_@@_define_xml_writer:Nn \_@@_write_inline:nn {
- \tl_if_blank:nF {#2} {
- <#1>#2</#1>
+\_@@_define_xml_content:Nn \_@@_write_inline:nn {
+ \_@@_write_inline:nnn {#1} {} {#2}
+}
+\_@@_define_xml_content:Nn \_@@_write_inline:nnn {
+ \tl_if_blank:nF {#3} {
+ <#1#2>#3</#1>
}
}
\cs_generate_variant:Nn \_@@_write_inline:nn {ne}
-\_@@_define_xml_writer:Nn \_@@_write_inline_i:nn {
- \_@@_indent: \_@@_write_inline:nn {#1} {#2}
+\_@@_define_xml_content:Nn \_@@_write_inline_i:nnn {
+ \_@@_indent: \_@@_write_inline:nnn {#1} {#2} {#3}
}
+\_@@_define_xml_content:Nn \_@@_write_inline_i:nn {
+ \_@@_write_inline_i:nnn {#1} {} {#2}
+}
\cctab_begin:N \g_@@_xml_cctab%
%
\bool_if:NTF \g_@@_minimum_bool {%
@@ -2211,10 +2393,13 @@
% \end{macrocode}
% \end{function}
% \begin{function}{\_@@_SpecifiedTradeProduct:nn}
+% \changes{v0.9c}{2024-12-08}{Don't use SellerAssignedID if format=basic, \issue{28}}
% \begin{macrocode}
-\_@@_define_xml_writer:Nn \_@@_SpecifiedTradeProduct:nn {%
+\_@@_define_xml_content:Nn \_@@_SpecifiedTradeProduct:nn {%
<ram:SpecifiedTradeProduct>
- \tl_if_empty:nF {#1} {%
+ \bool_lazy_or:nnF%
+ {\tl_if_blank_p:n {#1}}%
+ {\str_if_eq_p:Vn \g_@@_conformance_level_str {BASIC}} {%
\_@@_indent: <ram:SellerAssignedID>#1</ram:SellerAssignedID>
}%
\_@@_indent: <ram:Name>#2</ram:Name>
@@ -2379,6 +2564,13 @@
\int_gincr:N \g_@@_indent_int%
\_@@_write_rounded:nnn {2} {CalculatedAmount} {#4}%BT117
\_@@_write_xml:n {<ram:TypeCode>VAT</ram:TypeCode>}%BT118
+% \end{macrocode}
+% \changes{v0.9c}{2024-12-08}{Call exemption-reason-auto also locally inside ApplicableTradeTaxEntry}
+% \begin{macrocode}%
+ \begingroup
+ \bool_if:NT \g_@@_auto_exemption_bool {%
+ \keys_set:nn { zugferd / tax } {exemption-reason-auto=#1}
+ }%
\tl_if_blank:VF \l_@@_tax_exemption_reason_tl {%BT-120
\_@@_write_xml:e {<ram:ExemptionReason>
\l_@@_tax_exemption_reason_tl
@@ -2386,11 +2578,18 @@
}
{{\_@@_write_rounded:nnn {2} {BasisAmount} {#3}}}%BT-116
\_@@_write_xml:e {<ram:CategoryCode>#1</ram:CategoryCode>}%BT-118
- \tl_if_blank:VF \l_@@_tax_exemption_code_tl {%BT121
- \_@@_write_xml:e {<ram:ExemptionReasonCode>
- \l_@@_tax_exemption_code_tl
- </ram:ExemptionReasonCode>}
- }
+% \end{macrocode}
+% \changes{v0.9c}{2024-12-08}{Don't use exception-reason-code if format=BASIC \issue{28}}
+% \begin{macrocode}
+ \bool_lazy_or:nnF% BT121
+ {\tl_if_blank_p:V \l_@@_tax_exemption_code_tl}%
+ {\str_if_eq_p:Vn \g_@@_conformance_level_str {BASIC}}%
+ {%
+ \_@@_write_xml:e {%
+ <ram:ExemptionReasonCode>\l_@@_tax_exemption_code_tl</ram:ExemptionReasonCode>%
+ }%
+ }%
+ \endgroup
\_@@_write_xml:n {<ram:RateApplicablePercent>#2</ram:RateApplicablePercent>}%BT-119
\int_gdecr:N \g_@@_indent_int%
\_@@_write_xml:n {</ram:ApplicableTradeTax>}
@@ -2398,9 +2597,6 @@
%
\cctab_begin:N \g_@@_xml_cctab%
% ApplicableHeaderTradeSettlement
-\_@@_define_xml_writer:Nn \_@@_ApplicableHeaderTradeSettlement:nnnnnnnn {%
-
-}%
% \end{macrocode}
% ApplicableHeaderTradeSettlement needs to be splitted to be used in separate parts of the tabular.
% \begin{macrocode}
Modified: trunk/Master/texmf-dist/tex/latex/zugferd/zugferd-invoice.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zugferd/zugferd-invoice.sty 2024-12-09 21:13:19 UTC (rev 73080)
+++ trunk/Master/texmf-dist/tex/latex/zugferd/zugferd-invoice.sty 2024-12-09 21:13:34 UTC (rev 73081)
@@ -12,7 +12,7 @@
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008-05-04 or later.
%
-\ProvidesExplPackage{zugferd-invoice}{2024-11-17}{0.9b}{Invoice wrapper example package for the factur-x to create ZUGFerD invoices}
+\ProvidesExplPackage{zugferd-invoice}{2024-12-08}{0.9c}{Invoice wrapper example package for the factur-x to create ZUGFerD invoices}
\keys_define:nn {zugferd/invoice}{
default-vat .tl_set:N = \defaultVAT,
@@ -124,7 +124,7 @@
\PrintInvoiceSum{netto}{\fp_use:N \g__ptxcd_invoice_sum_fp}
\seq_map_inline:Nn \g__ptxcd_VAT_rates_seq {
\fp_compare:nNnF {\fp_use:c {g__ptxcd_invoice_sum_vat##1_fp}} = {0} {
- \zugferd_write_TaxEntry:nnnn {\use:c {__ptxcd_invoice_type_code##1:}} {##1} {\fp_use:c {g__ptxcd_invoice_base_vat##1_fp}} {\fp_use:c {g__ptxcd_invoice_sum_vat##1_fp}}
+ \zugferd_write_TaxEntry:ennn {\use:c {__ptxcd_invoice_type_code##1:}} {##1} {\fp_use:c {g__ptxcd_invoice_base_vat##1_fp}} {\fp_use:c {g__ptxcd_invoice_sum_vat##1_fp}}
\fp_gadd:Nn \g__ptxcd_tax_total_fp {\fp_use:c {g__ptxcd_invoice_sum_vat##1_fp}}
\PrintVatSum[{\fp_use:c {g__ptxcd_invoice_base_vat##1_fp}}]{##1 }{\fp_use:c {g__ptxcd_invoice_sum_vat##1_fp}}
}
Modified: trunk/Master/texmf-dist/tex/latex/zugferd/zugferd.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/zugferd/zugferd.sty 2024-12-09 21:13:19 UTC (rev 73080)
+++ trunk/Master/texmf-dist/tex/latex/zugferd/zugferd.sty 2024-12-09 21:13:34 UTC (rev 73081)
@@ -9,7 +9,7 @@
%% Copyright (C) 2023--2024 by Marei Peischl (peiTeX) <marei at peitex.de>
%%
\NeedsTeXFormat{LaTeX2e}[2023-11-01]
-\ProvidesExplPackage{zugferd}{2024-11-17}{0.9b}{Create ZUGFerd invoices using LaTeX}
+\ProvidesExplPackage{zugferd}{2024-12-08}{0.9c}{Create ZUGFerd invoices using LaTeX}
\tl_new:N \l__zugferd_tmp_tl
\str_new:N \g__zugferd_format_str
\str_new:N \g__zugferd_businessProcessId_str
@@ -94,7 +94,7 @@
}
\msg_error:nn {zugferd} {PDFmanagement-not-active}
}
-\IfPackageAtLeastF{pdfmanagement-testphase}{2024/09/13}{
+\IfPackageAtLeastTF{pdfmanagement-testphase}{2024/09/13}{}{
\msg_new:nnn {zugferd} {PDFmanagement-too-old} {
Your~version~of~\LaTeX's~PDF~management~is~too~old.
You~need~to~update~your~LaTeX~distribution~to~be~able~to~use~the~zugferd~package~correctly.
@@ -237,14 +237,10 @@
\pdfdict_put:nnn {l_pdffile/Filespec} {Desc}{(Factur-X/ZUGFeRD-Rechnung)}
\exp_args:NnV \pdffile_embed_file:nnn {\g__zugferd_xml_file_tl} \g__zugferd_xml_embedded_file_tl
{zugferd/rechnung}
+\group_end:
\pdfmanagement_add:nee
- {Catalog/Names/EmbeddedFiles}
- {\g__zugferd_xml_embedded_file_tl}
- {\pdf_object_ref:n{zugferd/rechnung}}
-\group_end:
-\pdfmanagement_add:nnx
-{Catalog/Names}
-{EmbeddedFiles}
+{Catalog/Names/EmbeddedFiles}
+{\g__zugferd_xml_embedded_file_tl}
{\pdf_object_ref:n{zugferd/rechnung}}
\pdfmanagement_add:nnx{Catalog}{AF}{\pdf_object_ref:n{zugferd/rechnung}}
}
@@ -306,6 +302,7 @@
\group_end:
}
\cs_generate_variant:Nn \zugferd_write_Item:nnnnnnn {ennnnnn}
+\cs_generate_variant:Nn \zugferd_write_TaxEntry:nnnn {ennn}
\bool_if:NTF \g__zugferd_write_xml_bool {
\cs_new:Nn \__zugferd_write_xml:n {
\iow_now:Ne \__zugferd_xml_writer_iow {\__zugferd_xml_auto_indent: #1}
@@ -367,17 +364,20 @@
%% 2019-2024 LaTeX Project
%% modifications have been made to support the mechanism if hyperref is not loaded
\cs_new:Nn \zugferd_disable_macros: {
-\let\{\textbraceleft
-\let\}\textbraceright
-\let\\\textbackslash
-\let\#\textnumbersign
-\let\$\textdollar
-\let\%\textpercent
-\let\&\textampersand
-\let\_\textunderscore
-\let\P\textparagraph
-\let\ldots\textellipsis
-\let\dots\textellipsis
+\let\{\c_left_brace_str
+\let\textbraceleft\c_left_brace_str
+\let\}\c_right_brace_str
+\let\textbraceright\c_right_brace_str
+\let\#\c_hash_str
+\let\textnumbersign\c_hash_str
+\let\$\c_dollar_str
+\let\textdollar\c_dollar_str
+\let\%\c_percent_str
+\let\&\c_ampersand_str
+\let\_\c_underscore_str
+\def\P{§}
+\def\ldots{…}
+\def\dots{…}
\def\\{\space}%
\def\newline{\space}%
\def\TeX{TeX}%
@@ -471,6 +471,41 @@
\hook_use:n {zugferd/disable-macros}
}
\hook_new:n {zugferd/disable-macros}
+\tl_new:N \g__zugferd_tmp_tl
+\cs_new:Nn \zugferd_tl_gset_escaped_xml:Nn {
+\group_begin:
+\zugferd_disable_macros:
+\__zugferd_escape_xml_aux:
+\tl_gset_rescan:Nnn #1 {
+\cctab_select:N \c_str_cctab
+\__zugferd_escape_xml_activate:
+ } {#2}
+\tl_gset:Ne #1 {#1}
+\group_end:
+}
+\cs_new:Nn \zugferd_tl_set_escaped_xml:Nn {
+\zugferd_tl_gset_escaped_xml:Nn \g__zugferd_tmp_tl {#2}
+\tl_set_eq:NN #1 \g__zugferd_tmp_tl
+}
+\cs_new:Nn \__zugferd_escape_xml_aux: {
+\edef\&{\tl_to_str:n {&}}
+\edef\textgreater{\tl_to_str:n {>}}
+\edef\textless{\tl_to_str:n {<}}
+\edef\textquotedbl{\tl_to_str:n {"}}
+\edef\textquotesingle{\tl_to_str:n {'}}
+\char_set_active_eq:NN > \textgreater
+\char_set_active_eq:NN < \textless
+\char_set_active_eq:NN " \textquotedbl
+\char_set_active_eq:NN ' \textquotesingle
+\char_set_active_eq:NN & \&
+}
+\cs_new:Nn \__zugferd_escape_xml_activate: {
+\char_set_catcode_active:N >
+\char_set_catcode_active:N <
+\char_set_catcode_active:N "
+\char_set_catcode_active:N '
+\char_set_catcode_active:N &
+}
\cs_set:Nn \zugferd_fp_set_rounded:Nn {
\__zugferd_number_format:nNn {2} \l__zugferd_tmp_tl {\fp_eval:n {#2}}
\fp_set:Nn #1 {\l__zugferd_tmp_tl }
@@ -491,6 +526,20 @@
document-type .choice:,
document-type / commercial-invoice .code:n =
\tl_gset:Nn \g__zugferd_DocumentTypeCode_tl {380},
+document-type / partial-invoice .code:n =
+\tl_gset:Nn \g__zugferd_DocumentTypeCode_tl {326},
+document-type / corrected-invoice .code:n =
+\tl_gset:Nn \g__zugferd_DocumentTypeCode_tl {384},
+document-type / self-billed-invoice .code:n =
+\tl_gset:Nn \g__zugferd_DocumentTypeCode_tl {389},
+document-type / credit-note .code:n =
+\tl_gset:Nn \g__zugferd_DocumentTypeCode_tl {381},
+document-type / partial-construction-invoice .code:n =
+\tl_gset:Nn \g__zugferd_DocumentTypeCode_tl {875},
+document-type / partial-final-construction-invoice .code:n =
+\tl_gset:Nn \g__zugferd_DocumentTypeCode_tl {876},
+document-type / final-construction-invoice .code:n =
+\tl_gset:Nn \g__zugferd_DocumentTypeCode_tl {877},
document-type .initial:n = commercial-invoice,
id .choice:,
id / komavar .code:n = \tl_gset:Nf \g__zugferd_id_tl {\scr at invoice@var},
@@ -562,7 +611,8 @@
\seq_set_split:Nnn \l_tmpa_seq {\\} {##1}
\keys_set:nx {zugferd / #1} {
lineone=\seq_item:Nn \l_tmpa_seq {1},
-linetwo=\seq_item:Nn \l_tmpa_seq {2}
+linetwo=\seq_item:Nn \l_tmpa_seq {2},
+linethree=\seq_item:Nn \l_tmpa_seq {3}
}
},
contact .code:n = {
@@ -588,15 +638,25 @@
}
}
}
+\cs_new:Nn \__zugferd_TradePartyIdentity:N {
+\__zugferd_TradePartyIdentity:eeeee
+{\prop_item:Nn #1 {id}}
+{\prop_item:Nn #1 {name}}
+{\prop_item:Nn #1 {legal-description}}
+{\prop_item:Nn #1 {legal-id}}
+{\prop_item:Nn #1 {trading-name}}
+}
\cs_new:Nn \__zugferd_PostalTradeAddress_short:N {
\exp_args:Ne \tl_if_blank:nF {\prop_item:Nn #1 {name}}
{<ram:Name>\prop_item:Nn #1 {name}</ram:Name>\iow_newline:\__zugferd_xml_auto_indent:}
-\__zugferd_PostalTradeAddress:eeeee
+\__zugferd_PostalTradeAddress:eeeeeee
{\prop_item:Nn #1 {postcode}}
{\prop_item:Nn #1 {lineone}}
{\prop_item:Nn #1 {linetwo}}
+{\prop_item:Nn #1 {linethree}}
{\prop_item:Nn #1 {city}}
{\prop_item:Nn #1 {country}}
+{\prop_item:Nn #1 {subdivision}}
}
\cs_new:Nn \__zugferd_PostalTradeAddress:N {%
\__zugferd_PostalTradeAddress:eeeeeee
@@ -603,10 +663,12 @@
{\prop_item:Nn #1 {postcode}}
{\prop_item:Nn #1 {lineone}}
{\prop_item:Nn #1 {linetwo}}
+{\prop_item:Nn #1 {linethree}}
{\prop_item:Nn #1 {city}}
{\prop_item:Nn #1 {country}}
-{\prop_item:Nn #1 {email}}
-{\prop_item:Nn #1 {vatid}}
+{\prop_item:Nn #1 {subdivision}}
+\__zugferd_UniversalCommunication:n {\prop_item:Nn #1 {email}}
+\__zugferd_TaxRegistration:nn {\prop_item:Nn #1 {vatid}} {\prop_item:Nn #1 {taxid}}
}%
\cs_new:Nn \__zugferd_DefinedTradeContact:N {%
\__zugferd_DefinedTradeContact:eeee
@@ -616,7 +678,23 @@
{\prop_item:Nn #1 {contact-email}}
}%
\cctab_begin:N \g__zugferd_xml_cctab%
-\__zugferd_define_xml_content:Nn \__zugferd_PostalTradeAddress:nnnnn {%
+\__zugferd_define_xml_content:Nn \__zugferd_TradePartyIdentity:nnnnn {%
+%%<!-- BT-29 -->
+\__zugferd_write_inline:nn {ram:ID} {#1}
+%%<!-- BT-27 -->
+\__zugferd_write_inline:nn {ram:Name} {#2}
+%%<!-- BT-33 -->
+\__zugferd_write_inline:nn {ram:Description} {#3}
+\tl_if_blank:eF {#4#5} {%
+<ram:SpecifiedLegalOrganization>
+%%%<!-- BT-30 -->
+\__zugferd_write_inline_i:nnn {ram:ID} {~schemeID="0088"} {#4}
+%%<!-- BT-28 -->
+\__zugferd_write_inline_i:nn {ram:TradingBusinessName} {#5}
+</ram:SpecifiedLegalOrganization>
+}%
+}%
+\__zugferd_define_xml_content:Nn \__zugferd_PostalTradeAddress:nnnnnnn {%
<ram:PostalTradeAddress>
\bool_if:NF \g__zugferd_minimum_bool {%
\__zugferd_indent: <ram:PostcodeCode>#1</ram:PostcodeCode>
@@ -626,27 +704,44 @@
\tl_if_blank:nF {#3} {%
\__zugferd_indent: <ram:LineTwo>#3</ram:LineTwo>
}%
-\__zugferd_indent: <ram:CityName>#4</ram:CityName>
+\tl_if_blank:nF {#4} {%
+\__zugferd_indent: <ram:LineThree>#4</ram:LineThree>
}%
-\__zugferd_indent: <ram:CountryID>#5</ram:CountryID>
+\__zugferd_indent: <ram:CityName>#5</ram:CityName>
+}%
+\__zugferd_indent: <ram:CountryID>#6</ram:CountryID>
+\bool_if:NF \g__zugferd_minimum_bool {%
+\tl_if_blank:nF {#7} {%
+\__zugferd_indent: <ram:CountrySubDivisionName>#7</ram:CountrySubDivisionName>
+}%
+}%
</ram:PostalTradeAddress>%
-}
-\__zugferd_define_xml_content:Nn \__zugferd_PostalTradeAddress:nnnnnnn {%
-\__zugferd_PostalTradeAddress:nnnnn {#1} {#2} {#3} {#4} {#5}%
-\bool_lazy_or:nnF {\g__zugferd_minimum_bool}%
-{\tl_if_blank_p:n {#6}}%
-{%
-\__zugferd_xml_newline_indent:%
+}%
+\bool_if:NTF \g__zugferd_minimum_bool {%
+\cs_set_eq:NN \__zugferd_UniversalCommunication:n \use_none:n%
+} {%
+\__zugferd_define_xml_content:Nn \__zugferd_UniversalCommunication:n {%
+\tl_if_blank:eF {#1} {
<ram:URIUniversalCommunication>
-\__zugferd_indent: <ram:URIID~schemeID="EM">#6</ram:URIID>
+\__zugferd_indent: <ram:URIID~schemeID="EM">#1</ram:URIID>
</ram:URIUniversalCommunication>%
}%
-\tl_if_empty:nF {#7} {
+}%
+}%
+\__zugferd_define_xml_content:Nn \__zugferd_TaxRegistration:nn {%
+%%%<!-- BT-34 -->
+\tl_if_blank:eF {#1} {
<ram:SpecifiedTaxRegistration>
-\__zugferd_indent: <ram:ID~schemeID="VA">#7</ram:ID>
+\__zugferd_indent: <ram:ID~schemeID="VA">#1</ram:ID>
</ram:SpecifiedTaxRegistration>%
}%
+%%%<!-- BT-32 -->
+\tl_if_blank:eF {#2} {
+<ram:SpecifiedTaxRegistration>
+\__zugferd_indent: <ram:ID~schemeID="FC">#2</ram:ID>
+</ram:SpecifiedTaxRegistration>%
}%
+}%
\__zugferd_define_xml_content:Nn \__zugferd_DefinedTradeContact:nnnn {%
\tl_if_blank:nT {#1} {\use_none:nnn} %
\bool_if:NT \g__zugferd_writeTradeContact_bool {%
@@ -682,7 +777,7 @@
\__zugferd_write_xml:n {<ram:SellerTradeParty>}%
\int_gincr:N \g__zugferd_indent_int%
\__zugferd_write_xml:e {%
-<ram:Name>\prop_item:Nn \g__zugferd_seller_AddressData_prop {name}</ram:Name>
+\__zugferd_TradePartyIdentity:N \g__zugferd_seller_AddressData_prop
\__zugferd_DefinedTradeContact:N \g__zugferd_seller_AddressData_prop%
\__zugferd_PostalTradeAddress:N \g__zugferd_seller_AddressData_prop%
}%
@@ -693,7 +788,7 @@
}%
\int_gincr:N \g__zugferd_indent_int%
\__zugferd_write_xml:e {%
-<ram:Name>\prop_item:Nn \g__zugferd_buyer_AddressData_prop {name}</ram:Name>%
+\__zugferd_TradePartyIdentity:N \g__zugferd_buyer_AddressData_prop
\bool_if:NF \g__zugferd_minimum_bool {
\__zugferd_DefinedTradeContact:N \g__zugferd_buyer_AddressData_prop%
\__zugferd_PostalTradeAddress:N \g__zugferd_buyer_AddressData_prop%
@@ -701,6 +796,9 @@
}%
\int_gdecr:N \g__zugferd_indent_int%
\__zugferd_write_xml:n {</ram:BuyerTradeParty>}%
+\clist_map_inline:nn {SellerOrder,BuyerOrder,Contract} {%
+\__zugferd_write_ReferencedDocument:n {##1}%
+}%
\int_gdecr:N \g__zugferd_indent_int%
\__zugferd_write_xml:n {</ram:ApplicableHeaderTradeAgreement>}%
\bool_if:NTF \g__zugferd_minimum_bool%
@@ -736,8 +834,8 @@
}%
}%
\cctab_end:
+\cs_generate_variant:Nn \__zugferd_TradePartyIdentity:nnnnn {eeeee}
\cs_generate_variant:Nn \__zugferd_DefinedTradeContact:nnnn {eeee}
-\cs_generate_variant:Nn \__zugferd_PostalTradeAddress:nnnnn {eeeee}%
\cs_generate_variant:Nn \__zugferd_PostalTradeAddress:nnnnnnn {eeeeeee}
\cs_generate_variant:Nn \__zugferd_ApplicableHeaderTradeDelivery:n {V}
\tl_new:N \g__zugferd_buyer_reference_tl
@@ -750,6 +848,26 @@
\tl_gset:Nn \g__zugferd_buyer_reference_tl {#1}
}
}
+\prop_new:N \g__zugferd_document_references_prop
+\clist_new:N \g__zugferd_buyer_document_references_clist
+\keys_define:nn {zugferd} {
+contract-reference .prop_gput:N = \g__zugferd_document_references_prop,
+purchaseorder-reference .prop_gput:N = \g__zugferd_document_references_prop,
+purchase-order-reference .meta:n = {purchaseorder-reference=#1},
+salesorder-reference .prop_gput:N = \g__zugferd_document_references_prop,
+sales-order-reference .meta:n = {salesorder-reference=#1},
+}
+\cctab_begin:N \g__zugferd_xml_cctab%
+\__zugferd_define_xml_writer:Nn \__zugferd_write_ReferencedDocument:n {%
+\prop_if_in:NeT \g__zugferd_document_references_prop {\str_lowercase:n {#1}-reference} {%
+\__zugferd_write_xml:e {%
+<ram:#1ReferencedDocument>
+\__zugferd_indent:<ram:IssuerAssignedID>\prop_item:Ne \g__zugferd_document_references_prop {\str_lowercase:n {#1}-reference}</ram:IssuerAssignedID>
+</ram:#1ReferencedDocument>%
+}%
+}%
+}%
+\cctab_end:
\ExplSyntaxOff
\providecommand*{\zugferd at paymentMeans@german}{
1 = Keine Zahlungsart definiert,
@@ -937,15 +1055,21 @@
end-date .tl_gset:N = \l__zugferd_end_date_tl,
end-date .initial:n =,
}%
-\__zugferd_define_xml_writer:Nn \__zugferd_write_inline:nn {
-\tl_if_blank:nF {#2} {
-<#1>#2</#1>
+\__zugferd_define_xml_content:Nn \__zugferd_write_inline:nn {
+\__zugferd_write_inline:nnn {#1} {} {#2}
}
+\__zugferd_define_xml_content:Nn \__zugferd_write_inline:nnn {
+\tl_if_blank:nF {#3} {
+<#1#2>#3</#1>
}
+}
\cs_generate_variant:Nn \__zugferd_write_inline:nn {ne}
-\__zugferd_define_xml_writer:Nn \__zugferd_write_inline_i:nn {
-\__zugferd_indent: \__zugferd_write_inline:nn {#1} {#2}
+\__zugferd_define_xml_content:Nn \__zugferd_write_inline_i:nnn {
+\__zugferd_indent: \__zugferd_write_inline:nnn {#1} {#2} {#3}
}
+\__zugferd_define_xml_content:Nn \__zugferd_write_inline_i:nn {
+\__zugferd_write_inline_i:nnn {#1} {} {#2}
+}
\cctab_begin:N \g__zugferd_xml_cctab%
\bool_if:NTF \g__zugferd_minimum_bool {%
\cs_set_eq:NN \__zugferd_write_note:n \use_none:n%
@@ -1028,9 +1152,11 @@
\__zugferd_indent: <ram:LineID>#1</ram:LineID>
</ram:AssociatedDocumentLineDocument>%
}%
-\__zugferd_define_xml_writer:Nn \__zugferd_SpecifiedTradeProduct:nn {%
+\__zugferd_define_xml_content:Nn \__zugferd_SpecifiedTradeProduct:nn {%
<ram:SpecifiedTradeProduct>
-\tl_if_empty:nF {#1} {%
+\bool_lazy_or:nnF%
+{\tl_if_blank_p:n {#1}}%
+{\str_if_eq_p:Vn \g__zugferd_conformance_level_str {BASIC}} {%
\__zugferd_indent: <ram:SellerAssignedID>#1</ram:SellerAssignedID>
}%
\__zugferd_indent: <ram:Name>#2</ram:Name>
@@ -1150,6 +1276,10 @@
\int_gincr:N \g__zugferd_indent_int%
\__zugferd_write_rounded:nnn {2} {CalculatedAmount} {#4}%BT117
\__zugferd_write_xml:n {<ram:TypeCode>VAT</ram:TypeCode>}%BT118
+\begingroup
+\bool_if:NT \g__zugferd_auto_exemption_bool {%
+\keys_set:nn { zugferd / tax } {exemption-reason-auto=#1}
+}%
\tl_if_blank:VF \l__zugferd_tax_exemption_reason_tl {%BT-120
\__zugferd_write_xml:e {<ram:ExemptionReason>
\l__zugferd_tax_exemption_reason_tl
@@ -1157,19 +1287,20 @@
}
{{\__zugferd_write_rounded:nnn {2} {BasisAmount} {#3}}}%BT-116
\__zugferd_write_xml:e {<ram:CategoryCode>#1</ram:CategoryCode>}%BT-118
-\tl_if_blank:VF \l__zugferd_tax_exemption_code_tl {%BT121
-\__zugferd_write_xml:e {<ram:ExemptionReasonCode>
-\l__zugferd_tax_exemption_code_tl
-</ram:ExemptionReasonCode>}
-}
+\bool_lazy_or:nnF% BT121
+{\tl_if_blank_p:V \l__zugferd_tax_exemption_code_tl}%
+{\str_if_eq_p:Vn \g__zugferd_conformance_level_str {BASIC}}%
+{%
+\__zugferd_write_xml:e {%
+<ram:ExemptionReasonCode>\l__zugferd_tax_exemption_code_tl</ram:ExemptionReasonCode>%
+}%
+}%
+\endgroup
\__zugferd_write_xml:n {<ram:RateApplicablePercent>#2</ram:RateApplicablePercent>}%BT-119
\int_gdecr:N \g__zugferd_indent_int%
\__zugferd_write_xml:n {</ram:ApplicableTradeTax>}
}%
\cctab_begin:N \g__zugferd_xml_cctab%
-\__zugferd_define_xml_writer:Nn \__zugferd_ApplicableHeaderTradeSettlement:nnnnnnnn {%
-
-}%
\__zugferd_define_xml_writer:Nn \__zugferd_ApplicableHeaderTradeSettlement_start: {%
\__zugferd_write_xml:n {<ram:ApplicableHeaderTradeSettlement>}%
\int_gincr:N \g__zugferd_indent_int%
More information about the tex-live-commits
mailing list.