Order normalizer
normalizeOrder: This function is used to map SFCCOrderintoSfOrder, which includes order details data.normalizeOrderListItem: This function maps SFCCProductItemintoSfOrderListItemwhich includes only basic order details, used to display data in an order list.
Parameters
normalizeOrder
| Name | Type | Default value | Description |
|---|---|---|---|
context | NormalizerContext | Context needed for the normalizer. Context contain a currency field that contains a currency code | |
input | Order | SFCC Order |
normalizeOrderListItem
| Name | Type | Default value | Description |
|---|---|---|---|
context | NormalizerContext | Context needed for the normalizer. | |
input | ProductItem | SFCC Order List Element |
Extending
The SfOrder is returned from the GetOrders Method. If the SfOrder structure doesn't contain the information you need for your Storefront, you can extend its logic using the addCustomFields API. The following example demonstrates how to extend SfOrder with a shipments field.
export const unifiedApiExtension = createUnifiedExtension({
normalizers: {
addCustomFields: [
{
normalizeOrder: (context, order) => ({
shipments: order.shipments,
}),
},
],
},
config: {
...
},
});
You can override the normalizeOrder, but it's also available to override the smaller normalizers such as normalizeAddress, normalizeShippingMethod.
Source
order.ts
import { ValidationError } from "@alokai/connect/middleware";
import { z } from "zod";
import { defineNormalizer } from "../defineNormalizer";
const shipmentSchema = z.looseObject({
shippingAddress: z.looseObject({}),
shippingMethod: z.looseObject({}),
});
const orderSchema = z.looseObject({
billingAddress: z.looseObject({}),
creationDate: z.string(),
orderNo: z.string(),
productItems: z.array(z.any()),
productTotal: z.number(),
shipments: z.array(shipmentSchema).min(1),
shippingTotal: z.number().nonnegative(),
taxTotal: z.number(),
});
export const normalizeOrder = defineNormalizer.normalizeOrder((context, input) => {
const result = orderSchema.safeParse(input);
if (!result.success) {
throw ValidationError.fromStandardSchemaError(result.error, "Missing required order fields");
}
const validated = result.data as typeof input & typeof result.data;
const subTotalWithoutTax = validated.productTotal - validated.taxTotal;
const { shippingAddress, shippingMethod } = validated.shipments[0]!;
const { normalizeAddress, normalizeMoney, normalizeOrderLineItem, normalizeShippingMethod } =
context.normalizers;
return {
billingAddress: normalizeAddress(validated.billingAddress),
id: validated.orderNo,
lineItems: validated.productItems.map((entry) => normalizeOrderLineItem(entry)),
orderDate: new Date(validated.creationDate).toISOString(),
paymentMethod: "CARD",
shippingAddress: normalizeAddress(shippingAddress!),
shippingMethod: normalizeShippingMethod(shippingMethod!)!,
status: validated.status ?? "UNKNOWN",
subtotalPrice: normalizeMoney(subTotalWithoutTax),
totalPrice: normalizeMoney(validated.productTotal),
totalShippingPrice: normalizeMoney(validated.shippingTotal),
totalTax: normalizeMoney(validated.taxTotal),
};
});