Skip to content

Transactions

Glossary

A transaction type or concept defines the transaction XML structure - the most common transaction type / concept is TransactionInfo but there are others like Logging Event, Update Report, etc.

A transaction is an XML document stored in the database.

A document is either a structured document received or sent to a trading partner (e.g. a PIDX invoice) or an attachment, such as a PDF. It is attached to a transaction.

A view is defined in the Views service and determines, for a specific transaction type, the searchable elements and the viewable elements within the transaction.

Features

Through the Transactions service UI, you can start a new search with different search parameters.

Transactions

The search parameters and the values of the response are associated with the selected view. They are customizable in the Views service.

Warning

If you have updated a view, you need to restart the Transactions service using the service lifecycle header to take the changes into account.

Enriched view

When you double click on a transaction, the server executes a script named [VIEW_APPKEY].View_[VIEW_NAME] and returns the HTML content of the transaction enriched with its values.

The script takes the XML and converts it into HTML. Here is a sample of a script.

// Get the slurped xml
def transactionInfo = p6.pipeline.getXml 'xml'

// Values
def businessDocName = transactionInfo.BusinessDocName.text()
def businessDocNumber = transactionInfo.BusinessDocNumber.text()

def sellerName = transactionInfo.KeyValue.find{it.Key == "Seller Name"}.Value.text()
def buyerName = transactionInfo.KeyValue.find{it.Key == "Buyer Name"}.Value.text()

def html = """
<div class="transaction-info-view-wrapper">
    <div class="row">
        <div class="col-xs-12 col-sm-6 transaction-info-section">
            <div class="transaction-info-header">Transaction: <strong><span class="right-spaced">${businessDocName}</span> ${businessDocNumber}</strong></div>
            <div class="row">
                <div class="col-xs-12 col-md-4">
                    <div class="transaction-info-label">Seller name</div>
                    <div class="transaction-info-value">${sellerName}</div>
                </div>
                <div class="col-xs-12 col-md-4">
                    <div class="transaction-info-label">Buyer name</div>
                    <div class="transaction-info-value">${buyerName}</div>
                </div>
            </div>
        </div>
    </div>
</div>
"""

p6.pipeline.put 'portalHtml', html, 'text/html'

The returned portalHtml allows a customised display of a variety of values; transaction details: additional information, status, attachments, workflow history etc. If no view script exists or the script fails to return portalHtml you will only see the transaction’s XML.

!!! tip title=”Translation” Since 6.9.9

Download of Attachments

The View script generated portalHtml can contain links like <div onclick="platform6.transactionDownload(this)"> that will allow the user to download attachments.

Here is an example of the XSLT required to generate the portalHtml:

<div class="col-xs-12 col-md-6">                        
    <div class="transaction-info-value">
        <div class="transaction-info-file">
            <xsl:variable name="srcDocExtension">
                <xsl:call-template name="get-file-extension">
                    <xsl:with-param name="path" select="CurrentDocumentURI"/>
                </xsl:call-template>
            </xsl:variable>

            <div onclick="platform6.transactionDownload(this)">
                <xsl:attribute name="class">
                    <xsl:value-of select="concat('ft-icon ft-icon-', $srcDocExtension)"/>
                </xsl:attribute>
                <xsl:attribute name="data-extension"><xsl:value-of select="$srcDocExtension"/></xsl:attribute>
                <xsl:attribute name="data-ids"><xsl:value-of select="$msgId"/></xsl:attribute>
                <xsl:attribute name="data-uri"><xsl:value-of select="CurrentDocumentURI"/></xsl:attribute>
                <xsl:attribute name="data-content-type"><xsl:value-of select="CurrentDocumentContentType"/></xsl:attribute>
                <xsl:attribute name="data-view">{{viewName}}</xsl:attribute>
            </div>

            <xsl:variable name="srcDocFileName">
                <xsl:call-template name="get-file-name">
                    <xsl:with-param name="path" select="CurrentDocumentURI"/>
                </xsl:call-template>
            </xsl:variable>
        </div>
    </div>
</div>

Warning

The function b2portal.messageDownload() is available for backward compatibility only and is now deprecated. platform6.transactionDownload() should now be used. (messageDownload requires the older message permissions whereas transactionDownload requires the current transaction based permission sets)

Important

If the elements contained in the transaction XML specify a file:// URI then the file path MUST be contained in an allowed download location. This is for security reasons. The configuration property: p6.allowed.paths is used to define the list of allowable download locations Defaults are: ${P6_DATA} and ${P6_TMP}

Display a transaction

Edit a transaction

You can also edit the transaction XML definition. It is validated on the save by the associated data model.

The transaction is not saved if the XML is invalid.

Edit a transaction

Finally, in addition of printing, deleting and refreshing, a transaction can be reprocessed using the Platform 6 routes. Have a look at the Views service guide section to see how a transaction can be routed.

Upload & Creation

The import / export feature available on the transaction screen allow the user to transfer transaction data across instances. It is exporting the XML content of the transaction.

Message Submission

Tip

Transactions can also be imported using P6Cmd

Visibility

By default, a P6 Instance has message submission disabled unless the following configuration property is set:

p6.messagesubmit.exclude = false

Note

The message submission endpoints are always available on an instance but not advertised via the /info endpoint response as default, instead they are advertised with an id of filesubmit

Having the permissions messages=submit or messages=* will display the buttons Upload files and Create transaction in the transaction screen.

Tip

To display only Upload files give messages=submit('bulk') permissions. For Create transaction give transactions=messages('single').

Stale session detection

The following configuration property can be set to override the default value of: 1200000 milli seconds (20 mins)

p6.default.messageSubmit.timeout

Default Script Name To Execute

The following configuration property can be used to override the default value of: MessageSubmission

p6.default.messageSubmit.script

Note

Since 6.9.7

The script used will be searched according to the appKey of the view (i.e. appKey.MessageSubmission) and then fallback to default one (i.e. MessageSubmission).

Response result for unprocessed files

The following configuration property can be used to override the default of: WARNING

p6.default.messageSubmit.unprocessedResult

It must be one of:

  • OK
  • WARNING
  • ERROR
MessageSubmission Script

This script will be executed when a submission session is committed or closed (when cancel = false)

The following pipeline variables will be made available to the MessageSubmission script:

  • attribute.[key]=[value] (attribute key/value pairs given when the session was created via the /new endpoint)
  • entity.[n].attribute.[key]=[value] (attribute key/value pairs given when a file entity was added to the session)
  • entity.[n].name (name of file entity)
  • entity.[n].givenName (the original name of file entity)
  • entity.[n].size (size of file entity)
  • entity.[n].uri (uri of server storage location of entity)
  • platform6.request.user.permissions (permissions string of user invoking the endpoints)
  • platform6.request.user (username of user invoking the endpoints)

Note

Since 6.9.7

Using the UI:

  • the attribute.type will have the value bulk (Upload files) or single (Create transaction)
  • the attribute.appKey will contain the appKey associated to the current view
  • the attribute.viewName will contain the name of the current view

The following pipeline variables are expected as a response and are mapped to the session status response:

  • _entity_[entity name]_id_[n]_ (Id(s) generated by processing the entity)
  • _entity_[entity name]_message_ (Per entity processing message)
  • _entity_[entity name]_result_ (Per entity result: One of OK, WARNING, ERROR)
  • platform6.response.status (Overall session processing result: true|false)
  • platform6.response.value (Overall session processing result message)

Example

int i = 0
boolean hasError = false    
while (null != p6.pipeline.get("entity." + i + ".name")) {
    def filename = p6.pipeline.get('entity.' + i + '.name')
    def givenName = p6.pipeline.get('entity.' + i + '.givenName')
    def file_uri = p6.pipeline.get('entity.' + i + '.uri')
    hasError |= !(checkSubmittedFile(filename, givenName, file_uri))
    i++
}

if (hasError) {
    p6.pipeline.put("platform6.response.status", "false")
    p6.pipeline.put("platform6.response.value", "At least one file has not been processed. Check files statuses")
} else {
    p6.pipeline.put("platform6.response.status", "true")
    p6.pipeline.put("platform6.response.value", "ok")
}

boolean checkSubmittedFile(filename, givenName, file_uri) {    
    if (!docType.endsWith('.xlsx')) {
        def errMsg = 'File type must be excel (.xlsx)'
        p6.pipeline.put("_entity_" + filename + "_result_", "ERROR")
        p6.pipeline.put("_entity_" + filename + "_message_", errMsg)
        p6.log.debug 'FILE ' + filename + ' => ERROR : ' + errMsg
        return false            
    } else {
        def srcFile = p6.uri.fileFromUrl(file_uri)
        def targetURI = 'file://' + P6_DATA + '/path/to/' + givenName
        def destFile = p6.uri.fileFromUrl(targetURI)
        FileUtils.copyFile(srcFile, destFile)

        p6.pipeline.put("_entity_" + filename + "_result_", "OK")
        p6.pipeline.put("_entity_" + filename + "_message_", "successMsg")
        p6.pipeline.put("_entity_" + filename + "_id_0_", 'id_of_the_created_transaction')
        return true
    }
}

Permissions

A permission transactions=allow(...) must be explicitly set for any user that wishes to access transactions and/or documents; the transactions=* permission is not sufficient.

By default, access to all transactions is denied with the transactions=allow("FILTER,FILTER,...") permission.

Multiple instances of FILTERS, separated by comma may be specified. FILTER is either:

  • *: access to all transactions is granted
  • "VIEW_NAME"(FILTER_EXPR, FILTER_EXPR,...): access to the VIEW_NAME view is granted under the condition(s) specified by the FILTER_EXPR.

Accessing all transactions under the VIEW_NAME view

Set FILTER_EXPR to *. For example: transactions=allow('MyView'(*))

Filtering transactions based on the transaction content in the VIEW_NAME view

Set FILTER_EXPR to "SEARCHABLE_NAME"="VALUE" where:

  • SEARCHABLE_NAME is the name of a searchable in the XML definition of that view
  • VALUE is the value to filter that searchable on

A special VALUE, %USER.EMAIL% will be auto-expanded to the current user email address allowing the set-up of automatic filtering of messages based on the user email. The email must be present in the message, at the XPath location indicated in the XML definition for the view.

For example: transactions=allow( "Invoices and Exceptions" ( "UserEmail" = "%USER.EMAIL%" ))

Filtering transactions based on the position of the user in the organization tree

Set FILTER_EXPR to either UNIT or BRANCH where:

  • UNIT means transactions dispatched to the same organization node as the user, and this one only.
  • BRANCH means transactions dispatched to the same organization node as the user, and any child of this node.

To dispatch a transaction to an organization node:

  1. The transaction must contain an XML element containing the full path to an organization node (the name of the XML element itself dow not matter).

    Example: <OrgPath>/Demo/Portals/Customer Portal/Customer A</OrgPath>

  2. The XML definition of the VIEW_NAME view must contain a searchable of type OrgPath with its XPath pointing to the element containing the organization node path in the transaction.

    <Searchable>
        <Name>OrgPath</Name>
        <Description>
            <EN>Organizational path</EN>
            <FR>Chemin organisationnel</FR>
        </Description>
        <XPath>/TransactionInfo/OrgPath//text()</XPath>
        <Type>OrgPath</Type>
    </Searchable>
    

Note

All permission names and uses are listed for Transactions and Documents.

Scripting

You can manage transactions with the Scripts service using the transaction DSL.