Sync Improv

Ramblings about JDE Integration – an innovative way

October 22, 2013
by blogger-hs
0 comments

Wouldn’t it be nice to write programs in C#/.Net to integrate external applications with E1? Harness your existing skill set or the (vast) existing pool of .Net resources? And do this using a familiar IDE – Visual Studio? Now you can, with Aellius LynX Business Integrator, an Oracle Validated product. LynX Business Integrator runs on top of EnterpriseOne’s application layer, so you are in compliance with EnterpriseOne’s security (i.e. no “back door” access).

EnterpriseOne Capabilities

Here’s what you can do with LynX Business Integrator:

  • Call Business Functions
  • Database Operations (Select, Insert, Update & Delete)
  • Upload and attach media objects
  • Transaction control (across the above three operations)
  • Call Reports

YouTube Demo

Architecture

Here is a simplified architecture diagram for LynX Business Integrator.

lbi architecture

  1. The external app creates an XML document and calls a web service.
  2. The web service passes the XML document to an integration server, which executes a LynX Business Process.
  3. The Business Process interacts with EntperiseOne internally through native C-API.

Business Process

The core of the integration is the Business Process. The Business Process consists of:

  • XML Schema to validate the XML document (submitted by the external app through the web service)
  • A .Net class written in C# (that implements a known interface)

XML Schema

The XML Schema accomplishes two things:

  • Provides a standard way to validate the document. So, you don’t have to write custom code, for example, to mandate that an address book number should be a numeric value with no fractions with a maximum length of 8.
  • Keep the same web service method for all integrations. For example, the external app can call the same web service method to upload Address Book records and query Address Book records. The difference between the two calls is in the XML document passed to the web service method.

Integration ID

The integration ID uniquely identifies a Business Process. The integration ID must be specified in the input document. This allows the system to identify the target XML Schema to validate the document.

Here is a sample document to find Address Book Records. The integration ID for this document is ERP.EOne.FindAddress.

[code language=”xml”]
<?xml version="1.0" encoding="utf-16"?>
<aelliusconnector>
<processsettings
aelliusrequestid="ERP.EOne.FindAddress"
environment="JDV910" debug="false" />
<document>
<input>
<MaxRecordCount>1000</MaxRecordCount>
<AddressNumber>500</AddressNumber>
<SearchType>C</SearchType>
</input>
</document>
</aelliusconnector>
[/code]

Here is a sample document to find Fixed Asset Records. The integration ID for this document is ERP.EOne.FindFixedAsset.

[code language=”xml”]
<aelliusconnector>
<processsettings
aelliusrequestid="ERP.EOne.FindFixedAsset"
environment="JDV910" debug="false" />
<document>
<input>
<MaxRecordCount>1000</MaxRecordCount>
<GetAllFields>false</GetAllFields>
<UnitNumber>1010220</UnitNumber>
</input>
</document>
</aelliusconnector>

[/code]

.Net Class Library

The .Net class library is created using a Visual Studio Template provided as part of the development toolset. This is just like any other .Net library. The .Net library must contain at least one class that implements the IIntegrationProcess interface. The LynX infrastructure calls a method (ProcessDocument) of the interface when a document is received by the web service. The meat of the integration is in this method:

  1. Retrieve the data from the XML document.
  2. Use LynX.Net API to access EnterpriseOne objects (see EnterpriseOne capabilities above)
  3. Create the output document. This document will be returned to the caller through the web service.

Note: There are no restrictions on what you can do in the .Net class. Everything that .Net has to offer is available to you.

The ProcessDocument method

This method is called by LynX to initiate the integration. A typical ProcessDocument method looks like this:

[code language=”csharp”]

public void ProcessDocument()
{
// deserialize the XML Document
BusinessDocument doc = (BusinessDocument)DocumentContext.Deserialize(typeof(Demo1.BusinessDocument));
DocumentContext.BusinessEntityObject = doc;
try
{
// use E1 objects in your process

// set the document’s status to true to signal that
// the request was successful
DocumentContext.DocumentStatus = true;
}
catch (Exception excpt)
{
// add errors to the output
DocumentContext.AddError(excpt, true);
}
finally
{
// serialize the typed class back to the XML document
if (DocumentContext.BusinessEntityObject != null)
{
BusinessDocument bd = DocumentContext.BusinessEntityObject as BusinessDocument;
DocumentContext.FinalizeOutput(bd.document.output, true, true);
}
}
}
[/code]

Retrieving data from the XML Document

You can use the XmlDocument object or deserialize the document to a typed object. The DocumentContext provides properties and methods to do this.

To access the XML document as an XmlDocument object:

[code language=”csharp”]
XmlDocument xml = DocumentContext.Document;
string line1 = ((XmlText)xml.SelectSingleNode("/aelliusconnector/document/input/AddressLine1/text()")).Value;
[/code]

To access the XML document as a typed object:

[code language=”csharp”]
BusinessDocument doc = (BusinessDocument)DocumentContext.Deserialize(typeof(Demo1.BusinessDocument));
string addressline1 = doc.document.input.AddressBook.AddressLine1;
[/code]

Using EnterpriseOne Objects in C#

So, how do we access E1 objects in C#? By generating typed classes that represent the underlying E1 object. dnetgen, a command line utility, creates typed classes for the specified E1 objects and compiles them into a library. That library is referenced in the business process library. The following screenshot shows how to generate a typed class for the F0005 object.

lbi architecture

Since F0005 is a typed class, it accurately represents the underlying E1 object. So, instead of using a generic class like this:

[code language=”csharp”]
TableObject tb = new TableObject("F0005");
f0005.AddCriteria(Parenthesis.None, Conjunction.And, "ProductCode", SingleValueOperator.EqualTo, "00");
string value = ((string)tb.GetSelectedValue("UserDefinedCode")).Trim();
[/code]

you write:

[code language=”csharp”]
F0005 f0005 = new F0005();
f0005.AddCriteria(Parenthesis.None, Conjunction.And, F0005.Column.ProductCode, SingleValueOperator.EqualTo,
"00");
string value = f0005.TcUserDefinedCode.SelectedValue.Trim();
[/code]

The difference? Using the generic class is prone to errors. If you mistype the value F0005 in the constructor, a runtime exception will be thrown. The typed class catches these errors during compile time. Also note the implicit string conversion to get the selected value in the generic class. In the typed version f0005.TcUserDefinedCode.SelectedValue is typed to string data type.

Creating the Output Document

Before the ProcessDocument method exits, the document is finalized. This is done using one of the FinalizeDocument overloads of the Document Context method. Finalizing the document indicates that you are done with the request and that it is ready for the caller (of the web service) to receive.

[code language=”csharp”]
BusinessDocument bd = DocumentContext.BusinessEntityObject as BusinessDocument;
DocumentContext.FinalizeOutput(bd.document.output, true, true);
[/code]

In the next post, I will give you examples of C# code that illustrate the E1 capabilities of this product.