{"version":3,"file":"static/js/f16e4c29500dc934ac5f.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/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\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 {discountLine.DiscountCost && (\r\n <>\r\n \r\n \r\n )}\r\n \r\n {` (${discountLine.EffectivePercentage !== undefined ? discountLine.EffectivePercentage : ''}%)`}\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 if (!isSalesLine) {\r\n\r\n const cloneCtx = cloneDeep(props.context.actionContext);\r\n cloneCtx.requestContext.app.config.enableStockCheck = true;\r\n\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 }\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// 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};\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","DiscountCost","PriceComponent","isSalesLine","price","CustomerContextualPrice","PeriodicDiscount","DiscountAmount","BasePrice","context","id","typeName","currencyCode","priceCurrency","undefined","EffectivePercentage","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","backorderInput","ProductAvailabilitiesForCartLineItems","apiSettings","getAvailabilitiesForCartLineItems","then","result","availability","avail","ProductAvailableQuantity","ProductId","productAvailableQuantity","AvailableQuantity","Quantity","ItemTypeValue","ReleasedProductType","Service","isTestOrScore","isTestOrScoreLoaded","criteria","ItemIds","ItemId","Context","ChannelId","channelId","getCatalogId","IncludeAttributes","searchByCriteriaAsync","callerContext","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","push","_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","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"],"sourceRoot":""}