/// <summary>
        /// Updates the product variant attribute value
        /// </summary>
        /// <param name="productVariantAttributeValue">The product variant attribute value</param>
        public void UpdateProductVariantAttributeValue(ProductVariantAttributeValue productVariantAttributeValue)
        {
            if (productVariantAttributeValue == null)
            {
                throw new ArgumentNullException("productVariantAttributeValue");
            }

            productVariantAttributeValue.Name = CommonHelper.EnsureNotNull(productVariantAttributeValue.Name);
            productVariantAttributeValue.Name = CommonHelper.EnsureMaximumLength(productVariantAttributeValue.Name, 100);


            if (!_context.IsAttached(productVariantAttributeValue))
            {
                _context.ProductVariantAttributeValues.Attach(productVariantAttributeValue);
            }

            _context.SaveChanges();

            if (this.CacheEnabled)
            {
                _cacheManager.RemoveByPattern(PRODUCTATTRIBUTES_PATTERN_KEY);
                _cacheManager.RemoveByPattern(PRODUCTVARIANTATTRIBUTES_PATTERN_KEY);
                _cacheManager.RemoveByPattern(PRODUCTVARIANTATTRIBUTEVALUES_PATTERN_KEY);
            }
        }
        /// <summary>
        /// Gets a product variant attribute value
        /// </summary>
        /// <param name="ProductVariantAttributeValueID">Product variant attribute value identifier</param>
        /// <returns>Product variant attribute value</returns>
        public static ProductVariantAttributeValue GetProductVariantAttributeValueByID(int ProductVariantAttributeValueID)
        {
            if (ProductVariantAttributeValueID == 0)
            {
                return(null);
            }

            string key  = string.Format(PRODUCTVARIANTATTRIBUTEVALUES_BY_ID_KEY, ProductVariantAttributeValueID);
            object obj2 = NopCache.Get(key);

            if (ProductAttributeManager.CacheEnabled && (obj2 != null))
            {
                return((ProductVariantAttributeValue)obj2);
            }

            DBProductVariantAttributeValue dbItem = DBProviderManager <DBProductAttributeProvider> .Provider.GetProductVariantAttributeValueByID(ProductVariantAttributeValueID);

            ProductVariantAttributeValue productVariantAttributeValue = DBMapping(dbItem);

            if (ProductAttributeManager.CacheEnabled)
            {
                NopCache.Max(key, productVariantAttributeValue);
            }
            return(productVariantAttributeValue);
        }
        /// <summary>
        /// Get product variant attribute values
        /// </summary>
        /// <param name="Attributes">Attributes</param>
        /// <returns>Product variant attribute values</returns>
        public static ProductVariantAttributeValueCollection ParseProductVariantAttributeValues(string Attributes)
        {
            ProductVariantAttributeValueCollection pvaValues     = new ProductVariantAttributeValueCollection();
            ProductVariantAttributeCollection      pvaCollection = ParseProductVariantAttributes(Attributes);

            foreach (ProductVariantAttribute pva in pvaCollection)
            {
                if (!pva.ShouldHaveValues)
                {
                    continue;
                }

                List <string> pvaValuesStr = ParseValues(Attributes, pva.ProductVariantAttributeID);
                foreach (string pvaValueStr in pvaValuesStr)
                {
                    if (!String.IsNullOrEmpty(pvaValueStr))
                    {
                        int pvaValueID = 0;
                        if (int.TryParse(pvaValueStr, out pvaValueID))
                        {
                            ProductVariantAttributeValue pvaValue = ProductAttributeManager.GetProductVariantAttributeValueByID(pvaValueID);
                            if (pvaValue != null)
                            {
                                pvaValues.Add(pvaValue);
                            }
                        }
                    }
                }
            }
            return(pvaValues);
        }
        protected void btnAdd_Click(object sender, EventArgs e)
        {
            try
            {
                ProductVariantAttribute productVariantAttribute = this.ProductAttributeService.GetProductVariantAttributeById(this.ProductVariantAttributeId);
                if (productVariantAttribute != null)
                {
                    var productVariantAttributeValue = new ProductVariantAttributeValue()
                    {
                        ProductVariantAttributeId = productVariantAttribute.ProductVariantAttributeId,
                        Name = txtNewName.Text,
                        PriceAdjustment= txtNewPriceAdjustment.Value,
                        WeightAdjustment= txtNewWeightAdjustment.Value,
                        IsPreSelected= cbNewIsPreSelected.Checked,
                        DisplayOrder= txtNewDisplayOrder.Value
                    };

                    this.ProductAttributeService.InsertProductVariantAttributeValue(productVariantAttributeValue);

                    SaveLocalizableContent(productVariantAttributeValue);

                    BindData();

                    txtNewName.Text = string.Empty;
                    txtNewPriceAdjustment.Value = 0;
                    txtNewWeightAdjustment.Value = 0;
                    txtNewDisplayOrder.Value = 1;
                }
            }
            catch (Exception exc)
            {
                ProcessException(exc);
            }
        }
        /// <summary>
        /// Formats attributes
        /// </summary>
        /// <param name="productVariant">Product variant</param>
        /// <param name="Attributes">Attributes</param>
        /// <param name="customer">Customer</param>
        /// <param name="Serapator">Serapator</param>
        /// <param name="HTMLEncode">A value indicating whether to encode (HTML) values</param>
        /// <returns>Attributes</returns>
        public static string FormatAttributes(ProductVariant productVariant, string Attributes,
                                              Customer customer, string Serapator, bool HTMLEncode)
        {
            StringBuilder result = new StringBuilder();

            ProductVariantAttributeCollection pvaCollection = ParseProductVariantAttributes(Attributes);

            foreach (ProductVariantAttribute pva in pvaCollection)
            {
                List <string> valuesStr = ParseValues(Attributes, pva.ProductVariantAttributeID);
                foreach (string valueStr in valuesStr)
                {
                    string pvaAttribute = string.Empty;
                    if (!pva.ShouldHaveValues)
                    {
                        pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.Name, valueStr);
                    }
                    else
                    {
                        ProductVariantAttributeValue pvaValue = ProductAttributeManager.GetProductVariantAttributeValueByID(Convert.ToInt32(valueStr));
                        if (pvaValue != null)
                        {
                            pvaAttribute = string.Format("{0}: {1}", pva.ProductAttribute.Name, pvaValue.Name);
                            decimal priceAdjustmentBase = TaxManager.GetPrice(productVariant, pvaValue.PriceAdjustment, customer);
                            decimal priceAdjustment     = CurrencyManager.ConvertCurrency(priceAdjustmentBase, CurrencyManager.PrimaryStoreCurrency, NopContext.Current.WorkingCurrency);
                            if (priceAdjustmentBase > 0)
                            {
                                string priceAdjustmentStr = PriceHelper.FormatPrice(priceAdjustment, false, false);
                                pvaAttribute += string.Format(" [+{0}]", priceAdjustmentStr);
                            }
                        }
                    }

                    if (!String.IsNullOrEmpty(pvaAttribute))
                    {
                        result.Append(Serapator);
                        if (HTMLEncode)
                        {
                            result.Append(HttpUtility.HtmlEncode(pvaAttribute));
                        }
                        else
                        {
                            result.Append(pvaAttribute);
                        }
                    }
                }
            }
            return(result.ToString());
        }
        private static ProductVariantAttributeValueCollection DBMapping(DBProductVariantAttributeValueCollection dbCollection)
        {
            if (dbCollection == null)
            {
                return(null);
            }

            ProductVariantAttributeValueCollection collection = new ProductVariantAttributeValueCollection();

            foreach (DBProductVariantAttributeValue dbItem in dbCollection)
            {
                ProductVariantAttributeValue item = DBMapping(dbItem);
                collection.Add(item);
            }

            return(collection);
        }
        /// <summary>
        /// Updates the product variant attribute value
        /// </summary>
        /// <param name="ProductVariantAttributeValueID">The product variant attribute value identifier</param>
        /// <param name="ProductVariantAttributeID">The product variant attribute mapping identifier</param>
        /// <param name="Name">The product variant attribute name</param>
        /// <param name="PriceAdjustment">The price adjustment</param>
        /// <param name="WeightAdjustment">The weight adjustment</param>
        /// <param name="IsPreSelected">The value indicating whether the value is pre-selected</param>
        /// <param name="DisplayOrder">The display order</param>
        /// <returns>Product variant attribute value</returns>
        public static ProductVariantAttributeValue UpdateProductVariantAttributeValue(int ProductVariantAttributeValueID,
                                                                                      int ProductVariantAttributeID, string Name, decimal PriceAdjustment,
                                                                                      decimal WeightAdjustment, bool IsPreSelected, int DisplayOrder)
        {
            DBProductVariantAttributeValue dbItem = DBProviderManager <DBProductAttributeProvider> .Provider.UpdateProductVariantAttributeValue(ProductVariantAttributeValueID,
                                                                                                                                                ProductVariantAttributeID, Name, PriceAdjustment, WeightAdjustment, IsPreSelected, DisplayOrder);

            ProductVariantAttributeValue productVariantAttributeValue = DBMapping(dbItem);

            if (ProductAttributeManager.CacheEnabled)
            {
                NopCache.RemoveByPattern(PRODUCTATTRIBUTES_PATTERN_KEY);
                NopCache.RemoveByPattern(PRODUCTVARIANTATTRIBUTES_PATTERN_KEY);
                NopCache.RemoveByPattern(PRODUCTVARIANTATTRIBUTEVALUES_PATTERN_KEY);
            }

            return(productVariantAttributeValue);
        }
        private static ProductVariantAttributeValue DBMapping(DBProductVariantAttributeValue dbItem)
        {
            if (dbItem == null)
            {
                return(null);
            }

            ProductVariantAttributeValue item = new ProductVariantAttributeValue();

            item.ProductVariantAttributeValueID = dbItem.ProductVariantAttributeValueID;
            item.ProductVariantAttributeID      = dbItem.ProductVariantAttributeID;
            item.Name             = dbItem.Name;
            item.PriceAdjustment  = dbItem.PriceAdjustment;
            item.WeightAdjustment = dbItem.WeightAdjustment;
            item.IsPreSelected    = dbItem.IsPreSelected;
            item.DisplayOrder     = dbItem.DisplayOrder;

            return(item);
        }
        /// <summary>
        /// Creates a copy of product with all depended data
        /// </summary>
        /// <param name="productId">The product identifier</param>
        /// <param name="name">The name of product duplicate</param>
        /// <param name="isPublished">A value indicating whether the product duplicate should be published</param>
        /// <param name="copyImages">A value indicating whether the product images should be copied</param>
        /// <returns>Product entity</returns>
        public Product DuplicateProduct(int productId, string name,
            bool isPublished, bool copyImages)
        {
            var product = GetProductById(productId);
            if (product == null)
                return null;

            Product productCopy = null;
            //uncomment this line to support transactions
            //using (var scope = new System.Transactions.TransactionScope())
            {
                // product
                productCopy = new Product()
                {
                    Name = name,
                    ShortDescription = product.ShortDescription,
                    FullDescription = product.FullDescription,
                    AdminComment = product.AdminComment,
                    TemplateId = product.TemplateId,
                    ShowOnHomePage = product.ShowOnHomePage,
                    MetaKeywords = product.MetaKeywords,
                    MetaDescription = product.MetaDescription,
                    MetaTitle = product.MetaTitle,
                    SEName = product.SEName,
                    AllowCustomerReviews = product.AllowCustomerReviews,
                    AllowCustomerRatings = product.AllowCustomerRatings,
                    Published = isPublished,
                    Deleted = product.Deleted,
                    CreatedOn = DateTime.UtcNow,
                    UpdatedOn = DateTime.UtcNow
                };
                InsertProduct(productCopy);

                if (productCopy == null)
                    return null;

                var languages = IoC.Resolve<ILanguageService>().GetAllLanguages(true);

                //localization
                foreach (var lang in languages)
                {
                    var productLocalized = GetProductLocalizedByProductIdAndLanguageId(product.ProductId, lang.LanguageId);
                    if (productLocalized != null)
                    {
                        var productLocalizedCopy = new ProductLocalized()
                        {
                            ProductId = productCopy.ProductId,
                            LanguageId = productLocalized.LanguageId,
                            Name = productLocalized.Name,
                            ShortDescription = productLocalized.ShortDescription,
                            FullDescription = productLocalized.FullDescription,
                            MetaKeywords = productLocalized.MetaKeywords,
                            MetaDescription = productLocalized.MetaDescription,
                            MetaTitle = productLocalized.MetaTitle,
                            SEName = productLocalized.SEName
                        };
                        InsertProductLocalized(productLocalizedCopy);
                    }
                }

                // product pictures
                if (copyImages)
                {
                    foreach (var productPicture in product.ProductPictures)
                    {
                        var picture = productPicture.Picture;

                        var pictureCopy = IoC.Resolve<IPictureService>().InsertPicture(picture.PictureBinary,
                            picture.MimeType,
                            picture.IsNew);

                        InsertProductPicture(new ProductPicture()
                        {
                            ProductId = productCopy.ProductId,
                            PictureId = pictureCopy.PictureId,
                            DisplayOrder = productPicture.DisplayOrder
                        });
                    }
                }

                // product <-> categories mappings
                foreach (var productCategory in product.ProductCategories)
                {
                    var productCategoryCopy = new ProductCategory()
                    {
                        ProductId = productCopy.ProductId,
                        CategoryId = productCategory.CategoryId,
                        IsFeaturedProduct = productCategory.IsFeaturedProduct,
                        DisplayOrder = productCategory.DisplayOrder
                    };

                    IoC.Resolve<ICategoryService>().InsertProductCategory(productCategoryCopy);
                }

                // product <-> manufacturers mappings
                foreach (var productManufacturers in product.ProductManufacturers)
                {
                    var productManufacturerCopy = new ProductManufacturer()
                    {
                        ProductId = productCopy.ProductId,
                        ManufacturerId = productManufacturers.ManufacturerId,
                        IsFeaturedProduct = productManufacturers.IsFeaturedProduct,
                        DisplayOrder = productManufacturers.DisplayOrder
                    };

                    IoC.Resolve<IManufacturerService>().InsertProductManufacturer(productManufacturerCopy);
                }

                // product <-> releated products mappings
                foreach (var relatedProduct in product.RelatedProducts)
                {
                    InsertRelatedProduct(
                        new RelatedProduct()
                        {
                            ProductId1 = productCopy.ProductId,
                            ProductId2 = relatedProduct.ProductId2,
                            DisplayOrder = relatedProduct.DisplayOrder
                        });
                }

                // product specifications
                foreach (var productSpecificationAttribute in IoC.Resolve<ISpecificationAttributeService>().GetProductSpecificationAttributesByProductId(product.ProductId))
                {
                    var psaCopy = new ProductSpecificationAttribute()
                    {
                        ProductId = productCopy.ProductId,
                        SpecificationAttributeOptionId = productSpecificationAttribute.SpecificationAttributeOptionId,
                        AllowFiltering = productSpecificationAttribute.AllowFiltering,
                        ShowOnProductPage = productSpecificationAttribute.ShowOnProductPage,
                        DisplayOrder = productSpecificationAttribute.DisplayOrder
                    };
                    IoC.Resolve<ISpecificationAttributeService>().InsertProductSpecificationAttribute(psaCopy);
                }

                // product variants
                var productVariants = GetProductVariantsByProductId(product.ProductId, true);
                foreach (var productVariant in productVariants)
                {
                    // product variant picture
                    int pictureId = 0;
                    if (copyImages)
                    {
                        var picture = productVariant.Picture;
                        if (picture != null)
                        {
                            var pictureCopy = IoC.Resolve<IPictureService>().InsertPicture(picture.PictureBinary, picture.MimeType, picture.IsNew);
                            pictureId = pictureCopy.PictureId;
                        }
                    }

                    // product variant download & sample download
                    int downloadId = productVariant.DownloadId;
                    int sampleDownloadId = productVariant.SampleDownloadId;
                    if (productVariant.IsDownload)
                    {
                        var download = productVariant.Download;
                        if (download != null)
                        {
                            var downloadCopy = new Download()
                                {
                                    UseDownloadUrl = download.UseDownloadUrl,
                                    DownloadUrl = download.DownloadUrl,
                                    DownloadBinary = download.DownloadBinary,
                                    ContentType = download.ContentType,
                                    Filename = download.Filename,
                                    Extension = download.Extension,
                                    IsNew = download.IsNew
                                };
                            IoC.Resolve<IDownloadService>().InsertDownload(downloadCopy);
                            downloadId = downloadCopy.DownloadId;
                        }

                        if (productVariant.HasSampleDownload)
                        {
                            var sampleDownload = productVariant.SampleDownload;
                            if (sampleDownload != null)
                            {
                                var sampleDownloadCopy = new Download()
                                {
                                    UseDownloadUrl = sampleDownload.UseDownloadUrl,
                                    DownloadUrl = sampleDownload.DownloadUrl,
                                    DownloadBinary = sampleDownload.DownloadBinary,
                                    ContentType = sampleDownload.ContentType,
                                    Filename = sampleDownload.Filename,
                                    Extension = sampleDownload.Extension,
                                    IsNew = sampleDownload.IsNew
                                };
                                IoC.Resolve<IDownloadService>().InsertDownload(sampleDownloadCopy);
                                sampleDownloadId = sampleDownloadCopy.DownloadId;
                            }
                        }
                    }

                    // product variant
                    var productVariantCopy = new ProductVariant()
                    {
                        ProductId = productCopy.ProductId,
                        Name = productVariant.Name,
                        SKU = productVariant.SKU,
                        Description = productVariant.Description,
                        AdminComment = productVariant.AdminComment,
                        ManufacturerPartNumber = productVariant.ManufacturerPartNumber,
                        IsGiftCard = productVariant.IsGiftCard,
                        GiftCardType = productVariant.GiftCardType,
                        IsDownload = productVariant.IsDownload,
                        DownloadId = downloadId,
                        UnlimitedDownloads = productVariant.UnlimitedDownloads,
                        MaxNumberOfDownloads = productVariant.MaxNumberOfDownloads,
                        DownloadExpirationDays = productVariant.DownloadExpirationDays,
                        DownloadActivationType = productVariant.DownloadActivationType,
                        HasSampleDownload = productVariant.HasSampleDownload,
                        SampleDownloadId = sampleDownloadId,
                        HasUserAgreement = productVariant.HasUserAgreement,
                        UserAgreementText = productVariant.UserAgreementText,
                        IsRecurring = productVariant.IsRecurring,
                        CycleLength = productVariant.CycleLength,
                        CyclePeriod = productVariant.CyclePeriod,
                        TotalCycles = productVariant.TotalCycles,
                        IsShipEnabled = productVariant.IsShipEnabled,
                        IsFreeShipping = productVariant.IsFreeShipping,
                        AdditionalShippingCharge = productVariant.AdditionalShippingCharge,
                        IsTaxExempt = productVariant.IsTaxExempt,
                        TaxCategoryId = productVariant.TaxCategoryId,
                        ManageInventory = productVariant.ManageInventory,
                        StockQuantity = productVariant.StockQuantity,
                        DisplayStockAvailability = productVariant.DisplayStockAvailability,
                        DisplayStockQuantity = productVariant.DisplayStockQuantity,
                        MinStockQuantity = productVariant.MinStockQuantity,
                        LowStockActivityId = productVariant.LowStockActivityId,
                        NotifyAdminForQuantityBelow = productVariant.NotifyAdminForQuantityBelow,
                        Backorders = productVariant.Backorders,
                        OrderMinimumQuantity = productVariant.OrderMinimumQuantity,
                        OrderMaximumQuantity = productVariant.OrderMaximumQuantity,
                        WarehouseId = productVariant.WarehouseId,
                        DisableBuyButton = productVariant.DisableBuyButton,
                        CallForPrice = productVariant.CallForPrice,
                        Price = productVariant.Price,
                        OldPrice = productVariant.OldPrice,
                        ProductCost = productVariant.ProductCost,
                        CustomerEntersPrice = productVariant.CustomerEntersPrice,
                        MinimumCustomerEnteredPrice = productVariant.MinimumCustomerEnteredPrice,
                        MaximumCustomerEnteredPrice = productVariant.MaximumCustomerEnteredPrice,
                        Weight = productVariant.Weight,
                        Length = productVariant.Length,
                        Width = productVariant.Width,
                        Height = productVariant.Height,
                        PictureId = pictureId,
                        AvailableStartDateTime = productVariant.AvailableStartDateTime,
                        AvailableEndDateTime = productVariant.AvailableEndDateTime,
                        Published = productVariant.Published,
                        Deleted = productVariant.Deleted,
                        DisplayOrder = productVariant.DisplayOrder,
                        CreatedOn = DateTime.UtcNow,
                        UpdatedOn = DateTime.UtcNow
                    };

                    InsertProductVariant(productVariantCopy);

                    //localization
                    foreach (var lang in languages)
                    {
                        var productVariantLocalized = GetProductVariantLocalizedByProductVariantIdAndLanguageId(productVariant.ProductVariantId, lang.LanguageId);
                        if (productVariantLocalized != null)
                        {
                            var productVariantLocalizedCopy = new ProductVariantLocalized()
                            {
                                ProductVariantId = productVariantCopy.ProductVariantId,
                                LanguageId = productVariantLocalized.LanguageId,
                                Name = productVariantLocalized.Name,
                                Description = productVariantLocalized.Description
                            };
                            InsertProductVariantLocalized(productVariantLocalizedCopy);
                        }
                    }

                    // product variant <-> attributes mappings
                    foreach (var productVariantAttribute in IoC.Resolve<IProductAttributeService>().GetProductVariantAttributesByProductVariantId(productVariant.ProductVariantId))
                    {
                        var productVariantAttributeCopy = new ProductVariantAttribute()
                        {
                            ProductVariantId = productVariantCopy.ProductVariantId,
                            ProductAttributeId = productVariantAttribute.ProductAttributeId,
                            TextPrompt = productVariantAttribute.TextPrompt,
                            IsRequired = productVariantAttribute.IsRequired,
                            AttributeControlTypeId = productVariantAttribute.AttributeControlTypeId,
                            DisplayOrder = productVariantAttribute.DisplayOrder
                        };
                        IoC.Resolve<IProductAttributeService>().InsertProductVariantAttribute(productVariantAttributeCopy);

                        // product variant attribute values
                        var productVariantAttributeValues = IoC.Resolve<IProductAttributeService>().GetProductVariantAttributeValues(productVariantAttribute.ProductVariantAttributeId);
                        foreach (var productVariantAttributeValue in productVariantAttributeValues)
                        {
                            var pvavCopy = new ProductVariantAttributeValue()
                            {
                                ProductVariantAttributeId = productVariantAttributeCopy.ProductVariantAttributeId,
                                Name = productVariantAttributeValue.Name,
                                PriceAdjustment = productVariantAttributeValue.PriceAdjustment,
                                WeightAdjustment = productVariantAttributeValue.WeightAdjustment,
                                IsPreSelected = productVariantAttributeValue.IsPreSelected,
                                DisplayOrder = productVariantAttributeValue.DisplayOrder
                            };
                            IoC.Resolve<IProductAttributeService>().InsertProductVariantAttributeValue(pvavCopy);

                            //localization
                            foreach (var lang in languages)
                            {
                                var pvavLocalized = IoC.Resolve<IProductAttributeService>().GetProductVariantAttributeValueLocalizedByProductVariantAttributeValueIdAndLanguageId(productVariantAttributeValue.ProductVariantAttributeValueId, lang.LanguageId);
                                if (pvavLocalized != null)
                                {
                                    var pvavLocalizedCopy = new ProductVariantAttributeValueLocalized()
                                    {
                                        ProductVariantAttributeValueId = pvavCopy.ProductVariantAttributeValueId,
                                        LanguageId = pvavLocalized.LanguageId,
                                        Name = pvavLocalized.Name
                                    };
                                    IoC.Resolve<IProductAttributeService>().InsertProductVariantAttributeValueLocalized(pvavLocalizedCopy);
                                }
                            }
                        }
                    }
                    foreach (var combination in IoC.Resolve<IProductAttributeService>().GetAllProductVariantAttributeCombinations(productVariant.ProductVariantId))
                    {
                        var combinationCopy = new ProductVariantAttributeCombination()
                        {
                            ProductVariantId = productVariantCopy.ProductVariantId,
                            AttributesXml = combination.AttributesXml,
                            StockQuantity = combination.StockQuantity,
                            AllowOutOfStockOrders = combination.AllowOutOfStockOrders
                        };
                        IoC.Resolve<IProductAttributeService>().InsertProductVariantAttributeCombination(combinationCopy);
                    }

                    // product variant tier prices
                    foreach (var tierPrice in productVariant.TierPrices)
                    {
                        InsertTierPrice(
                            new TierPrice()
                            {
                                ProductVariantId = productVariantCopy.ProductVariantId,
                                Quantity = tierPrice.Quantity,
                                Price = tierPrice.Price
                            });
                    }

                    // product variant <-> discounts mapping
                    foreach (var discount in productVariant.AllDiscounts)
                    {
                        IoC.Resolve<IDiscountService>().AddDiscountToProductVariant(productVariantCopy.ProductVariantId, discount.DiscountId);
                    }

                    // prices by customer role
                    foreach (var crpp in productVariant.CustomerRoleProductPrices)
                    {
                        this.InsertCustomerRoleProductPrice(
                            new CustomerRoleProductPrice()
                            {
                                CustomerRoleId = crpp.CustomerRoleId,
                                ProductVariantId = productVariantCopy.ProductVariantId,
                                Price = crpp.Price
                            }
                            );
                    }
                }

                //uncomment this line to support transactions
                //scope.Complete();
            }

            return productCopy;
        }
        protected void SaveLocalizableContentGrid(ProductVariantAttributeValue pvav)
        {
            if (pvav == null)
                return;

            if (!this.HasLocalizableContent)
                return;

            foreach (GridViewRow row in gvProductVariantAttributeValues.Rows)
            {
                Repeater rptrLanguageDivs2 = row.FindControl("rptrLanguageDivs2") as Repeater;
                if (rptrLanguageDivs2 != null)
                {
                    HiddenField hfProductVariantAttributeValueId = row.FindControl("hfProductVariantAttributeValueId") as HiddenField;
                    int pvavId = int.Parse(hfProductVariantAttributeValueId.Value);
                    if (pvavId == pvav.ProductVariantAttributeValueId)
                    {
                        foreach (RepeaterItem item in rptrLanguageDivs2.Items)
                        {
                            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
                            {
                                var txtLocalizedName = (TextBox)item.FindControl("txtLocalizedName");
                                var lblLanguageId = (Label)item.FindControl("lblLanguageId");

                                int languageId = int.Parse(lblLanguageId.Text);
                                string name = txtLocalizedName.Text;

                                bool allFieldsAreEmpty = string.IsNullOrEmpty(name);

                                var content = ProductAttributeManager.GetProductVariantAttributeValueLocalizedByProductVariantAttributeValueIdAndLanguageId(pvav.ProductVariantAttributeValueId, languageId);
                                if (content == null)
                                {
                                    if (!allFieldsAreEmpty && languageId > 0)
                                    {
                                        //only insert if one of the fields are filled out (avoid too many empty records in db...)
                                        content = ProductAttributeManager.InsertProductVariantAttributeValueLocalized(pvav.ProductVariantAttributeValueId,
                                            languageId, name);
                                    }
                                }
                                else
                                {
                                    if (languageId > 0)
                                    {
                                        content = ProductAttributeManager.UpdateProductVariantAttributeValueLocalized(content.ProductVariantAttributeValueLocalizedId,
                                            content.ProductVariantAttributeValueId, languageId, name);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        protected void SaveLocalizableContent(ProductVariantAttributeValue pvav)
        {
            if (pvav == null)
                return;

            if (!this.HasLocalizableContent)
                return;

            foreach (RepeaterItem item in rptrLanguageDivs.Items)
            {
                if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
                {
                    var txtNewLocalizedName = (TextBox)item.FindControl("txtNewLocalizedName");
                    var lblLanguageId = (Label)item.FindControl("lblLanguageId");

                    int languageId = int.Parse(lblLanguageId.Text);
                    string name = txtNewLocalizedName.Text;

                    bool allFieldsAreEmpty = string.IsNullOrEmpty(name);

                    var content = this.ProductAttributeService.GetProductVariantAttributeValueLocalizedByProductVariantAttributeValueIdAndLanguageId(pvav.ProductVariantAttributeValueId, languageId);
                    if (content == null)
                    {
                        if (!allFieldsAreEmpty && languageId > 0)
                        {
                            //only insert if one of the fields are filled out (avoid too many empty records in db...)
                            content = new ProductVariantAttributeValueLocalized()
                            {
                                ProductVariantAttributeValueId = pvav.ProductVariantAttributeValueId,
                                LanguageId = languageId,
                                Name = name
                            };
                            this.ProductAttributeService.InsertProductVariantAttributeValueLocalized(content);
                        }
                    }
                    else
                    {
                        if (languageId > 0)
                        {
                            content.LanguageId=languageId;
                            content.Name=name;
                            this.ProductAttributeService.UpdateProductVariantAttributeValueLocalized(content);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Updates the product variant attribute value
        /// </summary>
        /// <param name="productVariantAttributeValue">The product variant attribute value</param>
        public void UpdateProductVariantAttributeValue(ProductVariantAttributeValue productVariantAttributeValue)
        {
            if (productVariantAttributeValue == null)
                throw new ArgumentNullException("productVariantAttributeValue");

            productVariantAttributeValue.Name = CommonHelper.EnsureNotNull(productVariantAttributeValue.Name);
            productVariantAttributeValue.Name = CommonHelper.EnsureMaximumLength(productVariantAttributeValue.Name, 100);

            if (!_context.IsAttached(productVariantAttributeValue))
                _context.ProductVariantAttributeValues.Attach(productVariantAttributeValue);

            _context.SaveChanges();

            if (this.CacheEnabled)
            {
                _cacheManager.RemoveByPattern(PRODUCTATTRIBUTES_PATTERN_KEY);
                _cacheManager.RemoveByPattern(PRODUCTVARIANTATTRIBUTES_PATTERN_KEY);
                _cacheManager.RemoveByPattern(PRODUCTVARIANTATTRIBUTEVALUES_PATTERN_KEY);
            }
        }