{"version":3,"file":"ProductView.min.js","sources":["ProductView.js"],"sourcesContent":["(function ($, _, root, undefined) {\r\n 'use strict';\r\n\r\n var assetId = 'uc209-productview';\r\n\r\n // Main product controller\r\n function productViewController($viewContainer, productViewModel) {\r\n var model = productViewModel;\r\n var pubsub = root.PubSub;\r\n var utils = new util();\r\n var say = new notificator(pubsub, utils);\r\n var variantProcessorsMap = {};\r\n var flags = null;\r\n var cart = null;\r\n var rating = null;\r\n var gallery = null;\r\n var priceTotals = null;\r\n var packageComponents = null;\r\n var groupingProduct = null;\r\n\r\n if (model.discountID) {\r\n console.info(model.title + ' - Discount ID: ' + model.discountID);\r\n }\r\n\r\n return {\r\n init: function () {\r\n // Not optimal, but the call stack is complex with many dependecies and not async.\r\n // These causes problems if do load variant-selector-provider only in the initVariantsProcessor\r\n // Will be solved when ProductView.js will be rewritten in modules and web-components\r\n importShim('/components/archive/product/variant-selector-provider/variant-selector-provider.js').then(() => {\r\n var quantityDiscounts = new quantityDiscountsProcessor($viewContainer, model);\r\n var externalTracking = new externalTrackingProcessor();\r\n\r\n priceTotals = new priceTotalsProcessor($viewContainer, utils, model);\r\n priceTotals.init();\r\n\r\n if (model.isProductWithVariants) {\r\n var preselectedVariants = _getPreselectedVariantsFromQueryString();\r\n const options = {\r\n $productContainer: $viewContainer,\r\n productModel: model,\r\n priceTotals: priceTotals,\r\n quantityDiscountsProcessorInstance: quantityDiscounts,\r\n externalTrackingProcessorInstance: externalTracking,\r\n preselectedVariants: preselectedVariants,\r\n enableHistoryState: true,\r\n metadata: model.metadata,\r\n say: say,\r\n pubsub: pubsub,\r\n utils: utils,\r\n };\r\n initVariantsProcessor(options, variantProcessorsMap);\r\n }\r\n\r\n quantityDiscounts.renderQuantityDiscounts();\r\n\r\n if (model.packageComponentProducts) {\r\n _.each(model.packageComponentProducts, function (packageComponent) {\r\n if (packageComponent.isMainProductOfProductWithVariants) {\r\n const $componentProductContainer = $viewContainer.find('.js-component-products-list .js-component-product[data-uniqueid=\"' + packageComponent.uniqueId + '\"]');\r\n packageComponent.variantRelImageMatchRegExp = model.variantRelImageMatchRegExp;\r\n const options = {\r\n $productContainer: $componentProductContainer,\r\n productModel: packageComponent,\r\n priceTotals: priceTotals,\r\n metadata: model.metadata,\r\n say: say,\r\n pubsub: pubsub,\r\n utils: utils,\r\n };\r\n initVariantsProcessor(options, variantProcessorsMap);\r\n }\r\n });\r\n packageComponents = new packageComponentProcessor($viewContainer, model, utils);\r\n }\r\n\r\n if (model.groupingComponents) {\r\n groupingProduct = new groupingProductProcessor($viewContainer, model, utils, say, pubsub, priceTotals, variantProcessorsMap);\r\n groupingProduct.init();\r\n }\r\n\r\n if (model.additionalProducts) {\r\n _.each(model.additionalProducts, function (additionalProduct) {\r\n if (additionalProduct.isProductWithVariants) {\r\n const $additionalProductContainer = $viewContainer.find('.js-additional-product[data-uniqueid=\"' + additionalProduct.uniqueId + '\"]');\r\n additionalProduct.variantRelImageMatchRegExp = model.variantRelImageMatchRegExp;\r\n const options = {\r\n $productContainer: $additionalProductContainer,\r\n productModel: additionalProduct,\r\n priceTotals: priceTotals,\r\n metadata: model.metadata,\r\n say: say,\r\n pubsub: pubsub,\r\n utils: utils,\r\n };\r\n initVariantsProcessor(options, variantProcessorsMap);\r\n }\r\n });\r\n }\r\n\r\n // Initial calculation - some quantities may be pre-set\r\n priceTotals.updatePriceTotals();\r\n\r\n cart = new cartProcessor($viewContainer, model, say, pubsub, variantProcessorsMap, utils, priceTotals);\r\n cart.init();\r\n\r\n flags = new flagsProcessor($viewContainer, model);\r\n flags.init();\r\n\r\n rating = new ratingProcessor($viewContainer, model, pubsub);\r\n rating.init();\r\n\r\n var shoppingListHandler = new shoppingListProcessor($viewContainer, model, say, utils, variantProcessorsMap);\r\n shoppingListHandler.init();\r\n\r\n if (model.isPrintEnabled) {\r\n var printHanlder = new printProcessor($viewContainer, model);\r\n printHanlder.init();\r\n }\r\n\r\n var pdfHadnler = new pdfProcessor($viewContainer, model);\r\n pdfHadnler.init();\r\n\r\n if (model.isPriceRequestEnabled) {\r\n var priceRequestHandler = priceRequestProcessor($viewContainer);\r\n priceRequestHandler.init();\r\n }\r\n\r\n gallery = new galleryProcessor($viewContainer, model);\r\n gallery.init();\r\n\r\n externalTracking.reportProductsView($viewContainer, model);\r\n\r\n var enableRelationExtensionDataProcessing = model.isProductRelationsExtensionEnabled && model.isProductWithVariants && model.additionalProducts && model.additionalProducts.length;\r\n if (enableRelationExtensionDataProcessing) {\r\n var relExtDataProcessor = new relationExtensionDataProcessor($viewContainer, model, variantProcessorsMap, priceTotals, pubsub);\r\n relExtDataProcessor.init();\r\n }\r\n\r\n const similarProductsSelect = $viewContainer.find('select.js-similar-products-selector');\r\n if (similarProductsSelect.length) {\r\n similarProductsSelect.on('change', (e) => window.location = e.target.selectedOptions[0].dataset.url);\r\n }\r\n\r\n if (model.showWarehouseStockInfo) {\r\n const warehouseStocks = $viewContainer.find('stock-info-list').get(0);\r\n if (warehouseStocks) {\r\n warehouseStocks.setData(model.warehouseStocks);\r\n }\r\n }\r\n });\r\n }\r\n };\r\n\r\n function _getPreselectedVariantsFromQueryString() {\r\n var result = {}, queryString = location.search.slice(1), re = /sel(?:\\:|%3a){1}([^&=]+)=([^&]*)/gi, match;\r\n\r\n while ((match = re.exec(queryString))) {\r\n var paramKey = decodeURIComponent(match[1]).toLowerCase();\r\n var paramValue = decodeURIComponent(match[2].replace(/\\+/g, ' ')).toLowerCase();\r\n result[paramKey] = paramValue;\r\n }\r\n\r\n return result;\r\n }\r\n }\r\n\r\n root.productViewController = productViewController;\r\n\r\n $(function () {\r\n if (root.umwAssets && root.umwAssets[assetId]) {\r\n root.umwAssets[assetId].forEach(function (ctx) {\r\n if (ctx) {\r\n var mainPanelId = ctx.uniqueId;\r\n var $mainPanel = $(`#${mainPanelId}`);\r\n\r\n if ($mainPanel.length === 1) {\r\n var controller = new productViewController($mainPanel, ctx);\r\n controller.init();\r\n } else if ($mainPanel.length === 0) {\r\n console.warn(assetId + ': product view main panel element was not found by id#' + mainPanelId);\r\n } else {\r\n console.warn(assetId + ': found >1 product view main panel elements with id#' + mainPanelId);\r\n }\r\n }\r\n });\r\n }\r\n });\r\n\r\n // Notifications processor\r\n function notificator(pubsub, utils) {\r\n function _notify(message, notificationType, timeout) {\r\n if (typeof message === 'object' && message !== null) {\r\n message = utils.extractErrorMessageFromResponse(message);\r\n }\r\n\r\n if (pubsub) {\r\n pubsub.publish('notification.' + notificationType, { text: message, timeout: timeout, maxVisible: 3});\r\n } else {\r\n var notificationTypeMap = {\r\n 'error': 'error',\r\n 'alert': 'log',\r\n 'success': 'log',\r\n 'warning': 'warn'\r\n };\r\n\r\n root.console[notificationTypeMap[notificationType]].apply(this, [message]);\r\n }\r\n }\r\n\r\n return {\r\n warning: function (message, timeout) {\r\n _notify(message, 'warning', timeout || false);\r\n },\r\n error: function (message, timeout) {\r\n _notify(message, 'error', timeout || false);\r\n },\r\n success: function (message, timeout) {\r\n _notify(message, 'success', timeout || 30000);\r\n }\r\n };\r\n }\r\n\r\n // Variants processor\r\n function variantsProcessor($productContainer, product, metadata, preselectedVariants, say, pubsub, priceTotalsController, quantityDiscounts, externalTracking, utils, enableHistoryState) {\r\n var $container = $productContainer;\r\n var $declaredVariantSelectors = utils.$getProductContainerElements($container, '.js-variant-selector');\r\n\r\n var variantControllers = {};\r\n var isVariantProductShown = false;\r\n var suppressVariantProductDetailsLoading = false;\r\n\r\n var variantsState = { controlId: product.uniqueId, selectedVariantProd: null };\r\n var suppressVariantChangedEvent = false;\r\n\r\n var currentlyUnavailableVariantsMap = {};\r\n\r\n function _onVariantSelectionChanged(changedVariantType, newVariantValue) {\r\n var changedVariantController = _getVariantControllerById(changedVariantType.id);\r\n var prevVariantValue = changedVariantController.selectedValue;\r\n changedVariantController.selectedValue = newVariantValue || 0;\r\n\r\n var selectedVariantValues = _getSelectedVariants();\r\n var selectedVariantProduct = _getSelectedVariantProduct(selectedVariantValues);\r\n\r\n if (!suppressVariantProductDetailsLoading) {\r\n if (selectedVariantProduct) {\r\n const selectedVariant = changedVariantType.variants.find(x => x.id === newVariantValue);\r\n _loadVariantProductDetails(selectedVariantProduct, selectedVariant);\r\n } else if (isVariantProductShown) {\r\n // De-selection, or unavailable dimensions combination - load main product and show\r\n _loadVariantProductDetails();\r\n }\r\n }\r\n\r\n if (quantityDiscounts) {\r\n quantityDiscounts.renderQuantityDiscounts(selectedVariantValues);\r\n }\r\n\r\n pubsub.publish('variantprocessor.variant.changed', [newVariantValue, prevVariantValue, changedVariantController]);\r\n }\r\n\r\n function _filterUnavailableVariants(newVariantValue) {\r\n var selectedVariantValues = [];\r\n Object.values(variantControllers).forEach(variantController => {\r\n if (variantController.selectedValue > 0) {\r\n selectedVariantValues.push(variantController.selectedValue);\r\n }\r\n });\r\n\r\n if (newVariantValue) {\r\n selectedVariantValues = [newVariantValue];\r\n } else if (newVariantValue == 0) {\r\n currentlyUnavailableVariantsMap = {};\r\n }\r\n\r\n const isAnyVariantSelected = selectedVariantValues.length > 0;\r\n // set unavailable first\r\n product.variantProducts.forEach(variantProduct => {\r\n var isProductForCurrentSelection = selectedVariantValues.every(selectedVariantOption => variantProduct.variants.find(x => x === selectedVariantOption));\r\n if (!isAnyVariantSelected || isProductForCurrentSelection) {\r\n variantProduct.variants.forEach(variantId => {\r\n currentlyUnavailableVariantsMap[variantId] = { message: variantProduct.availabilityMessage, disabled: !variantProduct.exists };\r\n });\r\n }\r\n });\r\n // set available for selected variant values\r\n product.variantProducts.forEach(variantProduct => {\r\n var isProductForCurrentSelection = selectedVariantValues.every(selectedVariantOption => variantProduct.variants.find(x => x === selectedVariantOption));\r\n if ((!isAnyVariantSelected || isProductForCurrentSelection) && (variantProduct.isAvailable || product.isPriceRequestEnabled && variantProduct.exists)) {\r\n variantProduct.variants.forEach(variantId => {\r\n delete currentlyUnavailableVariantsMap[variantId];\r\n });\r\n }\r\n });\r\n\r\n _.each(variantControllers, function (variantController) {\r\n var preselectSingleAvailable = (_.isEmpty(preselectedVariants) || !preselectedVariants[variantController.variantType.name.toLowerCase()]) && variantController.variantType.variants.length === 1;\r\n variantController.selector.filterVariants(currentlyUnavailableVariantsMap, preselectSingleAvailable);\r\n });\r\n }\r\n\r\n function _processVariants() {\r\n var variantTypeToProductInfoMap = {};\r\n\r\n var selectedVariantTypes = [];\r\n var selectedVariantOptions = [];\r\n _.each(variantControllers, variantController => {\r\n if (variantController.selectedValue > 0) {\r\n selectedVariantTypes.push(variantController.variantType.id);\r\n selectedVariantOptions.push(variantController.selectedValue);\r\n }\r\n });\r\n\r\n const isAnyVariantSelected = selectedVariantOptions.length > 0;\r\n\r\n product.variantProducts.forEach(variantProduct => {\r\n var isProductForCurrentSelection = selectedVariantOptions.every(selectedVariantOption => variantProduct.variants.find(x => x === selectedVariantOption));\r\n if (!isAnyVariantSelected || isProductForCurrentSelection) {\r\n variantProduct.variants.forEach(variantId => {\r\n if (variantProduct.discountInfo) {\r\n variantTypeToProductInfoMap[variantId] = {\r\n discountInfo: variantProduct.discountInfo\r\n };\r\n }\r\n });\r\n }\r\n });\r\n\r\n _.each(variantControllers, function (variantController) {\r\n variantController.selector.processVariants(variantTypeToProductInfoMap);\r\n });\r\n }\r\n\r\n function _loadVariantProductDetails(variantProduct, selectedVariant) {\r\n var beforeLoadEvent = $.Event('variantsprocessor:beforeloadvariantproduct');\r\n $container.trigger(beforeLoadEvent, [variantProduct, selectedVariant]);\r\n\r\n if (beforeLoadEvent.isDefaultPrevented()) {\r\n isVariantProductShown = !!variantProduct;\r\n return;\r\n }\r\n\r\n $.blockUI({ message: '' });\r\n\r\n var selectedVariants = variantProduct ? variantProduct.variants : [];\r\n var $sellPriceFormatted = utils.$getProductContainerElements($container, '.js-sellprice-formatted');\r\n const isSellPriceVisible = $sellPriceFormatted.length > 0 && $sellPriceFormatted.is(':visible');\r\n\r\n $.ajax({\r\n url: root.R + 'handlers/public/productdata.ashx',\r\n type: 'GET',\r\n data: {\r\n a: 'GetDimDetails',\r\n ItemID: product.itemId,\r\n Dim1: selectedVariants[0] !== undefined ? selectedVariants[0] : 0,\r\n Dim2: selectedVariants[1] !== undefined ? selectedVariants[1] : 0,\r\n Dim3: selectedVariants[2] !== undefined ? selectedVariants[2] : 0,\r\n CanHandleDisallowedBuyDims: true,\r\n ImageWidth: product.previewImageWidth,\r\n ImgMod: product.previewImageMode,\r\n InclVat: product.sellPrice ? product.sellPrice.inclVat : null,\r\n includeWarehouseStock: product.showWarehouseStockInfo,\r\n priceVisible: isSellPriceVisible\r\n }\r\n })\r\n .always($.unblockUI)\r\n .done(function (variantProductDetails) {\r\n _updateViewProductWithNewData(variantProductDetails);\r\n\r\n if (enableHistoryState === true) {\r\n _updateHistory(variantProductDetails);\r\n }\r\n\r\n pubsub.publish('variantprocessor.variantproduct.updated', variantProductDetails);\r\n })\r\n .fail(function (errorResponse) {\r\n say.error(errorResponse);\r\n });\r\n\r\n function _updateViewProductWithNewData(newData) {\r\n // Note: all raw prices, discount percent, price2, price3, ean, measurements, weight and all other dimension-specific possible values are not supported at the moment (20.09.2018)\r\n product.isMainProductOfProductWithVariants = newData.IsMainProd;\r\n product.isVariantProductOfProductWithVariants = isVariantProductShown = !newData.IsMainProd;\r\n var $priceFromText = utils.$getProductContainerElements($container, '.js-price-fromtext');\r\n if ($priceFromText.length > 0) {\r\n $priceFromText.toggle(product.isMainProductOfProductWithVariants);\r\n }\r\n\r\n product.productId = newData.ProductID;\r\n $container.data('productid', product.productId);\r\n\r\n product.prodno = newData.ProdNo;\r\n utils.$getProductContainerElements($container, '.js-product-number').text(product.prodno);\r\n\r\n product.title = newData.FullTitle;\r\n utils.$getProductContainerElements($container, '.js-product-title').text(product.title);\r\n\r\n if (externalTracking) {\r\n externalTracking.reportProductDetailsView(product.productId);\r\n }\r\n\r\n if (newData.ImageURL) {\r\n product.mainImage = {\r\n id: newData.ImageID,\r\n title: newData.ImageText,\r\n description: newData.ImageText,\r\n actualWidth: newData.ImageActualWidth,\r\n actualHeight: newData.ImageActualHeight,\r\n thumbnailUrl: newData.ImageRelURL,\r\n previewUrl: newData.ImageURL,\r\n fullSizeUrl: newData.ImageLBURL,\r\n displayWidth: newData.ImagePreviewDisplayWidth,\r\n displayHeight: newData.ImagePreviewDisplayHeight\r\n };\r\n\r\n var $mainImage = utils.$getProductContainerElements($container, '.js-product-mainimage');\r\n if ($mainImage.length > 0) {\r\n $mainImage.attr('src', product.mainImage.previewUrl);\r\n $mainImage.attr('alt', product.mainImage.title);\r\n\r\n $mainImage.attr('data-imageid', product.mainImage.id);\r\n $mainImage.data('imageid', product.mainImage.id);\r\n\r\n if (product.mainImage.displayWidth && product.mainImage.displayHeight) {\r\n $mainImage.attr('width', product.mainImage.displayWidth);\r\n $mainImage.attr('height', product.mainImage.displayHeight);\r\n }\r\n\r\n if (product.galleryId) {\r\n var $mainImageGalleryLink = $mainImage.closest('[data-fancybox=\"' + product.galleryId + '\"]');\r\n if ($mainImageGalleryLink.length === 1) {\r\n $mainImageGalleryLink.attr('href', product.mainImage.fullSizeUrl);\r\n\r\n $mainImageGalleryLink.attr('data-caption', product.mainImage.description);\r\n $mainImageGalleryLink.data('caption', product.mainImage.description);\r\n\r\n $mainImageGalleryLink.attr('data-width', product.mainImage.actualWidth);\r\n $mainImageGalleryLink.data('width', product.mainImage.actualWidth);\r\n\r\n $mainImageGalleryLink.attr('data-height', product.mainImage.actualHeight);\r\n $mainImageGalleryLink.data('height', product.mainImage.actualHeight);\r\n }\r\n }\r\n }\r\n }\r\n\r\n product.stockText = newData.StockText;\r\n product.stockColor = newData.StockColor;\r\n\r\n var oldStockCssClass = product.stockCssClass;\r\n product.stockCssClass = newData.StockCssClass;\r\n\r\n var $stockText = utils.$getProductContainerElements($container, '.js-stock-text');\r\n\r\n if ($container.hasClass(oldStockCssClass)) $container.removeClass(oldStockCssClass);\r\n if ($stockText.hasClass(oldStockCssClass)) $stockText.removeClass(oldStockCssClass);\r\n\r\n if (product.stockCssClass) {\r\n $container.addClass(product.stockCssClass);\r\n $stockText.addClass(product.stockCssClass);\r\n }\r\n\r\n var hasDiscountCssClass = \"has-discount\";\r\n if (newData.HasDiscount && !$container.hasClass(hasDiscountCssClass)) {\r\n $container.addClass(hasDiscountCssClass);\r\n } else if (!newData.HasDiscount && $container.hasClass(hasDiscountCssClass)) {\r\n $container.removeClass(hasDiscountCssClass);\r\n }\r\n\r\n var $addProductToCart = utils.$getProductContainerElements($container, '.js-add-product-to-cart');\r\n var $vippsHurtigkasseButton = utils.$getProductContainerElements($container, '.js-vipps-hurtigkasse-button');\r\n if (newData.AllowBuy) {\r\n $addProductToCart.show();\r\n $vippsHurtigkasseButton.show();\r\n } else {\r\n $addProductToCart.hide();\r\n $vippsHurtigkasseButton.hide();\r\n }\r\n\r\n var stockDataColorVariable = $stockText.data('style-color-variable');\r\n\r\n if ($stockText.length > 0) {\r\n $stockText.text(product.stockText);\r\n if ($stockText.data('update-style-color') !== false) { // for backwards compatibility\r\n $stockText.css('color', product.stockColor || 'inherit');\r\n }\r\n if (stockDataColorVariable) {\r\n if(product.stockColor && product.stockColor.length > 0){\r\n $stockText[0].style.setProperty(stockDataColorVariable, product.stockColor);\r\n } else {\r\n $stockText.removeAttr('style');\r\n }\r\n }\r\n }\r\n\r\n if (product.sellPrice) {\r\n product.sellPrice.formatted = newData.Price;\r\n product.sellPrice.raw = newData.PriceRaw; // not available in the incoming data set\r\n\r\n var $sellPriceFormatted = utils.$getProductContainerElements($container, '.js-sellprice-formatted');\r\n if ($sellPriceFormatted.length > 0) {\r\n $sellPriceFormatted.text(product.sellPrice.formatted);\r\n }\r\n }\r\n\r\n if (product.sellPriceWithVAT) {\r\n product.sellPriceWithVAT.formatted = newData.PriceInclVat;\r\n delete product.sellPriceWithVAT.raw; // not available in the incoming data set\r\n\r\n var $sellPriceWithVatFormatted = utils.$getProductContainerElements($container, '.js-sellprice-withvat-formatted');\r\n if ($sellPriceWithVatFormatted.length > 0) {\r\n $sellPriceWithVatFormatted.text(product.sellPriceWithVAT.formatted);\r\n }\r\n }\r\n\r\n if (product.sellPriceWithoutVAT) {\r\n product.sellPriceWithoutVAT.formatted = newData.PriceExclVat;\r\n delete product.sellPriceWithoutVAT.raw; // not available in the incoming data set\r\n\r\n var $sellPriceWithoutVatFormatted = utils.$getProductContainerElements($container, '.js-sellprice-withoutvat-formatted');\r\n if ($sellPriceWithoutVatFormatted.length > 0) {\r\n $sellPriceWithoutVatFormatted.text(product.sellPriceWithoutVAT.formatted);\r\n }\r\n }\r\n\r\n if (product.beforePrice) {\r\n product.beforePrice.formatted = newData.OriginalPrice;\r\n delete product.beforePrice.raw; // not available in the incoming data set\r\n\r\n var $beforePriceFormatted = utils.$getProductContainerElements($container, '.js-beforeprice-formatted');\r\n if ($beforePriceFormatted.length > 0) {\r\n var $beforePriceElements = utils.$getProductContainerElements($container, '.js-beforeprice-value, .js-beforeprice-label').add($beforePriceFormatted);\r\n if (newData.HasDiscount) {\r\n $beforePriceFormatted.text(product.beforePrice.formatted);\r\n $beforePriceElements.show();\r\n $beforePriceElements.parent().removeClass('no-beforeprice-value');\r\n } else {\r\n $beforePriceElements.hide();\r\n $beforePriceElements.parent().addClass('no-beforeprice-value');\r\n }\r\n }\r\n }\r\n\r\n if (product.discountPrice) {\r\n product.discountPrice.formatted = newData.Discount;\r\n delete product.discountPrice.raw; // not available in the incoming data\r\n\r\n var $discountPriceFormatted = utils.$getProductContainerElements($container, '.js-discountprice-formatted');\r\n if ($discountPriceFormatted.length > 0) {\r\n var $discountPriceElements = utils.$getProductContainerElements($container, '.js-discountprice-value, .js-discountprice-label').add($discountPriceFormatted);\r\n\r\n if (newData.HasDiscount && product.discountPrice.formatted) {\r\n $discountPriceFormatted.text(product.discountPrice.formatted);\r\n\r\n $discountPriceElements.show();\r\n } else {\r\n $discountPriceElements.hide();\r\n }\r\n }\r\n }\r\n\r\n if (product.discountPercent) {\r\n product.discountPercent.formatted = newData.DiscountPercent;\r\n delete product.discountPercent.raw; // not available in the incoming data\r\n\r\n var $discountPercentFormatted = utils.$getProductContainerElements($container, '.js-discountpercent-formatted');\r\n if ($discountPercentFormatted.length > 0) {\r\n var $discountPercentElements = utils.$getProductContainerElements($container, '.js-discountpercent-value, .js-discountpercent-label').add($discountPercentFormatted);\r\n\r\n if (newData.HasDiscount && product.discountPercent.formatted) {\r\n $discountPercentFormatted.text('-' + product.discountPercent.formatted + '%');\r\n\r\n $discountPercentElements.show();\r\n } else {\r\n $discountPercentElements.hide();\r\n }\r\n }\r\n }\r\n\r\n if (product.discountToDate) {\r\n product.discountToDate.formatted = newData.DiscountToDate;\r\n delete product.discountToDate.raw; // not available in the incoming data\r\n\r\n var $discountToDateFormatted = utils.$getProductContainerElements($container, '.js-discounttodate-formatted');\r\n if ($discountToDateFormatted.length > 0) {\r\n var $discountToDateElements = utils.$getProductContainerElements($container, '.js-discounttodate-value, .js-discounttodate-label').add($discountToDateFormatted);\r\n\r\n if (newData.HasDiscount && product.discountToDate.formatted) {\r\n $discountToDateFormatted.text(product.discountToDate.formatted);\r\n\r\n $discountToDateElements.show();\r\n } else {\r\n $discountToDateElements.hide();\r\n }\r\n }\r\n }\r\n\r\n if (newData.DiscountID) {\r\n console.info(newData.FullTitle + ' - Discount ID: ' + newData.DiscountID);\r\n }\r\n\r\n if (product.comparablePrice) {\r\n product.comparablePrice.formatted = newData.ComparablePrice;\r\n delete product.comparablePrice.raw; // not available in the incoming data set\r\n\r\n var $comparablePriceFormatted = utils.$getProductContainerElements($container, '.js-comparableprice-formatted');\r\n if ($comparablePriceFormatted.length > 0) {\r\n $comparablePriceFormatted.text(product.comparablePrice.formatted);\r\n }\r\n }\r\n\r\n if (product.factorPrice) {\r\n product.factorPrice.formatted = newData.FactorPrice;\r\n delete product.factorPrice.raw; // not available in the incoming data set\r\n\r\n var $factorPriceFormatted = utils.$getProductContainerElements($container, '.js-factor-price-formatted');\r\n if ($factorPriceFormatted.length > 0) {\r\n $factorPriceFormatted.text(product.factorPrice.formatted);\r\n }\r\n }\r\n\r\n if (product.productInFactorPrice) {\r\n product.productInFactorPrice.formatted = newData.ProductInFactorPrice;\r\n delete product.productInFactorPrice.raw; // not available in the incoming data set\r\n\r\n var $productInFactorPriceFormatted = utils.$getProductContainerElements($container, '.js-product-in-factor-price-formatted');\r\n if ($productInFactorPriceFormatted.length > 0) {\r\n $productInFactorPriceFormatted.text(product.productInFactorPrice.formatted);\r\n }\r\n }\r\n\r\n var $replacementProductContainer = utils.$getProductContainerElements($container, '.js-replacement-product-container');\r\n if ($replacementProductContainer.length > 0) {\r\n if (newData.ReplacementProductInfo) {\r\n $replacementProductContainer.empty().html(newData.ReplacementProductInfo).show();\r\n } else {\r\n $replacementProductContainer.empty().hide();\r\n }\r\n }\r\n\r\n priceTotalsController.updatePriceTotals();\r\n\r\n // Supplier order info\r\n const supplierOrderInfoTooltip = utils.$getProductContainerElements($container, 'cms-tooltip').get(0);\r\n\r\n if (supplierOrderInfoTooltip) {\r\n const supplierOrderInfo = supplierOrderInfoTooltip.shadowRoot.querySelector('supplier-order-info');\r\n const $stockTextInfoIcon = utils.$getProductContainerElements($container, '.js-stock-text-info');\r\n\r\n if (supplierOrderInfo) {\r\n if (newData.InSupplierOrder === true) {\r\n supplierOrderInfoTooltip.visible = true;\r\n supplierOrderInfo.update(newData.ProductID);\r\n $stockTextInfoIcon.show();\r\n } else {\r\n supplierOrderInfoTooltip.visible = false;\r\n $stockTextInfoIcon.hide();\r\n }\r\n } else {\r\n console.warn('Supplier order info element not found.');\r\n }\r\n } else {\r\n console.warn('Supplier order info tooltip element not found.');\r\n }\r\n\r\n // Warehouse stock infos\r\n const warehouseStocks = utils.$getProductContainerElements($container, 'stock-info-list').get(0);\r\n if (warehouseStocks) {\r\n warehouseStocks.setData(newData.warehouseStocks);\r\n }\r\n }\r\n\r\n function _updateHistory(variantProductDetails) {\r\n if (root.history && typeof (root.history.pushState) !== 'undefined') {\r\n var urlParts = location.href.split('#', 2);\r\n var resultUrl = variantProductDetails.IsMainProd ? $.removeQueryStringParam(urlParts[0], 'dpid') : $.setQueryStringParam(urlParts[0], 'dpid', variantProductDetails.ProductID);\r\n resultUrl = urlParts.length === 1 ? resultUrl : resultUrl + '#' + urlParts[1];\r\n\r\n if (resultUrl !== location.href) {\r\n variantsState.selectedVariantProd = variantProduct;\r\n root.history.pushState(variantsState, null, resultUrl);\r\n }\r\n }\r\n }\r\n }\r\n\r\n function _selectVariantControllersValues(variants) {\r\n _.each(variantControllers, function (x) {\r\n var preselectVariantTypeValue = _.find(x.variantType.variants, function (y) { return _.indexOf(variants, y.id) !== -1; });\r\n if (preselectVariantTypeValue && preselectVariantTypeValue.id > 0) {\r\n x.selectedValue = preselectVariantTypeValue.id;\r\n x.selector.setSelected(preselectVariantTypeValue.id);\r\n } else {\r\n say.error('Variant type \"' + x.variantType.name + '\" has no corresponding variant value for the shown variant product. Please check variants configuration for the product.');\r\n }\r\n });\r\n }\r\n\r\n function _onHistoryPopState(evt) {\r\n var state = evt.originalEvent.state;\r\n if (state && state.controlId === product.uniqueId) {\r\n variantsState = state;\r\n suppressVariantChangedEvent = true;\r\n\r\n if (state.selectedVariantProd) {\r\n _selectVariantControllersValues(state.selectedVariantProd.variants);\r\n } else {\r\n _.each(variantControllers, function (x) {\r\n x.selectedValue = 0;\r\n x.selector.setSelected(0);\r\n });\r\n }\r\n\r\n suppressVariantChangedEvent = false;\r\n _loadVariantProductDetails(variantsState.selectedVariantProd);\r\n _filterUnavailableVariants();\r\n }\r\n }\r\n\r\n function _getVariantControllerById(variantTypeId) {\r\n return variantControllers['vt' + variantTypeId];\r\n }\r\n\r\n function _getVariantControllerByTypeName(variantTypeName) {\r\n var foundController = _.find(variantControllers, function (controller) {\r\n return utils.caseInsensetiveEquals(controller.variantType.name, variantTypeName);\r\n });\r\n\r\n return foundController;\r\n }\r\n\r\n function _selectVariantByName(variantTypeName, variantValueName) {\r\n if (variantTypeName && variantValueName) {\r\n var variantController = _getVariantControllerByTypeName(variantTypeName);\r\n if (variantController) {\r\n variantController.selector.setSelectedByName(variantValueName);\r\n }\r\n }\r\n }\r\n\r\n function _selectVariantByProductId(variantProductId) {\r\n const selectedVariants = _getPreselectedVariants(variantProductId);\r\n _.each(selectedVariants, function (preselectedVariantValue, preselectedVariantType) {\r\n _selectVariantByName(preselectedVariantType, preselectedVariantValue);\r\n });\r\n }\r\n\r\n function _getSelectedVariantProduct(selectedVariantValues) {\r\n var selectedVariantProduct = null;\r\n var isSelectionComplete = _.every(selectedVariantValues, function (x) { return x > 0; });\r\n if (isSelectionComplete) {\r\n var variantProductsForSelection = _getProductsForCurrentSelection();\r\n\r\n if (variantProductsForSelection.length === 0) {\r\n say.warning(metadata['noAvailableVariantProducts']);\r\n } else if (variantProductsForSelection.length === 1) {\r\n selectedVariantProduct = variantProductsForSelection[0];\r\n } else if (variantProductsForSelection.length > 1) {\r\n say.warning(metadata['invalidVariantsConfiguration'] + ' ' + metadata['multipleAvailableVariantProducts']);\r\n }\r\n }\r\n return selectedVariantProduct;\r\n\r\n function _getProductsForCurrentSelection() {\r\n var availableProducts = _.filter(product.variantProducts, function (x) {\r\n return _.every(selectedVariantValues, function (y) { return _.indexOf(x.variants, y) !== -1; });\r\n });\r\n\r\n return availableProducts;\r\n }\r\n }\r\n\r\n function _getSelectedVariants() {\r\n return _.map(variantControllers, function (currentController) {\r\n return currentController.selectedValue || 0;\r\n });\r\n }\r\n\r\n function _getNotSelectedVariants() {\r\n return _.filter(variantControllers, function (x) { return !(x.selectedValue > 0); });\r\n }\r\n\r\n function _isVariantsSelectionValid(prodTitle) {\r\n var notSelectedVariants = _getNotSelectedVariants();\r\n var isSelectionValid = notSelectedVariants.length === 0;\r\n\r\n if (!isSelectionValid) {\r\n var notSelectedVariantNames;\r\n _.each(notSelectedVariants, function (x, idx) {\r\n var name = '' + x.variantType.name + '';\r\n if (idx === 0) {\r\n notSelectedVariantNames = name;\r\n } else if (idx === notSelectedVariants.length - 1) {\r\n notSelectedVariantNames += (' ' + metadata['and'] + ' ' + name);\r\n } else {\r\n notSelectedVariantNames += (', ' + name);\r\n }\r\n });\r\n\r\n say.warning(prodTitle + ' - ' + metadata['pleaseSelect'] + ' ' + notSelectedVariantNames, 10000);\r\n }\r\n\r\n return isSelectionValid;\r\n }\r\n\r\n function _getPreselectedVariants(variantProductId) {\r\n if (variantProductId) {\r\n var variantProduct = _.find(product.variantProducts, function (x) { return x.productId === variantProductId });\r\n if (variantProduct) {\r\n const result = {};\r\n _.each(product.variantTypes, function (x) {\r\n var selectVariantValue = _.find(x.variants, function (y) { return _.indexOf(variantProduct.variants, y.id) !== -1; });\r\n if (selectVariantValue && selectVariantValue.id > 0) {\r\n result[x.name] = selectVariantValue.name;\r\n }\r\n });\r\n return result;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n return {\r\n init: function () {\r\n $declaredVariantSelectors.each(function () {\r\n const $selector = $(this);\r\n\r\n const showPricesInclVat = product.sellPrice ? product.sellPrice.inclVat : null;\r\n const viewBuilderName = $selector.data('viewbuilder') || '';\r\n const variantTypeId = $selector.data('varianttypeid');\r\n const loadAdditionalInfoDataAttrValue = $selector.data('loadadditionalinfo');\r\n let loadAdditionalInfo = null;\r\n if (typeof (loadAdditionalInfoDataAttrValue) == 'boolean') {\r\n loadAdditionalInfo = loadAdditionalInfoDataAttrValue;\r\n } else if (typeof (loadAdditionalInfoDataAttrValue) == 'string') {\r\n loadAdditionalInfo = loadAdditionalInfoDataAttrValue === 'true';\r\n } else {\r\n loadAdditionalInfo = product.groupingComponents ? false : true;\r\n }\r\n\r\n const variantSelector = root.createVariantSelector(viewBuilderName, this, product, variantTypeId, new Map(Object.entries(metadata)), showPricesInclVat, loadAdditionalInfo);\r\n variantSelector.render();\r\n\r\n const variantType = _.find(product.variantTypes, function (x) { return x.id === variantTypeId; });\r\n const variantController = {\r\n variantType: variantType,\r\n selectedValue: 0,\r\n selector: variantSelector,\r\n $elem: $selector\r\n };\r\n\r\n const variantControllerKey = 'vt' + variantTypeId;\r\n variantControllers[variantControllerKey] = variantController;\r\n });\r\n\r\n $declaredVariantSelectors.on('variantselector:changed', function (evt, changedVariantType, newVariantValue) {\r\n if (!suppressVariantChangedEvent) {\r\n _onVariantSelectionChanged(changedVariantType, newVariantValue);\r\n\r\n // If the single available variant is changing itself, then it is nothing to filter.\r\n if (_.keys(variantControllers).length > 1) {\r\n _filterUnavailableVariants(newVariantValue);\r\n }\r\n }\r\n });\r\n\r\n _filterUnavailableVariants(); // Initial filtering of variants that have no available products at all\r\n _processVariants();\r\n\r\n var initialVariantProduct = _.find(product.variantProducts, function (x) { return x.productId === product.productId; });\r\n if (initialVariantProduct) {\r\n variantsState.selectedVariantProd = initialVariantProduct;\r\n // Pre-select if variant product is shown initially\r\n suppressVariantProductDetailsLoading = true; // Suppress variant product loading while preselecting variants for already loaded variant products\r\n\r\n _selectVariantControllersValues(initialVariantProduct.variants);\r\n\r\n isVariantProductShown = true;\r\n\r\n suppressVariantProductDetailsLoading = false; // Restore variant product loading on variants change\r\n } else if (!_.isEmpty(preselectedVariants)) {\r\n _.each(preselectedVariants, function (preselectedVariantValue, preselectedVariantType) { _selectVariantByName(preselectedVariantType, preselectedVariantValue); });\r\n }\r\n\r\n if (enableHistoryState === true) {\r\n if (root.history && typeof (root.history.replaceState) !== 'undefined') {\r\n root.history.replaceState(variantsState, null, null);\r\n }\r\n\r\n $(root).on('popstate', _onHistoryPopState);\r\n }\r\n },\r\n $selectors: $declaredVariantSelectors,\r\n getSelectedVariantProduct: function () {\r\n var selectedVariantValues = _getSelectedVariants();\r\n return _getSelectedVariantProduct(selectedVariantValues);\r\n },\r\n getNotSelectedVariants: _getNotSelectedVariants,\r\n selectVariantByName: _selectVariantByName,\r\n selectVariantByProductId: _selectVariantByProductId,\r\n isVariantsSelectionValid: _isVariantsSelectionValid,\r\n };\r\n }\r\n function initVariantsProcessor(options, variantProcessorsMap) {\r\n var processor = new variantsProcessor(options.$productContainer, options.productModel, options.metadata, options.preselectedVariants, options.say, options.pubsub, options.priceTotals,\r\n options.quantityDiscountsProcessorInstance, options.externalTrackingProcessorInstance, options.utils, options.enableHistoryState);\r\n\r\n processor.init();\r\n variantProcessorsMap[options.productModel.uniqueId] = processor;\r\n }\r\n\r\n // Cart processor\r\n function cartProcessor($view, model, say, pubsub, variantProcessorsMap, utils, priceTotals) {\r\n var estore = root.PublicEStore;\r\n var productsInCartMap = {};\r\n var productsToCustomFieldIdsForOrderMap = {};\r\n var vippsDialogModule = null;\r\n var vippsDialog = null;\r\n var shouldResetOnDecisionCallback = false;\r\n function _addToCart(addToCartContracts, $handler) {\r\n $view.addClass('buying');\r\n $.when(estore.addToCart(addToCartContracts))\r\n .always(function () { $view.removeClass('buying'); })\r\n .done(function (dataContract) {\r\n pubsub.publish('frontend.productview.product.isbought');\r\n $handler.addClass('is-bought');\r\n setTimeout(function () {\r\n $handler.removeClass('is-bought');\r\n }, 2000);\r\n\r\n if (dataContract.status.toLowerCase() !== 'ok') {\r\n if (dataContract.result.items && dataContract.result.items.length) {\r\n _.each(dataContract.result.items, function (resultItem) {\r\n var itemStatus = resultItem.status.toLowerCase();\r\n var productModel = _getFirstProductModelByProductId(resultItem.productID);\r\n var statusMessage = [productModel.title, resultItem.message].join(' - ');\r\n switch (itemStatus) {\r\n case 'error':\r\n say.error(statusMessage);\r\n break;\r\n case 'warning':\r\n say.warning(statusMessage);\r\n break;\r\n }\r\n });\r\n } else {\r\n _showPublicEStoreError(dataContract);\r\n }\r\n } else {\r\n if (model.tempOrderLineId > 0) {\r\n root.location.href = model.cartUrl;\r\n }\r\n }\r\n })\r\n .fail(_showPublicEStoreError);\r\n }\r\n\r\n function _showPublicEStoreError(pefContract) {\r\n var exractedMessage;\r\n\r\n if (typeof pefContract === 'string') {\r\n exractedMessage = pefContract;\r\n } else {\r\n exractedMessage = pefContract.result && pefContract.result.items[0] ? pefContract.result.items[0].message : pefContract.message;\r\n }\r\n\r\n say.error(exractedMessage);\r\n }\r\n\r\n function _getCustomFieldsContract($container, customFieldIdsForOrder) {\r\n var customFields = {};\r\n var $customFieldControls = utils.$getProductContainerElements($container, '.js-custom-field');\r\n\r\n $customFieldControls.each(function () {\r\n var $customFieldControl = $(this);\r\n var customFieldId = $customFieldControl.data('customfieldid');\r\n var customFieldValue = $customFieldControl.is(':checkbox') ? $customFieldControl.is(':checked').toString() : $customFieldControl.val();\r\n\r\n if (_.indexOf(customFieldIdsForOrder, customFieldId) !== -1 && typeof customFieldValue !== 'undefined') {\r\n customFields[customFieldId] = customFieldValue;\r\n }\r\n });\r\n\r\n return customFields;\r\n }\r\n\r\n function _isFormValid($container, prodTitle) {\r\n var isFormValid = true;\r\n\r\n // Trigger jquery form validation\r\n var validator = $container.validate({ ignore: [] });\r\n var $requiredFields = utils.$getProductContainerElements($container, '[data-rule-required]');\r\n $requiredFields.each(function () {\r\n var $requiredField = $(this);\r\n isFormValid &= validator.element($requiredField);\r\n });\r\n\r\n if (!isFormValid) {\r\n say.warning(prodTitle + ' - ' + model.metadata['formIsInvalid']);\r\n }\r\n\r\n return isFormValid;\r\n }\r\n\r\n function _isQuantityValid(minQuantity, quantity, prodTitle) {\r\n\r\n var isQuantityValid = true;\r\n\r\n if (minQuantity && quantity < minQuantity) {\r\n say.warning(prodTitle + ' - ' + model.metadata['minQuantityIs'] + ' ' + minQuantity);\r\n isQuantityValid = false;\r\n }\r\n\r\n return isQuantityValid;\r\n }\r\n\r\n function _toggleCartIndicator(animate) {\r\n // Works for the general product only, not for additionals.\r\n var variantProductIds = model.variantProducts != null ? $.map(model.variantProducts, function (variant) { return variant.productId; }) : null;\r\n var displayedProductId = model.productId;\r\n var isMainProductDisplayed = model.isMainProductOfProductWithVariants;\r\n\r\n // Find if displayed product is in cart and collect its quantity-in-cart value.\r\n // If the displayed product is main product of a product with variants then sum up quantity-in-carts of all its variant products.\r\n var numberQuantityInCart = _.reduce(productsInCartMap, function (memo, qtyInCart, productId) {\r\n productId = parseInt(productId);\r\n\r\n var includeQtyInCart = productId === displayedProductId || isMainProductDisplayed && _.indexOf(variantProductIds, productId) > -1;\r\n\r\n return memo + (includeQtyInCart ? qtyInCart : 0);\r\n }, 0);\r\n\r\n var isProductInCart = numberQuantityInCart > 0;\r\n\r\n var $cartQuantity = utils.$getProductContainerElements($view, '.js-cart-quantity');\r\n var $cartIndicator = utils.$getProductContainerElements($view, '.js-cart-indicator');\r\n\r\n $cartQuantity.text(numberQuantityInCart);\r\n $cartQuantity.toggle(isProductInCart);\r\n\r\n if (isProductInCart) {\r\n if ($cartIndicator.length > 0) {\r\n $cartIndicator.show();\r\n if (animate) {\r\n $view.effect('transfer', { to: $cartIndicator }, 500, function () { $cartIndicator.effect('bounce', null, 500); });\r\n }\r\n }\r\n } else {\r\n $cartIndicator.hide();\r\n }\r\n }\r\n\r\n function _addToCartHandler(topic, dataContract) {\r\n var currentProduct = _findCurrentProductInTheContract(dataContract);\r\n if (currentProduct) {\r\n productsInCartMap[currentProduct.productID] = currentProduct.totalQuantityInTempOrderLine;\r\n _toggleCartIndicator(true);\r\n }\r\n }\r\n\r\n function _removeFromCartHandler(topic, dataContract) {\r\n _.each(dataContract.result.items, function (x) {\r\n if (x.status.toLowerCase() === 'ok') {\r\n var deletedProductId = x.productID;\r\n delete productsInCartMap[deletedProductId];\r\n\r\n var isVariantProductOfDisplayedMainProductDeleted = model.isMainProductOfProductWithVariants && _.some(model.variantProducts, function (variantProd) {\r\n return variantProd.productId === deletedProductId;\r\n });\r\n if (deletedProductId === model.productId || isVariantProductOfDisplayedMainProductDeleted) {\r\n _toggleCartIndicator();\r\n }\r\n }\r\n });\r\n }\r\n\r\n function _emptyCartHandler(topic, dataContract) {\r\n if (dataContract.status.toLowerCase() === 'ok') {\r\n productsInCartMap = {};\r\n\r\n _toggleCartIndicator();\r\n }\r\n }\r\n\r\n function _getCartInfoHandler(topic, dataContract) {\r\n var cartInfo = dataContract.result.detailedCartInfo;\r\n\r\n if (dataContract.status.toLowerCase() === 'ok') {\r\n productsInCartMap = {};\r\n\r\n if (cartInfo.products && cartInfo.products.length > 0) {\r\n _.each(cartInfo.products, function (x) {\r\n productsInCartMap[x.productID] = (productsInCartMap[x.productID] || 0) + x.quantity;\r\n });\r\n }\r\n\r\n _toggleCartIndicator();\r\n }\r\n }\r\n\r\n function _findCurrentProductInTheContract(contract) {\r\n var currentProduct = _.find(contract.result.items, function (x) {\r\n return x && x.status.toLowerCase() === 'ok' && (x.productID === model.productId || model.additionalProducts && model.additionalProducts.filter(function (value) { return value.productId === x.productID; }).length > 0);\r\n });\r\n\r\n return currentProduct;\r\n }\r\n\r\n function _getProductModelByUniqueId(uniqueId) {\r\n var productModel = null;\r\n\r\n if (uniqueId) {\r\n if (model.uniqueId === uniqueId) {\r\n // General product ᕦ(ò_óˇ)ᕤ\r\n productModel = model;\r\n } else {\r\n // Try find the product in additionals\r\n if (!productModel && model.additionalProducts) {\r\n productModel = model.additionalProducts.find(function (additionalProduct) { return additionalProduct.uniqueId === uniqueId; });\r\n }\r\n\r\n if (!productModel && model.packageComponentProducts) {\r\n productModel = model.packageComponentProducts.find(function (componentProduct) { return componentProduct.uniqueId === uniqueId; });\r\n }\r\n\r\n if (!productModel && model.groupingComponents) {\r\n model.groupingComponents.every(groupingComponent => {\r\n if (productModel) {\r\n return false;\r\n }\r\n productModel = groupingComponent.componentProducts.find(groupingComponentProduct => groupingComponentProduct.uniqueId === uniqueId);\r\n return true;\r\n });\r\n }\r\n }\r\n }\r\n\r\n if (!productModel) {\r\n console.warn(`Product model was not found by unique id ${uniqueId}`);\r\n }\r\n return productModel;\r\n }\r\n\r\n function _getFirstProductModelByProductId(productId) {\r\n var productModel = null;\r\n\r\n productId = parseInt(productId);\r\n\r\n if (productId) {\r\n if (model.productId === productId) {\r\n // General product ᕦ(ò_óˇ)ᕤ\r\n productModel = model;\r\n }\r\n\r\n if (!productModel && model.additionalProducts) {\r\n // Try find the product in additionals\r\n productModel = model.additionalProducts.find(function (additionalProduct) { return additionalProduct.productId === productId; });\r\n }\r\n\r\n if (!productModel && model.packageComponentProducts) {\r\n productModel = model.packageComponentProducts.find(function (componentProduct) { return componentProduct.productId === productId; });\r\n }\r\n\r\n if (!productModel && model.groupingComponents) {\r\n model.groupingComponents.every(groupingComponent => {\r\n if (productModel) {\r\n return false;\r\n }\r\n productModel = groupingComponent.componentProducts.find(groupingComponentProduct => groupingComponentProduct.productId === productId);\r\n return true;\r\n });\r\n }\r\n }\r\n\r\n if (!productModel) {\r\n console.warn(`First product model was not found by product id ${productId}`);\r\n }\r\n return productModel;\r\n }\r\n\r\n function _getAddToCartContractFromContainer($productContainer, buyType, parentProductId, parentProductUniqueId, packageQuantity) {\r\n var addToCartContracts = null;\r\n\r\n const productUniqueId = $productContainer.data('uniqueid');\r\n const productKey = $productContainer.data('uniquekey');\r\n const productType = $productContainer.data('producttype') || 'Product';\r\n var productModel = _getProductModelByUniqueId(productUniqueId);\r\n\r\n var customFieldIdsForOrder = productsToCustomFieldIdsForOrderMap[productModel.productId] ? productsToCustomFieldIdsForOrderMap[productModel.productId] : [];\r\n if (!customFieldIdsForOrder.length) {\r\n _.each(productModel.customFields, function (x) {\r\n if ((x.displayType === 'editable' || x.displayType === 'hidden') && x.includeInOrder) {\r\n customFieldIdsForOrder.push(x.id);\r\n }\r\n });\r\n productsToCustomFieldIdsForOrderMap[productModel.productId] = customFieldIdsForOrder;\r\n }\r\n\r\n var quantity = 0;\r\n var fraction = 0;\r\n\r\n switch ((buyType || '').toLowerCase()) {\r\n case 'fraction':\r\n fraction = utils.tryParseNumberOrDefault($productContainer.find('.js-fraction').val());\r\n break;\r\n case 'factor':\r\n quantity = $productContainer.find('.js-quantity').val() || 1;\r\n break;\r\n case 'package':\r\n var packageSize = productModel.packageSize || 1;\r\n var packageQty = $productContainer.find('.js-package-quantity').val() || 1;\r\n quantity = packageQty * packageSize;\r\n break;\r\n case 'package_component':\r\n quantity = productModel.initialQuantity.raw * packageQuantity;\r\n break;\r\n case 'grouping_product_component':\r\n quantity = utils.tryParseNumberOrDefault($productContainer.find('.js-quantity').val(), 1) * packageQuantity;\r\n break;\r\n default:\r\n quantity = utils.tryParseNumberOrDefault($productContainer.find('.js-quantity').val(), 1);\r\n fraction = utils.tryParseNumberOrDefault($productContainer.find('.js-fraction').val());\r\n break;\r\n }\r\n\r\n var minQuantity = productModel.minQuantity ? productModel.minQuantity.raw : undefined;\r\n\r\n if (_isFormValid($productContainer, productModel.title) && _isQuantityValid(minQuantity, quantity, productModel.title)) {\r\n var productVariantsProcessor = variantProcessorsMap[productModel.uniqueId];\r\n if (!productVariantsProcessor || productVariantsProcessor.isVariantsSelectionValid(productModel.title)) {\r\n\r\n var packageComponents = null, groupingComponentProducts = null, hasError = false;\r\n\r\n if (productModel.packageComponentProducts) {\r\n packageComponents = [];\r\n var $packageComponentsContainer = utils.$getProductContainerElements($productContainer, '.js-component-products-list');\r\n _.each(productModel.packageComponentProducts, function (packageComponent) {\r\n var $componentProductContainer = $packageComponentsContainer.find('.js-component-product[data-uniqueid=\"' + packageComponent.uniqueId + '\"]');\r\n var componentContracts = _getAddToCartContractFromContainer($componentProductContainer, 'package_component', productModel.productId, productModel.uniqueId, quantity);\r\n if (componentContracts) {\r\n packageComponents = packageComponents.concat(componentContracts);\r\n } else {\r\n hasError = true;\r\n }\r\n });\r\n }\r\n\r\n if (productModel.groupingComponents) {\r\n groupingComponentProducts = [];\r\n var $groupingProductContainer = utils.$getProductContainerElements($productContainer, '.js-grouping-product-container');\r\n productModel.groupingComponents.forEach(groupingComponent => {\r\n groupingComponent.componentProducts.forEach(groupingComponentProduct => {\r\n const $groupingProductProductContainer = $groupingProductContainer.find('.js-grouping-product[data-uniqueid=\"' + groupingComponentProduct.uniqueId + '\"]');\r\n let isSelected = $groupingProductProductContainer.data('isselected');\r\n isSelected = typeof (isSelected) === 'boolean' ? isSelected : false;\r\n if (isSelected) {\r\n var groupingProductContracts = _getAddToCartContractFromContainer($groupingProductProductContainer, 'grouping_product_component', productModel.productId, productModel.uniqueId, quantity);\r\n if (groupingProductContracts) {\r\n groupingComponentProducts = groupingComponentProducts.concat(groupingProductContracts);\r\n } else {\r\n hasError = true;\r\n }\r\n }\r\n });\r\n });\r\n }\r\n\r\n if (!hasError) {\r\n var addToCartContract = {\r\n productKey: productKey,\r\n productId: productModel.productId,\r\n productType: productType,\r\n parentProductId: parentProductId,\r\n quantity: quantity,\r\n fraction: fraction,\r\n customFields: _getCustomFieldsContract($productContainer, customFieldIdsForOrder),\r\n tempOrderLineId: productModel.tempOrderLineId,\r\n imageId: productModel.mainImage ? productModel.mainImage.id : undefined,\r\n componentOfPackageProductID: buyType === 'package_component' ? parentProductUniqueId : null,\r\n };\r\n\r\n addToCartContracts = [addToCartContract];\r\n\r\n if (packageComponents) {\r\n addToCartContract.packageProductID = productModel.uniqueId;\r\n addToCartContracts = addToCartContracts.concat(packageComponents);\r\n }\r\n\r\n if (groupingComponentProducts) {\r\n addToCartContracts = addToCartContracts.concat(groupingComponentProducts);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return addToCartContracts;\r\n }\r\n\r\n function _processVippsHurtigkasseCheckout(vippsHurtigkasseComponent) {\r\n $.when(_prepareCartForCheckout()).then(function (proceedToCheckout) {\r\n if (proceedToCheckout) {\r\n vippsHurtigkasseComponent.startCheckout(true);\r\n }\r\n }, _showPublicEStoreError);\r\n\r\n function _prepareCartForCheckout() {\r\n const deferred = $.Deferred();\r\n\r\n $.when(estore.getTempOrderLines(null, true)).then(function (tempOrderLinesResult) {\r\n\r\n if (tempOrderLinesResult.status.toLowerCase() === 'ok') {\r\n const areOtherProductsInCart = tempOrderLinesResult.result.items.length > 0;\r\n if (areOtherProductsInCart) {\r\n\r\n var $productContainer = utils.$getProductContainerFor(vippsHurtigkasseComponent);\r\n var addToCartContract = _getAddToCartContractFromContainer($productContainer);\r\n\r\n if (addToCartContract) {\r\n const lines = tempOrderLinesResult && tempOrderLinesResult.result ? tempOrderLinesResult.result.items : null;\r\n\r\n const currentGroupPrices = priceTotals.getCurrentTotals();\r\n const mainPriceGroup = currentGroupPrices && currentGroupPrices.length ? currentGroupPrices.find((g) => !g.group) : null;\r\n\r\n let productPrice = null;\r\n\r\n if (mainPriceGroup) {\r\n productPrice = mainPriceGroup.priceRaw;\r\n } else {\r\n const quantity = utils.tryParseNumberOrDefault($view.find('.js-quantity').val(), 1);\r\n productPrice = model.sellPrice.raw * quantity;\r\n }\r\n\r\n const currentCartSum = lines ? lines.map((i) => i.linePrice).reduce((a, c) => a + c, 0) : 0;\r\n const currentCartQuantity = lines ? lines.map((i) => i.quantity).reduce((a, c) => a + c, 0) : 0;\r\n\r\n const dialogData = {\r\n cartLink: model.cartUrl,\r\n cartCount: currentCartQuantity,\r\n cartSum: currentCartSum + productPrice,\r\n productPrice: productPrice\r\n };\r\n\r\n if (vippsDialog) {\r\n if (shouldResetOnDecisionCallback) {\r\n vippsDialog.setOnDecision(_onDecision);\r\n shouldResetOnDecisionCallback = false;\r\n }\r\n vippsDialog.show(dialogData);\r\n } else {\r\n vippsDialogModule.then((module) => {\r\n vippsDialog = new module.VippsBuyProductDialog(_onDecision);\r\n\r\n $view.append(vippsDialog);\r\n\r\n vippsDialog.show(dialogData);\r\n });\r\n }\r\n }\r\n } else {\r\n _addToCartAndResolveDeferred();\r\n }\r\n } else {\r\n deferred.reject(dataContract);\r\n }\r\n }, deferred.reject);\r\n\r\n return deferred.promise();\r\n\r\n function _onDecision(decision) {\r\n if (decision === 'only-product') {\r\n $.when(estore.emptyCart()).then(function () {\r\n _addToCartAndResolveDeferred();\r\n }, deferred.reject);\r\n } else if (decision === 'whole-cart') {\r\n _addToCartAndResolveDeferred();\r\n } else {\r\n console.warn('Unsupported decision from Vipps dialog: ' + decision);\r\n }\r\n\r\n }\r\n\r\n function _addToCartAndResolveDeferred() {\r\n var $productContainer = utils.$getProductContainerFor(vippsHurtigkasseComponent);\r\n var addToCartContract = _getAddToCartContractFromContainer($productContainer);\r\n\r\n if (addToCartContract) {\r\n $.when(estore.addToCart(addToCartContract, null, true)).then(function (addToCartResult) {\r\n if (addToCartResult.status.toLowerCase() === 'ok') {\r\n deferred.resolve(true);\r\n } else {\r\n deferred.reject(addToCartResult);\r\n }\r\n }, deferred.reject);\r\n } else {\r\n deferred.reject();\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n init: function () {\r\n estore.subscribe('estore.callback.shopcart.addtocart', _addToCartHandler);\r\n estore.subscribe('estore.callback.shopcart.removefromcart', _removeFromCartHandler);\r\n estore.subscribe('estore.callback.shopcart.emptycart', _emptyCartHandler);\r\n estore.subscribe('estore.callback.shopcart.getdetailedcartinfo', _getCartInfoHandler);\r\n\r\n $.when(estore.getDetailedCartInfo());\r\n\r\n var mainProductVariants = variantProcessorsMap[model.uniqueId];\r\n if (mainProductVariants) {\r\n pubsub.subscribe('variantprocessor.variantproduct.updated', function () { _toggleCartIndicator(); });\r\n }\r\n\r\n $view.find('.js-buy-button,.js-buy-additional-product-button').on('click', function (evt) {\r\n evt.preventDefault();\r\n\r\n var $buyButton = $(this);\r\n\r\n var $productContainer = utils.$getProductContainerFor(this);\r\n var buyType = $buyButton.data('buy-type');\r\n\r\n var addToCartContract = _getAddToCartContractFromContainer($productContainer, buyType);\r\n if (addToCartContract) {\r\n _addToCart(addToCartContract, $buyButton);\r\n }\r\n });\r\n\r\n $view.find('.js-batch-buy-button').on('click', function (evt) {\r\n evt.preventDefault();\r\n\r\n // Collect all products with quantity > 0\r\n var addToCartContracts = [];\r\n var allContractsAreValid = true;\r\n $view.find('.js-quantity').each(function () {\r\n var $quantity = $(this);\r\n var quantity = utils.tryParseNumberOrDefault($quantity.val());\r\n\r\n var contracts = null;\r\n if (quantity > 0) {\r\n var $prodContainer = utils.$getProductContainerFor($quantity);\r\n contracts = _getAddToCartContractFromContainer($prodContainer);\r\n if (contracts) {\r\n addToCartContracts = addToCartContracts.concat(contracts);\r\n } else {\r\n allContractsAreValid = false;\r\n }\r\n }\r\n });\r\n\r\n if (addToCartContracts.length) {\r\n if (allContractsAreValid) {\r\n _addToCart(addToCartContracts, $(this));\r\n }\r\n } else if (allContractsAreValid) {\r\n say.warning(model.metadata['nothingToBuy']);\r\n }\r\n });\r\n\r\n var vippsHurtigkasse = $view.find('vipps-hurtigkasse');\r\n\r\n if (vippsHurtigkasse && vippsHurtigkasse.length) {\r\n importShim('/components/checkout/vipps/cms-vipps-hurtigkasse.js');\r\n vippsDialogModule = importShim('/components/checkout/vipps/vipps-buy-product-dialog.js');\r\n\r\n vippsHurtigkasse.on('onbeforestart', function (evt) {\r\n evt.preventDefault();\r\n\r\n _processVippsHurtigkasseCheckout(evt.target);\r\n });\r\n\r\n window.addEventListener(\"pagehide\", (evt) => {\r\n if (evt.persisted) {\r\n jQuery.unblockUI();\r\n shouldResetOnDecisionCallback = true;\r\n }\r\n })\r\n }\r\n\r\n utils.initQuantityModifyButtons($view, '.js-quantity-modify-btn'); // deprecated from product view v2.7.0, left for backwards compatibility\r\n utils.initQuantityModifyButtons2($view, '.js-plus-minus-container');\r\n }\r\n };\r\n }\r\n\r\n // Flags processor\r\n function flagsProcessor($view, model) {\r\n var flagsHandlerUrl = root.R + 'startup/api/v1/acrhive/flags/connections/visible';\r\n var itemId = model.itemId;\r\n\r\n function _getFlags() {\r\n $.get(flagsHandlerUrl, { itemIds: [itemId], archiveType: 20, })\r\n .done(function (data) {\r\n if (!_.isEmpty(data)) {\r\n var flags = data[itemId];\r\n\r\n var $flagsTarget = $view.find('.js-flags-target');\r\n _.each(flags, function (flagDetails) {\r\n var $flag = $('',\r\n {\r\n 'class': 'flag flag-' + flagDetails.FlagID,\r\n text: flagDetails.Name,\r\n data: flagDetails\r\n });\r\n\r\n $flag.appendTo($flagsTarget);\r\n\r\n var replaceEmptyString = flagDetails.Name.replace(/\\s+/g, \"-\").toLowerCase();\r\n $('.uc-product-view').addClass(replaceEmptyString + ' flag-' + flagDetails.FlagID + '-' + replaceEmptyString);\r\n });\r\n }\r\n });\r\n }\r\n\r\n return {\r\n init: function () {\r\n _getFlags();\r\n }\r\n }\r\n }\r\n\r\n // Rating processor\r\n function ratingProcessor($view, model, pubsub) {\r\n var itemId = model.itemId;\r\n\r\n function _updateRating() {\r\n $.ajax({\r\n url: root.R + 'handlers/public/productdata.ashx?a=getrating&itemid=' + itemId,\r\n type: 'GET'\r\n })\r\n .done(function (ratingData) {\r\n // Update data model\r\n model.rating = ratingData.rating;\r\n model.commentsCount = ratingData.commentsCount;\r\n model.ratingsCount = ratingData.ratingsCount;\r\n model.hasUserPostedReview = ratingData.hasUserPostedReview;\r\n\r\n // Update UI\r\n _buildRatingView();\r\n\r\n $view.find('.js-add-review').toggle(!model.hasUserPostedReview);\r\n\r\n $view.find('.js-rating-comments-count').text(ratingData.commentsCount);\r\n $view.find('.js-rating-ratings-count').text(ratingData.commentsCount);\r\n });\r\n }\r\n\r\n function _buildRatingView() {\r\n var ratingTemplate = '<% _.each(stars, function(star){ %>\" aria-hidden=\"true\"><% }); %>';\r\n var ratingModel = { stars: _buildStars() };\r\n\r\n var $ratingHtml = _.template(ratingTemplate, ratingModel);\r\n\r\n $view.find('.js-rating-container').empty().append($ratingHtml);\r\n\r\n function _buildStars() {\r\n var starsCount = 5;\r\n var starredRatingValue = model.rating * starsCount;\r\n\r\n var stars = [];\r\n\r\n for (var wholeStar = 1; wholeStar <= starredRatingValue; wholeStar++) {\r\n stars.push('whole');\r\n }\r\n\r\n var incompleteStarValue = starredRatingValue - stars.length;\r\n if (incompleteStarValue > 0) {\r\n stars.push(incompleteStarValue > 0.5 ? 'whole' : 'half');\r\n }\r\n\r\n var emptyStars = starsCount - stars.length;\r\n for (var emptyStar = 0; emptyStar < emptyStars; emptyStar++) {\r\n stars.push('empty');\r\n }\r\n\r\n return stars;\r\n }\r\n }\r\n\r\n return {\r\n init: function () {\r\n $(function () {\r\n _buildRatingView();\r\n\r\n pubsub.subscribe('reviewscontrol.reviewaction', function (topic, itemId) {\r\n if (itemId === model.itemId) {\r\n _updateRating();\r\n }\r\n });\r\n\r\n $view.find('.js-add-review').click(function (evt) {\r\n evt.preventDefault();\r\n\r\n pubsub.publish('reviewscontrol.focus', model.itemId);\r\n });\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Print processor\r\n function printProcessor($view, model) {\r\n return {\r\n init: function () {\r\n $view.find('.js-print-button').on('click', function (evt) {\r\n evt.preventDefault();\r\n\r\n if (model.printPath) {\r\n var printUrl = root.R + model.printPath + '?ItemID=' + model.itemId + '&ProductID=' + model.productId;\r\n root.open(printUrl, 'remote', 'resizable=yes,status=0,menubar=0,scrollbars=1,left=0,top=0,width=780,height=950,location=0');\r\n } else {\r\n console.error('Print handler is not configured on the website');\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n // PDF processor\r\n function pdfProcessor($view, model) {\r\n return {\r\n init: function () {\r\n $view.find('.js-downloadpdf-button').on('click', function (evt) {\r\n evt.preventDefault();\r\n\r\n var pdfUrl = root.R + 'RenderToPdf.aspx?ProductID=' + model.productId;\r\n if (model.pdfTemplateId > 0) {\r\n pdfUrl += '&TemplateID=' + model.pdfTemplateId;\r\n }\r\n\r\n root.open(pdfUrl, '_blank');\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Gallery processor\r\n function galleryProcessor($view, model) {\r\n var fancyboxInstance;\r\n var fancyboxOptions = {\r\n selector: '[data-fancybox=\"' + model.galleryId + '\"]',\r\n loop: true,\r\n hash: false\r\n };\r\n\r\n return {\r\n init: function () {\r\n fancyboxInstance = $view.fancybox(fancyboxOptions);\r\n }\r\n }\r\n }\r\n\r\n // Shopping list & wish list processor\r\n function shoppingListProcessor($view, model, say, utils, variantProcessorsMap) {\r\n function _isVariantsSelectionValid(productVariantsProcessor) {\r\n var isSelectionValid;\r\n\r\n if (typeof productVariantsProcessor !== 'undefined' && productVariantsProcessor !== null) {\r\n var notSelectedVariants = productVariantsProcessor.getNotSelectedVariants();\r\n isSelectionValid = notSelectedVariants.length === 0;\r\n\r\n if (!isSelectionValid) {\r\n var notSelectedVariantNames;\r\n _.each(notSelectedVariants, function (x, idx) {\r\n var name = '' + x.variantType.name + '';\r\n if (idx === 0) {\r\n notSelectedVariantNames = name;\r\n } else if (idx === notSelectedVariants.length - 1) {\r\n notSelectedVariantNames += (' ' + model.metadata['and'] + ' ' + name);\r\n } else {\r\n notSelectedVariantNames += (', ' + name);\r\n }\r\n });\r\n\r\n say.warning(model.metadata['pleaseSelect'] + ' ' + notSelectedVariantNames + ' ' + model.metadata['toAddToShoppingList']);\r\n }\r\n } else {\r\n isSelectionValid = true;\r\n }\r\n\r\n return isSelectionValid;\r\n }\r\n\r\n return {\r\n init: function () {\r\n $view.find('.js-add-to-shopping-list-btn').click(function (evt) {\r\n evt.preventDefault();\r\n\r\n var $productContainer = utils.$getProductContainerFor(this);\r\n var productUniqueId = $productContainer.data('uniqueid');\r\n var productVariantsProcessor = variantProcessorsMap[productUniqueId];\r\n\r\n if (_isVariantsSelectionValid(productVariantsProcessor)) {\r\n var addType = $(this).data('add-type');\r\n\r\n var quantity = 0;\r\n var fraction = 0;\r\n\r\n switch ((addType || '').toLowerCase()) {\r\n case 'fraction':\r\n fraction = utils.tryParseNumberOrDefault($productContainer.find('.js-fraction').val());\r\n break;\r\n case 'factor':\r\n quantity = $productContainer.find('.js-quantity').val() || 1;\r\n break;\r\n default:\r\n quantity = utils.tryParseNumberOrDefault($productContainer.find('.js-quantity').val(), 1);\r\n fraction = utils.tryParseNumberOrDefault($productContainer.find('.js-fraction').val());\r\n break;\r\n }\r\n\r\n var contractForShoppingList = [\r\n {\r\n productId: model.productId,\r\n imageId: model.mainImage.id,\r\n quantity: quantity,\r\n fraction: fraction,\r\n customFields: model.customFields\r\n }\r\n ];\r\n root.showAddToCollectionPopup(contractForShoppingList);\r\n }\r\n });\r\n\r\n $view.find('.js-add-additional-product-to-shopping-list-btn').click(function (evt) {\r\n evt.preventDefault();\r\n\r\n var additionalProductId = $(this).data(\"additional-product-id\");\r\n var additionalProductModel = model.additionalProducts.filter(function (value) {\r\n return value.productId === additionalProductId;\r\n })[0];\r\n\r\n var quantity = utils.tryParseNumberOrDefault($view.find(\".js-additional-product-quantity[data-additional-product-id='\" + additionalProductId + \"']\").val(), 1);\r\n var fraction = utils.tryParseNumberOrDefault($view.find(\".js-additional-product-fraction[data-additional-product-id='\" + additionalProductId + \"']\").val());\r\n\r\n var contractForShoppingList = [\r\n {\r\n productId: additionalProductModel.productId,\r\n imageId: additionalProductModel.mainImage.id,\r\n quantity: quantity,\r\n fraction: fraction,\r\n }\r\n ];\r\n root.showAddToCollectionPopup(contractForShoppingList);\r\n });\r\n\r\n $view.find('.js-add-to-wish-list-btn').click(function (evt) {\r\n evt.preventDefault();\r\n var $wishListControl = $(this);\r\n\r\n var isAddToWishListAction = $wishListControl.hasClass('c-wish-list-btn_add');\r\n\r\n if (model.isAvailableToBuy) {\r\n\r\n root.updateWishList(model.productId, isAddToWishListAction ? 'add' : 'remove', wishListCallback);\r\n }\r\n\r\n function wishListCallback(dataContract) {\r\n if (dataContract.status.toLowerCase() === 'ok') {\r\n _.each(dataContract.result.items,\r\n function (prod) {\r\n if (prod.status.toLowerCase() === 'ok') {\r\n say.success(model.metadata['wishListUpdated']);\r\n\r\n $wishListControl.toggleClass('c-wish-list-btn_add', !isAddToWishListAction);\r\n $wishListControl.toggleClass('c-wish-list-btn_remove',\r\n isAddToWishListAction);\r\n } else {\r\n say.error(prod.message);\r\n }\r\n });\r\n } else {\r\n say.error(dataContract.message);\r\n }\r\n }\r\n\r\n });\r\n }\r\n }\r\n }\r\n\r\n function quantityDiscountsProcessor($view, model) {\r\n var $quantityDiscountsContainer = $view.find('.js-quantity-discounts');\r\n var $quantityDiscountsInfo = $view.find('.js-quantity-discounts-info');\r\n\r\n function renderQuantityDiscounts(selectedVariants) {\r\n $.ajax({\r\n url: root.R + 'handlers/public/estoredata.ashx',\r\n type: 'GET',\r\n data: {\r\n a: 'GetQuantityDiscounts',\r\n itemId: model.itemId,\r\n dim1: selectedVariants !== undefined && selectedVariants[0] !== undefined ? selectedVariants[0] : 0,\r\n dim2: selectedVariants !== undefined && selectedVariants[1] !== undefined ? selectedVariants[1] : 0,\r\n dim3: selectedVariants !== undefined && selectedVariants[2] !== undefined ? selectedVariants[2] : 0,\r\n showPrice: model.quantityDiscountVisibility === 'Price',\r\n format: 'html'\r\n }\r\n })\r\n .done(function (result) {\r\n if (result && result.length > 0) {\r\n $quantityDiscountsContainer.show();\r\n $quantityDiscountsInfo.html(result);\r\n } else {\r\n $quantityDiscountsContainer.hide();\r\n }\r\n })\r\n .fail(function () {\r\n $quantityDiscountsContainer.hide();\r\n });\r\n }\r\n\r\n return {\r\n renderQuantityDiscounts: function (selectedVariants) {\r\n if ($quantityDiscountsContainer.length > 0) {\r\n renderQuantityDiscounts(selectedVariants);\r\n }\r\n }\r\n }\r\n }\r\n\r\n function priceRequestProcessor($view) {\r\n return {\r\n init: function () {\r\n\r\n var $feedbackControlContainer = $('.js-feedback-control');\r\n var $feedbackControlContainer2 = $('.js-feedback-control2');\r\n var $priceRequestContainerBtn = $view.find('.js-price-request-btn');\r\n\r\n $feedbackControlContainer = $feedbackControlContainer2.length > 0 ? $feedbackControlContainer2 : $feedbackControlContainer;\r\n\r\n if ($feedbackControlContainer.length > 0) {\r\n $priceRequestContainerBtn.on('click', function () {\r\n $.fancybox.open({\r\n parentEl: \"form:first\",\r\n src: $feedbackControlContainer,\r\n type: 'inline'\r\n });\r\n });\r\n }\r\n\r\n }\r\n }\r\n }\r\n\r\n function externalTrackingProcessor() {\r\n function _reportAdditionalProductsView($viewContainer, model) {\r\n var viewProductName = $.trim(model.title || document.title);\r\n\r\n var $additionalProductsContainer = $viewContainer.find('.js-additional-product-list');\r\n var $additionalProducts = $additionalProductsContainer.find('.js-additional-product');\r\n\r\n if ($additionalProducts.length > 0) {\r\n var listName = viewProductName + ' > ' + ($additionalProductsContainer.data('listname') || model.metadata['additionalProductsTab']);\r\n var additionalProductIdsWithLinks = $additionalProducts.map(function () {\r\n var $prod = $(this);\r\n var productId = $prod.data('productid');\r\n var $links = $prod.find('.js-product-link');\r\n\r\n return { productId: productId, $links: $links };\r\n }).get();\r\n\r\n root.reportProductListView(root.productListType.relatedProducts, listName, additionalProductIdsWithLinks);\r\n }\r\n }\r\n\r\n return {\r\n reportProductsView: function ($viewContainer, model) {\r\n root.reportProductDetailsView(model.productId);\r\n\r\n _reportAdditionalProductsView($viewContainer, model);\r\n },\r\n reportProductDetailsView: function (productId) {\r\n root.reportProductDetailsView(productId);\r\n },\r\n };\r\n }\r\n\r\n function relationExtensionDataProcessor($viewContainer, model, variantProcessorsMap, priceTotalsController, pubsub) {\r\n var relationExtData = null;\r\n\r\n var additionalProdMap = {}; // { relID1: { prodID1: { product1 }}}\r\n _.each(model.additionalProducts, function (prod) {\r\n if (prod.group && prod.group.groupType === 'Relation') {\r\n var relationId = prod.group.groupId;\r\n if (!additionalProdMap[relationId]) {\r\n additionalProdMap[relationId] = {};\r\n }\r\n\r\n additionalProdMap[relationId][prod.productId] = prod;\r\n }\r\n });\r\n\r\n function _applyExtensionData(variantTypeName, variantValueName) {\r\n if (variantTypeName && variantValueName) {\r\n variantTypeName = variantTypeName.toLowerCase();\r\n variantValueName = variantValueName.toLowerCase();\r\n\r\n var extData = relationExtData[variantTypeName] ? relationExtData[variantTypeName][variantValueName] : null;\r\n if (extData) {\r\n var isAnyQuantityAffected = false;\r\n\r\n _.each(extData, function (extDataItem) {\r\n var productId = extDataItem.productID;\r\n if (productId === null) {\r\n // Regular non-variant products do not store their productID in relation data. Therefore, need to resolve productID first.\r\n productId = _getSingleProductIdByItemId(extDataItem.itemID);\r\n }\r\n\r\n var additionalProduct = _getAdditionalProduct(extDataItem.relationID, productId);\r\n if (additionalProduct) {\r\n var uniqueId = additionalProduct.uniqueId;\r\n if (uniqueId) {\r\n if (typeof (extDataItem.quantityInRelation) !== 'undefined') {\r\n $viewContainer.find('[data-uniqueid=\"' + uniqueId + '\"] .js-quantity').val(extDataItem.quantityInRelation);\r\n isAnyQuantityAffected = true;\r\n }\r\n\r\n if (typeof (extDataItem.variants) !== 'undefined') {\r\n var variantsProc = variantProcessorsMap[uniqueId];\r\n if (variantsProc) {\r\n _.each(extDataItem.variants, function (variantValue, variantType) { variantsProc.selectVariantByName(variantType, variantValue); });\r\n }\r\n }\r\n }\r\n }\r\n });\r\n\r\n if (isAnyQuantityAffected) {\r\n priceTotalsController.updatePriceTotals();\r\n }\r\n }\r\n }\r\n }\r\n\r\n function _getSelectedVariantTypeToValueNamePairs(product) {\r\n var namePairs = {};\r\n\r\n var variantProduct = _.find(product.variantProducts, function (x) { return x.productId === product.productId });\r\n if (variantProduct) {\r\n _.each(product.variantTypes, function (x) {\r\n var selectVariantValue = _.find(x.variants, function (y) { return _.indexOf(variantProduct.variants, y.id) !== -1; });\r\n if (selectVariantValue && selectVariantValue.id > 0) {\r\n namePairs[x.name] = selectVariantValue.name;\r\n }\r\n });\r\n }\r\n\r\n return namePairs;\r\n }\r\n\r\n function _renderExtensionDataGrids($extDataGridsContainer) {\r\n if (_.isEmpty(relationExtData) || _.isEmpty(additionalProdMap)) {\r\n $extDataGridsContainer.remove();\r\n } else {\r\n var extensionDataGridTemplateCompiled = _.template('<\\% _.each(columns, function(column) { %><\\% }); %><\\% _.each(_.sortBy(rows, \\'position\\'), function(prod) { %>\\'><\\% _.each(columns, function(column) { %><\\% }); %><\\% }); %>
<\\%= column %>
<\\%= prod.title %><\\%= prod.extDataMap[column] ? prod.extDataMap[column].quantityInRelation : \\'-\\' %>
');\r\n\r\n // Render a separate grid for every general product's variant type with extension data.\r\n // Join extension data with existing additional products and ignore extension data for not available additional products.\r\n // Remember that there can be same products in different relations having their own relation extension data. So the key to the product should be productId + relationId.\r\n // Try follow the visible positions of the additional products shown.\r\n var visiblePositionMap = {};\r\n $viewContainer.find('.js-additional-product[data-uniqueid]').each(function (idx, elem) {\r\n var uniqueId = $(elem).data('uniqueid');\r\n if (uniqueId) {\r\n visiblePositionMap[uniqueId] = idx;\r\n }\r\n });\r\n\r\n _.each(relationExtData, function (variantTypeExtData, variantTypeName) {\r\n var gridModel = { gridTitle: variantTypeName, columns: [], rows: {} };\r\n\r\n _.each(variantTypeExtData, function (relProdExtDataArray, variantValueName) {\r\n gridModel.columns.push(variantValueName);\r\n\r\n _.each(relProdExtDataArray, function (relProdExtData) {\r\n var rowId = relProdExtData.relationID + '_' + relProdExtData.productID;\r\n // If the correpsonding product is found in additionals then add it to rows.\r\n // If the product is not found then add null value so we do not check it once more.\r\n if (typeof (gridModel.rows[rowId]) === 'undefined') {\r\n var additionalProduct = _getAdditionalProduct(relProdExtData.relationID, relProdExtData.productID);\r\n if (additionalProduct) {\r\n var visiblePosition = visiblePositionMap[additionalProduct.uniqueId];\r\n gridModel.rows[rowId] = {\r\n uniqueId: additionalProduct.uniqueId,\r\n group: additionalProduct.group.groupName,\r\n title: additionalProduct.title,\r\n position: visiblePosition > -1 ? visiblePosition : undefined,\r\n extDataMap: {}\r\n }\r\n } else {\r\n gridModel.rows[rowId] = null;\r\n }\r\n }\r\n\r\n if (gridModel.rows[rowId] !== null) {\r\n gridModel.rows[rowId].extDataMap[variantValueName] = relProdExtData;\r\n }\r\n });\r\n });\r\n\r\n //filter rows with null value before template compilation\r\n gridModel.rows = _.filter(gridModel.rows, function (row) {\r\n return row !== null;\r\n });\r\n var gridHtml = extensionDataGridTemplateCompiled(gridModel);\r\n\r\n $extDataGridsContainer.append(gridHtml);\r\n });\r\n }\r\n }\r\n\r\n function _getAdditionalProduct(relationId, productId) {\r\n return additionalProdMap[relationId] ? additionalProdMap[relationId][productId] : undefined;\r\n }\r\n\r\n function _getSingleProductIdByItemId(itemId) {\r\n var singleProduct = _.find(model.additionalProducts, function (additionalProd) { return !additionalProd.isProductWithVariants && additionalProd.itemId === itemId });\r\n\r\n return singleProduct ? singleProduct.productId : null;\r\n }\r\n\r\n function _oneTimeVariantProdUpdateHandler(topic, variantProductDetails) {\r\n pubsub.unsubscribe(_oneTimeVariantProdUpdateHandler);\r\n\r\n if (!variantProductDetails.IsMainProd) {\r\n var preselectedVariants = _getSelectedVariantTypeToValueNamePairs(model);\r\n _.each(preselectedVariants, function (valueName, typeName) { _applyExtensionData(typeName, valueName); });\r\n }\r\n }\r\n\r\n return {\r\n init: function () {\r\n var mainProductVariantsProcessor = variantProcessorsMap[model.uniqueId];\r\n\r\n if (mainProductVariantsProcessor) {\r\n $.ajax({\r\n url: root.R + 'api/archive/relation/foritem/' + model.itemId + '/variant/ext-data',\r\n type: 'GET',\r\n data: {\r\n relationIds: _.keys(additionalProdMap)\r\n }\r\n })\r\n .done(function (relationExtensionData) {\r\n relationExtData = relationExtensionData;\r\n\r\n if (relationExtData) {\r\n if (model.isVariantProductOfProductWithVariants) {\r\n // Apply extension data immediately if variant product is shown initially\r\n var preselectedVariants = _getSelectedVariantTypeToValueNamePairs(model);\r\n _.each(preselectedVariants, function (valueName, typeName) { _applyExtensionData(typeName, valueName); });\r\n } else {\r\n pubsub.subscribe('variantprocessor.variantproduct.updated', _oneTimeVariantProdUpdateHandler);\r\n }\r\n\r\n mainProductVariantsProcessor.$selectors.on('variantselector:changed', function (evt, changedVariantType, newVariantValue) {\r\n if (newVariantValue > 0) {\r\n var mainVariantValueDetails = _.find(changedVariantType.variants, function (variant) { return variant.id === newVariantValue; });\r\n\r\n _applyExtensionData(changedVariantType.name, mainVariantValueDetails.name);\r\n }\r\n });\r\n }\r\n\r\n var $extDataGridsContainer = $viewContainer.find('.js-relation-extension-data-scheme');\r\n if ($extDataGridsContainer.length > 0) {\r\n _renderExtensionDataGrids($extDataGridsContainer);\r\n }\r\n })\r\n .fail(function (errorResponse) {\r\n console.error('[UMW]: Failed to get relation extension data', errorResponse);\r\n });\r\n }\r\n }\r\n }\r\n }\r\n\r\n function priceTotalsProcessor($view, utils, model) {\r\n var additionalsGroup = 'additionals';\r\n var defaultGroup = 'default';\r\n var defaultEmptyText = '0';\r\n var valueLoadingText = '...';\r\n var updateTimer = null;\r\n var _currentTotals = null;\r\n\r\n var $priceTotalsElements;\r\n\r\n var cache = { empty: [] };\r\n\r\n function _buildCacheKey(products) {\r\n var cacheKey = products && products.length > 0 ? JSON.stringify(products) : 'empty';\r\n\r\n return cacheKey;\r\n }\r\n\r\n function _setResults(groupedTotals) {\r\n var totalsMap = {};\r\n _.each(groupedTotals, function (g) {\r\n g.hasDiscount = g.origPrice !== g.price;\r\n\r\n totalsMap[g.group || defaultGroup] = g;\r\n });\r\n\r\n $priceTotalsElements.each(function () {\r\n var $elem = $(this);\r\n var $elemContainer = $elem.closest('.js-price-totals-container');\r\n\r\n var group = $elem.data('price-totals-group') || defaultGroup;\r\n\r\n var totals = totalsMap[group] || {};\r\n var totalsType = $elem.data('price-totals') || 'sellprice';\r\n\r\n var totalsValue;\r\n switch (totalsType.toLowerCase()) {\r\n case 'quantity':\r\n totalsValue = totals.quantity || defaultEmptyText;\r\n break;\r\n case 'price':\r\n case 'sellprice':\r\n totalsValue = totals.price || defaultEmptyText;\r\n break;\r\n case 'originalprice':\r\n case 'beforeprice':\r\n case 'before':\r\n totalsValue = totals.hasDiscount ? totals.origPrice : null;\r\n break;\r\n case 'discount':\r\n case 'discountprice':\r\n totalsValue = totals.hasDiscount ? totals.discPrice : null;\r\n break;\r\n default:\r\n totalsValue = null;\r\n break;\r\n }\r\n\r\n if (totalsValue !== null) {\r\n $elem.text(totalsValue).show();\r\n $elemContainer.show();\r\n } else {\r\n $elem.hide();\r\n $elemContainer.hide();\r\n }\r\n });\r\n\r\n const onTotalsUpdatedEvent = $.Event('priceTotalsProcessor:ontotalsupdated');\r\n $view.trigger(onTotalsUpdatedEvent, [groupedTotals]);\r\n }\r\n\r\n function _getProductsWithPositiveQuantities() {\r\n return $view.find('.js-quantity').map(function () {\r\n var $quantity = $(this);\r\n var quantity = utils.tryParseNumberOrDefault($quantity.val());\r\n\r\n var productContract = null;\r\n\r\n if (quantity > 0) {\r\n const $productContainer = utils.$getProductContainerFor($quantity);\r\n let isSelected = $productContainer.data('isselected');\r\n isSelected = typeof (isSelected) === 'boolean' ? isSelected : true;\r\n\r\n if (isSelected) {\r\n const productkey = $productContainer.data('uniquekey');\r\n const productId = $productContainer.data('productid');\r\n let groupName = $quantity.data('price-totals-group') || $productContainer.data('price-totals-group');\r\n if (!groupName) {\r\n // Auto-detect group name\r\n groupName = $productContainer.hasClass('js-additional-product') ? additionalsGroup : null;\r\n }\r\n\r\n productContract = {\r\n productkey: productkey,\r\n prodId: productId,\r\n parentProductId: model.productId !== productId ? model.productId : 0,\r\n itemId: model.itemId,\r\n quantity: quantity,\r\n productType: $productContainer.data('producttype') || 'Product',\r\n group: groupName,\r\n };\r\n }\r\n }\r\n\r\n return productContract;\r\n }).get();\r\n };\r\n\r\n function _updatePriceTotals() {\r\n var products = _getProductsWithPositiveQuantities();\r\n var cacheKey = _buildCacheKey(products);\r\n\r\n if (cache[cacheKey]) {\r\n _currentTotals = cache[cacheKey];\r\n _setResults(cache[cacheKey]);\r\n } else {\r\n $priceTotalsElements.text(valueLoadingText);\r\n\r\n $.ajax({\r\n async: false,\r\n url: root.R + 'handlers/public/productdata.ashx',\r\n type: 'POST',\r\n data: {\r\n a: 'GetProductListQuantityPrice',\r\n params: JSON.stringify({ products: products })\r\n }\r\n })\r\n .done(function (result) {\r\n cache[cacheKey] = result;\r\n _currentTotals = result;\r\n _setResults(result);\r\n })\r\n .fail(function (errResp) {\r\n var errorMessage = utils.extractErrorMessageFromResponse(errResp);\r\n console.error('Failed to calculate price totals. ', errorMessage);\r\n });\r\n }\r\n }\r\n\r\n return {\r\n init: function () {\r\n $priceTotalsElements = $view.find('[data-price-totals]');\r\n var isAnyElementFound = $priceTotalsElements.length > 0;\r\n\r\n if (isAnyElementFound) {\r\n $view.find('.js-quantity').on('change', function () {\r\n if (updateTimer) {\r\n root.clearTimeout(updateTimer);\r\n updateTimer = null;\r\n }\r\n\r\n updateTimer = root.setTimeout(_updatePriceTotals, 500);\r\n });\r\n }\r\n },\r\n updatePriceTotals: function () {\r\n if (updateTimer) {\r\n root.clearTimeout(updateTimer);\r\n updateTimer = null;\r\n }\r\n\r\n var isAnyElementFound = $priceTotalsElements.length > 0;\r\n\r\n if (isAnyElementFound) {\r\n _updatePriceTotals();\r\n }\r\n },\r\n getCurrentTotals() { return _currentTotals; }\r\n }\r\n }\r\n\r\n function packageComponentProcessor($view, model, utils) {\r\n var $packageComponentsContainer = utils.$getProductContainerElements($view, '.js-component-products-list');\r\n if (!model.packageComponentProducts || !$packageComponentsContainer.length) {\r\n return;\r\n }\r\n\r\n var $generalProdQty = utils.$getProductContainerElements($view, '.js-quantity');\r\n $generalProdQty.on('change', function () {\r\n var quantity = utils.tryParseNumberOrDefault($(this).val());\r\n _.each(model.packageComponentProducts, function (packageComponent) {\r\n var $componentProductContainer = $packageComponentsContainer.find('.js-component-product[data-uniqueid=\"' + packageComponent.uniqueId + '\"]');\r\n $componentProductContainer.find('.js-component-quantity').text(packageComponent.initialQuantity.raw * quantity);\r\n });\r\n\r\n });\r\n }\r\n\r\n function groupingProductProcessor($view, model, utils, say, pubsub, priceTotals, variantProcessorsMap) {\r\n const BuyMode = { \"SingleProduct\": 0, \"MultipleProducts\": 1, \"AllProducts\": 2 }\r\n const TemplateMarkup = { \"GroupingProductDefault\": 0, \"GroupingProductV2\": 1 };\r\n var $groupingProductContainer;\r\n var groupingProductMarkup;\r\n var isInitializing = true;\r\n var groupingProductTemplate;\r\n var docContentMap = {};\r\n\r\n function _getGroupingComponentProduct(componentUniqueId, productUniqueId) {\r\n const groupingProductComponent = _getGroupingComponent(componentUniqueId);\r\n const groupingComponentProduct = groupingProductComponent.componentProducts.find(x => x.uniqueId === productUniqueId);\r\n if (!groupingComponentProduct) {\r\n console.error(`Grouping product component product was not found by id = ${productUniqueId}`);\r\n }\r\n\r\n return groupingComponentProduct;\r\n }\r\n\r\n function _getGroupingComponent(componentUniqueId) {\r\n const groupingComponent = model.groupingComponents.find(x => x.uniqueId === componentUniqueId);\r\n if (!groupingComponent) {\r\n console.error(`Grouping component was not found by id = ${componentUniqueId}`);\r\n }\r\n return groupingComponent;\r\n }\r\n\r\n function _getGroupingComponentTemplate(groupingComponent, groupingProductId) {\r\n const componentTemplate = JSON.parse(JSON.stringify(groupingComponent))\r\n componentTemplate.componentProducts = groupingComponent.componentProducts.filter(x => x.groupingProductId == groupingProductId);\r\n componentTemplate.componentProducts.sort((x, y) => x.orderNo - y.orderNo);\r\n return componentTemplate;\r\n }\r\n\r\n function _toLocalFixed(number, fraction) {\r\n return number.toLocaleString(undefined, { minimumFractionDigits: fraction, maximumFractionDigits: fraction });\r\n }\r\n\r\n function _setPriceImpact($productPriceImpact, price) {\r\n $productPriceImpact.html(`${model.currencyCode} ${_toLocalFixed(price, 2)}`);\r\n if (price === 0) {\r\n $productPriceImpact.removeClass('increase');\r\n $productPriceImpact.removeClass('decrease');\r\n $productPriceImpact.addClass('noimpact');\r\n } else if (price > 0) {\r\n $productPriceImpact.addClass('increase');\r\n $productPriceImpact.removeClass('decrease');\r\n $productPriceImpact.removeClass('noimpact');\r\n } else {\r\n $productPriceImpact.removeClass('increase');\r\n $productPriceImpact.addClass('decrease');\r\n $productPriceImpact.removeClass('noimpact');\r\n }\r\n }\r\n\r\n function _setGroupingComponentStockInfo($componentContainer) {\r\n const componentUniqueId = $componentContainer.data('componentuniqueid');\r\n\r\n // stock info\r\n $componentContainer.find('[data-uniqueid]').each((i, groupingComponentProduct) => {\r\n const $productContainer = $(groupingComponentProduct);\r\n const productUniqueId = $productContainer.data('uniqueid');\r\n const componentProduct = _getGroupingComponentProduct(componentUniqueId, productUniqueId);\r\n\r\n const $stockInfoContainer = $productContainer.find('.js-stock-info');\r\n if ($stockInfoContainer) {\r\n const $stockText = $stockInfoContainer.find('.js-stock-text')\r\n if ($stockText) {\r\n $stockText.text(componentProduct.stockText);\r\n if (!$stockText.hasClass(componentProduct.stockCssClass)) {\r\n $stockText.addClass(componentProduct.stockCssClass);\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n function _setGroupingComponentPrices(groupedTotals) {\r\n // prices are always expected to be found; just in case it's missing due to a bug - will update prices with empty values so it is visible\r\n const groupingComponentProductPrices = groupedTotals ? groupedTotals.find(x => x.groupingComponentProductPrices)?.groupingComponentProductPrices : null;\r\n\r\n $groupingProductContainer.find('[data-componentuniqueid]').each((i, groupingComponentContainer) => {\r\n const $componentContainer = $(groupingComponentContainer);\r\n const componentUniqueId = $componentContainer.data('componentuniqueid');\r\n const groupingProductComponent = _getGroupingComponent(componentUniqueId);\r\n\r\n let selectedPrice = 0;\r\n // first: find and set prices for selected product\r\n $componentContainer.find('[data-uniqueid]').each((i, groupingComponentProduct) => {\r\n const $productContainer = $(groupingComponentProduct);\r\n const isSelected = $productContainer.data('isselected');\r\n if (!isSelected) {\r\n return;\r\n }\r\n\r\n const productUniqueId = $productContainer.data('uniqueid');\r\n const quantity = $productContainer.find('.js-quantity').val();\r\n const componentProduct = _getGroupingComponentProduct(componentUniqueId, productUniqueId);\r\n const sellPrice = groupingComponentProductPrices ? groupingComponentProductPrices[componentProduct.uniqueKey] : null;\r\n let sellPriceFormatted = '';\r\n if (sellPrice) {\r\n sellPriceFormatted = sellPrice.formatted;\r\n selectedPrice = sellPrice.raw * quantity;\r\n }\r\n\r\n $productContainer.find('.js-grouping-product-price').html(sellPriceFormatted);\r\n _setPriceImpact($productContainer.find('.js-grouping-product-price-impact'), 0);\r\n });\r\n\r\n // second: set prices for not selected product\r\n $componentContainer.find('[data-uniqueid]').each((i, groupingComponentProduct) => {\r\n const $productContainer = $(groupingComponentProduct);\r\n const isSelected = $productContainer.data('isselected');\r\n if (isSelected) {\r\n return;\r\n }\r\n\r\n const productUniqueId = $productContainer.data('uniqueid');\r\n const quantity = $productContainer.find('.js-quantity').val();\r\n const componentProduct = _getGroupingComponentProduct(componentUniqueId, productUniqueId);\r\n const sellPrice = groupingComponentProductPrices ? groupingComponentProductPrices[componentProduct.uniqueKey] : null;\r\n let sellPriceFormatted = '', diffPrice = 0;\r\n if (sellPrice) {\r\n sellPriceFormatted = sellPrice.formatted;\r\n const nonSelectedPrice = sellPrice.raw * quantity;\r\n diffPrice = groupingProductComponent.buyMode === BuyMode.SingleProduct ? nonSelectedPrice - selectedPrice : nonSelectedPrice;\r\n }\r\n\r\n $productContainer.find('.js-grouping-product-price').html(sellPriceFormatted);\r\n _setPriceImpact($productContainer.find('.js-grouping-product-price-impact'), diffPrice);\r\n });\r\n });\r\n }\r\n\r\n function _setAllComponentProductsNotSelected($componentContainer) {\r\n const groupingProductComponent = _getGroupingComponent($componentContainer.data('componentuniqueid'));\r\n if (groupingProductComponent.buyMode === BuyMode.SingleProduct) {\r\n const $productContainer = $componentContainer.find('[data-uniqueid]');\r\n $productContainer.data('isselected', false);\r\n $productContainer.removeClass('selected');\r\n }\r\n }\r\n\r\n function _toggleProductSelected($componentContainer, $productContainer, isSelected) {\r\n _setAllComponentProductsNotSelected($componentContainer);\r\n\r\n $productContainer.data('isselected', isSelected);\r\n if (isSelected) {\r\n $productContainer.addClass('selected');\r\n $productContainer.attr('data-isselected', isSelected);\r\n } else {\r\n $productContainer.removeClass('selected');\r\n $productContainer.attr('data-isselected', isSelected);\r\n }\r\n\r\n _setGroupingComponentStockInfo($componentContainer);\r\n }\r\n\r\n function _isComponentRequiredToBuy(buyMode) {\r\n return buyMode === BuyMode.SingleProduct || buyMode === BuyMode.AllProducts;\r\n }\r\n\r\n function _toggleQuantityValueInComponent($quantity){\r\n const $componentContainer = $quantity.closest('[data-componentuniqueid]');\r\n const componentUniqueId = $componentContainer.data('componentuniqueid');\r\n const groupingComponent = _getGroupingComponent(componentUniqueId);\r\n\r\n if (groupingProductMarkup === TemplateMarkup.GroupingProductV2){\r\n if (groupingComponent.buyMode === BuyMode.SingleProduct) {\r\n const $allExceptEditedInput = $componentContainer.find('.js-quantity').not($quantity);\r\n $allExceptEditedInput.val(0);\r\n $allExceptEditedInput.closest('.js-plus-minus-container-grouping-product').find('button[data-action=\"decrease\"]').attr('disabled', 'disabled');\r\n }\r\n }\r\n }\r\n\r\n function _setupControlElements() {\r\n switch(groupingProductMarkup){\r\n case TemplateMarkup.GroupingProductDefault: //Going to be deprecated. Use v2 instead.\r\n utils.initQuantityModifyButtons($groupingProductContainer, '.js-gp-quantity-modify-btn');\r\n break;\r\n case TemplateMarkup.GroupingProductV2:\r\n utils.initQuantityModifyButtons2($view, '.js-plus-minus-container-grouping-product');\r\n break;\r\n }\r\n\r\n $groupingProductContainer.find('.js-select-product').each((i, element) => {\r\n $(element).on('change', function (evt) {\r\n const $selectProductInput = $(this);\r\n const $componentContainer = $selectProductInput.closest('[data-componentuniqueid]');\r\n const $productContainer = utils.$getProductContainerFor($selectProductInput);\r\n const isSelected = $selectProductInput.is(':checked');\r\n const componentUniqueId = $componentContainer.data('componentuniqueid');\r\n const groupingComponent = _getGroupingComponent(componentUniqueId);\r\n\r\n // prevent uncheck if component is required and no more checked products\r\n if (!isSelected && _isComponentRequiredToBuy(groupingComponent.buyMode) && !$componentContainer.find('input[name=\"' + this.name + '\"]:checked').not(this).length) {\r\n $(this).prop('checked', true);\r\n return;\r\n }\r\n\r\n if (groupingComponent.buyMode === BuyMode.SingleProduct) {\r\n const $allExceptCheckedComponentSelectors = $componentContainer.find('input[name=\"' + this.name + '\"]').not(this);\r\n $allExceptCheckedComponentSelectors.prop('checked', false);\r\n }\r\n\r\n _toggleProductSelected($componentContainer, $productContainer, isSelected);\r\n\r\n priceTotals.updatePriceTotals();\r\n });\r\n });\r\n\r\n $('#root').on('click', function(event) {\r\n if (!$(event.target).closest($groupingProductContainer).length){\r\n $('.js-grouping-product').removeClass('active');\r\n }\r\n });\r\n\r\n $('.js-grouping-product').on('click', function() {\r\n const imageItem = $(this).find('.js-grouping-product-image');\r\n const imageItemSelected = $(this).closest('.grouping-component').find('.js-grouping-component-image-selected');\r\n const imageLinkItemSelected = $(this).closest('.grouping-component').find('.js-grouping-component-image-link-selected');\r\n\r\n $(this).closest('.js-grouping-product-container').find('.js-grouping-product').not(this).removeClass('active');\r\n $(this).addClass('active');\r\n\r\n if(imageItem.attr('src') != imageItemSelected.attr('src')) {\r\n imageLinkItemSelected.attr('href', imageItem.data('src'));\r\n imageLinkItemSelected.data({\r\n 'width': imageItem.data('width'),\r\n 'height': imageItem.data('height')\r\n });\r\n imageItemSelected.attr('src', imageItem.attr('src'));\r\n }\r\n });\r\n\r\n $groupingProductContainer.find('.js-quantity').each((i, element) => {\r\n const $quantityInput = $(element);\r\n $quantityInput.on('change', () => {\r\n const minAllowedQuantityDataAttr = $quantityInput.data('min-quantity');\r\n if(minAllowedQuantityDataAttr){\r\n const quantityValue = $quantityInput.val();\r\n const $selectProduct = $quantityInput.closest('.js-grouping-product').find('.js-select-product');\r\n quantityValue < minAllowedQuantityDataAttr ? $selectProduct.prop('checked', false) : $selectProduct.prop('checked', true);\r\n _toggleQuantityValueInComponent($quantityInput);\r\n }\r\n if(groupingProductMarkup === TemplateMarkup.GroupingProductV2){\r\n const $componentContainer = $quantityInput.closest('[data-componentuniqueid]');\r\n const $productContainer = $quantityInput.closest('.js-grouping-product');\r\n const isSelected = $productContainer.find('.js-select-product').is(':checked');\r\n _toggleProductSelected($componentContainer, $productContainer, isSelected);\r\n }\r\n priceTotals.updatePriceTotals();\r\n });\r\n });\r\n\r\n $groupingProductContainer.find('.js-more-info').each((i, element) => {\r\n const $infoLink = $(element);\r\n $infoLink.on('click', (evt) => {\r\n evt.preventDefault();\r\n const $productContainer = utils.$getProductContainerFor($infoLink);\r\n const $moreInfoCont = $productContainer.find('.js-more-info-cont');\r\n const $moreInfoContTeaser = $productContainer.find('.js-more-info-cont-teaser');\r\n const $moreInfoContContent = $productContainer.find('.js-more-info-cont-content');\r\n\r\n if ($moreInfoCont.length) {\r\n const $componentContainer = $infoLink.closest('[data-componentuniqueid]');\r\n const componentUniqueId = $componentContainer.data('componentuniqueid');\r\n const prodUniqueId = $productContainer.data('uniqueid');\r\n const componentProduct = _getGroupingComponentProduct(componentUniqueId, prodUniqueId);\r\n\r\n if (docContentMap.hasOwnProperty(componentProduct.itemId)) {\r\n $moreInfoCont.collapse('toggle');\r\n } else {\r\n $.ajax({\r\n url: root.R + 'api/document/getDocumentTeaserAndContent',\r\n type: 'GET',\r\n data: { itemId: componentProduct.itemId }\r\n })\r\n .done(function (result) {\r\n docContentMap[componentProduct.itemId] = result;\r\n $moreInfoContTeaser.html(result.teaser);\r\n $moreInfoContContent.html(result.content);\r\n $moreInfoCont.collapse('show');\r\n })\r\n .fail(function (errResp) {\r\n var errorMessage = utils.extractErrorMessageFromResponse(errResp);\r\n console.error('Failed to get document content', errorMessage);\r\n });\r\n }\r\n }\r\n });\r\n });\r\n }\r\n\r\n function _setProductContainerValues($productContainer, groupingComponentProduct, selectedVariant) {\r\n $productContainer.find('.js-grouping-product-link').attr({\r\n 'href': groupingComponentProduct.url,\r\n 'title': groupingComponentProduct.title\r\n });\r\n $productContainer.find('.js-grouping-product-title').html(groupingComponentProduct.title);\r\n const $groupingProductImage = $productContainer.find('.js-grouping-product-image');\r\n\r\n if ($groupingProductImage) {\r\n if (groupingComponentProduct.mainImage) {\r\n $groupingProductImage.attr('src', groupingComponentProduct.mainImage.previewUrl || '');\r\n $groupingProductImage.attr('alt', groupingComponentProduct.mainImage.title || '');\r\n } else {\r\n $groupingProductImage.attr('src', '');\r\n $groupingProductImage.attr('alt', '');\r\n }\r\n }\r\n\r\n const $groupingProductVariantImage = $productContainer.find('.js-grouping-product-variant-image');\r\n if ($groupingProductVariantImage) {\r\n if (selectedVariant && selectedVariant.image) {\r\n $groupingProductVariantImage.attr('src', selectedVariant.image.thumbnailUrl);\r\n $groupingProductVariantImage.attr('alt', selectedVariant.name);\r\n } else {\r\n $groupingProductVariantImage.attr('src', '');\r\n $groupingProductVariantImage.attr('alt', '');\r\n }\r\n }\r\n\r\n const $quantity = $productContainer.find('.js-quantity');\r\n const currentQuantity = utils.tryParseNumberOrDefault($quantity.val(), 1);\r\n const $componentContainer = $quantity.closest('[data-componentuniqueid]');\r\n const componentUniqueId = $componentContainer.data('componentuniqueid');\r\n const groupingComponent = _getGroupingComponent(componentUniqueId);\r\n\r\n if (groupingComponentProduct.initialQuantity.raw > currentQuantity) {\r\n _toggleQuantityValueInComponent($quantity)\r\n $quantity.val(groupingComponentProduct.initialQuantity.formatted);\r\n if (groupingProductMarkup === TemplateMarkup.GroupingProductV2 && groupingComponent.buyMode === BuyMode.MultipleProducts && groupingComponentProduct.initialQuantity.formatted >= groupingComponentProduct.minQuantity.raw){\r\n $quantity.closest('.js-plus-minus-container-grouping-product').find('button[data-action=\"decrease\"]').removeAttr('disabled');\r\n }\r\n }\r\n\r\n $productContainer.data({\r\n 'uniqueid': groupingComponentProduct.uniqueId,\r\n 'uniquekey': groupingComponentProduct.uniqueKey,\r\n 'productid': groupingComponentProduct.productId\r\n });\r\n }\r\n\r\n function _setVariantProductValues($productContainer, productId, groupingProductId, groupingProductIndex, selectedVariant) {\r\n const $componentContainer = $productContainer.closest('[data-componentuniqueid]');\r\n const componentUniqueId = $componentContainer.data('componentuniqueid');\r\n const groupingComponent = _getGroupingComponent(componentUniqueId);\r\n const componentTemplate = _getGroupingComponentTemplate(groupingComponent, groupingProductId)\r\n\r\n let componentProduct;\r\n if (productId) {\r\n componentProduct = componentTemplate.componentProducts.find(x => x.groupingProductId === groupingProductId && x.groupingProductIndex === groupingProductIndex && x.productId === productId);\r\n $productContainer.find('.js-select-product').prop('checked', true);\r\n } else {\r\n const productUniqueId = $productContainer.data('uniqueid');\r\n componentProduct = componentTemplate.componentProducts.find(x => x.uniqueId === productUniqueId);\r\n // find parent\r\n componentProduct = componentTemplate.componentProducts.find(x => x.groupingProductId === groupingProductId && x.groupingProductIndex === groupingProductIndex && x.productId === componentProduct.parentProductId);\r\n }\r\n\r\n if (componentProduct) {\r\n _setProductContainerValues($productContainer, componentProduct, selectedVariant);\r\n if (productId) {\r\n _toggleProductSelected($componentContainer, $productContainer, true);\r\n }\r\n } else {\r\n console.error(`Component product not found by id = ${productId}`);\r\n }\r\n }\r\n\r\n function _setupVariants(groupingProductId) {\r\n $groupingProductContainer.find('[data-uniqueid]').each((i, productContainer) => {\r\n const $productContainer = $(productContainer);\r\n const componentUniqueId = $productContainer.closest('[data-componentuniqueid]').data('componentuniqueid');\r\n const productUniqueId = $productContainer.data('uniqueid');\r\n const groupingProductIndex = $productContainer.data('groupingproductindex');\r\n\r\n const componentTemplate = _getGroupingComponentTemplate(_getGroupingComponent(componentUniqueId), groupingProductId)\r\n const componentProduct = _getGroupingComponentProduct(componentUniqueId, productUniqueId);\r\n\r\n if (componentProduct.isMainProductOfProductWithVariants) {\r\n $productContainer.on('variantsprocessor:beforeloadvariantproduct', (e, variantProduct, selectedVariant) => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n _setVariantProductValues($productContainer, variantProduct ? variantProduct.productId : null, groupingProductId, groupingProductIndex, selectedVariant);\r\n\r\n if (!isInitializing) {\r\n priceTotals.updatePriceTotals();\r\n }\r\n });\r\n\r\n const productVariantsProcessor = variantProcessorsMap[productUniqueId];\r\n const preselectedVariantProduct = componentTemplate.componentProducts.find(x => x.parentProductId === componentProduct.productId && x.groupingProductIndex === componentProduct.groupingProductIndex && x.isPreSelected);\r\n if (preselectedVariantProduct) {\r\n productVariantsProcessor.selectVariantByProductId(preselectedVariantProduct.productId);\r\n }\r\n }\r\n });\r\n }\r\n\r\n function _setupGroupingProductVariants() {\r\n $view.on('variantsprocessor:beforeloadvariantproduct', (e, variantProduct) => {\r\n const groupingProductId = !!variantProduct ? variantProduct.productId : model.groupingProductId;\r\n _generateGroupingProduct(groupingProductId);\r\n _setup(groupingProductId);\r\n });\r\n }\r\n\r\n function _generateGroupingProduct(groupingProductId) {\r\n\r\n $groupingProductContainer.empty();\r\n\r\n model.groupingComponents.sort((x, y) => x.orderNo - y.orderNo).forEach(groupingComponent => {\r\n const componentTemplate = _getGroupingComponentTemplate(groupingComponent, groupingProductId)\r\n\r\n const templateData = {\r\n groupingComponent: componentTemplate,\r\n BuyMode: { \"SingleProduct\": 0, \"MultipleProducts\": 1, \"AllProducts\": 2 },\r\n VariantViewType: { 0: \"dropdownvariant\", 1: \"tilesvariant\", 2: \"relimgtilesvariant\", 3: \"fancyboxrelimgtilesvariant\", 4: \"dropdownvariant2\", 5: \"dropdownvariant4\", 6: \"relimgtilesvariant2-outlet\", 7: \"tilesvariant2-outlet\", 8: \"relimgtilesvariant3-outlet\" },\r\n ComponentViewType: { \"Collapsed\": 0, \"Expanded\": 1 },\r\n settings: { showMoreInfoLink: model.showMoreInfoLinkForComponents },\r\n metadata: model.metadata\r\n };\r\n const groupingComponentContainer = _.template(groupingProductTemplate, templateData);\r\n const $groupingComponentContainer = $(groupingComponentContainer);\r\n $groupingProductContainer.append($groupingComponentContainer);\r\n groupingProductMarkup = $groupingProductContainer.find('[data-componentuniqueid]').data('markup') ?? TemplateMarkup.GroupingProductDefault;\r\n\r\n const $collapseExpandComponent = $groupingComponentContainer.find('.js-collapse-expand');\r\n const $collapseExpandCont = $groupingComponentContainer.find('.js-collapse-expand-cont');\r\n\r\n $collapseExpandComponent.on('click', (evt) => {\r\n evt.preventDefault();\r\n\r\n if ($collapseExpandCont.length) {\r\n $collapseExpandCont.collapse('toggle');\r\n }\r\n });\r\n\r\n componentTemplate.componentProducts.forEach(groupingComponentProduct => {\r\n if (groupingComponentProduct.groupingProductId === groupingProductId) {\r\n if (groupingComponentProduct.isMainProductOfProductWithVariants) {\r\n const $groupingComponentProductContainer = $groupingComponentContainer.find(`.js-grouping-product[data-uniqueid=\"${groupingComponentProduct.uniqueId}\"]`);\r\n groupingComponentProduct.variantRelImageMatchRegExp = model.variantRelImageMatchRegExp;\r\n const options = {\r\n $productContainer: $groupingComponentProductContainer,\r\n productModel: groupingComponentProduct,\r\n priceTotals: priceTotals,\r\n metadata: model.metadata,\r\n say: say,\r\n pubsub: pubsub,\r\n utils: utils,\r\n };\r\n initVariantsProcessor(options, variantProcessorsMap);\r\n }\r\n }\r\n });\r\n });\r\n }\r\n\r\n function _setup(groupingProductId) {\r\n isInitializing = true;\r\n\r\n _setupControlElements();\r\n _setupVariants(groupingProductId);\r\n\r\n $groupingProductContainer.find('[data-componentuniqueid]').each((i, groupingComponentContainer) => {\r\n _setGroupingComponentStockInfo($(groupingComponentContainer))\r\n });\r\n\r\n isInitializing = false;\r\n }\r\n\r\n return {\r\n init: function () {\r\n $groupingProductContainer = utils.$getProductContainerElements($view, '.js-grouping-product-container');\r\n if (!$groupingProductContainer) {\r\n console.error('Grouping product container was not found.')\r\n return;\r\n }\r\n\r\n var $groupingProductTemplateContainer = $('#uc209-grouping-product-template');\r\n if ($groupingProductTemplateContainer.length == 0 || !$groupingProductTemplateContainer[0].innerText) {\r\n console.error('Product is configured as package product but the package product template is not found.')\r\n new notificator(pubsub, utils).error('Produktet er konfigurert som pakkeprodukt, men pakkeproduktmalen ble ikke funnet.');\r\n return;\r\n }\r\n\r\n let groupingProductId = model.groupingProductId;\r\n\r\n const mainProductUniqueId = $view.data('uniqueid');\r\n const mainProductVariantsProcessor = variantProcessorsMap[mainProductUniqueId];\r\n if (mainProductVariantsProcessor) {\r\n const selectedVariantProduct = mainProductVariantsProcessor.getSelectedVariantProduct();\r\n if (selectedVariantProduct && selectedVariantProduct.productId) {\r\n groupingProductId = selectedVariantProduct.productId;\r\n }\r\n }\r\n\r\n groupingProductTemplate = $groupingProductTemplateContainer[0].innerText;\r\n\r\n _setupGroupingProductVariants();\r\n\r\n _generateGroupingProduct(groupingProductId);\r\n _setup(groupingProductId);\r\n\r\n $view.on('priceTotalsProcessor:ontotalsupdated', (_, groupedTotals) => _setGroupingComponentPrices(groupedTotals));\r\n },\r\n }\r\n }\r\n\r\n function util() {\r\n function _$getProductContainerFor(elem) {\r\n // It is the requirement that every product container should have data-uniqueid attirbute\r\n return $(elem).closest('[data-uniqueid]');\r\n }\r\n function _tryParseNumberOrDefault(rawValue, defaultValue) {\r\n var parsed;\r\n\r\n if (typeof rawValue === 'string') {\r\n parsed = parseFloat(rawValue.replace(',', '.'));\r\n } else {\r\n parsed = rawValue;\r\n }\r\n\r\n return parsed === 0 ? parsed : parsed || defaultValue || 0;\r\n }\r\n\r\n return {\r\n tryParseNumberOrDefault: _tryParseNumberOrDefault,\r\n $getProductContainerFor: _$getProductContainerFor,\r\n $getProductContainerElements: function ($container, selector) {\r\n // There might be situations when there are multiple product containers with the similar elements from differen products inside another product container.\r\n // An example: additional products that are rendered inside the general product's container.\r\n // In addition, there can be situations when the same product is rendered multiple times as additional or both as additional and as general product.\r\n // So, if we will try to find elements by selector, e.g. $view.find('.js-variant-selector') then jQuery will find variant selectors of the current product container and also all variant selectors of all nested product containers.\r\n // Therefore, we need to know for sure what elements belong to the current product container.\r\n // We can rely on the closest container with the data-uniqueid attribute (since it is a requirement to have it) and then compare the found element with the container from arguments.\r\n return $container.find(selector).filter(function () { return _$getProductContainerFor(this).is($container); });\r\n },\r\n trimAndLowerCase: function (str) {\r\n return (str || '').trim().toLowerCase();\r\n },\r\n caseInsensetiveEquals: function (str1, str2) {\r\n return typeof str1 === 'string' && typeof str2 === 'string'\r\n ? str1.trim().toLowerCase() === str2.trim().toLowerCase()\r\n : str1 === str2;\r\n },\r\n extractErrorMessageFromResponse: function (errorResponse) {\r\n var message;\r\n if (typeof errorResponse === 'object' && errorResponse !== null) {\r\n // Extract error message\r\n try {\r\n var parsedResponseBody = JSON.parse(errorResponse.responseText);\r\n message = parsedResponseBody.ExceptionMessage ? parsedResponseBody.ExceptionMessage : (parsedResponseBody.Message ? parsedResponseBody.Message : errorResponse.statusText);\r\n } catch (e) {\r\n message = errorResponse.statusText;\r\n }\r\n } else {\r\n message = errorResponse;\r\n }\r\n\r\n return message;\r\n },\r\n\r\n initQuantityModifyButtons2: function ($container, selector) {\r\n $container.find(selector).each(function(i, element){\r\n let $this = {\r\n \"quantity\": $(element).find('input'),\r\n \"button\": $(element).find('button'),\r\n \"label\": $(element).find('label'),\r\n \"labelQuantityText\": $(element).find('.js-quantity-text')\r\n }\r\n const _allowMinBreak = $(element).data('allow-min-break');\r\n const _stepAttr = _tryParseNumberOrDefault($this.quantity.attr('step'), 1);\r\n const _minAttrAllowedQuantity = _tryParseNumberOrDefault($this.quantity.attr('min'), 0);\r\n const _minDataAttrAllowedQuantity = _tryParseNumberOrDefault($this.quantity.data('min-quantity'), 0); //Has higher priority over minAllowedQuantity\r\n const _minAllowedQuantity = Math.max(_minAttrAllowedQuantity, _minDataAttrAllowedQuantity);\r\n\r\n let _quantity = _tryParseNumberOrDefault($this.quantity.val());\r\n\r\n $this.quantity.on('change', function () {\r\n const userTypedQuantity = _tryParseNumberOrDefault($this.quantity.val());\r\n\r\n if (_allowMinBreak === true) {\r\n _quantity = userTypedQuantity < _minAllowedQuantity ? 0 : userTypedQuantity;\r\n _quantity == 0 || _quantity < _minAllowedQuantity ? _disableDecreaseButton() : _enableDecreaseButton();\r\n } else{\r\n _quantity = Math.max(_minAllowedQuantity, userTypedQuantity);\r\n _quantity <= _minAllowedQuantity ? _disableDecreaseButton() : _enableDecreaseButton();\r\n }\r\n\r\n _updateView(_quantity, true);\r\n });\r\n\r\n $this.button.on('click', function () {\r\n const newQuantityValue = _tryParseNumberOrDefault($this.quantity.val()); //Protects in case it was set progrematically by other cotnrols\r\n switch ($(this).data('action')) {\r\n case 'decrease':\r\n if(_validateDecreaseAction(newQuantityValue)){\r\n _quantity = _getDecreasedQuantity(_quantity);\r\n _updateView(_quantity, true);\r\n _triggerQuantityInput();\r\n }\r\n break;\r\n case 'increase':\r\n _quantity = _getIncreasedQuantity(newQuantityValue);\r\n _updateView(_quantity, true);\r\n _triggerQuantityInput();\r\n break;\r\n }\r\n });\r\n\r\n const _triggerQuantityInput = () => {\r\n $this.quantity.trigger('change');\r\n $this.quantity.trigger('focusout'); // focusout triggers min/max validation check\r\n }\r\n\r\n const _enableDecreaseButton = () => {\r\n $($this.button[0]).removeAttr('disabled');\r\n };\r\n\r\n const _disableDecreaseButton = () => {\r\n $($this.button[0]).attr('disabled', 'disabled');\r\n };\r\n\r\n const _updateView = (value, formatValueFlag) => {\r\n const quantityFormated = formatValueFlag ? _formatQuantity(value) : value;\r\n $this.labelQuantityText.text(quantityFormated);\r\n $this.quantity.val(quantityFormated);\r\n _quantity = value;\r\n };\r\n\r\n const _formatQuantity = (value) => {\r\n const quantityHasDot = $this.quantity.val().indexOf('.') > 0;\r\n return quantityHasDot ? value.toFixed(1) : value.toFixed(0)\r\n }\r\n\r\n const _validateDecreaseAction = (quantity) => {\r\n return _getDecreasedQuantity(quantity) >= (_allowMinBreak === true ? 0 : _minAllowedQuantity);\r\n }\r\n\r\n const _getDecreasedQuantity = (quantity) => {\r\n return _allowMinBreak === true ?\r\n quantity - _stepAttr < _minAllowedQuantity ? 0 : quantity - _stepAttr\r\n : quantity - _stepAttr <= _minAllowedQuantity ? _minAllowedQuantity : quantity - _stepAttr;\r\n };\r\n\r\n const _getIncreasedQuantity = (quantity) => {\r\n return quantity + _stepAttr < _minAllowedQuantity ? _minAllowedQuantity : quantity + _stepAttr;\r\n };\r\n })\r\n },\r\n initQuantityModifyButtons: function ($container, selector) {\r\n $container.find(selector).on('click', function () {\r\n const $this = $(this);\r\n const dataAttributes = {\r\n actionType: $this.data('action'),\r\n quantityTxbId: $this.data('target'),\r\n };\r\n\r\n const $quantityInput = $('#' + dataAttributes.quantityTxbId);\r\n const quantityMin = $quantityInput.attr('min') || 0;\r\n const quantityMax = $quantityInput.attr('max');\r\n let quantity = _tryParseNumberOrDefault($quantityInput.val());\r\n\r\n switch (dataAttributes.actionType) {\r\n case 'decrease':\r\n quantity = --quantity;\r\n if (quantity <= quantityMin) {\r\n quantity = quantityMin;\r\n $this.attr('disabled', 'disabled');\r\n } else {\r\n $this.parent().find('[data-action=\"increase\"]').removeAttr('disabled');\r\n }\r\n break;\r\n case 'increase':\r\n quantity = ++quantity;\r\n if (quantityMax && quantity >= quantityMax) {\r\n quantity = quantityMax;\r\n $this.attr('disabled', 'disabled');\r\n } else {\r\n $this.parent().find('[data-action=\"decrease\"]').removeAttr('disabled');\r\n }\r\n break;\r\n }\r\n\r\n if (quantity < 0) {\r\n $quantityInput.val(0);\r\n } else {\r\n quantity = Math.round(quantity * 10) / 10;\r\n $quantityInput.val(quantity);\r\n }\r\n $quantityInput.trigger('change');\r\n $quantityInput.trigger('focusout'); // focusout triggers min/max validation check\r\n });\r\n }\r\n }\r\n }\r\n})(jQuery, _, window);"],"names":["$","_","root","undefined","assetId","productViewController","$viewContainer","productViewModel","model","pubsub","PubSub","utils","util","say","notificator","variantProcessorsMap","priceTotals","discountID","console","info","title","init","importShim","then","preselectedVariants","$view","quantityDiscounts","quantityDiscountsProcessor","externalTracking","externalTrackingProcessor","priceTotalsProcessor","isProductWithVariants","result","queryString","location","search","slice","re","match","exec","paramKey","decodeURIComponent","toLowerCase","paramValue","replace","_getPreselectedVariantsFromQueryString","initVariantsProcessor","$productContainer","productModel","quantityDiscountsProcessorInstance","externalTrackingProcessorInstance","enableHistoryState","metadata","renderQuantityDiscounts","packageComponentProducts","each","packageComponent","$componentProductContainer","isMainProductOfProductWithVariants","find","uniqueId","variantRelImageMatchRegExp","packageComponentProcessor","groupingComponents","groupingProductProcessor","additionalProducts","additionalProduct","$additionalProductContainer","updatePriceTotals","cartProcessor","flagsProcessor","ratingProcessor","shoppingListProcessor","isPrintEnabled","printProcessor","pdfProcessor","isPriceRequestEnabled","$feedbackControlContainer","$feedbackControlContainer2","$priceRequestContainerBtn","length","on","fancybox","open","parentEl","src","type","galleryProcessor","reportProductsView","isProductRelationsExtensionEnabled","relationExtensionDataProcessor","similarProductsSelect","window","e","target","selectedOptions","dataset","url","showWarehouseStockInfo","warehouseStocks","get","setData","_notify","message","notificationType","timeout","extractErrorMessageFromResponse","publish","text","maxVisible","error","alert","success","warning","apply","this","variantsProcessor","product","priceTotalsController","$container","$declaredVariantSelectors","$getProductContainerElements","variantControllers","isVariantProductShown","suppressVariantProductDetailsLoading","variantsState","controlId","selectedVariantProd","suppressVariantChangedEvent","currentlyUnavailableVariantsMap","_onVariantSelectionChanged","changedVariantType","newVariantValue","variantTypeId","id","changedVariantController","prevVariantValue","selectedValue","selectedVariantValues","_getSelectedVariants","selectedVariantProduct","_getSelectedVariantProduct","_loadVariantProductDetails","variants","x","_filterUnavailableVariants","Object","values","forEach","variantController","push","isAnyVariantSelected","variantProducts","variantProduct","isProductForCurrentSelection","every","selectedVariantOption","variantId","availabilityMessage","disabled","exists","isAvailable","preselectSingleAvailable","isEmpty","variantType","name","selector","filterVariants","selectedVariant","beforeLoadEvent","Event","trigger","isDefaultPrevented","blockUI","selectedVariants","isSellPriceVisible","$sellPriceFormatted","is","ajax","R","data","a","ItemID","itemId","Dim1","Dim2","Dim3","CanHandleDisallowedBuyDims","ImageWidth","previewImageWidth","ImgMod","previewImageMode","InclVat","sellPrice","inclVat","includeWarehouseStock","priceVisible","always","unblockUI","done","variantProductDetails","_updateViewProductWithNewData","newData","IsMainProd","isVariantProductOfProductWithVariants","$priceFromText","oldStockCssClass","toggle","productId","ProductID","prodno","ProdNo","FullTitle","reportProductDetailsView","ImageURL","mainImage","ImageID","ImageText","description","actualWidth","ImageActualWidth","actualHeight","ImageActualHeight","thumbnailUrl","ImageRelURL","previewUrl","fullSizeUrl","ImageLBURL","displayWidth","ImagePreviewDisplayWidth","displayHeight","ImagePreviewDisplayHeight","$mainImage","attr","galleryId","$mainImageGalleryLink","closest","stockText","StockText","stockColor","StockColor","stockCssClass","$stockText","StockCssClass","$addProductToCart","hasClass","removeClass","addClass","hasDiscountCssClass","HasDiscount","$vippsHurtigkasseButton","AllowBuy","show","hide","stockDataColorVariable","css","style","setProperty","removeAttr","formatted","Price","raw","PriceRaw","sellPriceWithVAT","PriceInclVat","$sellPriceWithVatFormatted","sellPriceWithoutVAT","PriceExclVat","$sellPriceWithoutVatFormatted","beforePrice","OriginalPrice","$beforePriceFormatted","$beforePriceElements","add","parent","discountPrice","Discount","$discountPriceFormatted","$discountPriceElements","discountPercent","DiscountPercent","$discountPercentFormatted","$discountPercentElements","discountToDate","DiscountToDate","$discountToDateFormatted","$discountToDateElements","DiscountID","comparablePrice","ComparablePrice","$comparablePriceFormatted","factorPrice","FactorPrice","$factorPriceFormatted","productInFactorPrice","ProductInFactorPrice","$productInFactorPriceFormatted","$replacementProductContainer","ReplacementProductInfo","empty","html","supplierOrderInfoTooltip","supplierOrderInfo","shadowRoot","querySelector","$stockTextInfoIcon","InSupplierOrder","visible","update","warn","history","urlParts","href","split","resultUrl","removeQueryStringParam","setQueryStringParam","pushState","fail","errorResponse","_selectVariantControllersValues","preselectVariantTypeValue","y","indexOf","setSelected","_onHistoryPopState","evt","state","originalEvent","_selectVariantByName","variantTypeName","variantValueName","controller","caseInsensetiveEquals","setSelectedByName","variantProductsForSelection","filter","map","currentController","_getNotSelectedVariants","$selector","showPricesInclVat","viewBuilderName","loadAdditionalInfoDataAttrValue","let","loadAdditionalInfo","variantSelector","createVariantSelector","Map","entries","render","variantTypes","$elem","variantControllerKey","keys","_processVariants","variantTypeToProductInfoMap","selectedVariantTypes","selectedVariantOptions","discountInfo","processVariants","initialVariantProduct","preselectedVariantValue","preselectedVariantType","replaceState","$selectors","getSelectedVariantProduct","getNotSelectedVariants","selectVariantByName","selectVariantByProductId","variantProductId","selectVariantValue","_getPreselectedVariants","isVariantsSelectionValid","prodTitle","notSelectedVariantNames","notSelectedVariants","isSelectionValid","idx","options","processor","estore","PublicEStore","productsInCartMap","productsToCustomFieldIdsForOrderMap","vippsDialogModule","vippsDialog","shouldResetOnDecisionCallback","_addToCart","addToCartContracts","$handler","when","addToCart","dataContract","setTimeout","status","items","resultItem","itemStatus","statusMessage","parseInt","componentProduct","groupingComponent","componentProducts","groupingComponentProduct","_getFirstProductModelByProductId","productID","join","_showPublicEStoreError","tempOrderLineId","cartUrl","pefContract","exractedMessage","_toggleCartIndicator","animate","variantProductIds","variant","displayedProductId","isMainProductDisplayed","numberQuantityInCart","reduce","memo","qtyInCart","isProductInCart","$cartQuantity","$cartIndicator","effect","to","_addToCartHandler","topic","currentProduct","value","totalQuantityInTempOrderLine","_removeFromCartHandler","deletedProductId","isVariantProductOfDisplayedMainProductDeleted","some","variantProd","_emptyCartHandler","_getCartInfoHandler","cartInfo","detailedCartInfo","products","quantity","_getAddToCartContractFromContainer","buyType","parentProductId","parentProductUniqueId","packageQuantity","productUniqueId","productKey","productType","customFieldIdsForOrder","customFields","displayType","includeInOrder","fraction","tryParseNumberOrDefault","val","packageSize","initialQuantity","hasError","packageComponents","$packageComponentsContainer","groupingComponentProducts","$groupingProductContainer","isQuantityValid","isFormValid","validator","minQuantity","validate","ignore","$requiredField","element","productVariantsProcessor","componentContracts","concat","$groupingProductProductContainer","isSelected","groupingProductContracts","addToCartContract","$customFieldControl","customFieldId","customFieldValue","toString","imageId","componentOfPackageProductID","packageProductID","_processVippsHurtigkasseCheckout","vippsHurtigkasseComponent","deferred","Deferred","getTempOrderLines","tempOrderLinesResult","areOtherProductsInCart","$getProductContainerFor","lines","currentGroupPrices","getCurrentTotals","mainPriceGroup","g","group","productPrice","priceRaw","currentCartSum","i","linePrice","c","currentCartQuantity","dialogData","cartLink","cartCount","cartSum","setOnDecision","_onDecision","module","VippsBuyProductDialog","append","_addToCartAndResolveDeferred","reject","promise","decision","emptyCart","addToCartResult","resolve","_prepareCartForCheckout","proceedToCheckout","startCheckout","subscribe","getDetailedCartInfo","preventDefault","$buyButton","allContractsAreValid","$quantity","contracts","vippsHurtigkasse","addEventListener","persisted","jQuery","initQuantityModifyButtons","initQuantityModifyButtons2","flagsHandlerUrl","itemIds","archiveType","$flagsTarget","flags","flagDetails","class","FlagID","Name","appendTo","replaceEmptyString","_buildRatingView","ratingModel","stars","starredRatingValue","rating","wholeStar","incompleteStarValue","emptyStars","emptyStar","_buildStars","$ratingHtml","template","ratingData","commentsCount","ratingsCount","hasUserPostedReview","click","printPath","printUrl","pdfUrl","pdfTemplateId","fancyboxOptions","loop","hash","contractForShoppingList","showAddToCollectionPopup","additionalProductId","additionalProductModel","$wishListControl","isAddToWishListAction","isAvailableToBuy","updateWishList","prod","toggleClass","$quantityDiscountsContainer","$quantityDiscountsInfo","dim1","dim2","dim3","showPrice","quantityDiscountVisibility","format","viewProductName","$additionalProducts","trim","document","$additionalProductsContainer","listName","additionalProductIdsWithLinks","$prod","$links","reportProductListView","productListType","relatedProducts","relationExtData","additionalProdMap","_applyExtensionData","isAnyQuantityAffected","extData","extDataItem","variantsProc","itemID","singleProduct","additionalProd","_getAdditionalProduct","relationID","quantityInRelation","variantValue","_getSelectedVariantTypeToValueNamePairs","namePairs","relationId","_oneTimeVariantProdUpdateHandler","unsubscribe","valueName","typeName","groupType","groupId","mainProductVariantsProcessor","relationIds","relationExtensionData","mainVariantValueDetails","$extDataGridsContainer","extensionDataGridTemplateCompiled","visiblePositionMap","remove","elem","variantTypeExtData","gridModel","gridTitle","columns","rows","gridHtml","relProdExtDataArray","relProdExtData","visiblePosition","rowId","groupName","position","extDataMap","row","$priceTotalsElements","additionalsGroup","defaultGroup","defaultEmptyText","updateTimer","_currentTotals","cache","_setResults","groupedTotals","totalsMap","onTotalsUpdatedEvent","hasDiscount","origPrice","price","totalsValue","$elemContainer","totals","discPrice","_updatePriceTotals","productContract","productkey","prodId","cacheKey","JSON","stringify","async","params","errResp","errorMessage","clearTimeout","BuyMode","SingleProduct","MultipleProducts","AllProducts","TemplateMarkup","GroupingProductDefault","GroupingProductV2","groupingProductMarkup","groupingProductTemplate","isInitializing","docContentMap","_getGroupingComponentProduct","componentUniqueId","groupingProductComponent","_getGroupingComponent","_getGroupingComponentTemplate","groupingProductId","componentTemplate","parse","sort","orderNo","_setPriceImpact","$productPriceImpact","currencyCode","toLocaleString","minimumFractionDigits","maximumFractionDigits","_setGroupingComponentStockInfo","$componentContainer","$stockInfoContainer","_toggleProductSelected","_setAllComponentProductsNotSelected","buyMode","_toggleQuantityValueInComponent","$allExceptEditedInput","not","_setupControlElements","$selectProductInput","$allExceptCheckedComponentSelectors","prop","event","imageItem","imageItemSelected","imageLinkItemSelected","width","height","$quantityInput","minAllowedQuantityDataAttr","quantityValue","$selectProduct","$infoLink","$moreInfoCont","$moreInfoContTeaser","$moreInfoContContent","hasOwnProperty","collapse","teaser","content","_setVariantProductValues","groupingProductIndex","_setProductContainerValues","$groupingProductImage","$groupingProductVariantImage","image","currentQuantity","uniqueid","uniquekey","uniqueKey","productid","_generateGroupingProduct","templateData","VariantViewType","0","1","2","3","4","5","6","7","8","ComponentViewType","Collapsed","Expanded","settings","showMoreInfoLink","showMoreInfoLinkForComponents","groupingComponentContainer","$groupingComponentContainer","$collapseExpandComponent","$collapseExpandCont","$groupingComponentProductContainer","_setup","productContainer","stopPropagation","preselectedVariantProduct","isPreSelected","$groupingProductTemplateContainer","innerText","mainProductUniqueId","_setGroupingComponentPrices","groupingComponentProductPrices","selectedPrice","sellPriceFormatted","diffPrice","nonSelectedPrice","_$getProductContainerFor","_tryParseNumberOrDefault","rawValue","defaultValue","parsed","parseFloat","trimAndLowerCase","str","str1","str2","parsedResponseBody","responseText","ExceptionMessage","Message","statusText","$this","button","label","labelQuantityText","_allowMinBreak","_stepAttr","_minAttrAllowedQuantity","_minDataAttrAllowedQuantity","_minAllowedQuantity","Math","max","_quantity","userTypedQuantity","_disableDecreaseButton","_enableDecreaseButton","_updateView","newQuantityValue","_validateDecreaseAction","_getDecreasedQuantity","_triggerQuantityInput","_getIncreasedQuantity","formatValueFlag","quantityFormated","_formatQuantity","toFixed","dataAttributes","quantityMin","quantityMax","round","umwAssets","ctx","mainPanelId","$mainPanel"],"mappings":"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"}