{"version":3,"file":"static/js/90580fa956548d291d4f.bundle.js","mappings":"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","sources":["webpack://bju-press/./src/themes/base/views/components/carticon.component.tsx?c302","webpack://bju-press/./src/themes/base/views/components/cartlineitem.component.tsx?ee83","webpack://bju-press/./src/utilities/analytics/analytics-dispatcher.ts?75be","webpack://bju-press/./src/utilities/class-name-helper.ts?dd10","webpack://bju-press/./src/utilities/data-attribute-parser.ts?7345","webpack://bju-press/./src/utilities/global-constants.ts?5882"],"sourcesContent":["// @CUSTOM: This component view extension is from adventureworks@9.47. Any custom changes noted are edits to the\r\n// adventureworks version, not core.\r\n\r\n/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport { IComponent, IComponentProps, msdyn365Commerce } from '@msdyn365-commerce/core';\r\nimport { ICartState } from '@msdyn365-commerce/global-state';\r\nimport { format, getPayloadObject, getTelemetryAttributes, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\n\r\n/**\r\n * ICartIconData: Interface for Cart Icon Data.\r\n */\r\nexport interface ICartIconData {\r\n cart?: ICartState;\r\n}\r\n\r\n/**\r\n * ICartIconComponentProps: Interface for Cart Icon component props.\r\n */\r\nexport interface ICartIconComponentProps extends IComponentProps {\r\n className?: string;\r\n cartLabel: string;\r\n cartQtyLabel: string;\r\n telemetryContent?: ITelemetryContent;\r\n salesAgreementPricePrompt?: string;\r\n electiveCount?: number; // @CUSTOM: Kit display - elective count to subtract from total item count\r\n}\r\n\r\n/**\r\n * ICartIconComponent: Interface for Cart Icon component.\r\n */\r\nexport interface ICartIconComponent extends IComponent {}\r\n\r\nconst CartIconComponentActions = {};\r\n\r\n/**\r\n *\r\n * CartIcon component.\r\n * @extends {React.FC}\r\n */\r\nconst CartIcon: React.FC = observer((props: ICartIconComponentProps) => {\r\n const {\r\n cartLabel,\r\n cartQtyLabel,\r\n electiveCount, // @CUSTOM: Kit display - elective count to subtract from total item count\r\n data: { cart }\r\n } = props;\r\n const defaultCartItemCount: number = 0;\r\n\r\n //------------------------------------------------------\r\n // @CUSTOM: Kit display - obtain elective item count\r\n // to subtract from total cart item count\r\n //------------------------------------------------------\r\n const totalItemCount = cart?.totalItemsInCart\r\n const adjustedItemCount = electiveCount && totalItemCount && (totalItemCount - electiveCount);\r\n const cartItem = adjustedItemCount || totalItemCount || defaultCartItemCount;\r\n //------------------------------------------------------\r\n\r\n let qtyLabel: string = '';\r\n const cartMaxQuantity: number = 99;\r\n const maxQuantityLabel: string = '99+';\r\n if (cartItem > cartMaxQuantity) {\r\n qtyLabel = maxQuantityLabel;\r\n } else {\r\n qtyLabel = format(cartQtyLabel, cartItem);\r\n }\r\n const label = format(cartLabel, cartItem);\r\n\r\n // Construct telemetry attribute to render\r\n const payLoad = getPayloadObject('click', props.telemetryContent!, 'cart-icon', '');\r\n const attributes = getTelemetryAttributes(props.telemetryContent!, payLoad);\r\n const style: React.CSSProperties = {\r\n visibility: cart ? 'visible' : 'hidden'\r\n };\r\n return (\r\n
\r\n
\r\n {qtyLabel}\r\n
\r\n
\r\n );\r\n});\r\n\r\nexport const CartIconComponent: React.FunctionComponent = msdyn365Commerce.createComponentOverride<\r\n // @ts-expect-error -- Compatible issue with the component override.\r\n ICartIconComponent\r\n>('CartIcon', { component: CartIcon, ...CartIconComponentActions });\r\n\r\nexport default CartIconComponent;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport MsDyn365, {\r\n IComponentProps,\r\n IGridSettings,\r\n IImageSettings,\r\n Image,\r\n isChannelTypeB2B,\r\n msdyn365Commerce\r\n} from '@msdyn365-commerce/core';\r\nimport { ICartState } from '@msdyn365-commerce/global-state';\r\nimport { ChannelDeliveryOptionConfiguration, SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\nimport { CartLine, ProductCatalog, SalesLine } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\nimport { ArrayExtensions, getFallbackImageUrl, ObjectExtensions, validateCatalogId } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { getPayloadObject, getTelemetryAttributes, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\r\nimport classNames from 'classnames';\r\nimport * as React from 'react';\r\n\r\nimport { PriceComponent, CartLinePriceEditor, ICartLinePriceEditorResources } from '@msdyn365-commerce/components';\r\n\r\n//----------------------------------------------------------\r\n// @CUSTOM: Backorder imports\r\n//----------------------------------------------------------\r\nimport { ReleasedProductType } from '@msdyn365-commerce/retail-proxy';\r\nimport { getAvailabilitiesForCartLineItems, ProductAvailabilitiesForCartLineItems } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { cloneDeep } from 'lodash';\r\nimport { ProductsDataActions } from '@msdyn365-commerce/retail-proxy';\r\nimport { DeliveryMode, createInventoryAvailabilitySearchCriteria, mapAggregatedProductInventoryInformation } from '@msdyn365-commerce-modules/retail-actions';\r\n//----------------------------------------------------------\r\n\r\n//----------------------------------------------------------\r\n// @CUSTOM: T&E imports\r\n//----------------------------------------------------------\r\nimport { getCatalogId } from '@msdyn365-commerce/core';\r\nimport { ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\r\nimport { convertProductAttributes } from '../../../../utilities/data-attribute-parser';\r\nimport { searchByCriteriaAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\n//----------------------------------------------------------\r\n\r\n//----------------------------------------------------------\r\n// @CUSTOM: Kit custom imports\r\n//----------------------------------------------------------\r\nimport { attrNames } from '../../../../utilities/global-constants';\r\nimport { convertCartAttributes } from '../../../../utilities/data-attribute-parser';\r\n//----------------------------------------------------------\r\n\r\n// @CUSTOM: custom analytics imports\r\nimport { publish } from '../../../../utilities/analytics/analytics-dispatcher';\r\nimport { SingleProductEvent } from '../../../../utilities/analytics/analytics-events';\r\n\r\n//----------------------------------------------------------\r\n// @CUSTOM: SKU display import\r\n//----------------------------------------------------------\r\nimport { clsHelper } from '../../../../utilities/class-name-helper';\r\nimport { labelResources } from '../../../../utilities/global-constants';\r\n//----------------------------------------------------------\r\n\r\n/**\r\n * ICartlineResourceString: Interface for specifying the\r\n * resource strings that the component needs.\r\n */\r\nexport interface ICartlineResourceString {\r\n /**\r\n * Display string for discount label.\r\n */\r\n discountStringText: string;\r\n\r\n /**\r\n * String for size key.\r\n */\r\n sizeString: string;\r\n\r\n /**\r\n * String for color key.\r\n */\r\n colorString: string;\r\n\r\n /**\r\n * String associated with the configuration product dimension.\r\n */\r\n configString: string;\r\n\r\n /**\r\n * String for style key.\r\n */\r\n styleString: string;\r\n\r\n /**\r\n * String for amount key.\r\n */\r\n amountString?: string;\r\n\r\n /**\r\n * Display string for quantity label.\r\n */\r\n quantityDisplayString: string;\r\n\r\n /**\r\n * Display string for quantity label.\r\n */\r\n inputQuantityAriaLabel: string;\r\n\r\n /**\r\n * Aria label for the decrement button in quantity component.\r\n */\r\n decrementButtonAriaLabel?: string;\r\n\r\n /**\r\n * Aria label for the increment button in quantity component.\r\n */\r\n incrementButtonAriaLabel?: string;\r\n\r\n /**\r\n * Original text screen reader.\r\n */\r\n originalPriceText: string;\r\n\r\n /**\r\n * Current text screen reader.\r\n */\r\n currentPriceText: string;\r\n\r\n /**\r\n * Shipping Charges Text.\r\n */\r\n shippingChargesText: string;\r\n\r\n priceEditorResources?: ICartLinePriceEditorResources;\r\n\r\n /**\r\n * Sales agreement price prompt text.\r\n */\r\n salesAgreementPricePrompt?: string;\r\n\r\n /**\r\n * Shipping text.\r\n */\r\n shippingText?: string;\r\n}\r\n\r\n/**\r\n * The data about the cart line and products.\r\n */\r\nexport interface ICartLineData {\r\n cartLine: CartLine | SalesLine;\r\n cartState?: ICartState;\r\n product?: SimpleProduct;\r\n catalogs?: ProductCatalog[];\r\n}\r\n\r\nexport type CartLineDisplayMode = 'DEFAULT' | 'COMPACT';\r\n\r\n/**\r\n * ICartLineProps: The props required to render cartLineitem.\r\n */\r\nexport interface ICartLineProps extends IComponentProps {\r\n /**\r\n * The flag to change the quantity component from interactivity to static.\r\n */\r\n disableQuantityInteractivity?: boolean;\r\n\r\n /**\r\n * The primary image url.\r\n */\r\n primaryImageUrl?: string;\r\n\r\n /**\r\n * The product url.\r\n */\r\n productUrl?: string;\r\n\r\n /**\r\n * GridSettings for the product image in cartLine.\r\n */\r\n gridSettings: IGridSettings;\r\n\r\n /**\r\n * ImageSettings for the product image in cartLine.\r\n */\r\n imageSettings: IImageSettings;\r\n\r\n /**\r\n * Boolean flag to indicate if the item is out of stock.\r\n */\r\n isOutOfStock?: boolean;\r\n\r\n /**\r\n * Flag to make quantity section editable.\r\n */\r\n isQuantityEditable?: boolean;\r\n\r\n /**\r\n * Max quantity for line item.\r\n */\r\n maxQuantity?: number;\r\n\r\n /**\r\n * Current quantity for line item.\r\n */\r\n currentQuantity?: number;\r\n\r\n /**\r\n * Resource string for the component.\r\n */\r\n resources: ICartlineResourceString;\r\n\r\n /**\r\n * SalesLine flag.\r\n */\r\n isSalesLine?: boolean;\r\n\r\n /**\r\n * Error message to show in place of quantity.\r\n */\r\n errorMessage?: string;\r\n\r\n /**\r\n * Display mode to use.\r\n */\r\n displayMode?: CartLineDisplayMode;\r\n\r\n /**\r\n * Inventory information label.\r\n */\r\n inventoryInformationLabel?: string;\r\n\r\n /**\r\n * Inventory information class name.\r\n */\r\n inventoryLabelClassName?: string;\r\n\r\n /**\r\n * Flag to show/hide shipping charges for line items.\r\n */\r\n showShippingChargesForLineItems?: boolean;\r\n\r\n /**\r\n * Boolean flag to indicate if cart state status is ready.\r\n */\r\n isCartStateReady?: boolean;\r\n\r\n /**\r\n * Chanel Delivery Option configuration is from api.\r\n */\r\n channelDeliveryOptionConfig?: ChannelDeliveryOptionConfiguration;\r\n\r\n /**\r\n * The telemetry content.\r\n */\r\n telemetryContent?: ITelemetryContent;\r\n\r\n /**\r\n * The cart line index.\r\n */\r\n lineIndex?: number;\r\n\r\n /**\r\n * The cart line delivery location.\r\n */\r\n deliveryLocation?: string;\r\n\r\n /**\r\n * Quantity onChange callback.\r\n */\r\n quantityOnChange?(cartLine: CartLine, newQuantity: number, lineIndex?: number): void;\r\n priceCurrency?: string;\r\n}\r\n\r\ninterface IDimensionStrings {\r\n /**\r\n * String for size key.\r\n */\r\n sizeString: string;\r\n\r\n /**\r\n * String for color key.\r\n */\r\n colorString: string;\r\n\r\n /**\r\n * String associated with the configuration product dimension.\r\n */\r\n configString: string;\r\n\r\n /**\r\n * String for style key.\r\n */\r\n styleString: string;\r\n\r\n /**\r\n * String for amount key.\r\n */\r\n amountString?: string;\r\n}\r\n\r\n//------------------------------------------------------\r\n// @CUSTOM: Class name utility for customizations that\r\n// want to use the same base class\r\n//------------------------------------------------------\r\nconst BASE_CLASS = 'msc-cart-line';\r\nconst cls = (fragment?: string) => clsHelper(BASE_CLASS, fragment);\r\n//------------------------------------------------------\r\n\r\nconst CartLineItemFunctions = {\r\n renderProductDimensions: (Product: SimpleProduct, DimensionStrings: IDimensionStrings) => {\r\n if (!Product || !Product.Dimensions) {\r\n return [];\r\n }\r\n\r\n return Product.Dimensions.map(productDimension => {\r\n if (productDimension.DimensionTypeValue === 1) {\r\n return (\r\n
\r\n \r\n {DimensionStrings.colorString}\r\n {productDimension.DimensionValue && productDimension.DimensionValue.Value}\r\n \r\n
\r\n );\r\n }\r\n\r\n if (productDimension.DimensionTypeValue === 2) {\r\n return (\r\n
\r\n \r\n {DimensionStrings.configString}\r\n {productDimension.DimensionValue?.Value}\r\n \r\n
\r\n );\r\n }\r\n\r\n if (productDimension.DimensionTypeValue === 3) {\r\n return (\r\n
\r\n \r\n {DimensionStrings.sizeString}\r\n {productDimension.DimensionValue?.Value}\r\n \r\n
\r\n );\r\n }\r\n\r\n if (productDimension.DimensionTypeValue === 4) {\r\n return (\r\n
\r\n \r\n {Product.IsGiftCard ? DimensionStrings.amountString : DimensionStrings.styleString}\r\n {productDimension.DimensionValue?.Value}\r\n \r\n
\r\n );\r\n }\r\n return null;\r\n });\r\n },\r\n renderDiscountLines: (props: ICartLineProps) => {\r\n if (!props.data.cartLine.DiscountLines || props.data.cartLine.DiscountLines.length === 0) {\r\n return null;\r\n }\r\n\r\n return props.data.cartLine.DiscountLines.map((discountLine, index) => {\r\n return (\r\n
\r\n \r\n {discountLine.OfferName ? discountLine.OfferName : ''}:{` ${props.resources.discountStringText || 'Discount'} `}\r\n \r\n \r\n \r\n \r\n {` (${discountLine.Percentage !== undefined ? discountLine.Percentage : ''}%)`}\r\n
\r\n );\r\n });\r\n },\r\n renderInventoryLabel: (props: ICartLineProps) => {\r\n // @CUSTOM: we do not want to show inventory status with backorders enabled\r\n return null;\r\n\r\n // if (!props.inventoryInformationLabel) {\r\n // return null;\r\n // }\r\n // const inventoryCssName = props.inventoryLabelClassName\r\n // ? `msc-cart-line__product-inventory-label ${props.inventoryLabelClassName}`\r\n // : 'msc-cart-line__product-inventory-label';\r\n // return {props.inventoryInformationLabel};\r\n },\r\n\r\n /**\r\n * Gets the react node for product unit of measure display.\r\n * @param props - ICartLineProps props.\r\n * @returns The node representing markup for unit of measure component.\r\n */\r\n renderUnitOfMeasure: (props: ICartLineProps) => {\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- Do not need type check for appsettings\r\n if (\r\n props.context.app.config &&\r\n (!props.context.app.config.unitOfMeasureDisplayType || props.context.app.config.unitOfMeasureDisplayType === 'none')\r\n ) {\r\n return undefined;\r\n }\r\n\r\n const product = props.data.product;\r\n if (!product || !product.DefaultUnitOfMeasure) {\r\n return undefined;\r\n }\r\n\r\n return (\r\n
\r\n {product.DefaultUnitOfMeasure}\r\n
\r\n );\r\n },\r\n renderShippingLabel: (props: ICartLineProps) => {\r\n const pickupDeliveryModeCode = props.context.request.channel?.PickupDeliveryModeCode;\r\n const channelDeliveryOptionConfig = props.channelDeliveryOptionConfig;\r\n const cartline = props.data.cartLine;\r\n let hasShippingMethod = false;\r\n if (channelDeliveryOptionConfig !== undefined) {\r\n hasShippingMethod = !!(\r\n cartline.DeliveryMode &&\r\n channelDeliveryOptionConfig.PickupDeliveryModeCodes?.some(deliveryMode => deliveryMode !== cartline.DeliveryMode)\r\n );\r\n } else {\r\n hasShippingMethod = !!(cartline.DeliveryMode && cartline.DeliveryMode !== pickupDeliveryModeCode);\r\n }\r\n if (!hasShippingMethod) {\r\n return undefined;\r\n }\r\n\r\n const shippingChargeLines = (cartline.ChargeLines || []).filter(chargeLine => chargeLine.IsShipping);\r\n\r\n if (shippingChargeLines.length === 0) {\r\n return undefined;\r\n }\r\n\r\n const freightFee = shippingChargeLines.reduce((chargeTotal, chargeLine) => {\r\n return chargeTotal + (chargeLine.CalculatedAmount || 0);\r\n }, 0);\r\n\r\n const priceComponent = (\r\n \r\n );\r\n return (\r\n <>\r\n \r\n {priceComponent}\r\n \r\n );\r\n },\r\n renderOtherCharges: (props: ICartLineProps) => {\r\n const cartline = props.data.cartLine;\r\n const otherCharges = cartline.ChargeLines?.filter(chargeline => !chargeline.IsShipping);\r\n\r\n return (\r\n (otherCharges &&\r\n otherCharges.map((otherCharge, key) => {\r\n return otherCharge && otherCharge.CalculatedAmount ? (\r\n
\r\n \r\n \r\n \r\n \r\n
\r\n ) : (\r\n ''\r\n );\r\n })) ||\r\n undefined\r\n );\r\n },\r\n\r\n /**\r\n * Render the sales agreement prompt.\r\n * @param props - The ICartLineProps.\r\n * @returns The JSX.Element.\r\n */\r\n renderSalesAgreementPrompt: (props: ICartLineProps): JSX.Element | null => {\r\n if (props.data.cartLine.SalesAgreementLineRecordId === 0) {\r\n return null;\r\n }\r\n return
{props.resources.salesAgreementPricePrompt}
;\r\n }\r\n};\r\n\r\n/**\r\n * Renders catalog label for the cart line.\r\n * @param props - Cart line props.\r\n * @returns Catalog label.\r\n */\r\nconst CatalogLabelComponent: React.FC = (props: ICartLineProps) => {\r\n const catalogId = props.data.cartLine.CatalogId;\r\n validateCatalogId(catalogId);\r\n\r\n if (!isChannelTypeB2B(props.context.actionContext.requestContext) || !catalogId || !ArrayExtensions.hasElements(props.data.catalogs)) {\r\n return null;\r\n }\r\n\r\n const catalog = props.data.catalogs.find(item => item.RecordId === catalogId);\r\n\r\n if (!catalog || !catalog.Name) {\r\n return null;\r\n }\r\n\r\n return
{catalog.Name}
;\r\n};\r\n\r\n// eslint-disable-next-line no-redeclare\r\nconst CartLine: React.FC = (props: ICartLineProps) => {\r\n\r\n const { isSalesLine, productUrl, resources } = props;\r\n const { product, cartLine } = props.data;\r\n\r\n // @CUSTOM: backorder customization\r\n const [isBackorder, backorderLoaded] = React.useState(false);\r\n React.useEffect(() => {\r\n\r\n const cloneCtx = cloneDeep(props.context.actionContext);\r\n cloneCtx.requestContext.app.config.enableStockCheck = true;\r\n if (!isSalesLine) {\r\n const backorderInput = new ProductAvailabilitiesForCartLineItems(cloneCtx.requestContext.apiSettings);\r\n getAvailabilitiesForCartLineItems(backorderInput, cloneCtx).then(result => {\r\n const availability = result?.find(avail => {\r\n return avail.ProductAvailableQuantity.ProductId === product?.RecordId;\r\n });\r\n const productAvailableQuantity = availability?.ProductAvailableQuantity.AvailableQuantity || 0\r\n\r\n if (\r\n cartLine.Quantity &&\r\n availability &&\r\n product?.ItemTypeValue !== ReleasedProductType.Service &&\r\n productAvailableQuantity < cartLine.Quantity\r\n ) {\r\n backorderLoaded(true);\r\n } else {\r\n backorderLoaded(false);\r\n }\r\n });\r\n\r\n } else { // @CUSTOM: When cartline represents a SalesLine, for Order Details display of backorder messaging\r\n if (product) {\r\n\r\n try {\r\n const shippingSearchCriteria = createInventoryAvailabilitySearchCriteria(\r\n cloneCtx,\r\n [product.RecordId],\r\n true,\r\n undefined,\r\n undefined,\r\n DeliveryMode.shipping\r\n );\r\n ProductsDataActions.getEstimatedAvailabilityAsync(\r\n { callerContext: cloneCtx },\r\n shippingSearchCriteria\r\n ).then(result => {\r\n\r\n const productInventoryInformation = [];\r\n if (result.ProductWarehouseInventoryAvailabilities) {\r\n const shippingInventory = mapAggregatedProductInventoryInformation(cloneCtx, result);\r\n if (ArrayExtensions.hasElements(shippingInventory)) {\r\n shippingInventory[0].deliveryType = DeliveryMode.shipping;\r\n productInventoryInformation.push(shippingInventory[0]);\r\n }\r\n }\r\n const availability = productInventoryInformation.find(avail => {\r\n return avail.ProductAvailableQuantity.ProductId === product.RecordId;\r\n })\r\n const availableQuantity = availability?.ProductAvailableQuantity.AvailableQuantity || 0;\r\n\r\n if (\r\n cartLine.Quantity &&\r\n availability &&\r\n product?.ItemTypeValue !== ReleasedProductType.Service &&\r\n availableQuantity < cartLine.Quantity\r\n ) {\r\n backorderLoaded(true);\r\n } else {\r\n backorderLoaded(false);\r\n }\r\n });\r\n } catch (error) {\r\n props.context.actionContext.telemetry.exception(error as Error);\r\n props.context.actionContext.telemetry.debug('cartlineitem component error: getEstimatedAvailabilityAsync');\r\n }\r\n }\r\n }\r\n\r\n }, [cartLine]);\r\n\r\n // @CUSTOM: T&E customization\r\n const [isTestOrScore, isTestOrScoreLoaded] = React.useState(true);\r\n React.useEffect(() => {\r\n\r\n if (!isSalesLine) {\r\n\r\n const criteria: ProductSearchCriteria = {\r\n ItemIds: [{ ItemId: product?.ItemId }],\r\n Context: {\r\n ChannelId: props.context.request.apiSettings.channelId,\r\n CatalogId: getCatalogId(props.context.request)\r\n },\r\n IncludeAttributes: true\r\n };\r\n\r\n searchByCriteriaAsync({ callerContext: props.context.actionContext }, criteria).then(results => {\r\n const productWithAttr = results[0];\r\n const formattedAtr = convertProductAttributes(productWithAttr?.AttributeValues || [])\r\n const isTesting = !!(formattedAtr[attrNames.testType] && formattedAtr[attrNames.testType] !== attrNames.isNotTest);\r\n const isScoring = !!(formattedAtr[attrNames.productType] && formattedAtr[attrNames.productType] === attrNames.scoringType);\r\n\r\n if (isTesting || isScoring) {\r\n isTestOrScoreLoaded(true);\r\n } else {\r\n isTestOrScoreLoaded(false);\r\n }\r\n });\r\n }\r\n }, []);\r\n\r\n //------------------------------------------------------\r\n // @CUSTOM: Kit contents display\r\n //------------------------------------------------------\r\n const lineAttributes = cartLine.AttributeValues && convertCartAttributes(cartLine.AttributeValues);\r\n const kitContents = lineAttributes && lineAttributes[attrNames.kitContents] as string;\r\n const kitElectives = lineAttributes && lineAttributes[attrNames.kitElectives] as string;\r\n const isElective = !!(lineAttributes && lineAttributes[attrNames.kitLineParentAssociation]);\r\n\r\n // Do not return kit cart lines if elective\r\n if (isElective) {\r\n return null;\r\n }\r\n\r\n // Hooks for toggling Show Contents section\r\n const [showKitContents, toggleShowKitContents] = React.useState(false);\r\n\r\n // Formatted kit contents to display\r\n const formattedKitContents = kitContents?.split('|');\r\n const showKitContentsText = lineAttributes && lineAttributes.showContentsText;\r\n //------------------------------------------------------\r\n\r\n const destructDimensionStrings = {\r\n sizeString: resources.sizeString,\r\n colorString: resources.colorString,\r\n styleString: resources.styleString,\r\n configString: resources.configString,\r\n amountString: resources.amountString\r\n };\r\n const fallbackImageUrl =\r\n product &&\r\n getFallbackImageUrl(\r\n product.ItemId,\r\n props.context.actionContext.requestContext.apiSettings,\r\n props.context.app?.config?.OmniChannelMedia\r\n );\r\n const imageSettings = props.imageSettings;\r\n imageSettings.cropFocalRegion = !ObjectExtensions.isNullOrUndefined(imageSettings);\r\n const { inputQuantityAriaLabel } = props.resources;\r\n const productDimensions = product && CartLineItemFunctions.renderProductDimensions(product, destructDimensionStrings);\r\n const renderDisountLines = CartLineItemFunctions.renderDiscountLines(props);\r\n const renderInventoryLabel = CartLineItemFunctions.renderInventoryLabel(props);\r\n const renderUnitOfMeasure = CartLineItemFunctions.renderUnitOfMeasure(props);\r\n const renderShippingLabel = CartLineItemFunctions.renderShippingLabel(props);\r\n const renderOtherCharges = CartLineItemFunctions.renderOtherCharges(props);\r\n const renderSalesAgreementPrompt = CartLineItemFunctions.renderSalesAgreementPrompt(props);\r\n const payLoad = getPayloadObject('click', props.telemetryContent!, '', product?.RecordId.toString());\r\n const prodAttribute = getTelemetryAttributes(props.telemetryContent!, payLoad);\r\n const productName = product?.Name || cartLine.Description;\r\n const imgeClassName = props.data.cartLine.IsInvoiceLine ? 'msc-cart-line__invoice-image' : 'msc-cart-line__product-image';\r\n\r\n const _generateErrorMessage = (): JSX.Element | null => {\r\n if (props.errorMessage) {\r\n return (\r\n
\r\n \r\n {props.errorMessage}\r\n
\r\n );\r\n }\r\n\r\n return null;\r\n };\r\n\r\n const _updateQuantity = (event: React.ChangeEvent) => {\r\n\r\n // @CUSTOM: publish events for add to cart or remove for analytics\r\n const newValue = Number.parseInt(event.target.value, 10)\r\n const quantityChange = Math.abs(newValue - (cartLine.Quantity || 0));\r\n\r\n const analyticsData: SingleProductEvent = {\r\n itemID: cartLine.ItemId!,\r\n name: product?.Name || '',\r\n discount: cartLine.DiscountAmount,\r\n variant: '',\r\n quantity: quantityChange,\r\n price: product?.BasePrice || cartLine.Price || 0,\r\n currency: props.context.request.channel?.Currency || 'USD',\r\n unitOfMeasure: cartLine.UnitOfMeasureSymbol\r\n };\r\n\r\n if (cartLine.Quantity && newValue > cartLine.Quantity) {\r\n\r\n // add to cart event\r\n publish('addToCart', analyticsData);\r\n\r\n } else if (cartLine.Quantity && newValue < cartLine.Quantity) {\r\n\r\n // remove from cart event\r\n publish('removeFromCart', analyticsData);\r\n }\r\n // end customization\r\n\r\n if (props.quantityOnChange) {\r\n props.quantityOnChange(props.data.cartLine, Number.parseInt(event.target.value, 10), props.lineIndex);\r\n }\r\n };\r\n\r\n const _generateMenu = (quantity: number) => {\r\n const nodes = [];\r\n\r\n for (let i = 1; i <= quantity; i++) {\r\n nodes.push(\r\n \r\n );\r\n }\r\n\r\n return nodes;\r\n };\r\n\r\n const _generateSelectMenu = (quantity: number, currentQuantity: number | undefined): JSX.Element => {\r\n return (\r\n \r\n {_generateMenu(quantity)}\r\n \r\n );\r\n };\r\n\r\n const _generateQuantityAndPrice = (): JSX.Element[] | null => {\r\n const nodes = [];\r\n\r\n if (props.isOutOfStock) {\r\n return null;\r\n }\r\n\r\n // No quantity selector for invoice line\r\n if (!props.data.cartLine.IsInvoiceLine) {\r\n if (props.isQuantityEditable && !props.data.product?.IsGiftCard && !kitContents && !isTestOrScore) { // @CUSTOM: Kit contents - only show quantity selector if product is not a kit with contents or T&E\r\n nodes.push(_generateSelectMenu(props.maxQuantity || 10, props.currentQuantity));\r\n } else {\r\n nodes.push(\r\n
\r\n \r\n {props.data.cartLine.Quantity}\r\n
\r\n );\r\n }\r\n }\r\n\r\n //--------------------------------------------------\r\n // @CUSTOM: Kit contents display - price updates\r\n //--------------------------------------------------\r\n const priceData = isSalesLine ? {\r\n price: {\r\n CustomerContextualPrice: (props.data.cartLine as SalesLine).NetAmountWithAllInclusiveTax,\r\n BasePrice: (props.data.cartLine as SalesLine).GrossAmount\r\n }\r\n } : {\r\n price: {\r\n CustomerContextualPrice: (props.data.cartLine as CartLine).ExtendedPrice,\r\n BasePrice: props.data.cartLine.NetPrice\r\n }\r\n };\r\n\r\n // If kit contains electives, add price to kit item\r\n if (kitElectives) {\r\n const electivePrices = kitElectives.split('|').map(elective => {\r\n const splitData = elective.split(':');\r\n return Number(splitData[1]);\r\n });\r\n\r\n const electiveSum = electivePrices.reduce((accumulator, currentValue) => {\r\n const electivePrice = props.currentQuantity ? props.currentQuantity * currentValue : currentValue;\r\n return accumulator + electivePrice;\r\n }, 0);\r\n\r\n priceData.price.CustomerContextualPrice && (priceData.price.CustomerContextualPrice += electiveSum);\r\n priceData.price.BasePrice && (priceData.price.BasePrice += electiveSum);\r\n }\r\n //--------------------------------------------------\r\n\r\n nodes.push(\r\n
\r\n \r\n
\r\n );\r\n\r\n return nodes;\r\n };\r\n\r\n //------------------------------------------------------\r\n // @CUSTOM: Getting product item ID for SKU display\r\n //------------------------------------------------------\r\n const itemId = product?.ItemId;\r\n const skuDisplay = itemId && (\r\n
\r\n {labelResources.sku}\r\n {itemId}\r\n
\r\n );\r\n //------------------------------------------------------\r\n\r\n if (props.displayMode === 'COMPACT') {\r\n const reducedDimensions: string = product?.Dimensions\r\n ? product.Dimensions.reduce((str, productDimension) => {\r\n if (productDimension.DimensionValue?.Value) {\r\n if (str) {\r\n return `${str}, ${productDimension.DimensionValue.Value}`;\r\n }\r\n\r\n return `${productDimension.DimensionValue.Value}`;\r\n }\r\n\r\n return str;\r\n }, '')\r\n : '';\r\n\r\n return (\r\n
\r\n
\r\n \r\n
\r\n
\r\n {MsDyn365.isBrowser ? (\r\n // @CUSTOM: Check global config if links back to PDP should be disabled\r\n !props.context.app.config.disableCartLineProductLinks ? (\r\n \r\n {productName}\r\n \r\n ) : (\r\n \r\n {productName}\r\n \r\n )\r\n ) : null}\r\n {/* @CUSTOM: SKU display */}\r\n {skuDisplay}\r\n {reducedDimensions !== '' ?
{reducedDimensions}
: ''}\r\n {renderUnitOfMeasure}\r\n {/* @CUSTOM: backorder customization */}\r\n {isBackorder &&
{props.context.app.config.backorderTextCartLine}
}\r\n {_generateQuantityAndPrice()}\r\n {props.data.cartLine.IsInvoiceLine && props.data.cartState && props.resources.priceEditorResources && (\r\n \r\n )}\r\n
\r\n {_generateErrorMessage()}\r\n
\r\n );\r\n }\r\n\r\n return (\r\n <>\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n \r\n {MsDyn365.isBrowser ? (\r\n // @CUSTOM: Check global config if links back to PDP should be disabled\r\n !props.context.app.config.disableCartLineProductLinks ? (\r\n \r\n {productName}\r\n \r\n ) : (\r\n \r\n {productName}\r\n \r\n )\r\n ) : null}\r\n {/* @CUSTOM: SKU display */}\r\n {skuDisplay}\r\n {ArrayExtensions.hasElements(productDimensions) ? (\r\n
{productDimensions}
\r\n ) : (\r\n ''\r\n )}\r\n {renderUnitOfMeasure}\r\n {renderDisountLines}\r\n {renderInventoryLabel}\r\n {props.showShippingChargesForLineItems &&
{renderShippingLabel}
}\r\n {renderOtherCharges}\r\n {renderSalesAgreementPrompt}\r\n {/* @CUSTOM: backorder customization */}\r\n {isBackorder &&
{props.context.app.config.backorderTextCartLine}
}\r\n
\r\n {_generateQuantityAndPrice()}\r\n {props.data.cartLine.IsInvoiceLine && props.data.cartState && props.resources.priceEditorResources && (\r\n \r\n )}\r\n
\r\n {/* @CUSTOM: Kit contents display */}\r\n {formattedKitContents && (\r\n
\r\n toggleShowKitContents(!showKitContents)}>\r\n {showKitContentsText}\r\n \r\n
\r\n {\r\n formattedKitContents.map((item, index) => {\r\n const isCustomized = item.includes('*');\r\n let productName = item;\r\n if (isCustomized) {\r\n productName = item.replace('*', '');\r\n }\r\n\r\n return (\r\n
\r\n {productName}\r\n
\r\n );\r\n })\r\n }\r\n
\r\n
\r\n )}\r\n {/* @CUSTOM: End kit contents display customization */}\r\n
\r\n {_generateErrorMessage()}\r\n \r\n );\r\n};\r\n\r\n// @ts-expect-error\r\nexport const CartLineItemComponent: React.FunctionComponent = msdyn365Commerce.createComponentOverride('CartLineItem', {\r\n component: CartLine,\r\n ...CartLineItemFunctions\r\n});\r\n\r\n\r\nexport default CartLineItemComponent;","//==============================================================================\r\n// Analytics Event Dispatcher (Simple Pub-Sub system)\r\n//\r\n// This module receives events and forwards them to the appropriate handlers\r\n// Subscriptions are managed using a subscriber ID to aid in unsubscribing\r\n//\r\n// NOTE: Singletons aren't compatible with SSR. This module acts as a singleton,\r\n// maintaining its data as a global. Modules MUST call subscribe on the client\r\n// ONLY (via componentDidMount).\r\n//\r\n// @TODO: Currently, only client-side events will be processed. Events generated\r\n// during server-side renders will be lost. If we move data to a data action\r\n// it can be persisted from server to client. That will allow us to queue up\r\n// events generated on the server or before subscriptions occur, and emit\r\n// them immediately upon subscription.\r\n//==============================================================================\r\nimport { EventHandler } from \"./analytics-events\";\r\n\r\n//==============================================================================\r\n// INTERFACES\r\n//==============================================================================\r\n\r\n// List of subscribers to a single event\r\ninterface EventSubscribers {\r\n [subscriber: string]: EventHandler;\r\n}\r\n\r\n//==============================================================================\r\n// GLOBALS\r\n//==============================================================================\r\n\r\n// List of subscriptions, organized by event name and then subscriber name\r\nconst subscriptions: { [eventName: string]: EventSubscribers } = {};\r\n\r\n//==============================================================================\r\n// FUNCTIONS\r\n//==============================================================================\r\n\r\n//==========================================================\r\n// Called by event emitters when an event occurs\r\n//\r\n// NOTE: This should only be called on the client! Events on\r\n// the server will be lost. They should instead be queued\r\n// via a data action cache.\r\n//==========================================================\r\nexport function publish(eventName: string, eventData: unknown): void {\r\n\r\n // Get the list of subscribers for this event\r\n const subscribers = Object.keys(subscriptions[eventName] || {});\r\n\r\n // Notify each subscriber\r\n subscribers.forEach(subscriber => subscriptions[eventName][subscriber](eventData));\r\n}\r\n\r\n//==========================================================\r\n// Called by event handlers when they self-register for events\r\n//==========================================================\r\nexport function subscribe(subscriber: string, eventName: string, handler: EventHandler): void {\r\n\r\n // If it's a new event, create an entry\r\n subscriptions[eventName] = subscriptions[eventName] || {};\r\n\r\n // Ensure this subscriber isn't already subscribed to this event\r\n if (subscriptions[eventName][subscriber]) {\r\n throw new Error(`Duplicate subscription request for ${subscriber}: ${eventName}`);\r\n }\r\n\r\n // Add the subscription\r\n subscriptions[eventName][subscriber] = handler;\r\n}\r\n\r\n//==========================================================\r\n// Unsubscribe from a single event\r\n//==========================================================\r\nexport function unsubscribe(subscriber: string, eventName: string): void {\r\n if (subscriptions[eventName] && subscriptions[eventName][subscriber]) {\r\n delete subscriptions[eventName][subscriber];\r\n }\r\n}\r\n","//==============================================================================\r\n// Class Name Helper\r\n//\r\n// Tool to standardize CSS class naming in module components and elements\r\n//==============================================================================\r\n\r\nexport function clsHelper(baseClass: string, fragment?: string, separator: string = '__'): string | undefined {\r\n return fragment ? `${baseClass}${separator}${fragment}` : undefined;\r\n}\r\n","//==============================================================================\r\n// D365 OData Attribute Parser\r\n//\r\n// In creating this, it became clear that \"attributes\" is a general term.\r\n//\r\n// Product attributes are a first-class entity. They have their own dedicated\r\n// fields and schema.\r\n//\r\n// The more generic term \"attributes\" is used as a generic extension system.\r\n// Almost every entity (including Product Attributes) has an ExtensionProperties\r\n// field for jamming extra information into. In some cases, D365 handles these\r\n// natively, such as sales order line and header attributes, or customer\r\n// attributes. Attributes using ExtensionProperties use the\r\n// CommerceProperty and CommercePropertyValue types.\r\n//\r\n// A major note about ExtensionProperty-based attributes: they have fields\r\n// for many different data types, but there's no indicator as to which\r\n// of the fields is actually used. The consumer of the data is expected to\r\n// know the data type ahead of time. In the case of D365-native attribute users\r\n// such as customers and sales orders, only the string type appears to work.\r\n//\r\n// This module includes parsers for generic ExtensionProperties-based attributes\r\n// and Product Attributes. Though different Product Attribute retail server\r\n// calls use the same AttributeValue entity to transmit the data, they appear\r\n// to return different fields from that entity. Because of this, two different\r\n// parser calls are included here. They currently share the same implementation,\r\n// but by including different call signatures we have the ability to diverge\r\n// the implementations if the need arises.\r\n//\r\n// A note about Product Attributes: These contain both a friendly name,\r\n// displayed to users in back office, and an internal name. The internal name\r\n// can be the same as the friendly name, but by convention we've been pushing\r\n// for a PascalCase scheme. At present, the searchByCriteria call returns only\r\n// the unfriendly name, and the GetAttributeValues call returns only the\r\n// friendly name. We don't have a known method of correlating the two. That may\r\n// be an argument for keeping the friendly and unfriendly names identical.\r\n//==============================================================================\r\nimport {\r\n CommerceProperty, // Generic attributes stored in ExtensionProperties\r\n CommercePropertyValue, // Generic attributes stored in AttributeValue\r\n AttributeValue, AttributeDataType, // Product attributes or Product Search Result attributes\r\n CustomerAttribute, // Customer attributes\r\n IDictionary,\r\n} from '@msdyn365-commerce/retail-proxy';\r\n\r\n//==============================================================================\r\n// INTERFACES AND CONSTANTS\r\n//==============================================================================\r\nexport type CommerceValueTypes = string | number | boolean | Date;\r\n\r\n// This is me giving up on proper typing. If doing this in TypeScript is possible, I don't know how.\r\n// For the key \"meta\", the type should be a hash of strings.\r\n// For all other keys, the type is a CommerceValueType.\r\nexport type AttributesWithMetadata = {\r\n [key: string]: CommerceValueTypes | IDictionary\r\n};\r\n\r\n// Type to support both internal and friendly name for attributes\r\nexport type AttributesLocalized = {\r\n [key: string]: {\r\n friendlyName?: string,\r\n value?: CommerceValueTypes | IDictionary\r\n }\r\n};\r\n\r\n// Return type for getTypeInfo()\r\ntype TypeData = {\r\n source: keyof AttributeValue,\r\n type: string,\r\n\r\n customerSource?: keyof CommercePropertyValue,\r\n};\r\n\r\n//==============================================================================\r\n// FUNCTIONS\r\n//==============================================================================\r\n\r\n//----------------------------------------------------------\r\n// This version handles ExtensionProperties conversion.\r\n//\r\n// While these have a bunch of potential fields, the value\r\n// is always stored within StringValue.\r\n// There isn't a data type field, so if the content wasn't\r\n// in StringValue we wouldn't know where to find it.\r\n//----------------------------------------------------------\r\nexport function convertExtensionProperties(attributeList: CommerceProperty[]): IDictionary {\r\n const output = {};\r\n\r\n attributeList.forEach(entry => {\r\n if (entry.Key) {\r\n output[entry.Key] = entry.Value?.StringValue; // Ecommerce seems to always use strings.\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the Name is always the friendly\r\n// name.\r\n// KeyName and ExtensionProperties aren't defined.\r\n//\r\n// These results seem to be missing CurrencyValue,\r\n// FloatValue, DateTimeOffsetValue\r\n// I don't know if those data types aren't allowed here.\r\n//\r\n// Return value: Hash of key: property values with variable\r\n// types. There is also a \"meta\" key containing a hash of\r\n// all the attribute keys and their corresponding types.\r\n//\r\n// Example:\r\n// {\r\n// flavor: 'bland',\r\n// calories: 5300,\r\n// meta: {\r\n// flavor: 'string',\r\n// calories: 'number'\r\n// }\r\n// }\r\n//----------------------------------------------------------\r\nexport function convertProductAttributes(attributeList: AttributeValue[]): AttributesWithMetadata {\r\n const output = {\r\n meta: {}\r\n };\r\n\r\n attributeList.forEach(attribute => {\r\n // These should always be present, but TypeScript insists they can be undefined.\r\n if (attribute.Name && attribute.DataTypeValue) {\r\n const typeData = getTypeInfo(attribute.DataTypeValue);\r\n output[attribute.Name] = attribute[typeData.source]; // Ecommerce seems to require strings\r\n output.meta[attribute.Name] = typeData.type;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the Name is the friendly\r\n// name while KeyName is the internal name.\r\n//\r\n// This makes use of combined attributes containing both\r\n// internal and friendly name to support localization.\r\n//\r\n// Return value: Hash of internal name keys containing an object with both the\r\n// friendly name and attribute value There is also a \"meta\" key containing a\r\n// hash of all the attribute keys and their corresponding types.\r\n//\r\n// Example:\r\n// {\r\n// flavor: {\r\n// friendlyName: Flavor,\r\n// value: 'bland'\r\n// },\r\n// calories: {\r\n// friendlyName: Calories,\r\n// value: 5300\r\n// },\r\n// meta: {\r\n// flavor: 'string',\r\n// calories: 'number'\r\n// }\r\n// }\r\n//----------------------------------------------------------\r\nexport function convertProductAttributesLocalized(attributeList: AttributeValue[]): AttributesLocalized {\r\n const output = {\r\n meta: {}\r\n };\r\n\r\n attributeList.forEach(attribute => {\r\n if (attribute.KeyName && attribute.DataTypeValue) {\r\n const typeData = getTypeInfo(attribute.DataTypeValue);\r\n output[attribute.KeyName] = {\r\n friendlyName: attribute.Name,\r\n value: attribute[typeData.source]\r\n };\r\n output.meta[attribute.KeyName] = typeData.type;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the\r\n// Name/KeyName/ExtensionProperties is always the unfriendly\r\n// name.\r\n//\r\n// These results are only missing the Swatches field.\r\n//\r\n// Though the returned value is a bit different, at present\r\n// the implementation for convertProductAttributes works for\r\n// search results.\r\n// If they diverge in the future, extend this function.\r\n//----------------------------------------------------------\r\nexport function convertSearchAttributes(attributeList: AttributeValue[]): AttributesWithMetadata {\r\n return convertProductAttributes(attributeList);\r\n}\r\n\r\n//----------------------------------------------------------\r\n// For these attributes, the Name is always the friendly\r\n// name. Value is always Text, and DataTypeValue is not\r\n// present here.\r\n//----------------------------------------------------------\r\nexport function convertCartAttributes(attributeList: AttributeValue[]): AttributesWithMetadata {\r\n const output = {};\r\n\r\n attributeList.forEach(attribute => {\r\n if (attribute.Name) {\r\n output[attribute.Name] = attribute.TextValue;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n//----------------------------------------------------------\r\nexport function convertCustomerAttributes(attributeList: CustomerAttribute[] | undefined): AttributesWithMetadata {\r\n const output = {\r\n meta: {}\r\n };\r\n\r\n attributeList?.forEach(attribute => {\r\n // These should always be present, but TypeScript insists they can be undefined.\r\n if (attribute.Name && attribute.DataTypeValue) {\r\n const typeData = getTypeInfo(attribute.DataTypeValue);\r\n output[attribute.Name] = attribute.AttributeValue && typeData.customerSource && attribute.AttributeValue[typeData.customerSource];\r\n output.meta[attribute.Name] = typeData.type;\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n//----------------------------------------------------------\r\n// Finds the source field and type for an attribute\r\n//\r\n// This should probably be extended to better support\r\n// currency, which seems to be two fields glued together.\r\n//----------------------------------------------------------\r\nfunction getTypeInfo(type: AttributeDataType): TypeData {\r\n\r\n // Awkward, but this helps TypeScript enforce strict type checking\r\n type TypeMapType = {\r\n [key in AttributeDataType]: TypeData\r\n };\r\n\r\n const typeMap: TypeMapType = {\r\n [AttributeDataType.None]: {source: 'TextValue', type: 'string'}, // We need to choose something\r\n [AttributeDataType.Currency]: {source: 'CurrencyValue', type: 'number'}, // Should also include CurrencyCode, which is a string?\r\n [AttributeDataType.DateTime]: {source: 'DateTimeOffsetValue', type: 'Date'},\r\n [AttributeDataType.Decimal]: {source: 'FloatValue', type: 'number'},\r\n [AttributeDataType.Integer]: {source: 'IntegerValue', type: 'number', customerSource: 'IntegerValue'},\r\n [AttributeDataType.Text]: {source: 'TextValue', type: 'string', customerSource: 'StringValue'},\r\n [AttributeDataType.TrueFalse]: {source: 'BooleanValue', type: 'boolean', customerSource: 'BooleanValue'},\r\n [AttributeDataType.Video]: {source: 'TextValue', type: 'string'},\r\n [AttributeDataType.Image]: {source: 'TextValue', type: 'string'}\r\n };\r\n\r\n return typeMap[type];\r\n}\r\n","//==============================================================================\r\n// Global Constants\r\n//\r\n// Consolidated list of constants reused across different modules and extensions\r\n//==============================================================================\r\n\r\n//----------------------------------------------------------\r\n// Attribute names list\r\n//----------------------------------------------------------\r\nexport const attrNames = {\r\n productType: 'Item Type',\r\n lineAttributes: 'LineAttributes',\r\n blacklistedShippingAreas: 'Embargoed shipping locations',\r\n kitConfigurator: 'KitConfigurator',\r\n kitContents: 'eCommBurstoutKitContents',\r\n kitFormats: 'eCommBurstoutKitFormats',\r\n kitElectives: 'eCommBurstoutKitElectives',\r\n kitSubstitutions: 'eCommBurstoutKitSubstitutions',\r\n kitLineSubstitutions: 'eCommBurstoutKitLineDetails',\r\n kitLineParentAssociation: 'eCommBurstoutKitOrderLineParentAssociation',\r\n kitLineChildAssociation: 'eCommBurstoutKitOrderLineChildAssociation',\r\n instructors: 'eCommInstructors',\r\n consultantCartAttribute: 'eCommConsultantId',\r\n isInstallmentEligible: 'eCommItemIsPPEligible',\r\n cashForCollege: 'eCommCash4College',\r\n dropShip: 'eCommDropShip',\r\n scoringType: 'TestScoring',\r\n studentId: 'eCommPTEStudentId',\r\n schoolIdPP: 'eCommPPSchoolId',\r\n testCoordinator: 'PTETestCoordinator',\r\n testEnrollment: 'PTESchoolEnrollment',\r\n testType: 'Test Type',\r\n testFormat: 'Test Format',\r\n testDate: 'eCommPTETestDate',\r\n testDateId: 'eCommPTETestDateId',\r\n testAdmin: 'eCommPTEAdminCustAccount',\r\n testProctorEmail: 'PTEProctorEmail',\r\n testProctorName: 'PTEProctorName',\r\n testProctorPhone: 'PTEProctorPhone',\r\n testProctorTimeZone: 'PTEProctorTimeZone',\r\n userAgreement: 'eCommUserAgreement',\r\n umbrellaGroup: 'UmbrellaGroupID',\r\n gradeLvl: 'Grade level',\r\n isNotTest: 'Other',\r\n onlineTest: 'Online test',\r\n purchaseItemType: 'TestBklt',\r\n notBuyable: 'Not Buyable',\r\n billingCountry: 'eCommBillingCountryCode',\r\n billingZipCode: 'eCommBillingZipPostalCode',\r\n paymentScheduleName: 'PaymentScheduleName',\r\n isDBOrder: 'IsDBOrder',\r\n troveAdminFirstName: \"TroveAdminFirstName\",\r\n troveAdminLastName: \"TroveAdminLastName\",\r\n troveAdminEmail: \"TroveAdminEmail\",\r\n troveAdminTelephone: \"TroveAdminTelephone\",\r\n troveAnnualLicense: \"TroveAnnualLicense\",\r\n troveProduct: \"Trove\",\r\n troveParticipant: \"TroveParticipant\",\r\n poNumber: \"CSPONumber\",\r\n publicSearchable: \"Publicly Searchable\"\r\n};\r\n\r\n//----------------------------------------------------------\r\n// Global label resources\r\n//----------------------------------------------------------\r\nexport const labelResources = {\r\n sku: 'SKU'\r\n};\r\n"],"names":["CartIcon","observer","props","cartLabel","cartQtyLabel","electiveCount","data","cart","totalItemCount","totalItemsInCart","cartItem","qtyLabel","format","label","payLoad","getPayloadObject","telemetryContent","attributes","getTelemetryAttributes","style","visibility","React","Object","assign","className","role","title","CartIconComponent","msdyn365Commerce","createComponentOverride","_objectSpread","component","cls","fragment","clsHelper","CartLineItemFunctions","renderProductDimensions","Product","DimensionStrings","Dimensions","map","productDimension","DimensionTypeValue","key","RecordId","colorString","DimensionValue","Value","configString","_productDimension$Dim","sizeString","_productDimension$Dim2","IsGiftCard","amountString","styleString","_productDimension$Dim3","renderDiscountLines","cartLine","DiscountLines","length","discountLine","index","OfferId","OfferName","resources","discountStringText","PriceComponent","isSalesLine","price","CustomerContextualPrice","PeriodicDiscount","DiscountAmount","BasePrice","context","id","typeName","currencyCode","priceCurrency","undefined","Percentage","renderInventoryLabel","renderUnitOfMeasure","app","config","unitOfMeasureDisplayType","product","DefaultUnitOfMeasure","renderShippingLabel","_props$context$reques","pickupDeliveryModeCode","request","channel","PickupDeliveryModeCode","channelDeliveryOptionConfig","cartline","hasShippingMethod","_channelDeliveryOptio","DeliveryMode","PickupDeliveryModeCodes","some","deliveryMode","shippingChargeLines","ChargeLines","filter","chargeLine","IsShipping","freightFee","reduce","chargeTotal","CalculatedAmount","priceComponent","freePriceText","shippingChargesText","renderOtherCharges","_cartline$ChargeLines","otherCharges","chargeline","otherCharge","Description","renderSalesAgreementPrompt","SalesAgreementLineRecordId","salesAgreementPricePrompt","CatalogLabelComponent","catalogId","CatalogId","validateCatalogId","isChannelTypeB2B","actionContext","requestContext","ArrayExtensions","hasElements","catalogs","catalog","find","item","Name","CartLineItemComponent","_props$context$app","_props$primaryImageUr2","productUrl","isBackorder","backorderLoaded","cloneCtx","_cloneDeep","enableStockCheck","shippingSearchCriteria","createInventoryAvailabilitySearchCriteria","shipping","ProductsDataActions","callerContext","then","result","productInventoryInformation","ProductWarehouseInventoryAvailabilities","shippingInventory","mapAggregatedProductInventoryInformation","deliveryType","push","availability","avail","ProductAvailableQuantity","ProductId","availableQuantity","AvailableQuantity","Quantity","ItemTypeValue","ReleasedProductType","Service","error","telemetry","exception","debug","backorderInput","ProductAvailabilitiesForCartLineItems","apiSettings","getAvailabilitiesForCartLineItems","productAvailableQuantity","isTestOrScore","isTestOrScoreLoaded","criteria","ItemIds","ItemId","Context","ChannelId","channelId","getCatalogId","IncludeAttributes","searchByCriteriaAsync","results","productWithAttr","formattedAtr","convertProductAttributes","AttributeValues","isTesting","attrNames","testType","isNotTest","isScoring","productType","scoringType","lineAttributes","convertCartAttributes","kitContents","kitElectives","kitLineParentAssociation","showKitContents","toggleShowKitContents","formattedKitContents","split","showKitContentsText","showContentsText","destructDimensionStrings","fallbackImageUrl","getFallbackImageUrl","OmniChannelMedia","imageSettings","cropFocalRegion","ObjectExtensions","isNullOrUndefined","inputQuantityAriaLabel","productDimensions","renderDisountLines","toString","prodAttribute","productName","imgeClassName","IsInvoiceLine","_generateErrorMessage","errorMessage","_updateQuantity","event","_props$context$reques2","newValue","Number","parseInt","target","value","quantityChange","Math","abs","analyticsData","itemID","name","discount","variant","quantity","Price","currency","Currency","unitOfMeasure","UnitOfMeasureSymbol","publish","quantityOnChange","lineIndex","_generateSelectMenu","currentQuantity","onChange","nodes","i","_generateMenu","_generateQuantityAndPrice","isOutOfStock","_props$data$product","isQuantityEditable","classNames","quantityDisplayString","maxQuantity","priceData","NetAmountWithAllInclusiveTax","GrossAmount","ExtendedPrice","NetPrice","electiveSum","elective","splitData","accumulator","currentValue","originalPriceText","currentPriceText","salesAgreementLineId","itemId","skuDisplay","labelResources","sku","displayMode","_props$primaryImageUr","reducedDimensions","str","_productDimension$Dim4","Image","src","primaryImageUrl","fallBackSrc","altText","gridSettings","loadFailureBehavior","MsDyn365","isBrowser","disableCartLineProductLinks","href","backorderTextCartLine","cartState","priceEditorResources","CartLinePriceEditor","showShippingChargesForLineItems","onClick","isCustomized","includes","replace","subscriptions","eventName","eventData","keys","forEach","subscriber","subscribe","handler","Error","baseClass","separator","arguments","attributeList","output","meta","attribute","DataTypeValue","typeData","getTypeInfo","source","type","TextValue","convertCustomerAttributes","AttributeValue","customerSource","AttributeDataType","None","DateTime","Decimal","Integer","Text","TrueFalse","Video","blacklistedShippingAreas","kitConfigurator","kitFormats","kitSubstitutions","kitLineSubstitutions","kitLineChildAssociation","instructors","consultantCartAttribute","isInstallmentEligible","cashForCollege","dropShip","studentId","schoolIdPP","testCoordinator","testEnrollment","testFormat","testDate","testDateId","testAdmin","testProctorEmail","testProctorName","testProctorPhone","testProctorTimeZone","userAgreement","umbrellaGroup","gradeLvl","onlineTest","purchaseItemType","notBuyable","billingCountry","billingZipCode","paymentScheduleName","isDBOrder","troveAdminFirstName","troveAdminLastName","troveAdminEmail","troveAdminTelephone","troveAnnualLicense","troveProduct","troveParticipant","poNumber","publicSearchable"],"sourceRoot":""}