Order normalizer
normalizeOrder
: This function is used to map CommercetoolsOrder
intoSfOrder
, which includes order details data.normalizeOrderListItem
: This function maps CommercetoolsOrderHistory
into UnifiedSfOrderListItem
which includes only basic order details, used to display an data in an order list.
Parametersri:link
normalizeOrder
ri:link
Name | Type | Default value | Description |
---|---|---|---|
context | NormalizerContext | Context needed for the normalizer | |
input | Order | Commercetools Order |
normalizeOrderListItem
ri:link
Name | Type | Default value | Description |
---|---|---|---|
context | NormalizerContext | Context needed for the normalizer | |
order | Order | Commercetools Order |
normalizeOrderLineItem
ri:link
Name | Type | Default value | Description |
---|---|---|---|
context | NormalizerContext | Context needed for the normalizer | |
lineItem | LineItem | Commercetools Line Item |
Extendingri:link
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 cartRef
field.
export const unifiedApiExtension = createUnifiedExtension({
normalizers: {
addCustomFields: [
{
normalizeOrder: (context, order) => ({
cartRef: order.cartRef,
}),
},
],
},
config: {
...
},
});
You can override the normalizeOrder
, but it's also available to override the smaller normalizers such as normalizeAddress
, normalizeShippingMethod
.
Sourceri:link
order.ts
/* eslint-disable complexity */
import type { BaseMoney, TaxedPrice } from "@vsf-enterprise/commercetools-types";
import { defineNormalizer } from "../defineNormalizer";
export const normalizeOrder = defineNormalizer.normalizeOrder((context, input) => {
const {
id,
createdAt,
orderState,
lineItems,
totalPrice,
taxedPrice,
shippingAddress,
shippingInfo,
billingAddress,
} = input;
if (
!id ||
!createdAt ||
!totalPrice ||
!taxedPrice ||
!lineItems ||
!Array.isArray(lineItems) ||
!shippingAddress ||
!shippingInfo ||
!shippingInfo.shippingMethod ||
!shippingInfo.price
) {
throw new Error("Missing required order fields");
}
const { normalizeMoney, normalizeAddress, normalizeOrderLineItem, normalizeShippingMethod } =
context.normalizers;
const shippingMethod = normalizeShippingMethod({
...shippingInfo.shippingMethod,
totalPrice: totalPrice,
});
const totalTax = calculateTotalTax(taxedPrice);
const subTotal = {
...totalPrice,
centAmount: totalPrice.centAmount - shippingInfo.price.centAmount - totalTax.centAmount,
};
return {
id,
orderDate: new Date(createdAt).toISOString(),
status: orderState ?? "UNKNOWN",
lineItems: lineItems.map((entry) => normalizeOrderLineItem(entry)),
subtotalPrice: normalizeMoney(subTotal),
totalShippingPrice: normalizeMoney(shippingInfo.price),
totalTax: normalizeMoney(totalTax),
totalPrice: normalizeMoney(totalPrice),
shippingAddress: normalizeAddress(shippingAddress),
billingAddress: billingAddress ? normalizeAddress(billingAddress) : null,
shippingMethod: shippingMethod!,
paymentMethod: "CARD",
};
});
function calculateTotalTax(taxedPrice: TaxedPrice) {
const { totalNet, totalGross } = taxedPrice;
const totalTax = totalGross.centAmount - totalNet.centAmount;
return {
type: totalGross.type,
centAmount: totalTax,
currencyCode: totalGross.currencyCode,
fractionDigits: totalGross.fractionDigits,
} satisfies BaseMoney;
}