Files
syspro/mapping/XSL_SYSPRO_DELIVERY/DELIVERY.xsl
T
Christian Schwarz 26afdf3e9a Oject-10438 Generate synthetic SGTIN-96 EPCs in test mode when EPCs absent
Both delivery paths (HU via E1EDL37/E1EDL44 and no-HU via E1EDL24) now
produce one SGTIN-96 XMLEPC per unit when EDI_DC40/TEST = 'X' and no
E1EPC03 URNs are present in the message. Serials are derived from
MD5(DOCNUM + SSCC+POSNR+counter) for HU items and MD5(DOCNUM + POSNR+counter)
for direct items, ensuring uniqueness across positions and handling units.
DeliveredQuantity in the no-HU path corrected from LGMNG to LFIMG.
2026-04-13 13:46:49 +02:00

257 lines
10 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="UTF-8"?>
<!-- 11.03.2026 Oject-10438 Merging all HUs into single message with multiple XMLSSCCGROUPS-->
<!-- 22.12.2023 DEV-8311 SAP sends delivery advices to stores MAPPING: SOURCE
- SAP ZFSHDLV TARGET - syspro internal Format -->
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge"
xmlns:gs1="urn:gs1:epc"
exclude-result-prefixes="xs ns0 gs1">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Wurzel-Template: nur eine Nachricht -->
<xsl:template match="/">
<ns0:Messages>
<ns0:Message1>
<xsl:apply-templates select="//ZFSHDLV/IDOC"/>
</ns0:Message1>
</ns0:Messages>
</xsl:template>
<!-- Template für IDOC: eine einzige XMLDESADV -->
<xsl:template match="ZFSHDLV/IDOC">
<xsl:variable name="docnum" select="normalize-space(EDI_DC40/DOCNUM)"/>
<xsl:variable name="testMode" select="EDI_DC40/TEST = 'X'"/>
<XMLDESADV>
<xsl:comment>SAP IDOC Number: <xsl:value-of select="EDI_DC40/DOCNUM"/> </xsl:comment>
<XMLDESADVHEADER>
<!-- DocumentId mit erster SSCC -->
<DocumentId>
<xsl:value-of select="E1EDL20/VBELN"/>
</DocumentId>
<!-- DeliveryNote: LIFEX oder VBELN -->
<DeliveryNote>
<xsl:value-of select="if (E1EDL20/LIFEX) then E1EDL20/LIFEX else E1EDL20/VBELN"/>
</DeliveryNote>
<DocumentType>XMLDESADV</DocumentType>
<DocumentSubType>
<xsl:call-template name="DocumentSubType">
<xsl:with-param name="LFART" select="E1EDL21/LFART"/>
</xsl:call-template>
</DocumentSubType>
<!-- DocumentDate (QUALF='015') -->
<DocumentDate>
<xsl:value-of
select="format-dateTime(
adjust-dateTime-to-timezone(
xs:dateTime(concat(
substring(E1EDL20/E1EDT13[QUALF='015']/NTANF,1,4),'-',
substring(E1EDL20/E1EDT13[QUALF='015']/NTANF,5,2),'-',
substring(E1EDL20/E1EDT13[QUALF='015']/NTANF,7,2),'T',
substring(E1EDL20/E1EDT13[QUALF='015']/NTANZ,1,2),':',
substring(E1EDL20/E1EDT13[QUALF='015']/NTANZ,3,2),':',
substring(E1EDL20/E1EDT13[QUALF='015']/NTANZ,5,2)
))),
'[Y0000]-[M00]-[D00]T[H00]:[m00]:[s00].[f0000000][Z]')
"/>
</DocumentDate>
<!-- DeliveryDate (QUALF='007') -->
<DeliveryDate>
<xsl:value-of
select="format-dateTime(
adjust-dateTime-to-timezone(
xs:dateTime(concat(
substring(E1EDL20/E1EDT13[QUALF='007']/NTANF,1,4),'-',
substring(E1EDL20/E1EDT13[QUALF='007']/NTANF,5,2),'-',
substring(E1EDL20/E1EDT13[QUALF='007']/NTANF,7,2),'T',
substring(E1EDL20/E1EDT13[QUALF='007']/NTANZ,1,2),':',
substring(E1EDL20/E1EDT13[QUALF='007']/NTANZ,3,2),':',
substring(E1EDL20/E1EDT13[QUALF='007']/NTANZ,5,2)
))),
'[Y0000]-[M00]-[D00]T[H00]:[m00]:[s00].[f0000000][Z]')
"/>
</DeliveryDate>
<!-- GLNs -->
<SenderGLN><xsl:value-of select="E1IDOCENHANCEMENT[IDENTIFIER='SENDERGLN']/DATA"/></SenderGLN>
<ReceipientGLN><xsl:value-of select="E1IDOCENHANCEMENT[IDENTIFIER='RECEIVERGLN']/DATA"/></ReceipientGLN>
<!-- leere Felder optional -->
<AllocationReference/>
<ReferenceSupplierOrder/>
<ReferenceBuyerOrder/>
<ReferenceDocument><xsl:value-of select="E1EDL20/VBELN"/></ReferenceDocument>
<SupplierGLN/>
<BuyerGLN/>
<DeliveryPartyGLN/>
<UltimateConsignyGLN/>
<ReturnGLN/>
<SendFromGLN/>
<SendToGLN/>
<DeliveryCurrency/>
</XMLDESADVHEADER>
<!-- Package Group -->
<XMLPACKAGEGROUP>
<NumberOfPackages>
<xsl:value-of select="if (E1EDL20/ANZPK and number(E1EDL20/ANZPK) > 0)
then format-number(E1EDL20/ANZPK, '#')
else '1'"/>
</NumberOfPackages>
<PackageCode>33E</PackageCode>
</XMLPACKAGEGROUP>
<!-- HUs pro HU eine XMLSSCCGROUP -->
<xsl:for-each select="E1EDL20/E1EDL37">
<XMLSSCCGROUP>
<SSCC>
<xsl:value-of select="
if (string-length(translate(normalize-space(EXIDV), '0123456789', '')) != 0)
then normalize-space(EXIDV)
else replace(normalize-space(EXIDV), '^0+', '')
"/>
</SSCC>
<PackageCode>33E</PackageCode>
<PackageType>BJ</PackageType>
<!-- Artikel für diese HU -->
<xsl:for-each select="E1EDL44">
<xsl:variable name="posnr" select="POSNR"/>
<xsl:variable name="rawGtin" select="normalize-space(../../../E1EDL20/E1EDL24[POSNR = $posnr]/EAN11)"/>
<xsl:variable name="gtin14" select="substring(concat('00000000000000', $rawGtin), string-length($rawGtin) + 1, 14)"/>
<xsl:variable name="qty" select="xs:integer(xs:decimal(./VEMNG))"/>
<xsl:variable name="sscc" select="normalize-space(../EXIDV)"/>
<xsl:variable name="hasEpc" select="E1EPC03[URN and string-length(normalize-space(URN)) > 0]"/>
<XMLITEMS>
<PositionNumber><xsl:value-of select="$posnr"/></PositionNumber>
<GTIN><xsl:value-of select="$rawGtin"/></GTIN>
<DeliveredQuantity>
<xsl:value-of select="xs:decimal(./VEMNG)"/>
</DeliveredQuantity>
<QuantityQualifier>
<xsl:call-template name="QuantityQualifier">
<xsl:with-param name="UoM" select="./VEMEH"/>
</xsl:call-template>
</QuantityQualifier>
<DeliveryPrice></DeliveryPrice>
<ReferenceSupplierOrder>
<xsl:value-of select="../../../E1EDL20/E1EDL24[POSNR = $posnr]/VGBEL"/>
</ReferenceSupplierOrder>
<ReferenceBuyerOrder></ReferenceBuyerOrder>
<!-- EPCs from message -->
<xsl:if test="$hasEpc">
<xsl:for-each select="E1EPC03[URN and string-length(normalize-space(URN)) > 0]">
<XMLEPC>
<EPC><xsl:value-of select="normalize-space(URN)"/></EPC>
</XMLEPC>
</xsl:for-each>
</xsl:if>
<!-- Test-mode synthetic EPCs: one per unit (VEMNG), keyed by SSCC+POSNR+counter -->
<xsl:if test="$testMode and not($hasEpc)">
<xsl:for-each select="1 to $qty">
<XMLEPC>
<EPC>
<xsl:value-of select="gs1:encodeSgtin96FromIdoc(
$gtin14,
$docnum,
concat($sscc, '-', $posnr, '-', string(.)),
xs:integer(1),
xs:integer(7)
)"/>
</EPC>
</XMLEPC>
</xsl:for-each>
</xsl:if>
</XMLITEMS>
</xsl:for-each>
</XMLSSCCGROUP>
</xsl:for-each>
<!-- Handle case when there are no handling units (E1EDL37) -->
<xsl:if test="not(E1EDL20/E1EDL37) and E1EDL20/E1EDL24">
<XMLSSCCGROUP>
<SSCC><xsl:value-of select="E1EDL20/VBELN"/></SSCC>
<PackageCode>33E</PackageCode>
<PackageType>BJ</PackageType>
<!-- Process direct items when no handling units exist -->
<xsl:for-each select="E1EDL20/E1EDL24">
<!-- Capture node values before context shifts inside the seq loop -->
<xsl:variable name="rawGtin" select="normalize-space(./EAN11)"/>
<xsl:variable name="gtin14" select="substring(concat('00000000000000', $rawGtin), string-length($rawGtin) + 1, 14)"/>
<xsl:variable name="posnr" select="string(./POSNR)"/>
<xsl:variable name="qty" select="xs:integer(xs:decimal(./LFIMG))"/>
<xsl:variable name="hasEpc" select="E1EPC03[URN and string-length(normalize-space(URN)) > 0]"/>
<XMLITEMS>
<PositionNumber>
<xsl:value-of select="./POSNR"/>
</PositionNumber>
<GTIN>
<xsl:value-of select="./EAN11"/>
</GTIN>
<DeliveredQuantity>
<xsl:value-of select="xs:decimal(./LFIMG)"/>
</DeliveredQuantity>
<QuantityQualifier>
<xsl:call-template name="QuantityQualifier">
<xsl:with-param name="UoM">
<xsl:value-of select="./MEINS"/>
</xsl:with-param>
</xsl:call-template>
</QuantityQualifier>
<DeliveryPrice></DeliveryPrice>
<ReferenceSupplierOrder>
<xsl:value-of select="./VGBEL"/>
</ReferenceSupplierOrder>
<ReferenceBuyerOrder></ReferenceBuyerOrder>
<!-- One unique SGTIN-96 EPC per unit (LFIMG actual qty) when test mode is active
and no E1EPC03 URN is present. Counter appended to POSNR makes
each serial unique: MD5(DOCNUM + POSNR-1), MD5(DOCNUM + POSNR-2) … -->
<xsl:if test="$testMode and not($hasEpc)">
<xsl:for-each select="1 to $qty">
<XMLEPC>
<EPC>
<xsl:value-of select="gs1:encodeSgtin96FromIdoc(
$gtin14,
$docnum,
concat($posnr, '-', string(.)),
xs:integer(1),
xs:integer(7)
)"/>
</EPC>
</XMLEPC>
</xsl:for-each>
</xsl:if>
</XMLITEMS>
</xsl:for-each>
</XMLSSCCGROUP>
</xsl:if>
</XMLDESADV>
</xsl:template>
<!-- Hilfs-Templates -->
<xsl:template name="DocumentSubType">
<xsl:param name="LFART"/>
<xsl:choose>
<xsl:when test="$LFART = 'ZIL'">DESADV_IBT</xsl:when>
<xsl:otherwise>DESADV_GI</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="QuantityQualifier">
<xsl:param name="UoM"/>
<xsl:choose>
<xsl:when test="$UoM = 'PCE'">12</xsl:when>
<xsl:otherwise>999</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>