Is it possible to use a converter (like input channel) inside a workflow?

Hi Service Connect Gurus!!

I have the doubt, is it possible to use a converter within a workflow?

  1. Launch workflow through BPM
  2. Within workflow find and read xml file in a shared folder and convert it with anyxml2xm in order to wraps it in the internal envelope format.

Thanks in advance! :smiley:

Hi Víctor,

What is the scenario you are looking to fulfill with the step-by-step you provided?

I mean, triggering a workflow from a BPM directive on the one hand, but having it read additional data from some external location – what it the relation between these two actions, could you please clarify?

Also – in your scenario, are Epicor ERP server & SC installed in a corporate LAN, or in SaaS?


The idea it’s to auto fill some data on AP Invoice based on an electronic file (XML) that suppliers provide to us, currently this process is manual, so in order to “automate” this process we need follow this flow:

Epicor ERP:
1.- When in Receipt Entry Receibed All checkbox is marked, trigger the BPM.

ESC Workflow:
2.- Pickup al XML file in a shared folder based on BPM Context Data (PONUM and SupplierID).
3.- Create an AP Invoice Group and APInvoice and fill some fields whit data whithin XML file previusly pikedup.


I see.

Let me experiment with an idea a bit; it is not possible to use the anyxml2Xml per se, but I think you should be able to load the XML from within an XSLT on the workflow, and that should cover your needs.

Alternatively – do you need to involve the user at all, given the XML somehow arrives from the supplier, and it is purchase order-specific, or does the user actually places the XML to that shared folder prior to ticking the checkbox?
If it is the latter – does the user perform actual naming of the XML on the shared folder?

I am asking this because SC can retrieve the XML from mail attachment on its own, as well as picking up the XML from a shared folder as well, triggering the workflow execution – or is in your case SC just reading the XML from the folder, fills the data in the message, and returns it to the calling BPM workflow for further processing (so, SC is not actually creating anything in the ERP, just loading the data for BPM directive/base logic to apply when the call to SC returns the data loaded from the XML)?


Honestly, this is exactly what AP Automation with DocStar does. If you provide DocStar a file with the known entities (Company and PO number is all you really need) then all the workflow is easy (does the three way match, prompts for approvals, etc.) and the XML file can be attached and stored.

That’s right, this can be done with Epicor ECM (formerly DocStar), sadly we don’t have an ECM license but we do have a Service Connect license. :smiley:

I already made a workflow that takes the XML file from email or a directory (depends on an input channel) and generates an AP Invoice Group and AP Invoice, but this only works in very specific cases, I want to automate this process completely not only for certain suppliers.

Thanks for the support, Ill keep looking for a solution.

What I’ve heard others do is load the doc (XML or Json) into a UD## or UD### table. It should fit completely in CHARACTER01. Then use SHORTCHAR01 as a state field. This makes the import dead simple and now you can run a first pass that checks for the state and performs different Epicor Functions against it. A freshly imported record will be a NEW state and you’d validate the fields. You may have a RECV state indicating you’re missing a receiver, etc. A simple dashboard showing documents by state would be used to monitor the imports. Once everything is good, you can load an AP Group and call it a day. All your logic is in a Function library and you might not even need ServiceConnect as you could import the files with just a REST call. Food for thought…

Here is the sample doing some magic.

This is a Start->Conversion->Finish that illustrates the approach (it was in AMS package and is called LoadXml) (4.1 KB) .

The error handling is a bit lacking, though I made the effort in its respect, however since I am building the error XML manually, if reason or description contain special characters, the locding of manually-built XML will fail, and the resulting node will be empty.

  • The workflow accepts the message according to UserSchemas/Standard/SingleDataValues.xsd schema, the conversion copies all the data from left to right.
  • The worflow additionally declares a SingleValues message extension according to the same schema (conversion does not copy it from left to right, but instead…)
  • The conversion picks dta/SingleValues/Strings/String1 and dta/SingleValues/Strings/String2 values, converting them to stirings
  • The conversion has a script block contianing the fucntion called LoadXmlFileFrom written in JScript accepting three parameters - baseFolder, namePart1, namePart2
  • The function builds the path to the file as <namePart1>_.xml, loads XML from that file and returns it back to the XSLT processing
  • The XSLT part then copies the content of the returned XML to the output document

The incoming message for it looks like this (while testing I used it from DESPoster to trigger the workflow):

<msg:msg xmlns:msg="">
  <msg:req tag="AMS\LoadXml">
      <SingleValues xmlns="">

The file I am loading is D:\Tst\p1_p2.xml D:\Tst\p1_p2.xml and looks like this:

<?xml version="1.0"?>
      <SingleValues xmlns="">

The workflow has a message extension declared (this will help to consume the loaded content later on):

If you unzip the zip file to your …\Epicor Service Connect\System\Services\DES\Processes\Custom\Packages\ folder (so that AMS folder appears right under Packages) and open the workflow in SC Workflow Designer, you should be able to review the only conversion).

Switch to the XSLT view.
At the beginning of the XSLT I am declaring two additional schema prefixes – xmlns:msxsl (needed to access MSXML xslt extensions and CustomHelper used to declare the helper function:

<xsl:stylesheet version="1.0" xmlns:xsl=""

A bit lower comes the script block that contains the LoadXmlFileFrom function written in JScript:

  <msxsl:script language="JScript" implements-prefix="CustomHelper"><![CDATA[  
       function LoadXmlFileFrom(basePath, namePart1, namePart2) {

         // Create a new XML Document object
         var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.6.0");
         xmlDoc.async = false;
         xmlDoc.validateOnParse = false;
         xmlDoc.resolveExternals = false;
         xmlDoc.preserveWhiteSpace = true;

           // Load data from external file
           if (!xmlDoc.load(basePath + "\\" + namePart1 + "_" + namePart2 + ".xml"))
             // Return the error in XML form
             var parseErr = xmlDoc.parseError;

             xmlDoc.loadXML("<ERROR Code=\"" + parseErr.errorCode.toString() + "\" Reason=\"" + parseErr.reason + "\" ></ERROR>");
           xmlDoc.loadXML("<ERROR Number=\"" + err.number.toString() + "\" Description=\"" + err.description + "\" ></ERROR>");

         return xmlDoc.documentElement;

later on, within msg:usr seciton – manual creation of msg:SingleValues container element, content of which is filled with the output of the function invocation; when invoking the function, second and third parameter values are taken from the incoming message:

            <xsl:element name="msg:usr">
              <!-- Manually create the enclosing element -->
              <xsl:element name="msg:SingleValues">
                <!-- Parse all elements out of the returned XML and add them to the output document -->
                select="CustomHelper:LoadXmlFileFrom('D:\Tst', string(msg:dta/ext_SingleDataValues:SingleValues/ext_SingleDataValues:Strings/ext_SingleDataValues:String1), string(msg:dta/ext_SingleDataValues:SingleValues/ext_SingleDataValues:Strings/ext_SingleDataValues:String2))">
                  <xsl:copy-of select="."></xsl:copy-of>
                <!-- Done! --></xsl:element>

And here is how the message looks in document tracking, when it reaches Finish element:

I hope this illustrates the approach in a reasonably clear way.