Back to Blog
8 min. read

Streamline Your Supply Chain #1: Converting Purchase Order JSON into X12 EDI 850 Format Using Mule 4

Efficient data exchange between trading partners in the supply chain is crucial to maintaining operational fluidity. One challenge companies face is converting purchase orders in JSON format to the X12 850 EDI standard, which is commonly used for electronic order exchange.

This article demonstrates how to utilize Mule 4’s X12 EDI Connector to transform a JSON purchase order into an X12 850 EDI message. X12 850 is a standard EDI transaction set used for electronic purchase orders. With this solution, companies can significantly enhance B2B integration and improve order management efficiency.

Prerequisites:

  • Mule 4 Runtime
  • Anypoint Studio
  • X12 EDI Connector installed in Anypoint Studio

Steps:

1. Create a Mule Flow:

  • Open Anypoint Studio and create a new Mule project.
  • Install X12 Module from Exchange
  • In the palette, search for and drag an HTTP Listener component onto the flow canvas. Configure the listener to receive incoming JSON requests.

2. Transform JSON to X12 850:

Drag a ‘Transform Message’ component onto the flow. After the ‘Transform Message’ component, drag the ‘Write’ operation from X12 Module.

										<ee:transform doc:name="PO_JSON_to_X12_4010_850"doc:id="d499d2fa-1931-4e79-bc3e-16bc6e4fe579" > 

<ee:message > 

<ee:set-payload resource="dwl/outbount-edi-po-850.dwl" />	 

</ee:message> 

</ee:transform> 

<x12:write doc:name="Write" doc:id="16ce0149-0e13-4a17-8ea7-5eeffe5830c0" config-ref="X12_Write_850"/> 
									
  • The X12:Write operation requires an X12 config reference. Create X12 config in global elements. 
										<x12:config name="X12_Write_850" doc:name="X12 EDI Config" doc:id=
"3ad4d9a7-54b6-4d78-a05f-a142671e16cc" interchangeIdQualifierSelf=
"ZZ" interchangeIdSelf="BUYER" groupIdSelf="BUYER" 
interchangeIdQualifierPartner="ZZ" interchangeIdPartner=
"SELLER" groupIdPartner="SELLER" lineEnding="CRLF" 
sendUniqueGroupNumbers="true" requireUniqueInterchanges="false"> 

<x12:schemas > 

<x12:schema value="/x12/004010/850.esl" /> 

</x12:schemas> 

</x12:config> 
									
  • In the config, we need to provide a schema for our 850 Purchase Order; you can find that schema in the X12 EDI Jar File. 
  • Look for the 850.esl file and copy it inside the resources -> schemas folder. There are many versions of 850 Purchase Orders. We are using the 004010 version. Also, copy the basedefs.esl file from the same 004010 version folder and paste it into the resources -> schemas folder. 
  • In the DataWeave editor, create a transformation script that maps the extracted JSON data to the corresponding X12 850 segments. 
										%dw 2.0 

output application/java 

type BigDecimal = Number {class : "java.math.BigDecimal"} 

var approvedDate = payload.PurchaseOrder.PODate 
--- { 

TransactionSets: { 

v004010: { 

"850": [{ 

Heading: { 

"020_BEG": { 

BEG01: if(payload.PurchaseOrder.POPurpose == "New") "00" else "01", 

BEG02: "NE", 

BEG03: payload.PurchaseOrder.PONumber as String default "", 

BEG05: (approvedDate.year ++ approvedDate.month ++ approvedDate.day) as Date {format: "yyyyMMdd"} }, 

"050_REF": [{ 

REF01: "VR", 

REF02: payload.PurchaseOrder.VendorId as String }], 

"060_PER": [{ 

PER01: "BD", 

PER02: payload.PurchaseOrder.BuyerName, 

PER03: "EM", 

PER04: payload.PurchaseOrder.BuyerEmailID }] }, 

Detail: { 

"010_PO1_Loop": payload.PurchaseOrder.POLineItems map (item, index) -> { 

"010_PO1": { 

PO101: item.LineNum, 

PO102: item.Quantity as Number, 

(PO103: "PH") if(item.UnitofMeasure == "Pack"), 

PO104: item.UnitPrice as BigDecimal, 

PO108: "MG", 

PO109: item.VendorItemNum }, 

"050_PID_Loop": [{ 

"050_PID": { 

PID01: "F", 

PID05: if(sizeOf(item.ItemDescription) > 79)item.ItemDescription[0 to 79] else item.ItemDescription } }], 

"350_N1_Loop": [{ 

"350_N1": { 

N101: "ST", 

N102: item.POLineLocation.ShipToLocation.ShipToLocationName, 

N103: "92", 

N104: item.POLineLocation.ShipToLocation.ShipToLocationCode }, 

"370_N3": [{ 

N301: item.POLineLocation.ShipToLocation.Address.AddressLine1, 

N302: item.POLineLocation.ShipToLocation.Address.AddressLine2 }], 

"380_N4": { 

N401: item.POLineLocation.ShipToLocation.Address.City, 

N402: item.POLineLocation.ShipToLocation.Address.State, 

N403: item.POLineLocation.ShipToLocation.Address.PostalCode, 

N404: item.POLineLocation.ShipToLocation.Address.Country } }] } }, 

Summary: { 

"010_CTT_Loop": { 

"010_CTT": { 

//CTT01: sizeOf(payload.PurchaseOrder.*POLineItems) 

CTT01: 4 } } } }] } } } 
									

Let’s try to understand the mapping between input JSON and x12 850 EDI output:

In the Transform Message component, the input JSON is transformed into a Java Object.

  1. There are 5 different components in the Output Java Object – Delimiters, TransactionSets, Interchange, Group, Interchange Acks To Send.
  2. Purchase Order details from input JSON are mapped to TransactionSets.
    If we look at the hierarchy of TransactionSets, there is version – v004010, then inside it 850 – which is a schema for purchase orders. Inside 850, there are different objects where you can map Purchase Order details.
  3. Purchase Order details such as: PONumber, PODate BuyerEmailId BuyerName, POPurpose, CustomerId, CustomerName, and POType are mapped to different objects inside Heading.
  4. POLineItems are mapped to objects inside the Details section.
  5. Heading:
    Note: Details of the fields used inside dwl are given below for other fields please refer to the X12 850 Specification sheet.

Each object inside Heading has different use:

  • 020_BEGBeginning Segment for Purchase Order  
  • Code identifying purpose of transaction set 
  • 00 Original / New 
  • 06 Confirmation 
  • 07 Duplicate 
  • 16 Proposed 
  • Code specifying the type of Purchase Order 
  • BE Blanket Order/Estimated Quantities (Not firm Commitment) 
  • BK Blanket Order (Quantity Firm) 
  • NE New 
  • RE Reorder 
  • SA Stand-alone Order 
  • Purchase Order Number
  • Date
  • 050_REFReference Identification 
  • VR – Vendor reference ID 
  • AO – Appointment Number  
  • BT – Batch Number  
  • CAT – Category Identifier
  • CH – Customer Catalog Number CNO – Commitment Number  
  • CO – Customer Order Number 
  • Note – There are many such values listed by X12 850 specification, I have listed on few  
  •  
  • Reference Identification as defined by REF01 
  • 050_REFAdministrative Communications Contact
  • Code identifying the major duty or responsibility of the person or group named 
  • AA – Authorized Representative 
  • BD – Buyer Name or Department 
  • DC – Delivery Contact 
  • FC – Forwarder Contact 
  • IC – Information Contact 
  • LG – Logistics Contact 
  • OC – Order Contact 
  • SU – Supplier Contact 
  • Name
  • Code identifying the type of communication number  
  • EM – Electronic Mail  
  • FX – Facsimile 
  • TE – Telephone 
  • Communication Number 

6. Detail

  • 010_PO1_Loop – Array of objects representing Baseline items (PO Line Items) in Purchase Order
    • 010_PO1 – Baseline Item Data
  • Alphanumeric characters assigned for differentiation within a transaction set 
  • Item Line Number in our case 
  • Quantity ordered 
  • Unit or Basis for Measurement Code 
  • Unit Price 
  • Product/Service ID Qualifier 
  • Product/Service IDIdentifying number for a product or service 
  •  050_PID_Loop – Product/Item Description  
    • 010_PO1 – Baseline Item Data 
  • Item Description Type  
  • Code indicating the format of a description 
  • F – Free-form 
  • S – Structured (From Industry Code List) 
  • X – Semi-structured (Code and Text) 
  • A free-form description to clarify the related data elements and their content 
  • 350_N1_Loop – Name Segment – To identify a party by type of organization, name, and code.
    Note: There can be only one iteration of the N1 loop in the detail area for each PO1 segment. 

    • 350_N1 – Baseline Item Data 
  • Entity Identifier Code 
  • CN – Consignee  
  • MA – Party for whom Item is Ultimately Intended 
  • ST – Ship To 
  • Name
  • Identification Code Qualifier 
  • Code identifying a party or other code 
  • 370_N3 Address Information To specify the location of the named party 
  • Address information 
  • Address information 
  • 380_N4 Geographic Location To specify the geographic place of the named party 
  • City Name 
  • State or Province Code 
  • Postal Code 
  • Country Code 

Summary

  • CTT_Loop – Transaction Totals – This segment is intended to provide hash totals to validate transaction completeness and correctness.
  • Identification Code Qualifier 

Reference – X12 850 Purchase Order

Deploy and Test:

  • Deploy the Mule application to your Mule runtime environment.
  • Send a POST request containing the JSON purchase order to the configured endpoint of the HTTP Listener.
  • Verify that the Mule flow successfully transforms the JSON data and generates the X12 850 EDI message in the specified output location.

Additional Considerations:

  • Error Handling: Implement error handling mechanisms to gracefully handle potential issues during data transformation or file writing.
  • Security: Ensure proper authentication and authorization mechanisms are in place when receiving and processing external requests.
  • Testing: Thoroughly test your Mule flow with various JSON payloads and edge cases to ensure accurate X12 EDI generation.

By following these steps, you can leverage Mule 4’s X12 EDI connector and DataWeave to automate converting of JSON purchase orders to X12 850 EDI messages, streamlining your B2B integrations.