Vue Storefront is now Alokai! Learn More
GetOrderDetails

GetOrderDetails

Implements GetOrderDetails Unified Method.

Source

/* eslint-disable max-statements */
import { defineApi } from "@vsf-enterprise/unified-api-bigcommerce";
import type {
  Order,
  OrderByCartResponse,
  OrderProductResponse,
  BigcommerceIntegrationContext,
} from "@vsf-enterprise/bigcommerce-api";
import { assignToNormalizerContext, getNormalizers } from "@vue-storefront/unified-data-model";

export const getOrderDetails = defineApi.getOrderDetails(async (context, args) => {
  const { id } = args;
  const orderId = Number.parseInt(id);
  const orderData = await context.api.getOrders({ min_id: orderId, max_id: orderId });
  const orderProducts = await context.api.getOrderProducts({ orderId });
  const orderShipping = await context.api.getOrderShippingAddresses({ orderId });

  const data: OrderByCartResponse = {
    ...(orderData![0] as Order),
    products: orderProducts,
    shipping_addresses: orderShipping,
  };

  const { normalizeOrder } = getNormalizers(context);
  assignToNormalizerContext(context, {
    imageGetter: await imageGetterFactory(orderProducts, context),
  });

  return normalizeOrder(data);
});

async function imageGetterFactory(
  orderProducts: OrderProductResponse,
  context: BigcommerceIntegrationContext,
) {
  if (context.config.unified.skipOrderImages) {
    return () => null;
  }

  const { data: orderImages } = await context.api.getProductsById({
    entityIds: orderProducts.map((product) => product.product_id).filter(Boolean),
  });

  if (!orderImages) {
    return () => null;
  }

  return (productId: number) => {
    const foundProduct = orderImages.find((product) => product.id === productId);

    if (!foundProduct?.images?.[0]) {
      return null;
    }

    return foundProduct.images[0];
  };
}