Introduction
In this article, I will show a way to read EDI TRADACOMS Order 9 messages and fill a Business Object with content. Ultimately, the goal is not read the entire message but just demonstrate how to read the message segments, data elements and data sub elements.
Background
TRADACOMS standards were designed for use in the UK, and are the most commonly used message formats for EDI in the UK. Although it covers a similar range to the UN/EDIFACT standard data published by the United Nations, TRADACOMS use different structures within the messages. The TRADACOMS standard comprises over 30 message types, covering all of the most common commercial transactions. This article will be focusing on the Order 9 Standard. More information can be found here.
When you look at the message for the first time, the content is difficult to understand; however, I will try to demonstrate an easy way to understand it. You can see a sample in Figure 1.
STX=ANA:1+5000000000000:SOME STORES
LTD+5010000000000:SUPPLIER UK LTD+070315:130233+000007+PASSW+ORDHDR+B'
MHD=1+ORDHDR:9'
TYP=0430+NEW-ORDERS'
SDT=5010000000000:000030034'
CDT=5000000000000'
FIL=1630+1+070315'
MTR=6'
MHD=2+ORDERS:9'
CLO=5000000000283:89828+EAST SOMEWHERE DEPOT'
ORD=70970::070315'
DIN=070321++0000'
OLD=1+5010210000000+114455441444:00893592:035921+12+60++++CRUSTY ROLLS:4 PACK'
OTR=1'
MTR=7'
MHD=3+ORDTLR:9'
OFT=1'
MTR=3'
END=3'
A TRADACOMS message contains Segments that start with a Segment Code (e.g., OLD=); each Segment represents Sections like Order Header, Details, or Trailer, and are terminated by a Segment Terminator ('). Each Segment contains many Data Elements delimited by (+), and each Data Element contains none or more Data Sub Elements delimited by (:). On these elements, you can find information like Order Date, Customer, Supplier, Product, Order Qty, etc. See Figure 2:
Parser
Before starting to explain the method I used to parse TRADACOMS messages, I would like to say there are many ways to parse delimited text files and I am just demonstrating one that worked fine for me. Figure 3 resumes the flow used to parse the message:
To manage the information extracted from the message, I use the classes in Figure 4:
The method used to read the message is based on the Split
function. The ParseMessage()
method of the Tradacoms
class splits the message by the delimiter ('), obtaining all the Segments.
public SegmentList ParseMessage()
{
SegmentList segList = new SegmentList();
string[] fileSegments = _fileContent.Split(delimiterSeg);
foreach (string str in fileSegments)
{
Segment seg = ParseSegment(str);
segList.Add(seg);
}
return segList;
}
After each Segment is parsed using the ParseSegment()
method, split by (+) to obtain all Data Elements, and then split each Data Element by (:) to obtain the Data Sub Elements, as you can see in Listing 1.
private Segment ParseSegment(string _segment)
{
string[] strSeg = _segment.Split(delimiterDataElem);
Segment seg = new Segment();
for (Int32 i = 0; i < strSeg.Length; i++)
{
if (i == 0)
{
seg.SegmentName = strSeg[i];
continue;
}
string[] strDataElem = strSeg[i].Split(delimiterDataSubElem);
DataElement dataElem = new DataElement();
for (Int32 j = 0; j < strDataElem.Length; j++)
{
DataSubElement dataSubElem = new DataSubElement();
dataSubElem.Value = strDataElem[j];
dataElem.DataSubElement.Add(dataSubElem);
}
seg.DataElement.Add(dataElem);
}
return seg;
}
Finally, once all the message is parsed, the ParseMessage()
method
returns a class SegmentList
which contains all the information that was extracted. Having the list with all segments, the next step is to iterate over each Segment and populate a corresponding property on the Business Object Order9
. The information is retrieved from the Segment object indicating the position through the method GetDataElement(int dataElementPosition)
and the overload GetDataElement(int dataElementPosition, int dataSubElementposition)
, as you can see in Listing 2.
foreach (Segment seg in segList)
{
switch (seg.SegmentName)
{
case "TYP":
{
orderType = new Order9Type();
orderType.OrderTypeCode = seg.GetDataElement(0);
orderType.OrderType = seg.GetDataElement(1);
break;
}
case "SDT":
{
supplier = new Order9Supplier();
supplier.SupplierGLN = seg.GetDataElement(0);
supplier.SupplierName = seg.GetDataElement(1);
break;
}
case "CDT":
{
customer = new Order9Customer();
customer.CustomerGLN = seg.GetDataElement(0);
customer.CustomerName = seg.GetDataElement(1);
break;
}
case "MHD":
{
if (seg.GetDataElement(1).Equals("ORDERS"))
{
order = new Order9(orderType, supplier, customer);
}
break;
}
case "CLO":
{
order.CustomerDepotGLN = seg.GetDataElement(0);
order.CustomerDepotCode = seg.GetDataElement(0, 1);
order.CustomerDepotAddress = seg.GetDataElement(2);
break;
}
case "ORD":
{
order.CustomerOrderNo = seg.GetDataElement(0);
order.OrderDate = ParseDate(seg.GetDataElement(0, 2));
break;
}
case "DIN":
{
order.DepotDate = ParseDate(seg.GetDataElement(0));
order.DepotTime = ParseTime(seg.GetDataElement(2));
break;
}
case "OLD":
{
Order9Line details = new Order9Line(order.Id);
details.LineNo = seg.GetDataElement(0);
details.ProductSupplierGTIN = seg.GetDataElement(1);
details.ProductSupplierCode = seg.GetDataElement(1, 1);
details.ProductGTIN = seg.GetDataElement(2);
details.ProductCustomerGTIN = seg.GetDataElement(3);
details.ProductCustomerCode = seg.GetDataElement(3, 1);
details.OrderUnit = Convert.ToInt32(seg.GetDataElement(4));
details.OrderQty = Convert.ToInt32(seg.GetDataElement(5));
details.ProductDescription = seg.GetDataElement(9);
order.Order9Lines.Add(details);
break;
}
case "OTR":
{
orderLst.Add(order);
break;
}
default:
break;
}
}
In this sample, I'm not mapping all the information in the Order 9 message to the Business Object.
Conclusion
The idea presented in this article demonstrates one way to retrieve information from TRADACOMS messages. This article has covered the basics of what TRADACOMS messages are. Far from a complete solution, the concepts presented here may be beneficial to those who are looking for a way to read EDI messages. I hope you find this useful.