Crucial Insight: Understanding ESHOPMAN Admin API Order Item Quantity Discrepancies

The ESHOPMAN community has brought to light a significant behavior within the Admin API's

query.graph
function that can silently impact the retrieval of order item quantities. This crucial insight details the specifics of this issue, its technical underpinnings, and provides essential workarounds to ensure your ESHOPMAN-powered storefronts, custom applications, and integrations maintain accurate order data.

The Silent Discrepancy in ESHOPMAN Order Item Quantities

When developers interact with the ESHOPMAN Admin API to fetch detailed order information, it's common practice to use

query.graph
to explicitly select only the necessary fields for optimized performance and reduced data transfer. However, a critical issue arises when attempting to retrieve
items[].quantity
specifically alongside other line-item fields (e.g.,
items.title
). While selecting all item fields with a wildcard (
items.*
) correctly returns the quantity, explicitly listing
items.quantity
can result in an
undefined
value for this vital field.

This behavior is particularly problematic because it occurs silently, without any error messages, warnings, or log entries. This means that downstream applications—such as custom storefront components deployed via HubSpot CMS, internal order processing systems, or analytical tools built on ESHOPMAN's Node.js/TypeScript backend—might inadvertently propagate this

undefined
value. Such data inaccuracies can lead to incorrect inventory updates, erroneous financial reporting, or manual corrections, severely impacting the operational efficiency and reliability of your headless commerce setup.

Why This Happens: A Deeper Look into ESHOPMAN's Data Mapping

The root cause of this discrepancy lies within ESHOPMAN's internal data mapping logic, specifically how public field names are translated into repository field names during a

query.graph
operation. The actual quantity value for an order item is stored on the
OrderItem
entity, which is publicly exposed as part of
order.items
. However, the system's mapping function incorrectly translates the public field
items.quantity
to target
items.item.quantity
, which refers to the
OrderLineItem
entity. Crucially, the
OrderLineItem
entity does not possess a
quantity
column.

Consequently, when the system attempts to retrieve

quantity
from
OrderLineItem
, it finds nothing, leading to the
undefined
result. It's worth noting that other fields like
unit_price
have built-in fallbacks that might retrieve values from
OrderLineItem
if the
OrderItem
value is missing. However,
quantity
and
raw_quantity
lack such a fallback mechanism, making them uniquely susceptible to this silent failure.

Reproducing the Issue in Your ESHOPMAN Environment

Here's a minimal reproduction example, adaptable for your ESHOPMAN Node.js environment, demonstrating the discrepancy when querying an order:

import { ExecArgs } from "@eshopman/framework/types"
import { ContainerRegistrationKeys, Modules } from "@eshopman/framework/utils"

export default async function checkItemQuantity({ container }: ExecArgs) {
  const orderModule = container.resolve(Modules.ORDER)
  const query = container.resolve(ContainerRegistrationKeys.QUERY)

  const [order] = await orderModule.createOrders([
    {
      currency_code: "usd",
      items: [{ title: "Product Name", quantity: 2, unit_price: 20 }],
    },
  ])

  const read = async (fields: string[]) => {
    const { data } = await query.graph({
      entity: "order",
      fields,
      filters: { id: order.id },
    })
    return data[0].items[0]
  }

  const wildcard = await read(["id", "items.*"])
  const explicit = await read(["id", "items.quantity", "items.title"])

  console.log("stored quantity                         :", 2)
  console.log("fields ['items.*']                      :", wildcard.quantity)
  console.log("fields ['items.quantity','items.title'] :", explicit.quantity)

  console.assert(explicit.quantity === wildcard.quantity) // This assertion will fail!
}

Effective Workarounds for ESHOPMAN Developers

Until a permanent fix is implemented, ESHOPMAN developers can employ the following strategies to reliably retrieve order item quantities and safeguard data integrity:

  • Use
    items.detail.quantity
    for Explicit Selection:
    This is the recommended explicit workaround. By requesting
    items.detail.quantity
    , the mapping correctly targets the
    OrderItem
    entity, ensuring the
    quantity
    field is selected. You would then access the value via
    item.detail.quantity
    .
    const { data } = await query.graph({
      entity: "order",
      fields: ["id", "items.detail.quantity", "items.title"],
      filters: { id },
    })
    
    const quantity = data[0].items[0].detail.quantity
    
  • Include
    items.*
    in Your Field List:
    While this approach will over-fetch data by retrieving all line-item properties, it guarantees that
    items.quantity
    is correctly populated. This might be an acceptable trade-off for less performance-critical operations or when dealing with smaller datasets.

The ESHOPMAN team is committed to providing a robust headless commerce platform. This community insight underscores the importance of precise field selection for optimized API calls and highlights the ongoing need for accurate data mapping and clear diagnostics when requested fields cannot be resolved. Ensuring data integrity is paramount for the reliability and success of all ESHOPMAN solutions, from dynamic HubSpot CMS storefronts to complex backend integrations.

Start with the tools

Explore migration tools

See options, compare methods, and pick the path that fits your store.

Explore migration tools