Skip to main content
 
 
Splunk Lantern

PO Monitoring: Acknowledgement of purchase orders

 

This article show you how to track the timely receipt of functional acknowledgments (for example, EDI 997) from suppliers, ensuring that they acknowledge the orders. This is a key performance indicator for companies that need to monitor purchase order (PO) lifecycles. PO monitoring plays a critical role in maintaining effective communication and coordination between buyers and suppliers, ensuring that all parties are aligned and informed throughout the process, and enhancing overall supply chain visibility. A proactive approach minimizes the risk of errors or delays, enabling businesses to maintain efficient operations and uphold customer satisfaction.

KPI search example

This KPI tracks the timely receipt of functional acknowledgments (for example, EDI 997) from suppliers, confirming that they have received and acknowledged the purchase order (EDI 850). Ensuring that suppliers acknowledge purchase orders is critical for confirming that they are aware of and processing the order. Functional acknowledgments that are not received within an expected time frame might indicate potential communication issues or that the supplier has not processed the order. Uncertainty about whether the supplier is acting on the order can cause significant delays.

There are two types of acknowledgments we can check. The first is the system-level acknowledgment (EDI 997), which indicates that the purchase order (PO) message was technically received. However, more importantly, in the full order-to-cash process cycle, the PO (EDI 850) is generated, followed by the supplier's business-level acknowledgment through an EDI 855 message. This response confirms that the supplier has received the PO.

First, to analyze the system-level acknowledgment, where EDI 850 (PO) pairs with EDI 997 (message acknowledgment), the following Splunk SPL example identifies an EDI 850 (Purchase Order) sent to a supplier and properly acknowledged. The search filters for successful transactions using the edi_ack_status with the "A" (Accepted) flag, indicating that the purchase order was correctly processed, and acknowledged.

index=supply_chain_edi sourcetype="edi:x12" edi_code IN (850, 997)
| table _time edi_ack_status edi_buyer edi_code edi_code_ack edi_cont_num edi_date edi_flag edi_requestor edi_responder edi_seller edi_sequence edi_time edi_tr_id edi_type 
| eval edi_ack_status_combo=edi_code+"-"+edi_code_ack+"-"+edi_ack_status
| eval edi_code_groupby=if(isnull(edi_code_ack), edi_code, edi_code_ack)
| stats last(_time) AS _time, last(edi_requestor) AS edi_requestor, last(edi_responder) AS edi_responder, first(edi_code) AS edi_type, values(edi_code) AS edi_code, last(edi_ack_status) AS edi_ack_status BY edi_tr_id edi_code_groupby
| search edi_ack_status=A

image16.png

This example identifies an EDI 850 (Purchase Order) sent to a supplier but without receiving an acknowledgment EDI 997. This could indicate that the manufacturer attempted to place an order, but without the acknowledgment, the order might not be fulfilled, potentially causing raw material shortages. The search filters for transactions that do not have the edi_ack_status with the "A" (Accepted) flag.

index=supply_chain_edi sourcetype="edi:x12" edi_code IN (850, 997)
| table _time edi_ack_status edi_buyer edi_code edi_code_ack edi_cont_num edi_date edi_flag edi_requestor edi_responder edi_seller edi_sequence edi_time edi_tr_id edi_type 
| eval edi_ack_status_combo=edi_code+"-"+edi_code_ack+"-"+edi_ack_status
| eval edi_code_groupby=if(isnull(edi_code_ack), edi_code, edi_code_ack)
| stats last(_time) AS _time, last(edi_requestor) AS edi_requestor, last(edi_responder) AS edi_responder, first(edi_code) AS edi_type, values(edi_code) AS edi_code, last(edi_ack_status) AS edi_ack_status BY edi_tr_id edi_code_groupby
| search edi_code_groupby=850 NOT edi_ack_status=A

image13.png

Search explanations

Splunk search Explanation
index=supply_chain_edi sourcetype="edi:x12" edi_code IN (850, 997) Select EDI X12 data by selecting sourcetype of edi:x12.
| table _time edi_ack_status edi_buyer edi_code edi_code_ack edi_cont_num edi_date edi_flag edi_requestor edi_responder edi_seller edi_sequence edi_time edi_tr_id edi_type Format the relevant fields into a table.
| eval edi_ack_status_combo=edi_code+"-"+edi_code_ack+"-"+edi_ack_status
| eval edi_code_groupby=if(isnull(edi_code_ack), edi_code, edi_code_ack)
Create a new evaluated field edi_ack_status_combo that combines edi_code, edi_code_ack, edi_ack_statusfield. Use another evalcommand to create edi_code_groupby field to join all EDI events with EDI 997 acknowledgment events.
| stats last(_time) AS _time, last(edi_requestor) AS edi_requestor, last(edi_responder) AS edi_responder, first(edi_code) AS edi_type, values(edi_code) AS edi_code, last(edi_ack_status) AS edi_ack_status BY edi_tr_id edi_code_groupby

Join all EDI events with EDI 997 (acknowledgment) events into a single event. A successfully joined event will have EDI edi_ack_status field that indicates there was a matching pair of EDI with EDI acknowledgment.

Events with null values in edi_ack_status means that there's no matching pair of EDI acknowledgments. Events with successfully joined EDIs have “A”, “E”, “R” flags indicating their status.

| search edi_code_groupby=850 NOT edi_ack_status=A Filter to select purchase order transactions that haven't received any acknowledgment or with flag “E” and “R” indicate processing problems. By using NOT edi_ack_status=A, we're omitting transactions with successful transmission status.

Now, we want to identify which PO items are associated with unacknowledged requests. The Splunk platform can dynamically parse data during the search, providing a powerful capability for creating data fields used for analysis and grouping. Below is a search example that helps identify specific parts at risk due to unacknowledged purchase orders sent to suppliers.

index=supply_chain_edi sourcetype="edi:x12" edi_code IN (860, 850, 997) 
| rex field=_raw max_match=100 "(?P<po_item>PO1\|[^\~]*)~"
| table _time edi_ack_status edi_buyer edi_code edi_code_ack edi_cont_num edi_date edi_flag edi_requestor edi_responder edi_seller edi_sequence edi_time edi_tr_id edi_type po_item
| eval edi_ack_status_combo=edi_code+"-"+edi_code_ack+"-"+edi_ack_status 
| eval edi_code_groupby=if(isnull(edi_code_ack), edi_code, edi_code_ack) 
| stats last(_time) AS _time, last(edi_requestor) AS edi_requestor, last(edi_responder) AS edi_responder, first(edi_code) AS edi_type, values(edi_code) AS edi_code, last(edi_ack_status) AS edi_ack_status, first(po_item) AS po_item BY edi_tr_id edi_code_groupby 
| search edi_code_groupby=850 NOT edi_ack_status=A 
| stats values(po_item) as po_item, count by edi_responder 
| sort - count
| head 10

The results indicate that the purchase orders are at risk of being delayed, which could hinder the timely preparation of the orders. Specifically, the search highlights which supplies are in jeopardy, helping to assess the potential impact on manufacturing if these supplies are critical to the production process.

image17.png

Search explanations

   
index=supply_chain_edi sourcetype="edi:x12" edi_code IN (850, 997) Select EDI X12 data by selecting sourcetype of edi:x12.
| rex field=_raw max_match=100 "(?P<po_item>PO1\|[^\~]*)~" Parse THE PO item information from purchase order EDI as po_item.
| table _time edi_ack_status edi_buyer edi_code edi_code_ack edi_cont_num edi_date edi_flag edi_requestor edi_responder edi_seller edi_sequence edi_time edi_tr_id edi_type po_item Format the relevant fields into a table, adding po_item to the table.
| eval edi_ack_status_combo=edi_code+"-"+edi_code_ack+"-"+edi_ack_status
| eval edi_code_groupby=if(isnull(edi_code_ack), edi_code, edi_code_ack)
Create a new evaluated field edi_ack_status_combo that combines edi_code, edi_code_ack, edi_ack_statusfield. Use another evalcommand to create edi_code_groupby field to join all EDI events with EDI 997 acknowledgment events.
| stats last(_time) AS _time, last(edi_requestor) AS edi_requestor, last(edi_responder) AS edi_responder, first(edi_code) AS edi_type, values(edi_code) AS edi_code, last(edi_ack_status) AS edi_ack_status BY edi_tr_id edi_code_groupby

Join all EDI events with EDI 997 (acknowledgment) events into a single event. A successfully joined event will have EDI edi_ack_status field that indicates there was a matching pair of EDI with EDI acknowledgment.

Events with null values in edi_ack_status means that there's no matching pair of EDI acknowledgments. Events with successfully joined EDIs have “A”, “E”, “R” flags indicating their status.

| search edi_code_groupby=850 NOT edi_ack_status=A Filter to select purchase order transactions that haven't received any acknowledgment or with flag “E” and “R” indicate processing problems. By using NOT edi_ack_status=A, we're omitting transactions with successful transmission status.
| stats values(po_item) AS po_item, count BY edi_responder Aggregate the previous results to which supplier with which supplies.
| sort - count
| head 10
Sort results and look at the top 10 suppliers and supplies.

Next steps

When you have this search running in your Splunk platform, return to the Monitoring purchase order lifecycles use case to learn how to share the results with stakeholders and to find other KPIs you might want to measure. You can also review the Supply Chain Optimization Solution Accelerator for more great use cases to help you use the Splunk platform to be successful in your supply chain operations.