Transform output for Coupa with custom XSLT

If the default output and data templates do not provide the output needed for your Coupa system, you can optionally use custom XSLT to transform output data to your liking. This is useful if you need to automate manual processes, or if you need to add additional information to the output.

This topic refers to the Coupa AP integration, which is the most current version of the Coupa integration and uses the latest version of the Coupa API.

There are two ways to apply custom XSLT in the target system settings:

  • Via a file that has been uploaded to the Resource view.

  • By pasting the XSLT directly in the target system settings.

Tungsten AP Essentials supports XSLT version 1.0. Other versions are not supported.

Your custom XSLT is applied to the Coupa integration output (Coupa REST API XML). You can optionally include:

  • The original document output from Tungsten AP Essentials in ReadSoft Online XML 2.0 format. Use this parameter in your XSLT to include the original document output.

    <xsl:param name="ApsXml"></xsl:param>
  • Target system settings in XML format. Use this parameter in your XSLT to include your target system settings:

    <xsl:param name="Configuration"></xsl:param>

    Sensitive information, such as connection settings, are not included. These settings are included:

    • Default chart of accounts (DefaultChartOfAccounts)

    • Default billing account template (BillingCombinationTemplate)

    • Line-item placeholder for header-only invoices HeaderInvoiceLineDescription

    • Default tax category DefaultTaxCategory

    • Custom field mapping CustomHeaderFieldMapping

    • Custom line-item field mapping CustomLineItemFieldMapping

    • Automatic tax line description AutomaticTaxLineDescription

    • Enforce line level taxation EnforceLineLevelTaxation

    • Calculate missing tax rates EnableMissedTaxParameterCalculation

    • Use remit-to code UseRemitToCode

    • Remit-to code template RemitToCodeMapping

    • Use default remit-to code UseDefaultRemitToCode

Example

In this example, we demonstrate how to utilize the original document output from Tungsten AP Essentials and target system settings.

Consider the following example XSLT that we will use to transform the final document output that is sent to Coupa:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <!-- This parameter includes the original XML output from Tungsten AP Essentials -->
  <xsl:param name="ApsXml"></xsl:param>
  <!-- This parameter includes the Export settings from the target system. -->
  <xsl:param name="Configuration"></xsl:param>
 
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
 
  <xsl:template match="invoice-header">
    <xsl:copy>
    <xsl:apply-templates/>
    <!-- Specify the value of a field. If this field does not exist in Coupa, it is ignored by Coupa. -->
    <example-header-field-1>Example text</example-header-field-1>
    <!-- Specify the value of a field, depending on a value in the target system settings. -->
    <example-header-field-2>
      <xsl:choose>
        <!-- Check the value of the default chart of accounts in the target system settings. -->
        <!-- If the default chart of accounts is "COA1", specify the value of customfield01 as the value of example-header-field-2. -->
        <!-- Otherwise, specify the value of customfield02 as the value of example-header-field-2. -->
        <!-- The values of customfield01 and customfield01 are taken from the original XML output from Tungsten AP Essentials. -->
        <xsl:when test="$Configuration/SystemConfiguration/DefaultChartOfAccounts = 'COA1'">
          <xsl:value-of select="$ApsXml/Batches/Batch/Documents/Document/HeaderFields/HeaderField[Type='customfield01']/Text"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$ApsXml/Batches/Batch/Documents/Document/HeaderFields/HeaderField[Type='customfield02']/Text"/>
        </xsl:otherwise>
      </xsl:choose>
    </example-header-field-2>
    </xsl:copy>
  </xsl:template>
 
</xsl:stylesheet>

By default, the Coupa integration output (Coupa REST API XML) is used as input to the XSL transformation. For this example, the XSL looks like this:

<?xml version="1.0" encoding="utf-8"?>
<invoice-header>
    <document-type>Invoice</document-type>
    <is-credit-note>false</is-credit-note>
    <invoice-date>20230314</invoice-date>
    <invoice-number>0001</invoice-number>
    <payment-order-number/>
    <total-with-taxes d2p1:nil="true" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance"/>
    <gross-total d2p1:nil="true" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance"/>
    <shipping-amount d2p1:nil="true" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance"/>
    <currency>
        <code>USD</code>
    </currency>
    <supplier>
        <number>74</number>
    </supplier>
    <account-type>
        <name>COA-910</name>
    </account-type>
    <invoice-lines>
        <invoice-line>
            <line-num>1</line-num>
            <description>Summary</description>
            <order-line-num d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance"/>
            <price>100.00</price>
            <quantity d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance"/>
            <TaxRate d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance"/>
            <TaxAmount d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance"/>
            <total d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance"/>
            <type>InvoiceAmountLine</type>
            <accounting-total d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance"/>
            <account>
                <code/>
                <segment-1>C1</segment-1>
                <segment-2>100</segment-2>
                <account-type>
                    <name>COA-910</name>
                </account-type>
            </account>
            <currency>
                <code>USD</code>
            </currency>
        </invoice-line>
    </invoice-lines>
    <line-level-taxation>false</line-level-taxation>
    <requester-lookup-name/>
</invoice-header>

The ApsXml parameter in the XSLT above imports original document output from Tungsten AP Essentials. In this example, we use the XML below. Note customfield01 and customfield02, whose values are used in the custom XSLT.

<?xml version="1.0" encoding="utf-8"?>
<Batches xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Batch>
        <Documents>
            <Document>
                <Parties>
                    <Party>
                        <Type>supplier</Type>
                        <Name>Acme</Name>
                        <ExternalId>74</ExternalId>
                    </Party>
                </Parties>
                <HeaderFields>
                    <HeaderField>
                        <Type>invoicenumber</Type>
                        <Text>0001</Text>
                    </HeaderField>
                    <HeaderField>
                        <Type>creditinvoice</Type>
                        <Text>false</Text>
                    </HeaderField>
                    <HeaderField>
                        <Type>invoicedate</Type>
                        <Text>20230314</Text>
                    </HeaderField>
                    <HeaderField>
                        <Type>invoicetotalvatexcludedamount</Type>
                        <Text>100.00</Text>
                    </HeaderField>
                    <HeaderField>
                        <Type>invoicecurrency</Type>
                        <Text>USD</Text>
                    </HeaderField>
                    <HeaderField>
                        <Type>chartofaccount</Type>
                        <Text>COA-910</Text>
                    </HeaderField>
                    <HeaderField>
                        <Type>customfield01</Type>
                        <Text>custom field 01 example data</Text>
                    </HeaderField>
                    <HeaderField>
                        <Type>customfield02</Type>
                        <Text>custom field 02 example data</Text>
                    </HeaderField>
                </HeaderFields>
            </Document>
        </Documents>
    </Batch>
</Batches>

The configuration parameter in the XSLT above utilizes the Export settings from the target system. For this example, the XML looks like this:

<SystemConfiguration>
    <DefaultChartOfAccounts>COA1</DefaultChartOfAccounts>
    <BillingCombinationTemplate>C1-100-3500-140000</BillingCombinationTemplate>
    <HeaderInvoiceLineDescription>Summary</HeaderInvoiceLineDescription>
    <DefaultTaxCategory/>
    <CustomHeaderFieldMapping/>
    <CustomLineItemFieldMapping/>
    <AutomaticTaxLineDescription>Automatic tax line</AutomaticTaxLineDescription>
    <EnforceLineLevelTaxation>false</EnforceLineLevelTaxation>
    <EnableMissedTaxParameterCalculation>false</EnableMissedTaxParameterCalculation>
    <UseRemitToCode>false</UseRemitToCode>
    <RemitToCodeMapping/>
    <UseDefaultRemitToCode>false</UseDefaultRemitToCode>
</SystemConfiguration>

Given the input above, the XSLT produces this output:

<?xml version="1.0" encoding="utf-8"?>
<invoice-header>
  <document-type>Invoice</document-type>
  <is-credit-note>false</is-credit-note>
  <invoice-date>20230314</invoice-date>
  <invoice-number>XSLT_test</invoice-number>
  <payment-order-number />
  <total-with-taxes d2p1:nil="true" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />
  <gross-total d2p1:nil="true" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />
  <shipping-amount d2p1:nil="true" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance" />
  <currency>
    <code>USD</code>
  </currency>
  <supplier>
    <number>74</number>
  </supplier>
  <account-type>
    <name>COA-910</name>
  </account-type>
  <invoice-lines>
    <invoice-line>
      <line-num>1</line-num>
      <description>Summary</description>
      <order-line-num d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
      <price>100.00</price>
      <quantity d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
      <TaxRate d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
      <TaxAmount d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
      <total d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
      <type>InvoiceAmountLine</type>
      <accounting-total d4p1:nil="true" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
      <account>
        <code />
        <segment-1>C1</segment-1>
        <segment-2>100</segment-2>
        <account-type>
          <name>COA-910</name>
        </account-type>
      </account>
      <currency>
        <code>USD</code>
      </currency>
    </invoice-line>
  </invoice-lines>
  <line-level-taxation>false</line-level-taxation>
  <requester-lookup-name />
  <example-header-field-1>Example text</example-header-field-1>
  <example-header-field-2>custom field 01 example data</example-header-field-2>
</invoice-header>

Note the results of the output. The value of example-header-field-1 is directly specified in the XSLT, whereas, the value of example-header-field-1 was determined by using values from the target system settings and the original document XML.

Try it yourself

Transforming output is an advanced procedure that requires knowledge of XML. These steps should be performed by a knowledgeable developer.

To transform output to Coupa using XSLT:

  1. Create your custom XSLT.
  2. Navigate to the Resources view and click ADD.
  3. Use the dialog that appears to select the file you created. The file appears in the Resources view after it uploads.
    Resources that contain executable code must be approved by Tungsten Automation personnel before they can be used.
  4. Select the Coupa AP target system service and click Configuration.
  5. In the XSL transformation setting, select XSLT resource file.
  6. Specify the XSLT file you created in step one in the XSL transformation file box and save your settings.
  7. Process a document through Tungsten AP Essentials and make sure you custom output is sent to Coupa properly.

    Be sure to test your transformation before you begin production.