{"version":3,"sources":["webpack:///./src/Utilities/cart-utils.tsx?94bc","webpack:///./src/Utilities/commerce-attributes-parser.tsx?9770","webpack:///./src/Utilities/analytics/google-analytics.ts?df4a","webpack:///./src/Utilities/analytics/analytics-dispatcher.ts?9802","webpack:///./src/models/notification-message-type.ts?e64a","webpack:///./src/common/subscription-commerce.values.tsx?6426","webpack:///./src/components/addtocart.component.tsx?2c04","webpack:///./src/modules/subscriptions-minicart/components/bottle-count-display.component.tsx?494a","webpack:///./src/Utilities/brand-code-parser.tsx?0b81","webpack:///./src/Utilities/productType.tsx?e262","webpack:///./src/modules/reset-subscription/reset-subscription.tsx?c9e8","webpack:///./src/Utilities/subscription-manager.tsx?8de0","webpack:///./src/modules/subscription-box/subscription-box.tsx?34ed"],"names":["CartUtilities","constructor","actionContext","cart","this","lines","amount","forEach","line","Quantity","ItemId","toLowerCase","NetPrice","TotalAmount","errorHandler","recordId","context","cartAmount","_addItem","cartState","frequency","getSubscriptionValues","result","updateSubscription","Key","SubscriptionCommerceValues","SUBSCRIPTION_FREQUENCY","Value","StringValue","app","config","defaultSubscriptionFrequencyId","item","isDigital","r","console","error","attributeUpdates","telemetry","extensionProps","ExtensionProperties","Object","keys","commerceKey","value","propToUpdate","find","commerceProp","push","updatedCartState","updateAsync","callerContext","update","GetCheckoutCartInput","request","apiSettings","refreshCart","propsToDel","extProp","propToDel","updatedCart","isSubscription","disableOOS","simpleProduct","getByIdsAsync","channelId","prod","attributesInput","AttributesForSelectedVariantInput","attributes","getAttributesForSelectedVariantAction","formattedResponse","getEstimatedAvailabilityAsync","ProductIds","DefaultWarehouseOnly","ProductWarehouseInventoryAvailabilities","map","product","ProductId","AvailableQuantity","PhysicalAvailable","productTypeAttribute","attribute","Name","availability","available","AddToCartAction","addToCartText","outOfStockText","typeName","productAttributes","data","id","quantity","productAvailability","isSubscriptionItem","useElicitAddToCart","overrideOutOfStock","onError","input","cartLine","CatalogId","requestContext","catalogId","Description","EntryMethodTypeValue","RecordId","count","TrackingId","UnitOfMeasureSymbol","DefaultUnitOfMeasure","location","channel","status","DeliveryMode","PickupDeliveryModeCode","FulfillmentStoreId","OrgUnitNumber","ShippingAddress","_buildAddressFromOrgUnitLocation","callbackResult","_elicitAddProductToCartInternal","additionalProperties","asSubscriptionItem","_shouldRetrySubstatus","substatus","cartLineToAdd","addAsSubscriptionItem","CartLines","undefined","quantityLimit","maxQuantityForCartLineItem","lineSet","productIdToFind","i","length","curLine","isLineSubscriptionLine","isCurLineSubscription","addNewLine","cartLineToUpdate","curQuantity","Id","IntegerValue","Math","min","updateCartLinesAsync","then","catch","warning","debug","newCartLine","subscriptionAttribute","Version","addCartLinesAsync","async","newCart","trace","subsatus","PostalAddressId","OrgUnitName","FullAddress","Address","Street","StreetNumber","City","DistrictName","BuildingCompliment","Postbox","ThreeLetterISORegionName","Country","ZipCode","Zip","County","CountyName","State","StateName","AttributeDataType","AttributeDataTextMap","0","2","3","4","5","6","CommerceAttributesParser","_attributes","_attributesMap","attributeValues","psuedoAttributeValues","parsedAttribute","_parseGetAttribute","name","attr","hash","entries","TextValue","toString","DataTypeValue","Text","_dataTypeMap","mappedTextValue","type","get","commerceAttr","Currency","Decimal","Integer","TrueFalse","DateTime","formatProductData","brand","brandCodeParser","description","appContext","variant","price","Price","category","discounts","coupon","discount","OfferName","join","subscription","subscribe","addToCart","event","ecommerce","currencyCode","add","products","dataLayer","removeFromCart","remove","productDetailView","detail","purchase","actionField","revenue","tax","shipping","orderSummary","subTotal","transactionId","confirmationId","affiliation","impression","impressions","idx","position","list","checkout","step","subscriptions","publish","eventName","eventData","subscriber","handler","Error","NotificationType","updateCart","props","setTimeout","cartInput","GlobalStateInput","BaseCartState","getCartState","onClick","_event","setDisabled","cartError","addToCartError","productToAdd","propogateError","getSelectedProduct","deliveryModeCode","ProductType","EventDeliveryMode","GiftCardItemId","EmailDeliveryModeCode","productType","check","isMixedProduct","failureReason","message","eventAlreadyExist","subLines","filterCartLines","subscriptionLines","totalBottlesInCart","countCartLineAmount","getNotificationMessage","createNotificationMessage","messagetype","getParsedAttributes","success","log","keyedInPrice","GiftCardBalance","IsPriceKeyedIn","IsGiftCardLine","buildGiftCardCartLine","emailDeliveryModeCode","getAddToCartResult","caseType","recentlyAddedCartLine","LineId","updateLineDeliverySpecificationsAsync","DeliverySpecification","DeliveryModeId","DeliveryPreferenceTypeValue","DeliveryAddress","navigationUrl","shouldNavigateToCart","window","assign","parent","top","postMessage","url","href","version","origin","propogateResult","cartActionResult","isElicitOnly","elicitAddProductToCart","addProductToCart","AddToCartComponentActions","AddToCart","disabled","useState","React","className","classnames","shouldShowOutOfStock","getLinkText","defaultProps","Dimensions","missingDimensions","filter","dimension","DimensionValue","availableQuantity","stockLeft","max","outOfStockThreshold","includeCurrentQuantity","enableStockCheck","Number","onAdd","BottleCountDisplay","_maxBottleCount","render","_fillBottleList","_generateBottleListFromProducts","slice","bottleList","newBottleIndex","_specializeIndex","rollingIndex","fragments","_cartFilteredLines","gridSettings","subscriptionProps","_getProductFromLine","lineIdx","Image","src","PrimaryImageUrl","alt","imageSettings","currentIndex","subscriptionsMinicart__discount10Percent","subscriptionsMinicart__discount15Percent","resources","brandCodeTable","currentBrandCode","brandFound","brandCode","brandName","isWine","isEvent","isGiftCard","isWineProduct","ResetSubscription","_didClearSubscription","clearSubscription","e","commerceValues","newValue","changedProperty","property","extension","findAndUpdateLine","isProductSubscribable","SUBSCRIPTION_PRODUCT","BooleanValue","freq","ext","SUBSCRIPTION_NAME","SUBCRIPTION_LINE","output","editObj","SubscriptionBox","super","_subscriptionBoxName","_publishNameToCart","debounce","bind","_onNameChange","_onFrequencyChange","_submitSubscriptionToCart","reaction","values","allSubscriptionsLink","destinationUrl","replace","subscriptionBox__name","subscriptionBox__delivery","headerText","_optionalRichTextRender","onChange","placeholder","SUBSCRIPTION_DEFAULT_NAME","_frequencyTable","richText","RichTextComponent","text","initialId","frequencyTable","firstId","_selectedFrequency","key","label","cartChanges","selectedFrequency","v","frequncy","target","__decorate","observable","observer"],"mappings":"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","file":"static/js/2.c718283d74f9210b279d.chunk.js","sourcesContent":["import { GetCheckoutCartInput } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { AsyncResult, IActionContext, ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ICartActionResult, ICartActionResultWithCart, ICartActionSubStatus, ICartState } from '@msdyn365-commerce/global-state';\r\nimport { ProductAvailableQuantity } from '@msdyn365-commerce/retail-proxy';\r\nimport { addCartLinesAsync, updateAsync, updateCartLinesAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/CartsDataActions.g';\r\nimport { getByIdsAsync, getEstimatedAvailabilityAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { Address, Cart, CartLine, CommerceProperty, OrgUnitLocation, SimpleProduct } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\nimport React from 'react';\r\nimport { SubscriptionCommerceValues } from '../common/subscription-commerce.values';\r\nimport { AddToCartAction, IAddToCartFailureResult } from '../components/addtocart.component';\r\nimport { AttributesForSelectedVariantInput, getAttributesForSelectedVariantAction } from '../dataActions/get-attributes-for-selected-variant';\r\nimport { getSubscriptionValues, isLineSubscriptionLine, updateSubscription } from './subscription-manager';\r\n\r\ntype itemInfo = {\r\n recordId: number;\r\n amount?: number;\r\n // tslint:disable-next-line: no-any\r\n context: ICoreContext<{ [x: string]: any }>;\r\n};\r\n\r\n/**\r\n * Util for adding items to cart via code\r\n */\r\n// tslint:disable-next-line: no-unnecessary-class\r\nexport class CartUtilities {\r\n\r\n protected actionContext: IActionContext;\r\n protected cart: ICartState;\r\n\r\n public static countCartLineAmount(lines: CartLine[]): number {\r\n let amount = 0;\r\n lines.forEach(line => amount += line.Quantity || 0);\r\n return amount;\r\n }\r\n\r\n public static countCartLineAmountNoGiftCards(lines: CartLine[]): number {\r\n let amount = 0;\r\n lines.forEach(line => {\r\n const isGiftCard = line.ItemId?.toLowerCase() === 'giftcard';\r\n if (!isGiftCard) {\r\n amount += line.Quantity || 0;\r\n }\r\n });\r\n return amount;\r\n }\r\n\r\n public static countCartLineNetPrice(lines: CartLine[]): number {\r\n let amount = 0;\r\n lines.forEach(line => amount += line.NetPrice || 0);\r\n return amount;\r\n }\r\n\r\n public static countCartLineDiscountedPrice(lines: CartLine[]): number {\r\n let amount = 0;\r\n lines.forEach(line => amount += line.TotalAmount || 0);\r\n return amount;\r\n }\r\n\r\n public static async elicitAddItemIdToCart({ recordId, amount, context }: itemInfo, errorHandler?: () => void): Promise {\r\n const cartAmount = amount || 1;\r\n return this._addItem({ recordId, amount: cartAmount, context }, false, errorHandler);\r\n }\r\n\r\n public static async elicitAddSubscriptionItemIdToCart({ recordId, context, amount }: itemInfo, cartState: AsyncResult): Promise {\r\n const { frequency } = getSubscriptionValues(cartState.result?.cart);\r\n\r\n if (!frequency) {\r\n await updateSubscription(\r\n cartState,\r\n [\r\n {\r\n Key: SubscriptionCommerceValues.SUBSCRIPTION_FREQUENCY,\r\n Value: {\r\n StringValue: context.app.config.defaultSubscriptionFrequencyId\r\n }\r\n }\r\n ],\r\n context\r\n );\r\n }\r\n\r\n return this._addItem({ recordId, context, amount: amount || 1 }, true);\r\n }\r\n\r\n public static async addItem(item: itemInfo, isDigital?: boolean): Promise {\r\n return this._addItem(item, false, (r) => { console.error('[CartUtilities.addItem] error occured', r); }, isDigital);\r\n }\r\n\r\n public static async editCartHeadExtensionProps(cartState: ICartState, context: ICoreContext, attributeUpdates: { [commerceKey: string]: string }): Promise {\r\n if (!cartState || !cartState.cart) {\r\n context.telemetry.error('[CartUtilities.updateAttributeValues] Failed to load cart');\r\n return;\r\n }\r\n\r\n const extensionProps = cartState.cart.ExtensionProperties || [];\r\n Object.keys(attributeUpdates).forEach(commerceKey => {\r\n const value = attributeUpdates[commerceKey];\r\n const propToUpdate = extensionProps.find(commerceProp => commerceProp.Key === commerceKey);\r\n if (propToUpdate) {\r\n propToUpdate.Value = {\r\n StringValue: value\r\n };\r\n } else {\r\n extensionProps.push({ Key: commerceKey, Value: { StringValue: value } });\r\n }\r\n });\r\n\r\n const updatedCartState = await updateAsync({ callerContext: context.actionContext }, cartState.cart);\r\n context.actionContext.update(new GetCheckoutCartInput(context.request.apiSettings), updatedCartState);\r\n\r\n await cartState.refreshCart({});\r\n }\r\n\r\n public static async removeCartHeadExtensionProps(cart: AsyncResult, context: ICoreContext, ...propsToDel: string[]): Promise {\r\n const cartState = await cart;\r\n\r\n // cartState.cart.ExtensionProperties = extProps.filter(extProp => !propsToDel.find(propToDel => propToDel === extProp));\r\n cartState.cart.ExtensionProperties?.forEach(extProp => {\r\n const isToRemove = propsToDel.find(propToDel => propToDel === extProp.Key);\r\n if (isToRemove && extProp.Value) {\r\n extProp.Value.StringValue = '';\r\n }\r\n });\r\n\r\n const updatedCart = await updateAsync({ callerContext: context.actionContext }, cartState.cart);\r\n context.actionContext.update(new GetCheckoutCartInput(context.request.apiSettings), updatedCart);\r\n }\r\n\r\n private static async _addItem({ recordId, amount, context }: itemInfo, isSubscription: boolean, errorHandler?: (result: IAddToCartFailureResult) => void, disableOOS?: boolean): Promise {\r\n // get simple products\r\n const simpleProducts = await getByIdsAsync({ callerContext: context.actionContext }, context.request.apiSettings.channelId, [+recordId]);\r\n const simpleProduct = simpleProducts.find(prod => !!prod);\r\n\r\n // get attributes of product\r\n const attributesInput = new AttributesForSelectedVariantInput(+recordId, context.request.apiSettings.channelId, simpleProduct);\r\n const attributes = await getAttributesForSelectedVariantAction(attributesInput, context.actionContext);\r\n\r\n // get availlability of product\r\n const availabilityAll = await getEstimatedAvailabilityAsync({ callerContext: context.actionContext }, { ProductIds: [recordId], DefaultWarehouseOnly: true});\r\n const formattedResponse = availabilityAll.ProductWarehouseInventoryAvailabilities?.map((product) => {\r\n return {ProductId: product.ProductId, AvailableQuantity: product.PhysicalAvailable, ExtensionProperties: product.ExtensionProperties};\r\n }) as ProductAvailableQuantity[];\r\n const productTypeAttribute = attributes && attributes.find(\r\n attribute => attribute.Name === 'Product Type'\r\n );\r\n const availability = formattedResponse.find(available => !!available);\r\n\r\n // add to cart\r\n await AddToCartAction(\r\n null as unknown as React.MouseEvent,\r\n {\r\n addToCartText: '',\r\n outOfStockText: '',\r\n context: context,\r\n typeName: '',\r\n\r\n productTypeAttribute: productTypeAttribute,\r\n productAttributes: attributes,\r\n data: { product: simpleProduct! },\r\n id: '',\r\n quantity: amount,\r\n productAvailability: availability,\r\n isSubscriptionItem: isSubscription,\r\n useElicitAddToCart: true,\r\n overrideOutOfStock: disableOOS || false,\r\n onError: errorHandler,\r\n },\r\n () => false\r\n );\r\n }\r\n\r\n constructor(actionContext: IActionContext, cart: ICartState) {\r\n this.actionContext = actionContext;\r\n this.cart = cart;\r\n }\r\n\r\n public async elicitAddProductToCart(input: { product: SimpleProduct; count?: number; location?: OrgUnitLocation; additionalProperties?: { asSubscriptionItem: boolean } }): Promise {\r\n const cartLine: CartLine = {\r\n CatalogId: this.actionContext.requestContext.apiSettings.catalogId,\r\n Description: input.product.Description,\r\n // TODO: Investigate this value and what it represents\r\n EntryMethodTypeValue: 3,\r\n ItemId: input.product.ItemId,\r\n ProductId: input.product.RecordId,\r\n Quantity: input.count || 1,\r\n TrackingId: '',\r\n UnitOfMeasureSymbol: input.product.DefaultUnitOfMeasure\r\n };\r\n\r\n if (input.location) {\r\n if (!this.actionContext.requestContext.channel) {\r\n return { status: 'FAILED' };\r\n }\r\n\r\n cartLine.DeliveryMode = this.actionContext.requestContext.channel.PickupDeliveryModeCode;\r\n cartLine.FulfillmentStoreId = input.location.OrgUnitNumber;\r\n cartLine.ShippingAddress = this._buildAddressFromOrgUnitLocation(input.location);\r\n }\r\n\r\n let callbackResult = await this._elicitAddProductToCartInternal(this.cart.cart, cartLine, this.actionContext, input.additionalProperties?.asSubscriptionItem!);\r\n if (callbackResult.status === 'SUCCESS' || !this._shouldRetrySubstatus(callbackResult.substatus)) {\r\n //\r\n } else {\r\n const refreshCartResult = await this.cart.refreshCart({});\r\n\r\n if (refreshCartResult.status === 'SUCCESS') {\r\n callbackResult = await this._elicitAddProductToCartInternal(this.cart.cart, cartLine, this.actionContext, input.additionalProperties?.asSubscriptionItem!);\r\n }\r\n }\r\n\r\n return { status: callbackResult.status, substatus: callbackResult.substatus };\r\n }\r\n\r\n // tslint:disable-next-line: cyclomatic-complexity tslint:disable-next-line: max-func-body-length\r\n private async _elicitAddProductToCartInternal(cart: Readonly, cartLineToAdd: CartLine, actionContext: IActionContext, addAsSubscriptionItem: boolean): Promise {\r\n if (!cart.CartLines) {\r\n return { cart: undefined, status: 'FAILED' };\r\n }\r\n\r\n const quantityLimit: number = actionContext.requestContext.app.config.maxQuantityForCartLineItem || 10;\r\n\r\n // let lineFound: number = -1;\r\n const lineSet: CartLine[] = [];\r\n const productIdToFind = cartLineToAdd.ProductId;\r\n\r\n for (let i = 0; i < cart.CartLines.length; i++) {\r\n if (cart.CartLines[i].ProductId === productIdToFind &&\r\n (cart.CartLines[i].DeliveryMode || '') === (cartLineToAdd.DeliveryMode || '') &&\r\n (cart.CartLines[i].FulfillmentStoreId || '') === (cartLineToAdd.FulfillmentStoreId || '')) {\r\n lineSet.push(cart.CartLines[i]);\r\n }\r\n }\r\n\r\n const curLine: CartLine | undefined = (addAsSubscriptionItem) ?\r\n lineSet.find(isLineSubscriptionLine) :\r\n lineSet.find(line => !isLineSubscriptionLine(line));\r\n\r\n const isCurLineSubscription = isLineSubscriptionLine(curLine);\r\n let addNewLine: boolean = !curLine;\r\n // if a line already exists, and you want to add it as a subscription item, but the current\r\n // line is NOT a subscription line\r\n if (curLine && addAsSubscriptionItem && !isCurLineSubscription) {\r\n addNewLine = true;\r\n // if a line exists, and you want to add it as a normal item, but the current line IS a\r\n // subscription line\r\n } else if (curLine && !addAsSubscriptionItem && isCurLineSubscription) {\r\n addNewLine = true;\r\n }\r\n\r\n if (!addNewLine) {\r\n const cartLineToUpdate = { ...curLine! };\r\n const curQuantity = cartLineToUpdate.Quantity || 0;\r\n\r\n if (curQuantity + (cartLineToAdd.Quantity || 1) > quantityLimit) {\r\n return { cart: { Id: cart.Id, ExtensionProperties: [{ Key: 'curQuantity', Value: { IntegerValue: curQuantity } }] }, status: 'FAILED', substatus: 'MAXQUANTITY' };\r\n }\r\n\r\n cartLineToUpdate.Quantity = Math.min((cartLineToUpdate.Quantity || 0) + (cartLineToAdd.Quantity || 0), quantityLimit);\r\n\r\n return updateCartLinesAsync({ callerContext: actionContext }, cart.Id, [cartLineToUpdate])\r\n .then(updatedCart => {\r\n return { cart: updatedCart, status: 'SUCCESS' } as ICartActionResultWithCart;\r\n }).catch(error => {\r\n actionContext.telemetry.warning(error);\r\n actionContext.telemetry.debug('Unable to Update Cart Line');\r\n\r\n return { cart: undefined, status: 'FAILED' } as ICartActionResultWithCart;\r\n });\r\n } else {\r\n const newCartLine = { ...cartLineToAdd };\r\n\r\n newCartLine.Quantity = Math.min(cartLineToAdd.Quantity || 1, quantityLimit);\r\n\r\n if (addAsSubscriptionItem) {\r\n const subscriptionAttribute: CommerceProperty = {\r\n Key: 'IsSubscription',\r\n Value: {\r\n StringValue: 'True'\r\n }\r\n };\r\n\r\n if (newCartLine.ExtensionProperties) {\r\n newCartLine.ExtensionProperties.push(subscriptionAttribute);\r\n } else {\r\n newCartLine.ExtensionProperties = [subscriptionAttribute];\r\n }\r\n }\r\n\r\n if (cart.Version) {\r\n return addCartLinesAsync({ callerContext: actionContext }, cart.Id, [newCartLine], cart.Version)\r\n .then(async newCart => {\r\n return { cart: newCart, status: 'SUCCESS' } as ICartActionResultWithCart;\r\n }).catch(error => {\r\n actionContext.telemetry.trace(error);\r\n actionContext.telemetry.trace('Unable to add Cart Line');\r\n\r\n return { cart: undefined, status: 'FAILED' } as ICartActionResultWithCart;\r\n });\r\n } else {\r\n actionContext.telemetry.warning('Unable to update Cart Line, Cart Version could not be found');\r\n }\r\n }\r\n return { cart: undefined, status: 'FAILED' } as ICartActionResultWithCart;\r\n }\r\n\r\n private _shouldRetrySubstatus(subsatus?: ICartActionSubStatus): boolean {\r\n if (!subsatus) {\r\n return true;\r\n }\r\n\r\n // all substatus currently don't result in a retry\r\n return false;\r\n }\r\n\r\n private _buildAddressFromOrgUnitLocation(location: OrgUnitLocation): Address {\r\n return {\r\n RecordId: location.PostalAddressId,\r\n Name: location.OrgUnitName,\r\n FullAddress: location.Address,\r\n Street: location.Street,\r\n StreetNumber: location.StreetNumber,\r\n City: location.City,\r\n DistrictName: location.DistrictName,\r\n BuildingCompliment: location.BuildingCompliment,\r\n Postbox: location.Postbox,\r\n ThreeLetterISORegionName: location.Country,\r\n ZipCode: location.Zip,\r\n County: location.County,\r\n CountyName: location.CountyName,\r\n State: location.State,\r\n StateName: location.StateName\r\n };\r\n }\r\n}","import { AttributeValue } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\n\r\n// importing enums have issues and this enum is not interfaced from CommerceTypes\r\nconst enum AttributeDataType {\r\n /**\r\n * The None member.\r\n */\r\n None = 0,\r\n /**\r\n * The Currency member.\r\n */\r\n Currency = 1,\r\n /**\r\n * The DateTime member.\r\n */\r\n DateTime = 2,\r\n /**\r\n * The Decimal member.\r\n */\r\n Decimal = 3,\r\n /**\r\n * The Integer member.\r\n */\r\n Integer = 4,\r\n /**\r\n * The Text member.\r\n */\r\n Text = 5,\r\n /**\r\n * The TrueFalse member.\r\n */\r\n TrueFalse = 6,\r\n /**\r\n * The Video member.\r\n */\r\n Video = 40,\r\n /**\r\n * The Image member.\r\n */\r\n Image = 41\r\n}\r\n\r\nconst AttributeDataTextMap = {\r\n 0: 'CURRENCY',\r\n 2: 'DATE',\r\n 3: 'NUMBER',\r\n 4: 'NUMBER',\r\n 5: 'STRING',\r\n 6: 'BOOLEAN'\r\n};\r\n\r\nexport type CommerceValueTypes = string | number | boolean | null;\r\n\r\nexport type ValueTypes = {\r\n value: T;\r\n type: DataType;\r\n};\r\nexport type DataType = 'CURRENCY' | 'DATE' | 'NUMBER' | 'STRING' | 'BOOLEAN';\r\n\r\nexport type ParsedValue = {\r\n name: string;\r\n value: T | null;\r\n type: DataType;\r\n};\r\n\r\ntype AttributeHash = { [name: string]: CommerceValueTypes };\r\n\r\n/**\r\n * Parses Commerce Datasets to make it easier to access data from Commerce\r\n * Objects\r\n *\r\n * **Bulk parsing method:**\r\n * ```\r\n * const fields = getMyFields.fromSomewhere(); // attributes[]\r\n * const parsedFields = CommerceAttributesParser(fields); // parse multiple attributes in bulk\r\n * console.log(parsedFields) // { [name: string]: ValueTypes }\r\n * ```\r\n *\r\n * **Using constructor method:**\r\n * ```\r\n * const fields = getMyFields.fromSomewhere(); // attributes[]\r\n * const commerceParser = new CommerceAttributesParser(fields); // parse multiple attributes\r\n * const isSoldOut\r\n * = commerceParser.get('soldOut') // returns { type: 'BOOLEAN', valueType: true }\r\n * console.log(isSoldOut);\r\n * ```\r\n *\r\n * **Using static method:**\r\n * ```\r\n * const soldOut = getMyFields.getField('soldOut');\r\n * // return type declaration is optional\r\n * const isSoldOut = CommerceAttributesParser.parse(soldOut); // parse single attribute\r\n * console.log(isSoldOut);\r\n * ```\r\n */\r\nexport default class CommerceAttributesParser {\r\n\r\n // type map from commerce number values to the properties found in the object\r\n private static _dataTypeMap: { [numType: number]: string } = {\r\n [AttributeDataType.Currency]: 'CurrencyCode',\r\n [AttributeDataType.Decimal]: 'IntegerValue', // this one is a guess\r\n [AttributeDataType.Integer]: 'IntegerValue',\r\n [AttributeDataType.Text]: 'TextValue',\r\n [AttributeDataType.TrueFalse]: 'BooleanValue',\r\n [AttributeDataType.DateTime]: 'DateTimeOffsetValue'\r\n };\r\n\r\n // raw array thats given when constructed\r\n private _attributes: AttributeValue[] = [];\r\n\r\n // map of attributes\r\n private _attributesMap: { [name: string]: AttributeValue } = {};\r\n\r\n /**\r\n * retrieve the correct piece of data from the object\r\n */\r\n public static parse(attribute: AttributeValue): ParsedValue | undefined {\r\n const parsedAttribute = CommerceAttributesParser._parseGetAttribute(attribute);\r\n if (!parsedAttribute) { return undefined; }\r\n return {\r\n name: attribute.Name!,\r\n ...parsedAttribute\r\n };\r\n }\r\n\r\n //----------------------------------------------------------\r\n // Convert an AttributeValue[] to a simple key:value hash\r\n //----------------------------------------------------------\r\n public static getParsedAttributes(attributes: AttributeValue[]): AttributeHash {\r\n const attributeValues = {};\r\n\r\n attributes.forEach(\r\n attr => attributeValues[attr.Name!] = CommerceAttributesParser._parseGetAttribute(attr)?.value\r\n );\r\n\r\n return attributeValues;\r\n }\r\n\r\n //----------------------------------------------------------\r\n // Convert a simplified attribute hash back to an unparsed\r\n // AttributeValue[]\r\n //----------------------------------------------------------\r\n public static unParseAttributes(hash: AttributeHash): AttributeValue[] {\r\n return Object.entries(hash).map(([name, value]) => ({\r\n Name: name,\r\n TextValue: value?.toString(),\r\n DataTypeValue: AttributeDataType.Text\r\n }));\r\n }\r\n\r\n private static _parseGetAttribute(attribute: AttributeValue): ValueTypes | null {\r\n const property = CommerceAttributesParser._dataTypeMap[attribute.DataTypeValue!];\r\n const value = attribute[property];\r\n const mappedTextValue = AttributeDataTextMap[attribute.DataTypeValue!];\r\n if (mappedTextValue) {\r\n return {\r\n value: value,\r\n type: mappedTextValue\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n constructor(attributes?: {\r\n attributeValues?: AttributeValue[];\r\n psuedoAttributeValues?: AttributeValue[];\r\n }) {\r\n if (attributes) {\r\n this._attributes = [\r\n ...(attributes?.attributeValues || []),\r\n ...(attributes?.psuedoAttributeValues || [])\r\n ];\r\n this._attributes.forEach(attribute => {\r\n if (attribute.Name) {\r\n this._attributesMap[attribute.Name] = attribute;\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * get a value from the collection of attributes given\r\n * @param name name of the attribute\r\n */\r\n public get(name: string): ParsedValue | undefined {\r\n const attribute = this._attributesMap[name];\r\n if (attribute) {\r\n const commerceAttr = CommerceAttributesParser._parseGetAttribute(attribute);\r\n if (!commerceAttr) { return undefined; }\r\n return {\r\n name: attribute.Name!,\r\n ...commerceAttr\r\n };\r\n }\r\n return undefined;\r\n }\r\n}","//==============================================================================\r\n//==============================================================================\r\nimport { IComponentProps } from '@msdyn365-commerce/core';\r\nimport { DiscountLine, IDictionary, SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\n\r\nimport { brandCodeParser } from '../brand-code-parser';\r\n\r\nimport { subscribe } from './analytics-dispatcher';\r\nimport * as GA from './ga-typings';\r\n\r\n//==============================================================================\r\n// CONSTANTS\r\n//==============================================================================\r\nconst SUBSCRIBER_NAME = 'GOOGLE_ANALYTICS';\r\nconst CURRENCY_CODE = 'USD';\r\n\r\nconst UNKNOWN_VALUE = 'unknown';\r\n\r\n//==============================================================================\r\n// INTERFACES\r\n//==============================================================================\r\n\r\n// Data passed to events that deal with a single product\r\ninterface ISingleProductProps extends IComponentProps {\r\n product: SimpleProduct;\r\n quantity: number;\r\n price: number;\r\n attributes: IDictionary | undefined;\r\n subscription: boolean;\r\n frequency?: string;\r\n discounts?: DiscountLine[];\r\n category?: string;\r\n}\r\n\r\n// Data passed to events that deal with multiple products\r\ninterface IMultiProductProps extends IComponentProps {\r\n confirmationId: string | undefined;\r\n\r\n // Transactions\r\n id: string; // The transaction ID\r\n revenue: number; // Specifies the total revenue or grand total associated with the transaction\r\n tax: number; // The total tax associated with the transaction\r\n shipping: number; // The shipping cost associated with the transaction\r\n affiliation?: string; // The store or affiliation from which this transaction occurred\r\n coupon?: string; // The transaction coupon redeemed with the transaction\r\n\r\n // Impressions\r\n list?: string;\r\n category?: string;\r\n\r\n // Checkout\r\n step?: number;\r\n\r\n // Common\r\n products: ISingleProductProps[];\r\n}\r\n\r\ninterface IExtendedProduct extends GA.IEECProduct {\r\n subscribe?: boolean; // Flag denoting that the item is a subscription rather than a one-time purchase\r\n frequency?: string; // If an item is part of a subscription, include the frequency of the subscription\r\n}\r\n\r\n// tslint:disable-next-line: no-any\r\ndeclare const dataLayer: any[] | undefined;\r\n\r\n//==============================================================================\r\n// Common Helpers\r\n//==============================================================================\r\nfunction formatProductData(data: ISingleProductProps): IExtendedProduct {\r\n\r\n // Convert internal event data to GA event data\r\n const product: IExtendedProduct = {\r\n id: data.product.ItemId || UNKNOWN_VALUE,\r\n name: data.product.Name || UNKNOWN_VALUE,\r\n brand: brandCodeParser({ description: data.product.Description, appContext: data.context }) || UNKNOWN_VALUE,\r\n variant: (data.attributes && data.attributes['Wine Bottle Size']) || UNKNOWN_VALUE, // Size for wine\r\n price: (data.price !== undefined) ? data.price : data.product.Price,\r\n quantity: data.quantity,\r\n };\r\n\r\n // Add optional entries\r\n data.category && (product.category = data.category);\r\n data.discounts && (product.coupon = data.discounts.map(discount => discount.OfferName).join(','));\r\n\r\n if (data.subscription) {\r\n product.subscribe = true;\r\n data.frequency && (product.frequency = data.frequency);\r\n }\r\n\r\n return product;\r\n}\r\n\r\n//==============================================================================\r\n// EVENT HANDLERS\r\n//==============================================================================\r\n\r\n//----------------------------------------------------------\r\n// Add to Cart\r\n//----------------------------------------------------------\r\nfunction addToCart(data: ISingleProductProps): void {\r\n\r\n // Convert internal event data to GA event data\r\n const product: IExtendedProduct = formatProductData(data);\r\n\r\n // Create an event rather than directly pushing to the data layer to enforce typing\r\n const event: GA.IAddToCartEvent = {\r\n event: 'addToCart',\r\n ecommerce: {\r\n currencyCode: CURRENCY_CODE,\r\n add: {\r\n products: [product]\r\n },\r\n }\r\n };\r\n\r\n if (typeof dataLayer !== 'undefined') {\r\n dataLayer.push(event);\r\n }\r\n}\r\n\r\n//----------------------------------------------------------\r\n// Remove from Cart\r\n//----------------------------------------------------------\r\nfunction removeFromCart(data: ISingleProductProps): void {\r\n\r\n // Convert internal event data to GA event data\r\n const product: IExtendedProduct = formatProductData(data);\r\n\r\n // Create an event rather than directly pushing to the data layer to enforce typing\r\n const event: GA.IRemoveFromCartEvent = {\r\n event: 'removeFromCart',\r\n ecommerce: {\r\n remove: {\r\n products: [product]\r\n },\r\n }\r\n };\r\n\r\n if (typeof dataLayer !== 'undefined') {\r\n dataLayer.push(event);\r\n }\r\n}\r\n\r\n//----------------------------------------------------------\r\n// Product Detail View (PDP visited)\r\n//----------------------------------------------------------\r\nfunction productDetailView(data: ISingleProductProps): void {\r\n\r\n // Convert internal event data to GA event data\r\n const product: IExtendedProduct = formatProductData(data);\r\n\r\n // Quantity isn't valid for this event. Rather than sending \"undefined\", remove it completely.\r\n delete product.quantity;\r\n\r\n // Create an event rather than directly pushing to the data layer to enforce typing\r\n const event: GA.IProductDetailViewEvent = {\r\n event: 'detail',\r\n ecommerce: {\r\n detail: {\r\n // actionField: {\r\n // list: '' // We have category at the product level. This would probably always be something like \"PDP\".\r\n // },\r\n products: [product]\r\n },\r\n }\r\n };\r\n\r\n if (typeof dataLayer !== 'undefined') {\r\n dataLayer.push(event);\r\n }\r\n}\r\n\r\n//----------------------------------------------------------\r\n// Purchase Complete\r\n//----------------------------------------------------------\r\nfunction purchase(data: IMultiProductProps): void {\r\n\r\n // Convert internal event data to GA event data\r\n const products: IExtendedProduct[] = data.products.map(formatProductData);\r\n\r\n // Create an event rather than directly pushing to the data layer to enforce typing\r\n const event: GA.IPurchaseEvent = {\r\n event: 'purchase',\r\n ecommerce: {\r\n purchase: {\r\n actionField: {\r\n id: data.id,\r\n revenue: data.revenue,\r\n tax: data.tax,\r\n shipping: data.shipping,\r\n },\r\n orderSummary: {\r\n subTotal: data.revenue - (data.tax + data.shipping),\r\n shipping: data.shipping,\r\n tax: data.tax,\r\n transactionId: data.confirmationId,\r\n confirmationId: data.id\r\n },\r\n products: products,\r\n },\r\n }\r\n };\r\n\r\n // Only add optional fields if they are present in the source (instead of sending \"undefined\")\r\n data.coupon && (event.ecommerce.purchase.actionField.coupon = data.coupon);\r\n data.affiliation && (event.ecommerce.purchase.actionField.affiliation = data.affiliation);\r\n\r\n if (typeof dataLayer !== 'undefined') {\r\n dataLayer.push(event);\r\n }\r\n}\r\n\r\n//----------------------------------------------------------\r\n// Product Impressions\r\n//----------------------------------------------------------\r\nfunction impression(data: IMultiProductProps): void {\r\n\r\n // Convert internal event data to GA event data\r\n const impressions: GA.IEECImpression[] = data.products.map((product, idx) => {\r\n\r\n return {\r\n id: product.product.ItemId || UNKNOWN_VALUE,\r\n name: product.product.Name || UNKNOWN_VALUE,\r\n brand: brandCodeParser({ description: product.product.Description, appContext: data.context }) || UNKNOWN_VALUE,\r\n variant: (product.attributes && product.attributes['Wine Bottle Size']) || UNKNOWN_VALUE,\r\n position: idx,\r\n price: product.product.Price,\r\n\r\n list: data.list, // The list or collection to which the product belongs (e.g. Search Results)\r\n category: data.category || UNKNOWN_VALUE // The category to which the product belongs (e.g. Apparel). Use / as a delimiter to specify up to 5-levels of hierarchy (e.g. Apparel/Men/T-Shirts)\r\n };\r\n });\r\n\r\n // Create an event rather than directly pushing to the data layer to enforce typing\r\n const event: GA.IImpressionEvent = {\r\n event: 'impression',\r\n ecommerce: {\r\n currencyCode: CURRENCY_CODE,\r\n impressions: impressions\r\n }\r\n };\r\n\r\n if (typeof dataLayer !== 'undefined') {\r\n dataLayer.push(event);\r\n }\r\n}\r\n\r\n//----------------------------------------------------------\r\n// Purchase Complete\r\n//----------------------------------------------------------\r\nfunction checkout(data: IMultiProductProps): void {\r\n\r\n // Convert internal event data to GA event data\r\n const products: IExtendedProduct[] = data.products.map(formatProductData);\r\n\r\n // Create an event rather than directly pushing to the data layer to enforce typing\r\n const event: GA.ICheckoutStepEvent = {\r\n event: 'checkout',\r\n ecommerce: {\r\n checkout: {\r\n actionField: {\r\n step: data.step,\r\n },\r\n products: products,\r\n },\r\n }\r\n };\r\n\r\n // Not entirely standard, but include it anyway\r\n if (data.coupon) {\r\n event.ecommerce.checkout.actionField.coupon = data.coupon;\r\n }\r\n\r\n if (typeof dataLayer !== 'undefined') {\r\n dataLayer.push(event);\r\n }\r\n}\r\n\r\n//==============================================================================\r\n//==============================================================================\r\n\r\n//----------------------------------------------------------\r\n//----------------------------------------------------------\r\nexport function init(): void {\r\n subscribe(SUBSCRIBER_NAME, 'addToCart', addToCart);\r\n subscribe(SUBSCRIBER_NAME, 'removeFromCart', removeFromCart);\r\n subscribe(SUBSCRIBER_NAME, 'productDetailView', productDetailView);\r\n subscribe(SUBSCRIBER_NAME, 'purchase', purchase);\r\n subscribe(SUBSCRIBER_NAME, 'impression', impression);\r\n subscribe(SUBSCRIBER_NAME, 'checkout', checkout);\r\n}\r\n","//==============================================================================\r\n// Analytics Event Dispatcher\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\r\n// This totally destroys the plugin pattern, but it's difficult to use that pattern\r\n// in a module system, particularly with server-side rendering-friendly webpack chunks.\r\nimport { init as GA_init } from './google-analytics';\r\n\r\n//==============================================================================\r\n//==============================================================================\r\n// tslint:disable-next-line: no-any\r\ntype IEventHandler = (eventData: any) => void;\r\n\r\n// List of subscribers to a single event\r\ninterface IEventSubscribers {\r\n [subscriber: string]: IEventHandler;\r\n}\r\n\r\n//==============================================================================\r\n//==============================================================================\r\n\r\n// List of subscriptions, organized by event name and then subscriber name\r\nconst subscriptions: { [eventName: string]: IEventSubscribers } = {};\r\n\r\n//----------------------------------------------------------\r\n//----------------------------------------------------------\r\n// tslint:disable-next-line: no-any\r\nexport function publish(eventName: string, eventData: any): void {\r\n if (subscriptions[eventName]) {\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//----------------------------------------------------------\r\n//----------------------------------------------------------\r\nexport function subscribe(subscriber: string, eventName: string, handler: IEventHandler): void {\r\n // If it's a new event, create an entry\r\n if (!subscriptions[eventName]) {\r\n subscriptions[eventName] = {};\r\n }\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 to 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//----------------------------------------------------------\r\n// Perform all init functions here (ugh!)\r\n//----------------------------------------------------------\r\nGA_init();","/**\r\n * enum to define all message types used in INotificationMessage\r\n */\r\nexport const enum NotificationType {\r\n info = 'info',\r\n success = 'success',\r\n warning = 'warning',\r\n error = 'error',\r\n validation = 'validation',\r\n none = 'none'\r\n}\r\n","\r\n/**\r\n * internal subscription name values to be used\r\n *\r\n * authors should not be exposed to these values\r\n */\r\nexport enum SubscriptionCommerceValues {\r\n\r\n /**\r\n * commerce attribute name\r\n */\r\n SUBSCRIPTION_NAME = 'Subscription Name',\r\n\r\n /**\r\n * commerce attribute name\r\n */\r\n SUBSCRIPTION_FREQUENCY = 'Frequency',\r\n\r\n /**\r\n * commerce line attribute for identifying is subscription\r\n */\r\n SUBCRIPTION_LINE = 'IsSubscription',\r\n\r\n SUBSCRIPTION_PRODUCT = 'Add to Subscription',\r\n\r\n SUBSCRIPTION_DEFAULT_NAME = 'My Wine Box'\r\n}","import { IActionContext, IComponent, IComponentProps } from '@msdyn365-commerce/core';\r\nimport classnames from 'classnames';\r\nimport React, { useState } from 'react';\r\n\r\nimport { BaseCartState, getCartState, GlobalStateInput, ICartActionResult, ICartState } from '@msdyn365-commerce/global-state';\r\nimport { AttributeValue, CartLine, OrgUnitLocation, ProductAvailableQuantity, ProductDimension, SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\nimport { addCartLinesAsync, updateCartLinesAsync, updateLineDeliverySpecificationsAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/CartsDataActions.g';\r\n\r\nimport getNotificationMessage, { createNotificationMessage } from '../dataActions/get-notification-message';\r\nimport { NotificationType } from '../models/notification-message-type';\r\nimport { publish } from '../Utilities/analytics/analytics-dispatcher';\r\nimport { CartUtilities } from '../Utilities/cart-utils';\r\nimport CommerceAttributesParser from '../Utilities/commerce-attributes-parser';\r\nimport ProductType from '../Utilities/productType';\r\nimport { filterCartLines } from '../Utilities/subscription-manager';\r\n\r\nexport interface IAddToCartComponentProps extends IComponentProps<{ product: SimpleProduct; emailDeliveryModeCode?: string | undefined; keyedInPrice?: number | undefined }> {\r\n shouldNavigateToCart?: boolean;\r\n className?: string;\r\n addToCartText: string;\r\n outOfStockText: string;\r\n disabled?: boolean;\r\n quantity?: number;\r\n navigationUrl?: string;\r\n productAvailability?: ProductAvailableQuantity;\r\n getSelectedProduct?: Promise;\r\n isSubscriptionItem?: boolean;\r\n useElicitAddToCart: boolean;\r\n productTypeAttribute: AttributeValue | undefined;\r\n productAttributes: AttributeValue[];\r\n overrideOutOfStock?: boolean;\r\n onAdd?(result: ICartActionResult): void;\r\n onError?(result: IAddToCartFailureResult): void;\r\n}\r\n\r\nexport declare type ICartActionFailureReason = 'EMPTYINPUT' | 'MISSINGDIMENSION' | 'OUTOFSTOCK' | 'CARTACTIONFAILED' | 'MIXEDCART';\r\nexport interface IAddToCartFailureResult {\r\n failureReason: ICartActionFailureReason;\r\n\r\n stockLeft?: number;\r\n cartActionResult?: ICartActionResult;\r\n missingDimensions?: ProductDimension[];\r\n}\r\n\r\nexport interface IAddtoCartComponent extends IComponent {\r\n onClick(): (event: React.MouseEvent, props: IAddToCartComponentProps) => void;\r\n}\r\n\r\nconst buildGiftCardCartLine = (product: SimpleProduct, keyedInPrice?: number, quantity?: number, catalogId?: number, deliveryModeCode?: string): CartLine => {\r\n return {\r\n DeliveryMode: deliveryModeCode,\r\n CatalogId: catalogId || 0,\r\n Description: product.Description,\r\n EntryMethodTypeValue: 3,\r\n ItemId: product.ItemId,\r\n ProductId: product.RecordId,\r\n Quantity: quantity || 1,\r\n Price: keyedInPrice,\r\n NetPrice: keyedInPrice,\r\n GiftCardBalance: keyedInPrice,\r\n TrackingId: '',\r\n UnitOfMeasureSymbol: product.DefaultUnitOfMeasure,\r\n IsPriceKeyedIn: true,\r\n IsGiftCardLine: true\r\n };\r\n};\r\n\r\nconst updateCart = (props: IAddToCartComponentProps) => {\r\n setTimeout(async () => {\r\n const context = props.context;\r\n const cartInput = new GlobalStateInput('CARTSTATE', BaseCartState, context.actionContext.requestContext.apiSettings);\r\n const newCart = await getCartState(context.actionContext);\r\n context.actionContext.update(cartInput, newCart);\r\n await newCart.refreshCart({});\r\n }, 10);\r\n};\r\n\r\n// tslint:disable-next-line: cyclomatic-complexity max-func-body-length\r\nconst onClick = async (_event: React.MouseEvent, props: IAddToCartComponentProps, setDisabled: (disabled: boolean) => void): Promise => {\r\n const cartError = addToCartError(props);\r\n let productToAdd = props.data.product;\r\n\r\n if (cartError) {\r\n propogateError(props, cartError);\r\n return;\r\n }\r\n\r\n if (!(props.getSelectedProduct === undefined)) {\r\n productToAdd = (await props.getSelectedProduct) || props.data.product;\r\n }\r\n\r\n const cartState = await getCartState(props.context.actionContext);\r\n\r\n // Checking type of current Product Item before adding to cart\r\n const deliveryModeCode = props.productTypeAttribute?.TextValue === 'Ticket'\r\n ? ProductType.EventDeliveryMode\r\n : productToAdd.ItemId?.toLowerCase() === props.context.request.channel?.GiftCardItemId?.toLowerCase()\r\n ? props.context.request.channel?.EmailDeliveryModeCode\r\n : null;\r\n\r\n const productType = new ProductType();\r\n productType.check(deliveryModeCode, props.context);\r\n\r\n // Checking type of Product items which is already added in the CART.\r\n cartState.cart.CartLines?.find((product) => {\r\n productType.check(product.DeliveryMode, props.context);\r\n });\r\n\r\n // If it's a MIXED TYPE then don't proceed\r\n if (productType.isMixedProduct()) {\r\n propogateError(props, { failureReason: 'MIXEDCART' });\r\n return;\r\n }\r\n\r\n let message = (props.quantity! > 1) ?\r\n `${props.quantity} items added to your cart`\r\n : `${props.quantity} item added to your cart`;\r\n\r\n const eventAlreadyExist = cartState.cart.CartLines && cartState.cart.CartLines.find(cartLine => cartLine.ItemId === productToAdd.ItemId);\r\n\r\n if (props.isSubscriptionItem) {\r\n const subLines = filterCartLines(cartState.cart).subscriptionLines;\r\n const totalBottlesInCart = CartUtilities.countCartLineAmount(subLines);\r\n if (totalBottlesInCart + props.quantity! > 12) {\r\n getNotificationMessage( // eslint-disable-line\r\n createNotificationMessage({ message: `No more than 12 bottles per subscription. You currently have ${totalBottlesInCart} bottles added.`, messagetype: NotificationType.error }),\r\n props.context.actionContext\r\n );\r\n return;\r\n }\r\n }\r\n\r\n // All error conditions (except those generated by server Add requests) have been processed. It's safe to emit an event.\r\n publish('addToCart', {\r\n product: props.data.product,\r\n quantity: props.quantity,\r\n attributes: CommerceAttributesParser.getParsedAttributes(props.productAttributes),\r\n subscription: props.isSubscriptionItem,\r\n context: props.context,\r\n });\r\n\r\n // Check for TICKETS type. if cart already have item then we will just update the quantity.\r\n if (props.productTypeAttribute?.TextValue === 'Ticket' && eventAlreadyExist) {\r\n const quantityLimit: number = props.context.actionContext.requestContext.app.config.maxQuantityForCartLineItem || 10;\r\n\r\n // Don't continue if QTY is equal/Greater then MAX Quantity.\r\n if ((eventAlreadyExist.Quantity || 0) >= quantityLimit) { return; }\r\n\r\n // Adding Quantity to the current cartLine\r\n eventAlreadyExist.Quantity = Math.min((eventAlreadyExist.Quantity || 0) + (props.quantity || 0), quantityLimit);\r\n\r\n // Update Quantity\r\n await updateCartLinesAsync({ callerContext: props.context.actionContext }, cartState.cart.Id, [eventAlreadyExist])\r\n .then(updatedCart => {\r\n getNotificationMessage( // eslint-disable-line\r\n createNotificationMessage({ message, messagetype: NotificationType.success }),\r\n props.context.actionContext\r\n );\r\n updateCart(props);\r\n }).catch(error => {\r\n console.log('ERROR', error);\r\n return;\r\n });\r\n\r\n } else if (productToAdd.ItemId?.toLowerCase() === props.context.request.channel?.GiftCardItemId?.toLowerCase()) {\r\n const cartLineToUpdate = buildGiftCardCartLine(productToAdd, props.data.keyedInPrice, 1, 0, props.data.emailDeliveryModeCode);\r\n await addCartLinesAsync({ callerContext: props.context.actionContext }, cartState.cart.Id, [cartLineToUpdate], cartState.cart.Version ? cartState.cart.Version : null)\r\n .then(async updatedCart => {\r\n await cartState.refreshCart({});\r\n\r\n const giftMessage = 'Gift card added to your cart';\r\n\r\n getNotificationMessage( // eslint-disable-line\r\n createNotificationMessage({ message: giftMessage, messagetype: NotificationType.success }),\r\n props.context.actionContext\r\n );\r\n updateCart(props);\r\n })\r\n .catch(error => {\r\n console.log(error);\r\n return;\r\n });\r\n } else {\r\n await getAddToCartResult(props.useElicitAddToCart, props.context.actionContext, cartState, { product: productToAdd, count: props.quantity, additionalProperties: { asSubscriptionItem: props.isSubscriptionItem! } })\r\n .then(async result => {\r\n if (result.status === 'SUCCESS') {\r\n await cartState.refreshCart({});\r\n const caseType = (props.quantity! > 1) ? 'items' : 'item';\r\n message = `${props.quantity} ${caseType} added to your cart`;\r\n if (props.isSubscriptionItem) {\r\n message = `${props.quantity} ${caseType} added to your subscription box`;\r\n }\r\n\r\n getNotificationMessage( // eslint-disable-line\r\n createNotificationMessage({ message, messagetype: NotificationType.success }),\r\n props.context.actionContext\r\n );\r\n if (props.productTypeAttribute?.TextValue === 'Ticket') {\r\n const emailDeliveryModeCode = ProductType.EventDeliveryMode;\r\n const recentlyAddedCartLine = cartState.cart.CartLines && cartState.cart.CartLines.find(cartLine => cartLine.ItemId === productToAdd.ItemId);\r\n if (recentlyAddedCartLine && recentlyAddedCartLine.LineId !== emailDeliveryModeCode) {\r\n await updateLineDeliverySpecificationsAsync({ callerContext: props.context.actionContext },\r\n cartState.cart.Id,\r\n [{\r\n LineId: recentlyAddedCartLine.LineId ? recentlyAddedCartLine.LineId : '',\r\n DeliverySpecification: {\r\n DeliveryModeId: emailDeliveryModeCode,\r\n DeliveryPreferenceTypeValue: 1,\r\n DeliveryAddress: {\r\n }\r\n }\r\n }])\r\n .then(newCart => cartState.refreshCart({}));\r\n }\r\n }\r\n\r\n if (props.navigationUrl && props.shouldNavigateToCart) {\r\n window.location.assign(props.navigationUrl);\r\n }\r\n if (parent === top) {\r\n window.parent.postMessage({ url: window.location.href, version: cartState.cart.Version }, window.location.origin);\r\n }\r\n propogateResult(props, result);\r\n } else {\r\n propogateError(props, { failureReason: 'CARTACTIONFAILED', cartActionResult: result });\r\n setDisabled(false);\r\n }\r\n\r\n });\r\n }\r\n};\r\n\r\nconst getAddToCartResult = async (\r\n isElicitOnly: boolean,\r\n actionContext: IActionContext,\r\n cartState: ICartState,\r\n input: {\r\n product: SimpleProduct;\r\n count?: number;\r\n location?: OrgUnitLocation;\r\n additionalProperties?: { asSubscriptionItem: boolean };\r\n }): Promise => {\r\n if (isElicitOnly) {\r\n await cartState.refreshCart({});\r\n return new CartUtilities(actionContext, cartState).elicitAddProductToCart(input);\r\n } else {\r\n return cartState.addProductToCart(input);\r\n }\r\n};\r\n\r\nconst AddToCartComponentActions = {\r\n onClick: onClick\r\n};\r\n\r\nconst AddToCart: React.FC = (props: IAddToCartComponentProps) => {\r\n const [disabled, setDisabled] = useState(false);\r\n\r\n const onClickHandler = (event: React.MouseEvent) => { return AddToCartComponentActions.onClick(event, props, setDisabled); };\r\n return (\r\n \r\n {getLinkText(props)}\r\n \r\n );\r\n};\r\n\r\n// Set default props\r\nAddToCart.defaultProps = {\r\n quantity: 1\r\n};\r\n\r\nconst getLinkText = (props: IAddToCartComponentProps): string => {\r\n if (!shouldShowOutOfStock(props, false)) {\r\n return props.addToCartText;\r\n }\r\n\r\n return props.outOfStockText;\r\n};\r\n\r\nconst addToCartError = (props: IAddToCartComponentProps): IAddToCartFailureResult | undefined => {\r\n if (!props.data || !props.data.product.RecordId) {\r\n // No product exists, won't be able to add to cart\r\n return { failureReason: 'EMPTYINPUT' };\r\n }\r\n\r\n if (props.data.product.Dimensions) {\r\n const missingDimensions = props.data.product.Dimensions.filter(dimension => !(dimension.DimensionValue && dimension.DimensionValue.Value));\r\n\r\n if (missingDimensions.length > 0) {\r\n // At least one dimension with no value exists on the product, won't be able to add to cart\r\n return { failureReason: 'MISSINGDIMENSION', missingDimensions: missingDimensions };\r\n }\r\n }\r\n\r\n if (shouldShowOutOfStock(props, true)) {\r\n const availableQuantity = (props.productAvailability && props.productAvailability.AvailableQuantity) || 0;\r\n const stockLeft = Math.max(availableQuantity - props.context.app.config.outOfStockThreshold, 0);\r\n\r\n return { failureReason: 'OUTOFSTOCK', stockLeft: stockLeft };\r\n }\r\n\r\n // Only allow adding to cart if not showing out of stock\r\n return undefined;\r\n};\r\n\r\nconst shouldShowOutOfStock = (props: IAddToCartComponentProps, includeCurrentQuantity: boolean): boolean => {\r\n if (props.context.app.config.enableStockCheck === false) {\r\n // Out of stock turn off, don't bother showing out of stock\r\n return false;\r\n }\r\n\r\n if (props.overrideOutOfStock) {\r\n return false;\r\n }\r\n\r\n if (!props.data || !props.data.product.RecordId) {\r\n // No product exists, don't bother showing out of stock\r\n return false;\r\n }\r\n\r\n if (props.data.product.Dimensions) {\r\n if (props.data.product.Dimensions.find(dimension => !(dimension.DimensionValue && dimension.DimensionValue.Value))) {\r\n // At least one dimension with no value exists on the product, so also don't show out of stock\r\n return false;\r\n }\r\n }\r\n\r\n if ((props.data.product.ItemId?.toLowerCase() === props.context.request.channel?.GiftCardItemId?.toLowerCase()) || (\r\n props.productAvailability &&\r\n props.productAvailability.AvailableQuantity !== undefined &&\r\n props.productAvailability.AvailableQuantity >= Number(props.context.app.config.outOfStockThreshold) + (includeCurrentQuantity ? Number(props.quantity) : 1))) {\r\n return false;\r\n } else {\r\n // Out of stock\r\n return true;\r\n }\r\n};\r\n\r\nconst propogateResult = (props: IAddToCartComponentProps, result: ICartActionResult): void => {\r\n if (props.onAdd) {\r\n props.onAdd(result);\r\n }\r\n};\r\n\r\nconst propogateError = (props: IAddToCartComponentProps, result: IAddToCartFailureResult): void => {\r\n if (props.onError) {\r\n props.onError(result);\r\n }\r\n};\r\n\r\n// Following code is been replaced with 'AddToCart' in last line\r\n// @ts-ignore\r\n// export const AddToCartComponent: React.FunctionComponent = msdyn365Commerce.createComponent(\r\n// 'AddToCart',\r\n// { component: AddToCart, ...AddToCartComponentActions }\r\n// );\r\n\r\nexport const AddToCartAction = onClick;\r\nexport default AddToCart;","import * as React from 'react';\r\n\r\nimport { Image } from '@msdyn365-commerce/core';\r\nimport { CartLine, SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\nimport { filterCartLines } from '../../../Utilities/subscription-manager';\r\nimport { ISubscriptionsMinicartData } from '../subscriptions-minicart.data';\r\nimport { ISubscriptionsMinicartProps } from '../subscriptions-minicart.props.autogenerated';\r\n\r\ninterface IBottleCountDisplay {\r\n subscriptionProps: ISubscriptionsMinicartProps;\r\n}\r\n\r\n/**\r\n * declaration for component that renders a list that displays the percent off\r\n */\r\nexport class BottleCountDisplay extends React.Component {\r\n\r\n private readonly _maxBottleCount: number = 12;\r\n\r\n public render(): JSX.Element {\r\n return (\r\n
\r\n {this._fillBottleList(this._generateBottleListFromProducts().slice(0, this._maxBottleCount))}\r\n
\r\n );\r\n }\r\n\r\n private _fillBottleList(bottleList: JSX.Element[]): JSX.Element[] {\r\n for (let newBottleIndex = bottleList.length; newBottleIndex < this._maxBottleCount; newBottleIndex++) {\r\n bottleList.push(\r\n (\r\n
\r\n
\r\n {this._specializeIndex(newBottleIndex)}\r\n
\r\n )\r\n );\r\n }\r\n return bottleList;\r\n }\r\n\r\n private _generateBottleListFromProducts(): JSX.Element[] {\r\n let rollingIndex = 0;\r\n const fragments: JSX.Element[] = [];\r\n this._cartFilteredLines.subscriptionLines?.forEach((line) => {\r\n\r\n const gridSettings = this.props.subscriptionProps.context.actionContext.requestContext.gridSettings;\r\n const product = this._getProductFromLine(line);\r\n for (let lineIdx = 0; lineIdx < line.Quantity!; lineIdx++) {\r\n fragments.push((\r\n
\r\n {gridSettings && product &&\r\n \r\n }\r\n {this._specializeIndex(rollingIndex)}\r\n
\r\n ));\r\n rollingIndex++;\r\n }\r\n });\r\n return fragments;\r\n }\r\n\r\n private _getProductFromLine(line: CartLine): SimpleProduct | undefined {\r\n const { products: { result: products } } = this.props.subscriptionProps.data;\r\n return products?.find(product => product.ItemId === line.ItemId);\r\n }\r\n\r\n private _specializeIndex(currentIndex: number): JSX.Element | null {\r\n const {\r\n subscriptionsMinicart__discount10Percent,\r\n subscriptionsMinicart__discount15Percent\r\n } = this.props.subscriptionProps.resources;\r\n if (currentIndex === 3) {\r\n return
{subscriptionsMinicart__discount10Percent}
;\r\n } else if (currentIndex === 11) {\r\n return
{subscriptionsMinicart__discount15Percent}
;\r\n }\r\n return null;\r\n }\r\n\r\n private get _cartFilteredLines(): {\r\n subscriptionLines: CartLine[];\r\n lines: CartLine[];\r\n } {\r\n return filterCartLines(this.props.subscriptionProps.data.cart.result?.cart);\r\n }\r\n}","import { ICoreContext } from '@msdyn365-commerce/core-internal';\r\ninterface IBrandCodeProps {\r\n description?: string;\r\n appContext: ICoreContext<{\r\n // any is just matching the types here.\r\n // tslint:disable-next-line: no-any\r\n [x: string]: any;\r\n }>;\r\n}\r\n\r\ntype BrandCodeTable = {\r\n brandName: string;\r\n brandCode: string;\r\n}[];\r\n\r\n/**\r\n * for converting a brand code to a brand name\r\n *\r\n */\r\nexport function brandCodeParser({ description, appContext }: IBrandCodeProps): string {\r\n\r\n // for mocking\r\n // const brandCodeTable: BrandCodeTable = [{ brandName: '14Hands', brandCode: 'FTH' }];\r\n\r\n const brandCodeTable = appContext.app.config.brandCodeTable as BrandCodeTable;\r\n\r\n // this is a safety check to ensure that brand code table does NOT crash in local or\r\n // if brand code table is somehow not connecting right to the global config. it will\r\n // essentially act as if there are no brand codes declared - keeping how everything\r\n // looks originally\r\n if (!brandCodeTable) { return ''; }\r\n\r\n // a brand code may and may only appear in the first three characters of a string\r\n // we are lowercasing in the off-chance that the authors type them differently between\r\n // the sources\r\n const currentBrandCode = description && description.slice(0, 3).toLowerCase();\r\n const brandFound = brandCodeTable.find(brand => brand.brandCode.toLowerCase() === currentBrandCode);\r\n if (brandFound) { return brandFound.brandName; }\r\n return '';\r\n}","import { ICoreContext } from '@msdyn365-commerce/core';\r\n\r\n/**\r\n * ProductType for checking product Type\r\n */\r\n// tslint:disable-next-line: no-unnecessary-class\r\nexport default class ProductType {\r\n public static EventDeliveryMode:string = '40.5';\r\n private isWine:boolean = false;\r\n private isEvent:boolean = false;\r\n private isGiftCard:boolean = false;\r\n\r\n // TODO: Temporary solution till we get better solution in checking product type in Cart\r\n public check(DeliveryMode: string | undefined | null, context?: ICoreContext):void {\r\n if (DeliveryMode && DeliveryMode === (context?.request.channel?.EmailDeliveryModeCode || '40')) {\r\n this.isGiftCard = true;\r\n } else if (DeliveryMode && DeliveryMode === ProductType.EventDeliveryMode) {\r\n this.isEvent = true;\r\n } else {\r\n this.isWine = true;\r\n }\r\n }\r\n\r\n public isWineProduct(): boolean {\r\n return this.isWine && !this.isEvent && !this.isGiftCard;\r\n }\r\n\r\n public isMixedProduct(): boolean {\r\n return Number(this.isWine) + Number(this.isEvent) + Number(this.isGiftCard) >= 2;\r\n }\r\n}\r\n","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\n\r\nimport * as React from 'react';\r\n\r\nimport { clearSubscription } from '../../Utilities/subscription-manager';\r\nimport { IResetSubscriptionData } from './reset-subscription.data';\r\nimport { IResetSubscriptionProps } from './reset-subscription.props.autogenerated';\r\n\r\n/**\r\n *\r\n * ResetSubscription component\r\n * @extends {React.PureComponent>}\r\n */\r\nclass ResetSubscription extends React.PureComponent> {\r\n\r\n private _didClearSubscription: boolean = false;\r\n\r\n public render(): JSX.Element | null {\r\n if (!this._didClearSubscription && this.props.data.cart.result) {\r\n clearSubscription(this.props.data.cart.result, this.props.context)\r\n .then(() => this.props.telemetry.debug('[ResetSubscription] cleared subscription cart'))\r\n .catch((e) => this.props.telemetry.error('[ResetSubscription] failed to clear subscription cart', e));\r\n this._didClearSubscription = true;\r\n }\r\n return
;\r\n }\r\n}\r\n\r\nexport default ResetSubscription;\r\n","import { GetCheckoutCartInput } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ICartState } from '@msdyn365-commerce/global-state';\r\nimport { AsyncResult, AttributeValue, Cart, CartLine, CommerceProperty } from '@msdyn365-commerce/retail-proxy';\r\nimport { updateAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/CartsDataActions.g';\r\nimport { SubscriptionCommerceValues } from '../common/subscription-commerce.values';\r\n\r\nexport async function updateSubscription(cart: AsyncResult, commerceValues: CommerceProperty[], context: ICoreContext): Promise {\r\n const cartState = cart && cart.status === 'SUCCESS' && cart.result;\r\n if (\r\n !cartState ||\r\n !cartState.cart\r\n ) {\r\n context.telemetry.error('Failed to add subscription properties to Cart. Unable to load Cart');\r\n } else {\r\n commerceValues.forEach(newValue => { findAndUpdateLine(newValue, cartState.cart); });\r\n\r\n const updatedCart = await updateAsync({ callerContext: context.actionContext }, cartState.cart);\r\n context.actionContext.update(new GetCheckoutCartInput(context.request.apiSettings), updatedCart);\r\n\r\n await (await cart).refreshCart({});\r\n }\r\n}\r\n\r\nexport function isProductSubscribable(productAttributes?: AttributeValue[]): boolean {\r\n return !!productAttributes?.find(attr => attr.Name === SubscriptionCommerceValues.SUBSCRIPTION_PRODUCT)?.BooleanValue;\r\n}\r\n\r\nexport function getSubscriptionValues(cart?: Cart): { frequency: string | undefined; name: string | undefined } {\r\n const freq = cart?.ExtensionProperties?.find(ext => ext.Key === SubscriptionCommerceValues.SUBSCRIPTION_FREQUENCY);\r\n const name = cart?.ExtensionProperties?.find(ext => ext.Key === SubscriptionCommerceValues.SUBSCRIPTION_NAME);\r\n\r\n return { frequency: freq?.Value?.StringValue, name: name?.Value?.StringValue };\r\n}\r\n\r\nexport function isLineSubscriptionLine(line?: CartLine): boolean {\r\n return !!line?.ExtensionProperties?.find(ext => ext.Key === SubscriptionCommerceValues.SUBCRIPTION_LINE);\r\n}\r\n\r\ninterface ICategorizedLines {\r\n subscriptionLines: CartLine[];\r\n lines: CartLine[];\r\n}\r\nexport function filterCartLines(cart?: Cart): ICategorizedLines {\r\n const output: ICategorizedLines = {\r\n subscriptionLines: [],\r\n lines: [],\r\n };\r\n\r\n cart?.CartLines?.forEach(line => {\r\n const isSubscriptionLine = isLineSubscriptionLine(line);\r\n if (isSubscriptionLine) {\r\n output.subscriptionLines.push(line);\r\n } else {\r\n output.lines.push(line);\r\n }\r\n });\r\n\r\n return output;\r\n}\r\n\r\n/**\r\n * NOTE: WILL ONLY CLEAR TOP LEVEL NOT ITEMS\r\n */\r\nexport async function clearSubscription(cartState?: ICartState, context?: ICoreContext): Promise {\r\n if (!cartState || !context) { return; }\r\n\r\n const cart: Cart = cartState.cart;\r\n\r\n // add keys here to erase their string values\r\n const editObj = {\r\n [SubscriptionCommerceValues.SUBSCRIPTION_NAME]: true,\r\n [SubscriptionCommerceValues.SUBSCRIPTION_FREQUENCY]: true\r\n };\r\n\r\n // ensure extprops exists\r\n cart.ExtensionProperties = cart.ExtensionProperties || [];\r\n cart.ExtensionProperties.forEach(extension => {\r\n if (editObj[extension.Key!] && extension.Value) {\r\n extension.Value.StringValue = '';\r\n }\r\n });\r\n const updatedCart = await updateAsync({ callerContext: context.actionContext }, cart);\r\n context.actionContext.update(new GetCheckoutCartInput(context.request.apiSettings), updatedCart);\r\n}\r\n\r\n// im expecting to eventually turn this into a namespace class with a bunch of commerce attribute transformations\r\n// but its only one now so no point\r\nfunction findAndUpdateLine(changedProperty: CommerceProperty, cart: Cart): void {\r\n cart.ExtensionProperties = cart.ExtensionProperties || [];\r\n const property = cart.ExtensionProperties.find(extension => extension.Key === changedProperty.Key);\r\n if (property) {\r\n property.Value = changedProperty.Value;\r\n } else {\r\n cart.ExtensionProperties.push(changedProperty);\r\n }\r\n}\r\n","/*---------------------------------------------------------------------------------------------\r\n * Copyright (c) Microsoft Corporation. All rights reserved.\r\n * Licensed under the MIT License. See License.txt in the project root for license information.\r\n *--------------------------------------------------------------------------------------------*/\r\nimport { RichText, RichTextComponent } from '@msdyn365-commerce/core';\r\nimport { CommerceProperty } from '@msdyn365-commerce/retail-proxy';\r\nimport debounce from 'lodash/debounce';\r\nimport { observable, reaction } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\nimport { SubscriptionCommerceValues } from '../../common/subscription-commerce.values';\r\nimport { getSubscriptionValues, updateSubscription } from '../../Utilities/subscription-manager';\r\nimport { ISubscriptionBoxData } from './subscription-box.data';\r\nimport { IFrequencyTableData, ISubscriptionBoxProps } from './subscription-box.props.autogenerated';\r\n\r\nexport interface ISubscriptionBoxViewProps extends ISubscriptionBoxProps { }\r\n\r\nexport interface ISubscriptionBoxViewState {\r\n boxName: string;\r\n}\r\n\r\n/**\r\n *\r\n * SubscriptionBox component\r\n * @extends {React.Component>}\r\n */\r\n@observer\r\nclass SubscriptionBox extends React.Component, ISubscriptionBoxViewState> {\r\n\r\n /**\r\n * stores the user's typed name\r\n */\r\n @observable private _subscriptionBoxName: string = '';\r\n\r\n /**\r\n * stores the user's selected frequency, gets defaulted in constructor\r\n */\r\n @observable private _selectedFrequency: IFrequencyTableData | undefined;\r\n\r\n constructor(props: ISubscriptionBoxProps) {\r\n super(props);\r\n\r\n // debounce function now has typings and requires an intermediate function to use properly.\r\n // implement later. new typings declare DebouncedFunc<() => Promise> not () => Promise\r\n this._publishNameToCart = debounce(this._publishNameToCart.bind(this), 500) as unknown as () => Promise;\r\n this._onNameChange = this._onNameChange.bind(this);\r\n this._onFrequencyChange = this._onFrequencyChange.bind(this);\r\n this._submitSubscriptionToCart = this._submitSubscriptionToCart.bind(this);\r\n\r\n reaction(\r\n () => [this.props.data.cart?.result],\r\n () => {\r\n const values = getSubscriptionValues(this.props.data.cart.result?.cart);\r\n this._subscriptionBoxName = values.name!;\r\n if (values.name && this.props.config.allSubscriptionsLink && this.props.config.allSubscriptionsLink.destinationUrl) {\r\n window.location.replace(this.props.config.allSubscriptionsLink.destinationUrl);\r\n }\r\n }\r\n );\r\n }\r\n\r\n public render(): JSX.Element {\r\n if (!this.props.data.cart?.result) { return
; }\r\n const { subscriptionBox__name, subscriptionBox__delivery } = this.props.resources;\r\n const { className, headerText } = this.props.config;\r\n const values = getSubscriptionValues(this.props.data.cart.result.cart);\r\n return (\r\n
\r\n {headerText && this._optionalRichTextRender(headerText, 'subscription-box-header')}\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n {this._frequencyTable(values.frequency)}\r\n
\r\n
\r\n
\r\n );\r\n }\r\n\r\n /**\r\n * optionally renders richtext if the richtext exists, just a utility function for\r\n * not having to repeat conditionals all over the place\r\n *\r\n * @param richText rich text to render\r\n * @param greyText if the text is to be greyed, reference mock as to why\r\n */\r\n private _optionalRichTextRender(richText: RichText, className?: string): JSX.Element | null {\r\n return ;\r\n }\r\n\r\n /**\r\n * renders the JSX for the frequency table\r\n */\r\n private _frequencyTable(initialId?: string): JSX.Element {\r\n const { frequencyTable } = this.props.config;\r\n\r\n let firstId: string | undefined;\r\n if (!initialId && this._selectedFrequency) {\r\n firstId = this.props.config.frequencyTable?.find(freq => !!freq)?.id;\r\n }\r\n return (\r\n \r\n );\r\n }\r\n\r\n private async _submitSubscriptionToCart({ freq, name }: { freq?: boolean; name?: boolean }): Promise {\r\n\r\n // we need to parse this form's format into how the cart likes to\r\n // handle things\r\n const cartChanges: CommerceProperty[] = [];\r\n\r\n // start frequency attempt with the selected frequency\r\n let selectedFrequency: string | undefined = this._selectedFrequency?.id;\r\n\r\n // if they are submitting without touching, attempt to grab their current one in session\r\n if (!selectedFrequency) {\r\n selectedFrequency = getSubscriptionValues(this.props.data.cart.result?.cart).frequency;\r\n }\r\n\r\n // if they didn't have one in session and this is their submit attempt,\r\n // use the top level frequency. this should always be in sync with what they see as\r\n // they have never touched the dropdown if they reach here\r\n if (!selectedFrequency) {\r\n selectedFrequency = this.props.config.frequencyTable?.find(v => !!v)!.id;\r\n }\r\n\r\n cartChanges.push({\r\n Key: SubscriptionCommerceValues.SUBSCRIPTION_FREQUENCY,\r\n Value: {\r\n StringValue: selectedFrequency\r\n }\r\n });\r\n\r\n cartChanges.push({\r\n Key: SubscriptionCommerceValues.SUBSCRIPTION_NAME,\r\n Value: {\r\n StringValue: this._subscriptionBoxName\r\n }\r\n });\r\n\r\n await updateSubscription(this.props.data.cart, cartChanges, this.props.context);\r\n return;\r\n }\r\n\r\n private async _publishNameToCart(): Promise {\r\n return this._submitSubscriptionToCart({ name: true });\r\n }\r\n\r\n /**\r\n * change event for selecting a new frequency\r\n */\r\n private async _onFrequencyChange(event: React.ChangeEvent): Promise {\r\n this._selectedFrequency = this.props.config.frequencyTable?.find(frequncy => frequncy.id === event.target.value);\r\n return this._submitSubscriptionToCart({ freq: true });\r\n }\r\n\r\n /**\r\n * change event for the subscription name\r\n */\r\n private async _onNameChange(event: React.ChangeEvent): Promise {\r\n this._subscriptionBoxName = event.target.value;\r\n return this._publishNameToCart();\r\n }\r\n}\r\n\r\nexport default SubscriptionBox;"],"sourceRoot":""}