Querying Purchase Orders

Inside this guide:
Prerequisites
Introduction
Querying for schedule changes
Querying for booking data
Using webhooks
Next steps

Prerequisites

To cover this use case, Zencargo must be the source of truth for Purchase Order Management. Consult your team to see if this case applies to you. Generally, if your manufacturers are being onboarded to Zencargo to update POs and make bookings, Zencargo becomes the source of truth for PO data before the booking stage, and you will want to keep your ERP in sync using these queries. If this isn't the case, you might be looking for the Packing List guide.

Introduction

The purchaseOrder query allows you to retrieve the latest state of information Zencargo holds about all Purchase Orders.

During these guides, we'll use a single sample Purchase Order to explain the query. If you want to follow along, it's a good idea to create a Purchase Order using the PurchaseOrdersCreateOrder outlined in the Creating Purchase Orders guide as we'll be using the same references in this guide. As a reminder, we send Zencargo a data structure that looks like this:

{
  "orderReferenceNumber": "PO-SEAWARD-2",
  "orderDate": "2021-01-01",
  "manufacturerID": "uuid12345",
  "originID": "uuid12345",
  "destinationID": "uuid98765",
  "orderedLineItems": [
    {
      "productSku": "10000",
      "quantityOrdered": 10000,
      "cbm": 32.0,
      "initialCargoReadyDate": "2020-03-16",
      "requiredDeliveryDate": "2020-05-04",
      "erpLineId": "YOUR_ERP_LINE_ID",
    },
    {
      "productSku": "20000",
      "quantityOrdered": 50000,
      "cbm": 38.0,
      "initialCargoReadyDate": "2020-03-16",
      "requiredDeliveryDate": "2020-05-04",
      "erpLineId": "YOUR_ERP_LINE_ID",
    }
  ]
}

If you've followed the Creating Purchase Orders guide, you'll be familiar with the data model. To briefly reiterate it here:

Refer back to the Creating Purchase Orders guide or the Concepts guide to learn more about the data model.

Now let's explore a few use cases for querying purchase order data.

Querying for schedule changes

So, let's imagine a scenario where your PO is created and the production begins. Manufacturers update Zencargo with the latest cargo ready date and expected fulfilled quantity, and Zencargo calculates the latest delivery estimate. This is all data you likely want to query to update your internal systems.

For now we'll focus on querying a single PO using the orderReferenceNumber that you provided. Review the purchaseOrder query arguments to see more advanced filters.

Note: the query and example below are for illustrative purposes for a single PO. If you're regularly planning to poll Zencargo, consider using filters to retrieve multiple objects in one call.

We'll be using the API Console to save time having to authenticate. Copy and paste this into your API console query section to get started.

POST /graphql
Query

query($orderReferenceNumber: String!) { 
  purchaseOrders(orderReferenceNumber: $orderReferenceNumber) {
    nodes {
      orderReferenceNumber
      orderedLineItems {
        product {
          skuCode
        }
        lots {
          cargoReadyDate {
            date
          }
          estimatedDeliveryDate
          quantityFulfilled
        }
        erpLineId
      }
    }
  }
}

Variables

{
  "orderReferenceNumber": "PO-SEAWARD-2"
}

JSON Response

{
  "data": {
    "purchaseOrders": {
      "nodes": [
        {
          "orderReferenceNumber": "PO-SEAWARD-2",
          "orderedLineItems": [
            {
              "lots": [
                {
                  "cargoReadyDate": {
                    "date": "2021-03-24"
                  },
                  "estimatedDeliveryDate": "2021-05-14",
                  "quantityFulfilled": 10000,
                }
              ],
              "erpLineId": "YOUR_ERP_LINE_ID",
              "product": {
                "skuCode": "10000"
              }
            },
            {
              "lots": [
                {
                  "cargoReadyDate": {
                    "date": "2021-03-24"
                  },
                  "estimatedDeliveryDate": "2021-05-14",
                  "quantityFulfilled": 50000
                }
              ],
              "erpLineId": "YOUR_ERP_LINE_ID",
              "product": {
                "skuCode": "20000"
              }
            }
          ]
        }
      ]
    }
  }
}

Let's pick this data apart to examine what it means. First, remember that our Purchase Order originally contained two OrderedLineItem objects:

From the return value, we can see that something has changed:

Note carefully that the data was retrieved inside the Lot objects. This is because the Lot is the place where the latest state is stored. Zencargo takes in OrderedLineItem objects (and stores them for analytics) and then updates Lot objects. If you're querying, it's 99% likely that you want to retrieve Lot information, not OrderedLineItem information, because that's where the latest data is.

So, what has happened? In the real world, the manufacturer has experienced a delay and the goods are no longer going to be ready on the initial date - this has caused a delay to the estimated delivery date. By querying for this information, you can update your ERP or other systems to reflect the delay. What's more, you can explore the cargoReadyDate object, which is a RichDate, to see why the delay happened.

Expanding the data being requested in the cargoReadyDate object would show us this data:

# inside the lot
cargoReadyDate {
  date
  lastUpdated {
    updatedAt
  }
  reasonForChange {
    category
    description
  }
}
{
  "cargoReadyDate": {
    "date": "2021-03-24",
    "lastUpdated": {
      "updatedAt": "2021-02-12"
    },
    "reasonForChange": {
      "category": "raw_materials",
      "description": "there was an issue with sourcing raw materials"
    }
  }
}

Depending on how sophisticated your system is, you might want to trigger specific actions based on the new dates, or even the reasons.

Querying for booking data

When the manufacturer eventually books the goods, you can retrieve this information via API too to keep systems up to date and send advanced notices of arrivals. Let's amend that original query to include booking information to illustrate this.

POST /graphql
Query

query($orderReferenceNumber: String!) { 
  purchaseOrders(orderReferenceNumber: $orderReferenceNumber) {
    nodes {
      orderReferenceNumber
      orderedLineItems {
        erpLineId
        product {
          skuCode
        }
        lots {
          quantityFulfilled
          estimatedDeliveryDate
          booking {
            zencargoReference
            stage { 
              value
            }
            modeOfTransport
            estimatedArrival {
                date 
                time 
                timeZone
            }
          }
        }
      }
    }
  }
}

Variables

{
  "orderReferenceNumber": "PO-SEAWARD-2"
}

JSON Response

{
  "data": {
    "purchaseOrders": {
      "nodes": [
        {
          "orderReferenceNumber": "PO-SEAWARD-2",
          "orderedLineItems": [
            {
              "lots": [
                {
                  "booking": {
                    "estimatedArrival": {
                      "date": "2022-05-10",
                      "time": "15:00:00",
                      "timeZone": "Europe/London"
                    }, 
                    "modeOfTransport": "OCEAN",
                    "stage": {
                      "value": "departed_pol"
                    },
                    "zencargoReference": "ZBLUTH-647"
                  },
                  "estimatedDeliveryDate": "2021-05-14",
                  "quantityFulfilled": 10000
                }
              ],
              "erpLineId": "YOUR_ERP_LINE_ID",
              "product": {
                "skuCode": "10000"
              }
            },
            {
              "lots": [
                {
                  "booking": {
                    "estimatedArrival": {
                      "date": "2022-05-10",
                      "time": "15:00:00",
                      "timeZone": "Europe/London"
                    },
                    "modeOfTransport": "OCEAN",
                    "stage": {
                      "value": "departed_pol"
                    },
                    "zencargoReference": "ZBLUTH-647"
                  },
                  "estimatedDeliveryDate": "2021-05-14",
                  "quantityFulfilled": 49000
                }
              ],
              "erpLineId": "YOUR_ERP_LINE_ID",
              "product": {
                "skuCode": "20000"
              }
            }
          ]
        }
      ]
    }
  }
}

First, note that we've retrieved the data inside a Booking object available inside each Lot. You could have used the bookings query to get this information as well. It's the same object, and it's up to you how you want to query for this data and which data points you want back.

Now, let's examine this payload:

You may want to update your ERP, or store a reference to the booking that the PO is inside. Many customers update their warehousing teams with the arrival date, and the quantities. Once you know the booking, you will be able to make subsequent queries for the Packing List information - which is where you'll find detailed information like quantities, volume and cargo details - using the packingLists query which is described in the Packing Lists guide.

Querying for ERP line id

It is also possible to query the ERP line id of each ordered line item if you have provided them when creating or updating the Purchasing Order.

POST /graphql
Query

query($orderReferenceNumber: String!) { 
  purchaseOrders(orderReferenceNumber: $orderReferenceNumber) {
    nodes {
      orderedLineItems {
        erpLineId
        ...
      }
    }
  }
}

Variables

{
  "orderReferenceNumber": "PO-SEAWARD-2"
}

JSON Response

{
  "data": {
    "purchaseOrders": {
      "nodes": [
        {
          "orderReferenceNumber": "PO-SEAWARD-2",
          "orderedLineItems": [
            {
              "erpLineId": "YOUR_ERP_LINE_ID"
            }
          ]
        }
      ]
    }
  }
}

Using Webhooks

Zencargo employs webhooks to allow our API clients to update data when things change. We regularly review and update the webhooks topics and encourage you to make use of the existing ones, and tell us when you need to fall back to polling so we can explore adding more topics.

Specifically to purchase orders, you can subscribe to webhook topics:

You should explore the Webhooks Introduction to learn more.

Next Steps