Generating EDI X12 Documents

Generating EDI X12 Documents

Nowadays, the majority of organizations have embraced Electronic Data Interchange (EDI) as a standard practice. Seamless integration of EDI enables the exchange of a wide range of document types, such as purchase orders, invoices, and requests for quotations. This streamlined process enhances efficiency and facilitates smoother operations.

Often, these organizations function as trading partners, facilitating the regular exchange of specific goods or services. This exchange is a vital component of their B2B networks or supply chains. Through this collaborative relationship, they ensure seamless operations and optimize efficiency in their respective industries.

Although some companies utilize comprehensive EDI systems, it is common for EDI to be just one of several integrations that need support. Investing in a traditional, costly system is often not feasible. In this scenario, it is possible to create a streamlined integration by leveraging one of the accessible open-source tools.

In this blog post, we will provide a concise overview of the fundamentals of Electronic Data Interchange (EDI), the structure of EDI documents, and present a real-life example of a lightweight EDI X12 implementation. We will showcase the utilization of Smooks V2, a popular open-source library for the Java programming language, to demonstrate the seamless integration of EDI into your applications.

What is EDI?

Electronic Data Interchange (EDI) facilitates the seamless exchange of electronic business documents between organizations, guided by mutually agreed-upon rules. In essence, EDI serves as a standardized electronic format that replaces traditional paper-based documents such as purchase orders and invoices. By automating these transactions, companies can save valuable time and mitigate costly errors that often arise from manual processing.

EDI transactions enable the direct transfer of information between computer applications in two collaborating organizations. Additionally, EDI standards dictate the precise location and sequence of data within a document. This automated capability empowers companies to swiftly share information, surpassing the efficiency of traditional methods reliant on paper documents.

The most common documents exchanged via EDI are purchase orders (EDI 850), invoices (EDI 810), and advance ship notices (EDI 856). 

The example of the EDI X12 850 document:

ISA*01*0000000000*01*0000000000*ZZ*ABCDEFGHIJKLMNO*ZZ*123456789012345*200706*1015*U*00401*000001001*0*P*^~
GS*PO*ABCDEFGHIJKLMNO*123456789012345*20200706*1015*1001*X*004010~
ST*850*0001~
N1*BY*XYZ CUSTOMER*91*0001122268292~
N1*ST*XYZ CUSTOMER SHIPTO*91*0001122268292~
N1*SE*ELECTRIC*91*1234~
N1*N4*ELECTRIC*91*1234~
PO1*1*3~
PID*F*MONITOR~
REF*GX*1234-01~
REF*WS*LOC1~
REF*BO*LOC2-LOC3-LOC4~
PO1*2*200~
PID*F*TV~
REF*GX*1234-02~
REF*WS*LOC1~
REF*BO*LOC2-LOC3-LOC4~
CTT*2~
SE*17*0001~
GE*1*1001~
IEA*1*000001001~

We can draw an analogy between EDI and paper documents sent by regular mail in envelopes. The topmost envelope (ISA/IEA Envelope) consists of one or more envelopes (GS/GE Envelopes), which, in turn, contain the documents themselves, each in a separate envelope (ST/SE Envelopes). 

The ISA/IEA envelope contains the addresses of the receiving and sending companies. The type of documents in this envelope is "written" on the GS/GE envelope. Such an envelope contains only documents of one type - orders, invoices, etc. Also, on this envelope, it can be "written" to which department of the recipient company the final documents are sent.

Finally, the most recent envelopes contain the final documents themselves - for example, order.

The document can be depicted as a schema:

Look into every segment separately:

Interchange is structuring a data set according to rules defined by the standard of X12, the data exchange between EDI users. Interchange is more than a document. In most cases, it is a group of documents. However, it can also contain only one document. Interchange starts from segment ISA and ends with segment IEA (ISA/IEA envelope). ISA segment is used, among other things, for routing documents between participants.

functional group is a group (set) of documents (orders, invoices, delivery status, etc.) which are interchangeable. It is located between segments GS/GE.

Document or transaction set is an end set of data used for information exchange between EDI participants. The transaction set is a document that companies use in their work - for example, an invoice or purchase order (PO).

segment is a combination of related or composite data grouped to describe useful information. For example, it can contain information about products like color, weight, size, etc. A segment can appear one time or repeat multiple times.

How to generate EDI using Smooks V2?

Smooks is an extensible Java framework used to build XML and non-XML data (CSV, EDI, Java, etс.) processing applications. It offers APIs, along with a configuration model, which allows defining transformations between predefined formats - for instance, XML to CSV, XML to JSON, etc. Apart from being a lightweight platform to build the required custom processing logic, Smooks provides some useful features you can use individually or combine smoothly. 

To use Smooks, you need to add the following dependency to your project. As we can use only EDI to XML mapping, we should add only a cartridge for that.

<dependency>
    <groupId>org.smooks.cartridges.edi</groupId>
    <artifactId>smooks-edi-cartridge</artifactId>
    <version>2.0.0-M3</version>
</dependency>

To start, we should look at the file that we would like to generate - for example, EDI X12 850. We will use the file we defined in the previous section.

Then we should define a mapping from EDI to XML, and we can use the same file for visa-versa. 

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
  xmlns:ibmEdiFmt="http://www.ibm.com/dfdl/EDI/Format"
  xmlns:ibmSchExtn="http://www.ibm.com/schema/extensions">

  <xsd:import namespace="http://www.ibm.com/dfdl/EDI/Format"
    schemaLocation="/EDIFACT-Common/IBM_EDI_Format.dfdl.xsd"/>

  <xsd:annotation>
    <xsd:appinfo source="http://www.ogf.org/dfdl/">
      <dfdl:format ref="ibmEdiFmt:EDIFormat"/>
    </xsd:appinfo>
  </xsd:annotation>

  <xsd:element ibmSchExtn:docRoot="true" name="X850Interchange">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:sequence dfdl:initiatedContent="yes">
          <xsd:element dfdl:initiator="ISA" dfdl:ref="ibmEdiFmt:EDISegmentFormat"
            name="interchange-header">
            <xsd:complexType>
              <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
                <xsd:element name="auth-qual" type="alpha2-2"/>
                <xsd:element name="auth-id" type="alpha10-10"/>
                <xsd:element name="security-qual" type="alpha2-2"/>
                <xsd:element name="security-id" type="alpha10-10"/>
                <xsd:element name="sender-qual" type="alpha2-2"/>
                <xsd:element name="sender-id" type="alpha15-15"/>
                <xsd:element name="receiver-qual" type="alpha2-2"/>
                <xsd:element name="receiver-id" type="alpha15-15"/>
                <xsd:element name="date" type="alpha6-6"/>
                <xsd:element name="time" type="alpha4-4"/>
                <xsd:element name="standard" type="alpha1-1"/>
                <xsd:element name="version" type="alpha5-5"/>
                <xsd:element name="interchange-control-number" type="alpha9-9"/>
                <xsd:element name="ack" type="alpha1-1"/>
                <xsd:element name="test" type="alpha1-1"/>
                <xsd:element name="s-delimiter" type="alpha1-1"/>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
          <xsd:element dfdl:initiator="GS" dfdl:ref="ibmEdiFmt:EDISegmentFormat"
            name="group-header">
            <xsd:complexType>
              <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
                <xsd:element name="code" type="alpha2-2"/>
                <xsd:element name="sender" type="alpha15-15"/>
                <xsd:element name="receiver" type="alpha15-15"/>
                <xsd:element name="date" type="alpha8-8"/>
                <xsd:element name="time" type="alpha4-4"/>
                <xsd:element name="group-control-number" type="alpha1-9"/>
                <xsd:element name="standard" type="alpha1-2"/>
                <xsd:element name="version" type="alpha1-12"/>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
          <xsd:element dfdl:initiator="ST" dfdl:ref="ibmEdiFmt:EDISegmentFormat"
            name="transaction-set-header">
            <xsd:complexType>
              <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
                <xsd:element name="code" type="alpha3-3"/>
                <xsd:element name="transaction-set-control-number" type="alpha4-9"/>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>

        <xsd:element name="party-identifications">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element dfdl:initiator="N1" dfdl:ref="ibmEdiFmt:EDISegmentFormat"
                name="party-identifications" maxOccurs="unbounded">
                <xsd:complexType>
                  <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
                    <xsd:element name="entity-ic" type="alpha2-3"/>
                    <xsd:element name="name" type="alpha1-60"/>
                    <xsd:element name="id-code-qualifier" type="alpha1-2"/>
                    <xsd:element name="id-code" type="alpha2-80"/>
                  </xsd:sequence>
                </xsd:complexType>
              </xsd:element>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>

        <xsd:element name="items">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element ref="items" maxOccurs="unbounded"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>

        <xsd:element dfdl:initiator="CTT" dfdl:ref="ibmEdiFmt:EDISegmentFormat"
          name="transaction-totals">
          <xsd:complexType>
            <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
              <xsd:element name="number-of-line-items" type="alpha1-6"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
        <xsd:element dfdl:initiator="SE" dfdl:ref="ibmEdiFmt:EDISegmentFormat"
          name="transaction-set-trailer">
          <xsd:complexType>
            <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
              <xsd:element name="number-of-included-segments" type="alpha1-10"/>
              <xsd:element name="transaction-set-control-number" type="alpha4-9"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
        <xsd:element dfdl:initiator="GE" dfdl:ref="ibmEdiFmt:EDISegmentFormat"
          name="functional-group-trailer">
          <xsd:complexType>
            <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
              <xsd:element name="number-of-transaction-sets" type="alpha1-6"/>
              <xsd:element name="group-control-number" type="alpha1-9"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
        <xsd:element dfdl:initiator="IEA" dfdl:ref="ibmEdiFmt:EDISegmentFormat"
          name="interchange-control-trailer">
          <xsd:complexType>
            <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
              <xsd:element name="number-of-function-groups-included" type="alpha1-5"/>
              <xsd:element name="interchange-control-number" type="alpha9-9"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>

      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element ibmSchExtn:docRoot="true" name="items">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element dfdl:ref="ibmEdiFmt:EDISegmentFormat" dfdl:initiator="PO1"
          name="baseline_item_data">
          <xsd:complexType>
            <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
              <xsd:element name="assigned_identification" type="alpha1-20"/>
              <xsd:element name="quantity" type="alpha1-15"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
        <xsd:element dfdl:ref="ibmEdiFmt:EDISegmentFormat" dfdl:initiator="PID"
          name="item_description">
          <xsd:complexType>
            <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
              <xsd:element name="item_description_type" type="alpha1-2"/>
              <xsd:element minOccurs="0" name="description" type="alpha1-80"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
        <xsd:element dfdl:initiator="REF" dfdl:ref="ibmEdiFmt:EDISegmentFormat"
          name="reference-information" maxOccurs="3">
          <xsd:complexType>
            <xsd:sequence dfdl:ref="ibmEdiFmt:EDISegmentSequenceFormat">
              <xsd:element name="id_qualifier" type="alpha2-3"/>
              <xsd:element name="reference_id" type="alpha1-50"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:simpleType name="alpha1-1">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="1"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-2">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="2"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-5">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="5"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-6">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="6"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-9">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="9"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-10">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="10"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-12">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="12"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-15">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="15"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-20">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="20"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-50">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="50"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-60">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="60"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha1-80">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="80"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha2-2">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="2"/>
      <xsd:maxLength value="2"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha2-3">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="2"/>
      <xsd:maxLength value="3"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha2-80">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="50"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha3-3">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="3"/>
      <xsd:maxLength value="3"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha4-4">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="4"/>
      <xsd:maxLength value="4"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha4-9">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="4"/>
      <xsd:maxLength value="9"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha5-5">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="5"/>
      <xsd:maxLength value="5"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha6-6">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="6"/>
      <xsd:maxLength value="6"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha8-8">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="8"/>
      <xsd:maxLength value="8"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha9-9">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="9"/>
      <xsd:maxLength value="9"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha10-10">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="10"/>
      <xsd:maxLength value="10"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="alpha15-15">
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="15"/>
      <xsd:maxLength value="15"/>
    </xsd:restriction>
  </xsd:simpleType>
</xsd:schema>

To define a conversion, we can use a config file or programmatically. The advantage of programmatic configuration is that we can change configuration on the runtime. 

We will look into both of those configurations.

Using Config file to convert:

Config file parse-config.xml:

<?xml version="1.0"?>
<smooks-resource-list
  xmlns="https://www.smooks.org/xsd/smooks-2.0.xsd"
  xmlns:edi="https://www.smooks.org/xsd/smooks/edi-2.0.xsd">

    <edi:parser schemaURI="/blog/mapping.dfdl.xsd"
      segmentTerminator="~%NL;" dataElementSeparator="*" validationMode="Full"/>
</smooks-resource-list>

Config file serialize-config.xml:

<?xml version="1.0"?>
<smooks-resource-list
  xmlns="https://www.smooks.org/xsd/smooks-2.0.xsd"
  xmlns:edi="https://www.smooks.org/xsd/smooks/edi-2.0.xsd">

    <edi:unparser unparseOnElement="*" schemaURI="/blog/mapping.dfdl.xsd"
      segmentTerminator="~%NL;" dataElementSeparator="*" validationMode="Full"/>
</smooks-resource-list>

Execute conversion:

@Test
  void parseBlog850() throws Exception {
    // Convert EDI -> XML
    Smooks ediToXml = new Smooks("blog/parse-config.xml");
    final byte[] ediInput = Files

.readAllBytes(Paths.get(EdiTest.class.getClassLoader().getResource("blog/input.edi").toURI()));

    StringResult result = new StringResult();
    ediToXml.filterSource(new StreamSource(new ByteArrayInputStream(ediInput)), result);
    String xmlResult = result.getResult();
    System.out.printf("Converted to XML:%s %n", xmlResult);

    // Convert XML -> EDI
    Smooks xmlToEdi = new Smooks("blog/serialize-config.xml");

xmlToEdi.setFilterSettings(FilterSettings.newSaxNgSettings().setDefaultSerializationOn(false));
    final byte[] xmlInput = xmlResult.getBytes();

    StringResult ediResult = new StringResult();
    xmlToEdi.filterSource(new StreamSource(new ByteArrayInputStream(xmlInput)), ediResult);
    System.out.printf("Converted to EDI:%s %n", ediResult.getResult());
  }

Programmatical conversion:

@Test
  void parseBlogProgrammatically850() throws Throwable {
    // Convert EDI -> XML
    Smooks ediToXmlSmooks = new Smooks();
    final var ediReaderConfigurator = new EdiReaderConfigurator("blog/mapping.dfdl.xsd");
    ediReaderConfigurator.setDataElementSeparator("*");
    ediReaderConfigurator.setSegmentTerminator("~%NL;");
    ediToXmlSmooks.setReaderConfig(ediReaderConfigurator);

    final byte[] ediInput = Files

.readAllBytes(Paths.get(EdiTest.class.getClassLoader().getResource("blog/input.edi").toURI()));
    StringResult result = new StringResult();
    ediToXmlSmooks.filterSource(new StreamSource(new ByteArrayInputStream(ediInput)), result);
    String xmlResult = result.getResult();
    System.out.printf("Converted to XML:%s %n", xmlResult);

    // Convert XML -> EDI
    Smooks xmlToEdiSmooks = new Smooks();
    DfdlSchema dfdlSchema = new
DfdlSchema(EdiTest.class.getClassLoader().getResource("blog/mapping.dfdl.xsd").toURI(),
        new HashMap<>() {{
          this.put("{http://www.ibm.com/dfdl/EDI/Format}SegmentTerm", "~%NL;");
          this.put("{http://www.ibm.com/dfdl/EDI/Format}FieldSep", "*");
          this.put("{http://www.ibm.com/dfdl/EDI/Format}CompositeSep", "^");
          this.put("{http://www.ibm.com/dfdl/EDI/Format}EscapeChar", "?");
          this.put("{http://www.ibm.com/dfdl/EDI/Format}RepeatSep", "*");
          this.put("{http://www.ibm.com/dfdl/EDI/Format}DecimalSep", ".");
          this.put("{http://www.ibm.com/dfdl/EDI/Format}GroupingSep", ",");
        }}, ValidationMode.Full, false, false, null);
    DfdlUnparser dfdlUnparser = new DfdlUnparser(dfdlSchema.compile());

// this is required because of a bug in DfdlUnparser
    ResourceConfig resourceConfig = new DefaultResourceConfig();
    resourceConfig.setParameter("schemaURI", "");
    xmlToEdiSmooks.getApplicationContext().getRegistry().lookup(new LifecycleManagerLookup())
        .applyPhase(dfdlUnparser, new PostConstructLifecyclePhase(
            new Scope(xmlToEdiSmooks.getApplicationContext().getRegistry(), resourceConfig,
                dfdlUnparser)));

    xmlToEdiSmooks.addVisitor(dfdlUnparser, "*");

xmlToEdiSmooks.setFilterSettings(FilterSettings.newSaxNgSettings().setDefaultSerializationOn(false));
‍
    result = new StringResult();
    xmlToEdiSmooks.filterSource(new StreamSource(new ByteArrayInputStream(xmlResult.getBytes())), result);
    System.out.printf("Converted to EDI:%s %n", result.getResult());
  }

The result

<X850Interchange>
  <interchange-header>
    <auth-qual>01</auth-qual>
    <auth-id>0000000000</auth-id>
    <security-qual>01</security-qual>
    <security-id>0000000000</security-id>
    <sender-qual>ZZ</sender-qual>
    <sender-id>ABCDEFGHIJKLMNO</sender-id>
    <receiver-qual>ZZ</receiver-qual>
    <receiver-id>123456789012345</receiver-id>
    <date>200706</date>
    <time>1015</time>
    <standard>U</standard>
    <version>00401</version>
    <interchange-control-number>000001001</interchange-control-number>
    <ack>0</ack>
    <test>P</test>
    <s-delimiter>^</s-delimiter>
  </interchange-header>
  <group-header>
    <code>PO</code>
    <sender>ABCDEFGHIJKLMNO</sender>
    <receiver>123456789012345</receiver>
    <date>20200706</date>
    <time>1015</time>
    <group-control-number>1001</group-control-number>
    <standard>X</standard>
    <version>004010</version>
  </group-header>
  <transaction-set-header>
    <code>850</code>
    <transaction-set-control-number>0001</transaction-set-control-number>
  </transaction-set-header>
  <party-identifications>
    <party-identifications>
      <entity-ic>BY</entity-ic>
      <name>XYZ CUSTOMER</name>
      <id-code-qualifier>91</id-code-qualifier>
      <id-code>0001122268292</id-code>
    </party-identifications>
    <party-identifications>
      <entity-ic>ST</entity-ic>
      <name>XYZ CUSTOMER SHIPTO</name>
      <id-code-qualifier>91</id-code-qualifier>
      <id-code>0001122268292</id-code>
    </party-identifications>
    <party-identifications>
      <entity-ic>SE</entity-ic>
      <name>ELECTRIC</name>
      <id-code-qualifier>91</id-code-qualifier>
      <id-code>1234</id-code>
    </party-identifications>
    <party-identifications>
      <entity-ic>N4</entity-ic>
      <name>ELECTRIC</name>
      <id-code-qualifier>91</id-code-qualifier>
      <id-code>1234</id-code>
    </party-identifications>
  </party-identifications>
  <items>
    <items>
      <baseline_item_data>
        <assigned_identification>1</assigned_identification>
        <quantity>3</quantity>
      </baseline_item_data>
      <item_description>
        <item_description_type>F</item_description_type>
        <description>MONITOR</description>
      </item_description>
      <reference-information>
        <id_qualifier>GX</id_qualifier>
        <reference_id>1234-01</reference_id>
      </reference-information>
      <reference-information>
        <id_qualifier>WS</id_qualifier>
        <reference_id>LOC1</reference_id>
      </reference-information>
      <reference-information>
        <id_qualifier>BO</id_qualifier>
        <reference_id>LOC2-LOC3-LOC4</reference_id>
      </reference-information>
    </items>
    <items>
      <baseline_item_data>
        <assigned_identification>2</assigned_identification>
        <quantity>200</quantity>
      </baseline_item_data>
      <item_description>
        <item_description_type>F</item_description_type>
        <description>TV</description>
      </item_description>
      <reference-information>
        <id_qualifier>GX</id_qualifier>
        <reference_id>1234-02</reference_id>
      </reference-information>
      <reference-information>
        <id_qualifier>WS</id_qualifier>
        <reference_id>LOC1</reference_id>
      </reference-information>
      <reference-information>
        <id_qualifier>BO</id_qualifier>
        <reference_id>LOC2-LOC3-LOC4</reference_id>
      </reference-information>
    </items>
  </items>
  <transaction-totals>
    <number-of-line-items>2</number-of-line-items>
  </transaction-totals>
  <transaction-set-trailer>
    <number-of-included-segments>17</number-of-included-segments>
    <transaction-set-control-number>0001</transaction-set-control-number>
  </transaction-set-trailer>
  <functional-group-trailer>
    <number-of-transaction-sets>1</number-of-transaction-sets>
    <group-control-number>1001</group-control-number>
  </functional-group-trailer>
  <interchange-control-trailer>
    <number-of-function-groups-included>1</number-of-function-groups-included>
    <interchange-control-number>000001001</interchange-control-number>
  </interchange-control-trailer>
</X850Interchange>

The bottom line

Generating EDI is crucial for B2B processes since electronic document interchange remains a preferred approach to exchanging documents and transactions between companies of different sizes, including small ones. Among the most critical benefits of generating EDI are the following: 

  • Save time and money by automating processes that were previously performed manually using paper documents;
  • Increase efficiency and productivity since sharing and processing business documents requires less time and provides better accuracy;
  • Reduce errors thanks to rigid standardization. That ensures information is appropriately formatted before entering business processes and applications;
  • Improve traceability and reporting as you can integrate electronic documents with various IT systems for supporting data collection, visibility, and further analysis;
  • Ensure a positive customer experience because EDI allows you to execute transactions efficiently and deliver products or services in a timely and reliable manner. 

How AgileVision can help

Over the past several years, AgileVision has helped many businesses connect to EDI or integrate it into their business systems. Do you need some help choosing the most suitable EDI solution for your company?