What is EDI? Electronic Data Interchange


1. Warehouse Operations Simulation Model

In our Python script, we will replicate several warehousing processes from the angle of EDI message exchange

  • Inbound shipment messages containing details like SKU and quantity
  • Putaway confirmations with SKUs and putaway locations

Logistic Operations — (Image by Author)

These messages enable the ERP and Warehouse Management systems (WMS) synchronization, drive efficiency and reduce errors.

  • Message 1: informing the warehouse teams that a shipment is coming for inbound via the WMS (ERP -> WMS)
  • Message 2: warehouse teams inform the distribution planning team that the pallet has been put in stock and is ready to be ordered (WMS -> ERP)

2. Build a simulation model with Python

Let’s simulate these message exchanges using the EDI norm ANSI X12

  1. Inbound: goods are received at the warehouse
    An EDI message (Warehouse Shipping Order — 940) notifies the warehouse of an incoming shipment and its details.
  2. Putaway: after receiving, goods are stored at a specific location
    A confirmation EDI message (Warehouse Stock Transfer Receipt Advice — 944) is returned to the ERP to confirm the putaway.
  3. Picking: for an order, items are picked from storage locations
    This EDI message (Warehouse Shipping Order — 940) can be used to instruct the warehouse on which items to pick.
  4. Outbound: shipping to the customer
    An EDI message (Warehouse Shipping Advice — 945) is sent to the ERP to confirm that the goods have been shipped.

Here is the simplified version of the Python script,

# Author: Samir Saci
# Note: this script has been simplified for educational purposes.

class EDIMessage:
def __init__(self, message_id):
self.message_id = message_id
self.content = ""

def add_segment(self, segment):
self.content += segment + "n"

def get_message(self):
return f"ST*{self.message_id}*1n{self.content}SE*2*1"

class Warehouse:
def __init__(self):
self.inventory = {}

def receive_inbound(self, message):
lines = message.content.split("n")
for line in lines:
if line.startswith("N1"):
_, _, sku, quantity, unit = line.split("*")
self.inventory[sku] = self.inventory.get(sku, 0) + int(quantity)
print("Received Inbound Shipment:n", message.content)

def process_putaway(self, sku):
message = EDIMessage("944")
if sku in self.inventory:
message.add_segment(f"N1*ST*{sku}*{self.inventory[sku]}*units")
print("Putaway Confirmation:n", message.get_message())
return message
else:
print("SKU not found in inventory.")

def process_picking(self, message):
lines = message.content.split("n")
for line in lines:
if line.startswith("N1"):
_, _, sku, quantity, unit = line.split("*")
if self.inventory[sku] >= int(quantity):
self.inventory[sku] -= int(quantity)
else:
print(f"Insufficient quantity for SKU {sku}")
print("Processed Picking Order:n", message.content)

def process_outbound(self, picking_message):
message = EDIMessage("945")
lines = picking_message.content.split("n")
for line in lines:
if line.startswith("N1"):
_, _, sku, quantity, unit = line.split("*")
message.add_segment(f"N1*ST*{sku}*{quantity}*boxes")
print("Outbound Shipment Confirmation:n", message.get_message())
return message

Initiate the model and create your inbound order

  • 2 different SKUs received in cartons
  • {Qty 1: 50 boxes, Qty 2: 40 boxes}
# Initiate the model
warehouse = Warehouse()

# Inbound Process
inbound_message = EDIMessage("940")
inbound_message.add_segment("N1*ST*SKU123*50*boxes")
inbound_message.add_segment("N1*ST*SKU124*40*boxes")
warehouse.receive_inbound(inbound_message)
print("Inventory of {}: {} boxes".format("SKU123",warehouse.inventory["SKU123"]))
print("Inventory of {}: {:,} boxes".format("SKU124",warehouse.inventory["SKU124"]))

And the output looks like this,

N1*ST*SKU123*50*boxes
N1*ST*SKU124*40*boxes

Inventory of SKU123: 50 boxes
Inventory of SKU124: 40 boxes

  • The two messages that have been transmitted
  • Inventories of received items have been updated with the received quantity

Putaway confirmation

# Putaway Process
warehouse.process_putaway("SKU123")
  • This message sends a putaway confirmation for “SKU123”
ST*944*1
N1*ST*SKU123*50*units
SE*2*1

Picking orders and outbound shipments

  • The two SKUs are picked with quantities below their inventory level
# Picking Process (Picking goods for an order)
picking_message = EDIMessage("940")
picking_message.add_segment("N1*ST*SKU123*10*boxes")
picking_message.add_segment("N1*ST*SKU124*5*boxes")
warehouse.process_picking(picking_message)
print("Inventory of {}: {} boxes".format("SKU123",warehouse.inventory["SKU123"]))
print("Inventory of {}: {:,} boxes".format("SKU124",warehouse.inventory["SKU124"]))

# Outbound Process (Sending out goods)
warehouse.process_outbound()

Output,

N1*ST*SKU123*10*boxes
N1*ST*SKU124*5*boxes

Inventory of SKU123: 40 boxes
Inventory of SKU124: 35 boxes

ST*945*1
N1*ST*SKU123*10*boxes
N1*ST*SKU124*5*boxes
SE*2*1

  • 2 picking orders with 10 and 5 boxes for “SKU123” and “SKU124”
  • The inventory has been updated
  • The outbound orders are taking the quantities picked

Error Detection & Handling

We did not introduce this model for the sole purpose of coding.

The idea is to understand how we can create various checks to handle errors when writing or reading messages.

EDI is not exempt from data quality issues like

  • Missing data, incorrect data format, invalid codes, …
  • Logical inconsistencies causing significant operational disruptions

Therefore, implementing robust data checks and validations is crucial for ensuring the accuracy and reliability of Electronic Data Interchange.

Example of error handling for receiving orders

def receive_inbound(self, message):
lines = message.content.split("n")
for line in lines:
if line.startswith("N1"):
try:
_, _, sku, quantity, unit = line.split("*")

# SKU or quantity is missing
if not sku or not quantity:
print("Error: SKU or quantity missing.")
return

# Quantity is an integer
quantity = int(quantity)

# Negative or zero quantities
if quantity <= 0:
print("Error: Quantity must be positive.")
return

self.inventory[sku] = self.inventory.get(sku, 0) + quantity
except ValueError:
print("Error: Incorrect data format.")
return

print("Received Inbound Shipment:n", message.content)

This piece of code is:

  • Checking if quantities are missing or not in the integer format
  • Verify that all quantities are positive
  • Raise an error if needed

With Python, you can support your infrastructure team in automating testing for the development of new EDI messages.



Source link

Leave a Comment