public void Can_save_and_load_productVariantAttributeCombination()
        {
            var pvac = new ProductVariantAttributeCombination
            {
                AttributesXml         = "Some XML",
                StockQuantity         = 2,
                AllowOutOfStockOrders = true,
                Sku = "Sku1",
                ManufacturerPartNumber = "ManufacturerPartNumber1",
                Gtin            = "Gtin1",
                OverriddenPrice = 0.01M,
                Product         = GetTestProduct()
            };

            var fromDb = SaveAndLoadEntity(pvac);

            fromDb.ShouldNotBeNull();
            fromDb.AttributesXml.ShouldEqual("Some XML");
            fromDb.StockQuantity.ShouldEqual(2);
            fromDb.AllowOutOfStockOrders.ShouldEqual(true);
            fromDb.Sku.ShouldEqual("Sku1");
            fromDb.ManufacturerPartNumber.ShouldEqual("ManufacturerPartNumber1");
            fromDb.Gtin.ShouldEqual("Gtin1");
            fromDb.OverriddenPrice.ShouldEqual(0.01M);
        }
        public virtual void UpdateProductVariantAttributeCombination(ProductVariantAttributeCombination combination)
        {
            if (combination == null)
            {
                throw new ArgumentNullException("combination");
            }

            //if (combination.IsDefaultCombination)
            //{
            //	EnsureSingleDefaultVariant(combination);
            //}
            //else
            //{
            //	// check if it was default before modification...
            //	// but make it Type-Safe (resistant to code refactoring ;-))
            //	Expression<Func<ProductVariantAttributeCombination, bool>> expr = x => x.IsDefaultCombination;
            //	string propertyToCheck = expr.ExtractPropertyInfo().Name;

            //	object originalValue = null;
            //	if (_productVariantAttributeCombinationRepository.GetModifiedProperties(combination).TryGetValue(propertyToCheck, out originalValue))
            //	{
            //		bool wasDefault = (bool)originalValue;
            //		if (wasDefault)
            //		{
            //			// we can't uncheck the default variant within a combination list,
            //			// we would't have a default combination anymore.
            //			combination.IsDefaultCombination = true;
            //		}
            //	}
            //}

            _pvacRepository.Update(combination);
        }
예제 #3
0
        public void Can_save_and_load_productVariantAttributeCombination()
        {
            var pvac = new ProductVariantAttributeCombination
            {
                AttributesXml         = "Some XML",
                StockQuantity         = 2,
                AllowOutOfStockOrders = true,
                ProductVariant        = new ProductVariant
                {
                    Name         = "Product variant name 1",
                    CreatedOnUtc = new DateTime(2010, 01, 03),
                    UpdatedOnUtc = new DateTime(2010, 01, 04),
                    Product      = new Product()
                    {
                        Name         = "Name 1",
                        Published    = true,
                        Deleted      = false,
                        CreatedOnUtc = new DateTime(2010, 01, 01),
                        UpdatedOnUtc = new DateTime(2010, 01, 02)
                    }
                }
            };

            var fromDb = SaveAndLoadEntity(pvac);

            fromDb.ShouldNotBeNull();
            fromDb.AttributesXml.ShouldEqual("Some XML");
            fromDb.StockQuantity.ShouldEqual(2);
            fromDb.AllowOutOfStockOrders.ShouldEqual(true);
        }
예제 #4
0
        public void Can_get_final_product_price_with_variant_combination_price()
        {
            var product = new Product
            {
                Id    = 1,
                Name  = "Product name 1",
                Price = 9.99M,
                CustomerEntersPrice = false,
                Published           = true,
            };

            var combination = new ProductVariantAttributeCombination
            {
                Id        = 1,
                Price     = 18.90M,
                ProductId = 1
            };

            product.MergeWithCombination(combination);

            _discountService.Expect(ds => ds.GetAllDiscounts(DiscountType.AssignedToCategories)).Return(new List <Discount>());
            _discountService.Expect(ds => ds.GetAllDiscounts(DiscountType.AssignedToManufacturers)).Return(new List <Discount>());

            _priceCalcService.GetFinalPrice(product, null, 0, true, 1).ShouldEqual(18.90M);
        }
        public virtual void InsertProductVariantAttributeCombination(ProductVariantAttributeCombination combination)
        {
            if (combination == null)
            {
                throw new ArgumentNullException("combination");
            }

            _pvacRepository.Insert(combination);
        }
예제 #6
0
        /// <summary>
        /// Deletes a product variant attribute combination
        /// </summary>
        /// <param name="combination">Product variant attribute combination</param>
        public virtual void DeleteProductVariantAttributeCombination(ProductVariantAttributeCombination combination)
        {
            if (combination == null)
            {
                throw new ArgumentNullException("combination");
            }

            _productVariantAttributeCombinationRepository.Delete(combination);

            //event notification
            _eventPublisher.EntityDeleted(combination);
        }
        protected void btnNewProductVariantAttributeCombination_Click(object sender, EventArgs e)
        {
            try
            {
                ProductVariant productVariant = this.ProductService.GetProductVariantById(this.ProductVariantId);
                if (productVariant != null)
                {
                    string attributes            = ctrlSelectProductAttributes.SelectedAttributes;
                    int    stockQuantity         = txtStockQuantity.Value;
                    bool   allowOutOfStockOrders = cbAllowOutOfStockOrders.Checked;

                    List <string> warnings = this.ShoppingCartService.GetShoppingCartItemAttributeWarnings(ShoppingCartTypeEnum.ShoppingCart,
                                                                                                           productVariant.ProductVariantId, attributes, 1, false);
                    if (warnings.Count > 0)
                    {
                        StringBuilder warningsSb = new StringBuilder();
                        for (int i = 0; i < warnings.Count; i++)
                        {
                            warningsSb.Append(Server.HtmlEncode(warnings[i]));
                            if (i != warnings.Count - 1)
                            {
                                warningsSb.Append("<br />");
                            }
                        }

                        pnlCombinationWarningsr.Visible = true;
                        lCombinationWarnings.Text       = warningsSb.ToString();
                    }
                    else
                    {
                        var combination = new ProductVariantAttributeCombination()
                        {
                            ProductVariantId      = productVariant.ProductVariantId,
                            AttributesXml         = attributes,
                            StockQuantity         = stockQuantity,
                            AllowOutOfStockOrders = allowOutOfStockOrders
                        };
                        this.ProductAttributeService.InsertProductVariantAttributeCombination(combination);
                    }
                    BindCombinations();
                }
            }
            catch (Exception exc)
            {
                processAjaxError(exc);
            }
        }
예제 #8
0
        public virtual void InsertProductVariantAttributeCombination(ProductVariantAttributeCombination combination)
        {
            if (combination == null)
            {
                throw new ArgumentNullException("combination");
            }

            //if (combination.IsDefaultCombination)
            //{
            //	EnsureSingleDefaultVariant(combination);
            //}

            _pvacRepository.Insert(combination);

            //event notification
            _eventPublisher.EntityInserted(combination);
        }
예제 #9
0
        public virtual Product GetProductByIdentificationNumber(
            string identificationNumber,
            out ProductVariantAttributeCombination attributeCombination,
            bool includeHidden = false,
            bool untracked     = true)
        {
            attributeCombination = null;

            if (string.IsNullOrWhiteSpace(identificationNumber))
            {
                return(null);
            }

            identificationNumber = identificationNumber.Trim();

            var pq =
                from x in untracked ? _productRepository.TableUntracked : _productRepository.Table
                where !x.Deleted && (x.Sku == identificationNumber || x.ManufacturerPartNumber == identificationNumber || x.Gtin == identificationNumber)
                select x;

            if (!includeHidden)
            {
                pq = pq.Where(x => x.Visibility <= ProductVisibility.SearchResults && x.Published);
            }

            var product = pq.FirstOrDefault();

            if (product != null)
            {
                return(product);
            }

            var pvaq =
                from x in untracked ? _productVariantAttributeCombinationRepository.TableUntracked : _productVariantAttributeCombinationRepository.Table
                where !x.Product.Deleted && (x.Sku == identificationNumber || x.ManufacturerPartNumber == identificationNumber || x.Gtin == identificationNumber)
                select x;

            if (!includeHidden)
            {
                pvaq = pvaq.Where(x => x.Product.Visibility <= ProductVisibility.SearchResults && x.Product.Published && x.IsActive);
            }

            attributeCombination = pvaq.FirstOrDefault();

            return(attributeCombination?.Product);
        }
        /// <summary>
        /// Updates a product variant attribute combination
        /// </summary>
        /// <param name="combination">Product variant attribute combination</param>
        public virtual void UpdateProductVariantAttributeCombination(ProductVariantAttributeCombination combination)
        {
            if (combination == null)
            {
                throw new ArgumentNullException("combination");
            }

            _productVariantAttributeCombinationRepository.Update(combination);

            //cache
            _cacheManager.RemoveByPattern(PRODUCTATTRIBUTES_PATTERN_KEY);
            _cacheManager.RemoveByPattern(PRODUCTVARIANTATTRIBUTES_PATTERN_KEY);
            _cacheManager.RemoveByPattern(PRODUCTVARIANTATTRIBUTEVALUES_PATTERN_KEY);
            _cacheManager.RemoveByPattern(PRODUCTVARIANTATTRIBUTECOMBINATIONS_PATTERN_KEY);

            //event notification
            _eventPublisher.EntityUpdated(combination);
        }
예제 #11
0
        private static dynamic ToDynamic(ProductVariantAttributeCombination attributeCombination, DataExporterContext ctx)
        {
            if (attributeCombination == null)
            {
                return(null);
            }

            dynamic result = new DynamicEntity(attributeCombination);

            result.DeliveryTime = ctx.DeliveryTimes.TryGetValue(attributeCombination.DeliveryTimeId ?? 0, out var deliveryTime)
                ? ToDynamic(deliveryTime, ctx)
                : null;

            result.QuantityUnit = ctx.QuantityUnits.TryGetValue(attributeCombination.QuantityUnitId ?? 0, out var quantityUnit)
                ? ToDynamic(quantityUnit, ctx)
                : null;

            return(result);
        }
예제 #12
0
        public void Can_save_and_load_productVariantAttributeCombination()
        {
            var pvac = new ProductVariantAttributeCombination
            {
                AttributesXml         = "Some XML",
                StockQuantity         = 2,
                Sku                   = "X1000",
                Price                 = 9.80M,
                AllowOutOfStockOrders = true,
                Product               = GetTestProduct()
            };

            var fromDb = SaveAndLoadEntity(pvac);

            fromDb.ShouldNotBeNull();
            fromDb.AttributesXml.ShouldEqual("Some XML");
            fromDb.StockQuantity.ShouldEqual(2);
            fromDb.Sku.ShouldEqual("X1000");
            fromDb.Price.ShouldEqual(9.80M);
            fromDb.AllowOutOfStockOrders.ShouldEqual(true);
        }
예제 #13
0
        private void ProcessAttributes(
            Product product,
            Product clone,
            string newName,
            bool copyImages,
            Dictionary <int, Picture> clonedPictures,
            IEnumerable <Language> languages)
        {
            // Former attribute id > clone
            var pvaMap = new Dictionary <int, ProductVariantAttribute>();

            // Former attribute value id > clone
            var pvavMap = new Dictionary <int, ProductVariantAttributeValue>();

            var pictureSeName = _pictureService.GetPictureSeName(newName);

            foreach (var pva in product.ProductVariantAttributes)
            {
                var pvaClone = new ProductVariantAttribute
                {
                    ProductAttributeId     = pva.ProductAttributeId,
                    TextPrompt             = pva.TextPrompt,
                    IsRequired             = pva.IsRequired,
                    AttributeControlTypeId = pva.AttributeControlTypeId,
                    DisplayOrder           = pva.DisplayOrder
                };

                clone.ProductVariantAttributes.Add(pvaClone);

                // Save associated value (used for combinations copying)
                pvaMap[pva.Id] = pvaClone;

                // Product variant attribute values
                foreach (var pvav in pva.ProductVariantAttributeValues)
                {
                    var pvavClone = new ProductVariantAttributeValue
                    {
                        Name             = pvav.Name,
                        Color            = pvav.Color,
                        PriceAdjustment  = pvav.PriceAdjustment,
                        WeightAdjustment = pvav.WeightAdjustment,
                        IsPreSelected    = pvav.IsPreSelected,
                        DisplayOrder     = pvav.DisplayOrder,
                        ValueTypeId      = pvav.ValueTypeId,
                        LinkedProductId  = pvav.LinkedProductId,
                        Quantity         = pvav.Quantity,
                        PictureId        = copyImages ? pvav.PictureId : 0                  // we'll clone this later
                    };

                    pvaClone.ProductVariantAttributeValues.Add(pvavClone);

                    // Save associated value (used for combinations copying)
                    pvavMap.Add(pvav.Id, pvavClone);
                }
            }

            // >>>>>> Commit
            Commit();

            // Attribute value localization
            foreach (var pvav in product.ProductVariantAttributes.SelectMany(x => x.ProductVariantAttributeValues).ToArray())
            {
                foreach (var lang in languages)
                {
                    var name = pvav.GetLocalized(x => x.Name, lang, false, false);
                    if (!String.IsNullOrEmpty(name))
                    {
                        var pvavClone = pvavMap.Get(pvav.Id);
                        if (pvavClone != null)
                        {
                            _localizedEntityService.SaveLocalizedValue(pvavClone, x => x.Name, name, lang.Id);
                        }
                    }
                }
            }

            // Clone attribute value images
            if (copyImages)
            {
                // Reduce value set to those with assigned pictures
                var allValueClonesWithPictures = pvavMap.Values.Where(x => x.PictureId > 0).ToArray();
                // Get those pictures for cloning
                var allPictures = _pictureService.GetPicturesByIds(allValueClonesWithPictures.Select(x => x.PictureId).ToArray(), true);

                foreach (var pvavClone in allValueClonesWithPictures)
                {
                    var picture = allPictures.FirstOrDefault(x => x.Id == pvavClone.PictureId);
                    if (picture != null)
                    {
                        var pictureClone = CopyPicture(picture, pictureSeName);
                        clonedPictures[pvavClone.PictureId] = pictureClone;
                        pvavClone.PictureId = pictureClone.Id;
                    }
                }
            }

            // >>>>>> Commit attributes & values
            Commit();

            // attribute combinations
            using (var scope = new DbContextScope(lazyLoading: false, forceNoTracking: false))
            {
                scope.LoadCollection(product, (Product p) => p.ProductVariantAttributeCombinations);
            }

            foreach (var combination in product.ProductVariantAttributeCombinations)
            {
                // Generate new AttributesXml according to new value IDs
                string newAttributesXml = "";
                var    parsedProductVariantAttributes = _productAttributeParser.ParseProductVariantAttributes(combination.AttributesXml);
                foreach (var oldPva in parsedProductVariantAttributes)
                {
                    if (!pvaMap.ContainsKey(oldPva.Id))
                    {
                        continue;
                    }

                    var newPva = pvaMap.Get(oldPva.Id);

                    if (newPva == null)
                    {
                        continue;
                    }

                    var oldPvaValuesStr = _productAttributeParser.ParseValues(combination.AttributesXml, oldPva.Id);
                    foreach (var oldPvaValueStr in oldPvaValuesStr)
                    {
                        if (newPva.ShouldHaveValues())
                        {
                            // attribute values
                            int oldPvaValue = oldPvaValueStr.Convert <int>();
                            if (pvavMap.ContainsKey(oldPvaValue))
                            {
                                var newPvav = pvavMap.Get(oldPvaValue);
                                if (newPvav != null)
                                {
                                    newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml, newPva, newPvav.Id.ToString());
                                }
                            }
                        }
                        else
                        {
                            // just a text
                            newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml, newPva, oldPvaValueStr);
                        }
                    }
                }

                var newAssignedPictureIds = new HashSet <string>();
                foreach (var strPicId in combination.AssignedPictureIds.EmptyNull().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    var newPic = clonedPictures.Get(strPicId.Convert <int>());
                    if (newPic != null)
                    {
                        newAssignedPictureIds.Add(newPic.Id.ToString(CultureInfo.InvariantCulture));
                    }
                }

                var combinationClone = new ProductVariantAttributeCombination
                {
                    AttributesXml         = newAttributesXml,
                    StockQuantity         = combination.StockQuantity,
                    AllowOutOfStockOrders = combination.AllowOutOfStockOrders,
                    Sku  = combination.Sku,
                    Gtin = combination.Gtin,
                    ManufacturerPartNumber = combination.ManufacturerPartNumber,
                    Price = combination.Price,
                    AssignedPictureIds = copyImages ? String.Join(",", newAssignedPictureIds) : null,
                    Length             = combination.Length,
                    Width               = combination.Width,
                    Height              = combination.Height,
                    BasePriceAmount     = combination.BasePriceAmount,
                    BasePriceBaseAmount = combination.BasePriceBaseAmount,
                    DeliveryTimeId      = combination.DeliveryTimeId,
                    QuantityUnitId      = combination.QuantityUnitId,
                    IsActive            = combination.IsActive
                                          //IsDefaultCombination = combination.IsDefaultCombination
                };

                clone.ProductVariantAttributeCombinations.Add(combinationClone);
            }

            // >>>>>> Commit combinations
            Commit();
        }
예제 #14
0
        /// <summary>
        /// Create a copy of product with all depended data
        /// </summary>
        /// <param name="product">The product</param>
        /// <param name="newName">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>
        /// <param name="copyAssociatedProducts">A value indicating whether the copy associated products</param>
        /// <returns>Product entity</returns>
        public virtual Product CopyProduct(Product product, string newName, bool isPublished, bool copyImages, bool copyAssociatedProducts = true)
        {
            if (product == null)
            {
                throw new ArgumentNullException("product");
            }

            if (String.IsNullOrEmpty(newName))
            {
                throw new ArgumentException("Product name is required");
            }

            Product productCopy = null;
            var     utcNow      = DateTime.UtcNow;

            // product download & sample download
            int downloadId       = product.DownloadId;
            int?sampleDownloadId = product.SampleDownloadId;

            if (product.IsDownload)
            {
                var download = _downloadService.GetDownloadById(product.DownloadId);
                if (download != null)
                {
                    var downloadCopy = new Download()
                    {
                        DownloadGuid   = Guid.NewGuid(),
                        UseDownloadUrl = download.UseDownloadUrl,
                        DownloadUrl    = download.DownloadUrl,
                        DownloadBinary = download.DownloadBinary,
                        ContentType    = download.ContentType,
                        Filename       = download.Filename,
                        Extension      = download.Extension,
                        IsNew          = download.IsNew,
                    };
                    _downloadService.InsertDownload(downloadCopy);
                    downloadId = downloadCopy.Id;
                }

                if (product.HasSampleDownload)
                {
                    var sampleDownload = _downloadService.GetDownloadById(product.SampleDownloadId.GetValueOrDefault());
                    if (sampleDownload != null)
                    {
                        var sampleDownloadCopy = new Download()
                        {
                            DownloadGuid   = Guid.NewGuid(),
                            UseDownloadUrl = sampleDownload.UseDownloadUrl,
                            DownloadUrl    = sampleDownload.DownloadUrl,
                            DownloadBinary = sampleDownload.DownloadBinary,
                            ContentType    = sampleDownload.ContentType,
                            Filename       = sampleDownload.Filename,
                            Extension      = sampleDownload.Extension,
                            IsNew          = sampleDownload.IsNew
                        };
                        _downloadService.InsertDownload(sampleDownloadCopy);
                        sampleDownloadId = sampleDownloadCopy.Id;
                    }
                }
            }

            // product
            productCopy = new Product()
            {
                ProductTypeId          = product.ProductTypeId,
                ParentGroupedProductId = product.ParentGroupedProductId,
                VisibleIndividually    = product.VisibleIndividually,
                Name                 = newName,
                ShortDescription     = product.ShortDescription,
                FullDescription      = product.FullDescription,
                ProductTemplateId    = product.ProductTemplateId,
                AdminComment         = product.AdminComment,
                ShowOnHomePage       = product.ShowOnHomePage,
                MetaKeywords         = product.MetaKeywords,
                MetaDescription      = product.MetaDescription,
                MetaTitle            = product.MetaTitle,
                AllowCustomerReviews = product.AllowCustomerReviews,
                LimitedToStores      = product.LimitedToStores,
                Sku = product.Sku,
                ManufacturerPartNumber = product.ManufacturerPartNumber,
                Gtin                             = product.Gtin,
                IsGiftCard                       = product.IsGiftCard,
                GiftCardType                     = product.GiftCardType,
                RequireOtherProducts             = product.RequireOtherProducts,
                RequiredProductIds               = product.RequiredProductIds,
                AutomaticallyAddRequiredProducts = product.AutomaticallyAddRequiredProducts,
                IsDownload                       = product.IsDownload,
                DownloadId                       = downloadId,
                UnlimitedDownloads               = product.UnlimitedDownloads,
                MaxNumberOfDownloads             = product.MaxNumberOfDownloads,
                DownloadExpirationDays           = product.DownloadExpirationDays,
                DownloadActivationType           = product.DownloadActivationType,
                HasSampleDownload                = product.HasSampleDownload,
                SampleDownloadId                 = sampleDownloadId,
                HasUserAgreement                 = product.HasUserAgreement,
                UserAgreementText                = product.UserAgreementText,
                IsRecurring                      = product.IsRecurring,
                RecurringCycleLength             = product.RecurringCycleLength,
                RecurringCyclePeriod             = product.RecurringCyclePeriod,
                RecurringTotalCycles             = product.RecurringTotalCycles,
                IsShipEnabled                    = product.IsShipEnabled,
                IsFreeShipping                   = product.IsFreeShipping,
                AdditionalShippingCharge         = product.AdditionalShippingCharge,
                IsEsd                            = product.IsEsd,
                IsTaxExempt                      = product.IsTaxExempt,
                TaxCategoryId                    = product.TaxCategoryId,
                ManageInventoryMethod            = product.ManageInventoryMethod,
                StockQuantity                    = product.StockQuantity,
                DisplayStockAvailability         = product.DisplayStockAvailability,
                DisplayStockQuantity             = product.DisplayStockQuantity,
                MinStockQuantity                 = product.MinStockQuantity,
                LowStockActivityId               = product.LowStockActivityId,
                NotifyAdminForQuantityBelow      = product.NotifyAdminForQuantityBelow,
                BackorderMode                    = product.BackorderMode,
                AllowBackInStockSubscriptions    = product.AllowBackInStockSubscriptions,
                OrderMinimumQuantity             = product.OrderMinimumQuantity,
                OrderMaximumQuantity             = product.OrderMaximumQuantity,
                AllowedQuantities                = product.AllowedQuantities,
                DisableBuyButton                 = product.DisableBuyButton,
                DisableWishlistButton            = product.DisableWishlistButton,
                AvailableForPreOrder             = product.AvailableForPreOrder,
                CallForPrice                     = product.CallForPrice,
                Price                            = product.Price,
                OldPrice                         = product.OldPrice,
                ProductCost                      = product.ProductCost,
                SpecialPrice                     = product.SpecialPrice,
                SpecialPriceStartDateTimeUtc     = product.SpecialPriceStartDateTimeUtc,
                SpecialPriceEndDateTimeUtc       = product.SpecialPriceEndDateTimeUtc,
                CustomerEntersPrice              = product.CustomerEntersPrice,
                MinimumCustomerEnteredPrice      = product.MinimumCustomerEnteredPrice,
                MaximumCustomerEnteredPrice      = product.MaximumCustomerEnteredPrice,
                LowestAttributeCombinationPrice  = product.LowestAttributeCombinationPrice,
                Weight                           = product.Weight,
                Length                           = product.Length,
                Width                            = product.Width,
                Height                           = product.Height,
                AvailableStartDateTimeUtc        = product.AvailableStartDateTimeUtc,
                AvailableEndDateTimeUtc          = product.AvailableEndDateTimeUtc,
                DisplayOrder                     = product.DisplayOrder,
                Published                        = isPublished,
                Deleted                          = product.Deleted,
                CreatedOnUtc                     = utcNow,
                UpdatedOnUtc                     = utcNow,
                DeliveryTimeId                   = product.DeliveryTimeId,
                QuantityUnitId                   = product.QuantityUnitId,
                BasePriceEnabled                 = product.BasePriceEnabled,
                BasePriceMeasureUnit             = product.BasePriceMeasureUnit,
                BasePriceAmount                  = product.BasePriceAmount,
                BasePriceBaseAmount              = product.BasePriceBaseAmount,
                BundleTitleText                  = product.BundleTitleText,
                BundlePerItemShipping            = product.BundlePerItemShipping,
                BundlePerItemPricing             = product.BundlePerItemPricing,
                BundlePerItemShoppingCart        = product.BundlePerItemShoppingCart
            };

            _productService.InsertProduct(productCopy);

            //search engine name
            _urlRecordService.SaveSlug(productCopy, productCopy.ValidateSeName("", productCopy.Name, true), 0);

            var languages = _languageService.GetAllLanguages(true);

            //localization
            foreach (var lang in languages)
            {
                var name = product.GetLocalized(x => x.Name, lang.Id, false, false);
                if (!String.IsNullOrEmpty(name))
                {
                    _localizedEntityService.SaveLocalizedValue(productCopy, x => x.Name, name, lang.Id);
                }

                var shortDescription = product.GetLocalized(x => x.ShortDescription, lang.Id, false, false);
                if (!String.IsNullOrEmpty(shortDescription))
                {
                    _localizedEntityService.SaveLocalizedValue(productCopy, x => x.ShortDescription, shortDescription, lang.Id);
                }

                var fullDescription = product.GetLocalized(x => x.FullDescription, lang.Id, false, false);
                if (!String.IsNullOrEmpty(fullDescription))
                {
                    _localizedEntityService.SaveLocalizedValue(productCopy, x => x.FullDescription, fullDescription, lang.Id);
                }

                var metaKeywords = product.GetLocalized(x => x.MetaKeywords, lang.Id, false, false);
                if (!String.IsNullOrEmpty(metaKeywords))
                {
                    _localizedEntityService.SaveLocalizedValue(productCopy, x => x.MetaKeywords, metaKeywords, lang.Id);
                }

                var metaDescription = product.GetLocalized(x => x.MetaDescription, lang.Id, false, false);
                if (!String.IsNullOrEmpty(metaDescription))
                {
                    _localizedEntityService.SaveLocalizedValue(productCopy, x => x.MetaDescription, metaDescription, lang.Id);
                }

                var metaTitle = product.GetLocalized(x => x.MetaTitle, lang.Id, false, false);
                if (!String.IsNullOrEmpty(metaTitle))
                {
                    _localizedEntityService.SaveLocalizedValue(productCopy, x => x.MetaTitle, metaTitle, lang.Id);
                }

                var bundleTitleText = product.GetLocalized(x => x.BundleTitleText, lang.Id, false, false);
                if (!String.IsNullOrEmpty(bundleTitleText))
                {
                    _localizedEntityService.SaveLocalizedValue(productCopy, x => x.BundleTitleText, bundleTitleText, lang.Id);
                }

                //search engine name
                _urlRecordService.SaveSlug(productCopy, productCopy.ValidateSeName("", name, false), lang.Id);
            }

            // product pictures
            if (copyImages)
            {
                foreach (var productPicture in product.ProductPictures)
                {
                    var picture     = productPicture.Picture;
                    var pictureCopy = _pictureService.InsertPicture(
                        _pictureService.LoadPictureBinary(picture),
                        picture.MimeType,
                        _pictureService.GetPictureSeName(newName),
                        true);
                    _productService.InsertProductPicture(new ProductPicture()
                    {
                        ProductId    = productCopy.Id,
                        PictureId    = pictureCopy.Id,
                        DisplayOrder = productPicture.DisplayOrder
                    });
                }
            }

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

                _categoryService.InsertProductCategory(productCategoryCopy);
            }

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

                _manufacturerService.InsertProductManufacturer(productManufacturerCopy);
            }

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

            // product <-> cross sells mappings
            foreach (var csProduct in _productService.GetCrossSellProductsByProductId1(product.Id, true))
            {
                _productService.InsertCrossSellProduct(
                    new CrossSellProduct()
                {
                    ProductId1 = productCopy.Id,
                    ProductId2 = csProduct.ProductId2,
                });
            }

            // product specifications
            foreach (var productSpecificationAttribute in product.ProductSpecificationAttributes)
            {
                var psaCopy = new ProductSpecificationAttribute()
                {
                    ProductId = productCopy.Id,
                    SpecificationAttributeOptionId = productSpecificationAttribute.SpecificationAttributeOptionId,
                    AllowFiltering    = productSpecificationAttribute.AllowFiltering,
                    ShowOnProductPage = productSpecificationAttribute.ShowOnProductPage,
                    DisplayOrder      = productSpecificationAttribute.DisplayOrder
                };
                _specificationAttributeService.InsertProductSpecificationAttribute(psaCopy);
            }

            //store mapping
            var selectedStoreIds = _storeMappingService.GetStoresIdsWithAccess(product);

            foreach (var id in selectedStoreIds)
            {
                _storeMappingService.InsertStoreMapping(productCopy, id);
            }

            // product <-> attributes mappings
            var associatedAttributes      = new Dictionary <int, int>();
            var associatedAttributeValues = new Dictionary <int, int>();

            foreach (var productVariantAttribute in _productAttributeService.GetProductVariantAttributesByProductId(product.Id))
            {
                var productVariantAttributeCopy = new ProductVariantAttribute()
                {
                    ProductId              = productCopy.Id,
                    ProductAttributeId     = productVariantAttribute.ProductAttributeId,
                    TextPrompt             = productVariantAttribute.TextPrompt,
                    IsRequired             = productVariantAttribute.IsRequired,
                    AttributeControlTypeId = productVariantAttribute.AttributeControlTypeId,
                    DisplayOrder           = productVariantAttribute.DisplayOrder
                };
                _productAttributeService.InsertProductVariantAttribute(productVariantAttributeCopy);
                //save associated value (used for combinations copying)
                associatedAttributes.Add(productVariantAttribute.Id, productVariantAttributeCopy.Id);

                // product variant attribute values
                var productVariantAttributeValues = _productAttributeService.GetProductVariantAttributeValues(productVariantAttribute.Id);
                foreach (var productVariantAttributeValue in productVariantAttributeValues)
                {
                    var pvavCopy = new ProductVariantAttributeValue()
                    {
                        ProductVariantAttributeId = productVariantAttributeCopy.Id,
                        Name             = productVariantAttributeValue.Name,
                        ColorSquaresRgb  = productVariantAttributeValue.ColorSquaresRgb,
                        PriceAdjustment  = productVariantAttributeValue.PriceAdjustment,
                        WeightAdjustment = productVariantAttributeValue.WeightAdjustment,
                        IsPreSelected    = productVariantAttributeValue.IsPreSelected,
                        DisplayOrder     = productVariantAttributeValue.DisplayOrder,
                        ValueTypeId      = productVariantAttributeValue.ValueTypeId,
                        LinkedProductId  = productVariantAttributeValue.LinkedProductId,
                        Quantity         = productVariantAttributeValue.Quantity,
                    };
                    _productAttributeService.InsertProductVariantAttributeValue(pvavCopy);

                    //save associated value (used for combinations copying)
                    associatedAttributeValues.Add(productVariantAttributeValue.Id, pvavCopy.Id);

                    //localization
                    foreach (var lang in languages)
                    {
                        var name = productVariantAttributeValue.GetLocalized(x => x.Name, lang.Id, false, false);
                        if (!String.IsNullOrEmpty(name))
                        {
                            _localizedEntityService.SaveLocalizedValue(pvavCopy, x => x.Name, name, lang.Id);
                        }
                    }
                }
            }

            // attribute combinations
            foreach (var combination in _productAttributeService.GetAllProductVariantAttributeCombinations(product.Id))
            {
                //generate new AttributesXml according to new value IDs
                string newAttributesXml = "";
                var    parsedProductVariantAttributes = _productAttributeParser.ParseProductVariantAttributes(combination.AttributesXml);
                foreach (var oldPva in parsedProductVariantAttributes)
                {
                    if (associatedAttributes.ContainsKey(oldPva.Id))
                    {
                        int newPvaId = associatedAttributes[oldPva.Id];
                        var newPva   = _productAttributeService.GetProductVariantAttributeById(newPvaId);
                        if (newPva != null)
                        {
                            var oldPvaValuesStr = _productAttributeParser.ParseValues(combination.AttributesXml, oldPva.Id);
                            foreach (var oldPvaValueStr in oldPvaValuesStr)
                            {
                                if (newPva.ShouldHaveValues())
                                {
                                    //attribute values
                                    int oldPvaValue = int.Parse(oldPvaValueStr);
                                    if (associatedAttributeValues.ContainsKey(oldPvaValue))
                                    {
                                        int newPvavId = associatedAttributeValues[oldPvaValue];
                                        var newPvav   = _productAttributeService.GetProductVariantAttributeValueById(newPvavId);
                                        if (newPvav != null)
                                        {
                                            newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml,
                                                                                                           newPva, newPvav.Id.ToString());
                                        }
                                    }
                                }
                                else
                                {
                                    //just a text
                                    newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml,
                                                                                                   newPva, oldPvaValueStr);
                                }
                            }
                        }
                    }
                }
                var combinationCopy = new ProductVariantAttributeCombination()
                {
                    ProductId             = productCopy.Id,
                    AttributesXml         = newAttributesXml,
                    StockQuantity         = combination.StockQuantity,
                    AllowOutOfStockOrders = combination.AllowOutOfStockOrders,

                    // SmartStore extension
                    Sku  = combination.Sku,
                    Gtin = combination.Gtin,
                    ManufacturerPartNumber = combination.ManufacturerPartNumber,
                    Price = combination.Price,
                    AssignedPictureIds = copyImages ? combination.AssignedPictureIds : null,
                    Length             = combination.Length,
                    Width               = combination.Width,
                    Height              = combination.Height,
                    BasePriceAmount     = combination.BasePriceAmount,
                    BasePriceBaseAmount = combination.BasePriceBaseAmount,
                    DeliveryTimeId      = combination.DeliveryTimeId,
                    QuantityUnitId      = combination.QuantityUnitId,
                    IsActive            = combination.IsActive
                                          //IsDefaultCombination = combination.IsDefaultCombination
                };
                _productAttributeService.InsertProductVariantAttributeCombination(combinationCopy);
            }

            // tier prices
            foreach (var tierPrice in product.TierPrices)
            {
                _productService.InsertTierPrice(
                    new TierPrice()
                {
                    ProductId      = productCopy.Id,
                    StoreId        = tierPrice.StoreId,
                    CustomerRoleId = tierPrice.CustomerRoleId,
                    Quantity       = tierPrice.Quantity,
                    Price          = tierPrice.Price
                });
            }

            // product <-> discounts mapping
            foreach (var discount in product.AppliedDiscounts)
            {
                productCopy.AppliedDiscounts.Add(discount);
                _productService.UpdateProduct(productCopy);
            }

            // update "HasTierPrices" and "HasDiscountsApplied" properties
            _productService.UpdateHasTierPricesProperty(productCopy);
            _productService.UpdateLowestAttributeCombinationPriceProperty(productCopy);
            _productService.UpdateHasDiscountsApplied(productCopy);

            // associated products
            if (copyAssociatedProducts && product.ProductType != ProductType.BundledProduct)
            {
                var searchContext = new ProductSearchContext()
                {
                    ParentGroupedProductId = product.Id,
                    PageSize   = int.MaxValue,
                    ShowHidden = true
                };

                string copyOf             = _localizationService.GetResource("Admin.Common.CopyOf");
                var    associatedProducts = _productService.SearchProducts(searchContext);

                foreach (var associatedProduct in associatedProducts)
                {
                    var associatedProductCopy = CopyProduct(associatedProduct, string.Format("{0} {1}", copyOf, associatedProduct.Name), isPublished, copyImages, false);
                    associatedProductCopy.ParentGroupedProductId = productCopy.Id;

                    _productService.UpdateProduct(productCopy);
                }
            }

            // bundled products
            var bundledItems = _productService.GetBundleItems(product.Id, true);

            foreach (var bundleItem in bundledItems)
            {
                var newBundleItem = bundleItem.Item.Clone();
                newBundleItem.BundleProductId = productCopy.Id;
                newBundleItem.CreatedOnUtc    = utcNow;
                newBundleItem.UpdatedOnUtc    = utcNow;

                _productService.InsertBundleItem(newBundleItem);

                foreach (var itemFilter in bundleItem.Item.AttributeFilters)
                {
                    var newItemFilter = itemFilter.Clone();
                    newItemFilter.BundleItemId = newBundleItem.Id;

                    _productAttributeService.InsertProductBundleItemAttributeFilter(newItemFilter);
                }
            }

            return(productCopy);
        }
        public virtual void CreateAllProductVariantAttributeCombinations(Product product)
        {
            // Delete all existing combinations.
            _pvacRepository.DeleteAll(x => x.ProductId == product.Id);

            var attributes = GetProductVariantAttributesByProductId(product.Id);

            if (attributes == null || attributes.Count <= 0)
            {
                return;
            }

            var mappedAttributes = attributes
                                   .SelectMany(x => x.ProductVariantAttributeValues)
                                   .ToDictionarySafe(x => x.Id, x => x.ProductVariantAttribute);

            var toCombine    = new List <List <ProductVariantAttributeValue> >();
            var resultMatrix = new List <List <ProductVariantAttributeValue> >();
            var tmp          = new List <ProductVariantAttributeValue>();

            foreach (var attr in attributes)
            {
                var attributeValues = attr.ProductVariantAttributeValues.ToList();
                if (attributeValues.Count > 0)
                {
                    toCombine.Add(attributeValues);
                }
            }

            if (toCombine.Count > 0)
            {
                CombineAll(toCombine, resultMatrix, 0, tmp);

                using (var scope = new DbContextScope(ctx: _pvacRepository.Context, autoCommit: false, autoDetectChanges: false, validateOnSave: false, hooksEnabled: false))
                {
                    ProductVariantAttributeCombination combination = null;
                    var idx = 0;

                    foreach (var values in resultMatrix)
                    {
                        idx++;
                        var attributesXml = "";

                        foreach (var value in values)
                        {
                            attributesXml = mappedAttributes[value.Id].AddProductAttribute(attributesXml, value.Id.ToString());
                        }

                        combination = new ProductVariantAttributeCombination
                        {
                            ProductId             = product.Id,
                            AttributesXml         = attributesXml,
                            StockQuantity         = 10000,
                            AllowOutOfStockOrders = true,
                            IsActive = true
                        };

                        _pvacRepository.Insert(combination);
                    }

                    scope.Commit();
                }
            }

            //foreach (var y in resultMatrix)
            //{
            //	var sb = new System.Text.StringBuilder();
            //	foreach (var x in y)
            //	{
            //		sb.AppendFormat("{0} ", x.Name);
            //	}
            //	sb.ToString().Dump();
            //}
        }
예제 #16
0
 public static ProductVariantAttributeCombination ToEntity(this ProductVariantAttributeCombinationModel model, ProductVariantAttributeCombination entity)
 {
     MapperFactory.Map(model, entity);
     return(entity);
 }
예제 #17
0
        // TODO: (mg) (core) Complete ProductService.AdjustInventoryAsync method.
        // SendQuantityBelowStoreOwnerNotification should be send by caller after (!) database commit.
        public virtual async Task <AdjustInventoryResult> AdjustInventoryAsync(Product product, bool decrease, int quantity, string attributesXml)
        {
            Guard.NotNull(product, nameof(product));

            var result = new AdjustInventoryResult();

            switch (product.ManageInventoryMethod)
            {
            case ManageInventoryMethod.ManageStock:
            {
                result.StockQuantityOld = product.StockQuantity;

                result.StockQuantityNew = decrease
                            ? product.StockQuantity - quantity
                            : product.StockQuantity + quantity;

                var newPublished             = product.Published;
                var newDisableBuyButton      = product.DisableBuyButton;
                var newDisableWishlistButton = product.DisableWishlistButton;

                // Check if the minimum quantity is reached.
                switch (product.LowStockActivity)
                {
                case LowStockActivity.DisableBuyButton:
                    newDisableBuyButton      = product.MinStockQuantity >= result.StockQuantityNew;
                    newDisableWishlistButton = product.MinStockQuantity >= result.StockQuantityNew;
                    break;

                case LowStockActivity.Unpublish:
                    newPublished = product.MinStockQuantity <= result.StockQuantityNew;
                    break;
                }

                product.StockQuantity         = result.StockQuantityNew;
                product.DisableBuyButton      = newDisableBuyButton;
                product.DisableWishlistButton = newDisableWishlistButton;
                product.Published             = newPublished;

                // Send email notification.
                if (decrease && product.NotifyAdminForQuantityBelow > result.StockQuantityNew)
                {
                    //_services.MessageFactory.SendQuantityBelowStoreOwnerNotification(product, _localizationSettings.DefaultAdminLanguageId);
                }
            }
            break;

            case ManageInventoryMethod.ManageStockByAttributes:
            {
                //var combination = _productAttributeParser.FindProductVariantAttributeCombination(product.Id, attributesXml);
                ProductVariantAttributeCombination combination = null;
                if (combination != null)
                {
                    result.StockQuantityOld = combination.StockQuantity;

                    result.StockQuantityNew = decrease
                                ? combination.StockQuantity - quantity
                                : combination.StockQuantity + quantity;

                    combination.StockQuantity = result.StockQuantityNew;
                }
            }
            break;

            case ManageInventoryMethod.DontManageStock:
            default:
                // Do nothing.
                break;
            }

            //var attributeValues = _productAttributeParser.ParseProductVariantAttributeValues(attributesXml);
            var attributeValues = new List <ProductVariantAttributeValue>();

            var productLinkageValues = attributeValues
                                       .Where(x => x.ValueType == ProductVariantAttributeValueType.ProductLinkage)
                                       .ToList();

            foreach (var chunk in productLinkageValues.Slice(100))
            {
                var linkedProductIds = chunk.Select(x => x.LinkedProductId).Distinct().ToArray();
                var linkedProducts   = await _db.Products.GetManyAsync(linkedProductIds, true);

                var linkedProductsDic = linkedProducts.ToDictionarySafe(x => x.Id);

                foreach (var value in chunk)
                {
                    if (linkedProductsDic.TryGetValue(value.LinkedProductId, out var linkedProduct))
                    {
                        await AdjustInventoryAsync(linkedProduct, decrease, quantity *value.Quantity, string.Empty);
                    }
                }
            }

            return(result);
        }
예제 #18
0
        private void ProcessAttributes(Product product, Product clone, IEnumerable <Language> languages)
        {
            using (var scope = new DbContextScope(lazyLoading: false, forceNoTracking: false))
            {
                scope.LoadCollection(product, (Product p) => p.ProductVariantAttributes);
                scope.LoadCollection(product, (Product p) => p.ProductVariantAttributeCombinations);
            }

            // Former attribute id > clone.
            var pvaMap = new Dictionary <int, ProductVariantAttribute>();
            // Former attribute value id > clone.
            var pvavMap = new Dictionary <int, ProductVariantAttributeValue>();

            // Product attributes.
            foreach (var pva in product.ProductVariantAttributes)
            {
                var pvaClone = new ProductVariantAttribute
                {
                    ProductId              = clone.Id,
                    ProductAttributeId     = pva.ProductAttributeId,
                    TextPrompt             = pva.TextPrompt,
                    IsRequired             = pva.IsRequired,
                    AttributeControlTypeId = pva.AttributeControlTypeId,
                    DisplayOrder           = pva.DisplayOrder
                };
                _productAttributeService.InsertProductVariantAttribute(pvaClone);

                // Save associated value (used for combinations copying).
                pvaMap[pva.Id] = pvaClone;
            }

            // >>>>>> Commit attributes.
            Commit();

            // Product variant attribute values.
            foreach (var pva in product.ProductVariantAttributes)
            {
                var pvaClone = pvaMap[pva.Id];
                foreach (var pvav in pva.ProductVariantAttributeValues)
                {
                    var pvavClone = new ProductVariantAttributeValue
                    {
                        ProductVariantAttributeId = pvaClone.Id,
                        Name             = pvav.Name,
                        Color            = pvav.Color,
                        PriceAdjustment  = pvav.PriceAdjustment,
                        WeightAdjustment = pvav.WeightAdjustment,
                        IsPreSelected    = pvav.IsPreSelected,
                        DisplayOrder     = pvav.DisplayOrder,
                        ValueTypeId      = pvav.ValueTypeId,
                        LinkedProductId  = pvav.LinkedProductId,
                        Quantity         = pvav.Quantity,
                        MediaFileId      = pvav.MediaFileId
                    };

                    _productAttributeService.InsertProductVariantAttributeValue(pvavClone);

                    // Save associated value (used for combinations copying)
                    pvavMap.Add(pvav.Id, pvavClone);
                }
            }

            // >>>>>> Commit attribute values.
            Commit();

            // Attribute value localization.
            foreach (var pvav in product.ProductVariantAttributes.SelectMany(x => x.ProductVariantAttributeValues).ToArray())
            {
                foreach (var lang in languages)
                {
                    var name = pvav.GetLocalized(x => x.Name, lang, false, false);
                    if (!string.IsNullOrEmpty(name))
                    {
                        var pvavClone = pvavMap.Get(pvav.Id);
                        if (pvavClone != null)
                        {
                            _localizedEntityService.SaveLocalizedValue(pvavClone, x => x.Name, name, lang.Id);
                        }
                    }
                }
            }

            // Attribute combinations.
            foreach (var combination in product.ProductVariantAttributeCombinations)
            {
                // Generate new AttributesXml according to new value IDs.
                string newAttributesXml = "";
                var    parsedProductVariantAttributes = _productAttributeParser.ParseProductVariantAttributes(combination.AttributesXml);
                foreach (var oldPva in parsedProductVariantAttributes)
                {
                    if (!pvaMap.ContainsKey(oldPva.Id))
                    {
                        continue;
                    }

                    var newPva = pvaMap.Get(oldPva.Id);

                    if (newPva == null)
                    {
                        continue;
                    }

                    var oldPvaValuesStr = _productAttributeParser.ParseValues(combination.AttributesXml, oldPva.Id);
                    foreach (var oldPvaValueStr in oldPvaValuesStr)
                    {
                        if (newPva.ShouldHaveValues())
                        {
                            var oldPvaValue = oldPvaValueStr.ToInt();
                            if (pvavMap.ContainsKey(oldPvaValue))
                            {
                                var newPvav = pvavMap.Get(oldPvaValue);
                                if (newPvav != null)
                                {
                                    newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml, newPva, newPvav.Id.ToString());
                                }
                            }
                        }
                        else
                        {
                            // Simple text value.
                            newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml, newPva, oldPvaValueStr);
                        }
                    }
                }

                var combinationClone = new ProductVariantAttributeCombination
                {
                    ProductId             = clone.Id,
                    AttributesXml         = newAttributesXml,
                    StockQuantity         = combination.StockQuantity,
                    AllowOutOfStockOrders = combination.AllowOutOfStockOrders,
                    Sku  = combination.Sku,
                    Gtin = combination.Gtin,
                    ManufacturerPartNumber = combination.ManufacturerPartNumber,
                    Price = combination.Price,
                    AssignedMediaFileIds = combination.AssignedMediaFileIds,
                    Length              = combination.Length,
                    Width               = combination.Width,
                    Height              = combination.Height,
                    BasePriceAmount     = combination.BasePriceAmount,
                    BasePriceBaseAmount = combination.BasePriceBaseAmount,
                    DeliveryTimeId      = combination.DeliveryTimeId,
                    QuantityUnitId      = combination.QuantityUnitId,
                    IsActive            = combination.IsActive
                                          //IsDefaultCombination = combination.IsDefaultCombination
                };

                _productAttributeService.InsertProductVariantAttributeCombination(combinationClone);
            }

            // >>>>>> Commit combinations.
            Commit();
        }
        private void CheckProductStoragesPriceAndQuantites(ImportEntity importEntity)
        {
            var product           = _productService.GetProductBySku(importEntity.ProductSku);
            var productVariantGet = _productAttributeService.GetProductVariantAttributesByProductId(product.Id);

            //связываем продукт и свойство(склад)
            if (!productVariantGet.Any())
            {
                var productVariantAttribute = new ProductVariantAttribute();
                productVariantAttribute.ProductId              = product.Id;
                productVariantAttribute.ProductAttributeId     = 1; //TODO:другой способ ввода id
                productVariantAttribute.AttributeControlTypeId = 1;
                _productAttributeService.InsertProductVariantAttribute(productVariantAttribute);
            }

            var needPreselected = true;

            foreach (var entity in importEntity.Storages)
            {
                //связываем названия свойств с маппингом продуктов и свойств
                var productVariantGetForValue =
                    _productAttributeService.GetProductVariantAttributesByProductId(product.Id).FirstOrDefault();
                var productVariantValueGet =
                    _productAttributeService.GetProductVariantAttributeValues(productVariantGetForValue.Id);
                var productVariantAttr = productVariantValueGet.FirstOrDefault(x => x.Name.Equals(entity.Name));

                var isPreselected = PreSelectedUpdate(entity, ref needPreselected);
                //цена для отображения
                if (isPreselected)
                {
                    product.Price = entity.Price;
                    _productService.UpdateProduct(product);
                }
                if (productVariantAttr == null)
                {
                    var productVariantAttributeValue  = new ProductVariantAttributeValue();
                    var productVariantAttributeForMap =
                        _productAttributeService.GetProductVariantAttributesByProductId(product.Id)
                        .FirstOrDefault();
                    productVariantAttributeValue.ProductVariantAttributeId =
                        productVariantAttributeForMap != null
                            ? productVariantAttributeForMap.Id
                            : new int();
                    productVariantAttributeValue.Name          = entity.Name;
                    productVariantAttributeValue.IsPreSelected = isPreselected;

                    _productAttributeService.InsertProductVariantAttributeValue(
                        productVariantAttributeValue);
                }
                else
                {
                    productVariantAttr.IsPreSelected = PreSelectedUpdate(entity, ref needPreselected);
                    _productAttributeService.UpdateProductVariantAttributeValue(productVariantAttr);
                }



                //связываем продукт и значения свойств
                var productVariantAttributeCombinationsGet =
                    _productAttributeService.GetAllProductVariantAttributeCombinations(product.Id);

                var productVariantAttributeValueForXml = _productService.GetProductBySku(importEntity.ProductSku)
                                                         .ProductVariantAttributes.FirstOrDefault()
                                                         .ProductVariantAttributeValues.FirstOrDefault(x => x.Name.Equals(entity.Name));
                var productVariantAttributeCombination = productVariantAttributeCombinationsGet.FirstOrDefault(
                    x => x.Sku.Equals(entity.Name));

                if (productVariantAttributeCombination == null)
                {
                    productVariantAttributeCombination = new ProductVariantAttributeCombination();
                    var productXml = "<Attributes><ProductVariantAttribute ID='" +
                                     productVariantAttributeValueForXml.ProductVariantAttributeId +
                                     "'><ProductVariantAttributeValue><Value>" +
                                     productVariantAttributeValueForXml.Id +
                                     "</Value></ProductVariantAttributeValue></ProductVariantAttribute></Attributes>";

                    productVariantAttributeCombination.ProductId       = product.Id;
                    productVariantAttributeCombination.AttributesXml   = productXml;
                    productVariantAttributeCombination.StockQuantity   = entity.Quantity;
                    productVariantAttributeCombination.OverriddenPrice = entity.Price;
                    productVariantAttributeCombination.Sku             = entity.Name;

                    _productAttributeService.InsertProductVariantAttributeCombination(
                        productVariantAttributeCombination);
                }
                else
                {
                    productVariantAttributeCombination.StockQuantity   = entity.Quantity;
                    productVariantAttributeCombination.OverriddenPrice = entity.Price;
                    _productAttributeService.UpdateProductVariantAttributeCombination(productVariantAttributeCombination);
                }
            }
        }
예제 #20
0
        /// <summary>
        /// Validates shopping cart item
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="shoppingCartType">Shopping cart type</param>
        /// <param name="productVariant">Product variant</param>
        /// <param name="selectedAttributes">Selected attributes</param>
        /// <param name="customerEnteredPrice">Customer entered price</param>
        /// <param name="quantity">Quantity</param>
        /// <param name="automaticallyAddRequiredProductVariantsIfEnabled">Automatically add required product variants if enabled</param>
        /// <returns>Warnings</returns>
        public virtual IList <string> GetShoppingCartItemWarnings(Customer customer, ShoppingCartType shoppingCartType,
                                                                  ProductVariant productVariant, string selectedAttributes, decimal customerEnteredPrice,
                                                                  int quantity, bool automaticallyAddRequiredProductVariantsIfEnabled)
        {
            if (productVariant == null)
            {
                throw new ArgumentNullException("productVariant");
            }

            var warnings = new List <string>();

            var product = productVariant.Product;

            if (product == null)
            {
                warnings.Add(string.Format("Product (Id={0}) can not be loaded", productVariant.ProductId));
                return(warnings);
            }

            if (product.Deleted || productVariant.Deleted)
            {
                warnings.Add("Product is deleted");
                return(warnings);
            }

            if (!product.Published || !productVariant.Published)
            {
                warnings.Add("Product is not published");
            }

            if (shoppingCartType == ShoppingCartType.ShoppingCart && productVariant.DisableBuyButton)
            {
                warnings.Add("Buying is disabled for this product");
            }

            if (shoppingCartType == ShoppingCartType.Wishlist && productVariant.DisableWishlistButton)
            {
                warnings.Add("Wishlist is disabled for this product");
            }

            if (shoppingCartType == ShoppingCartType.ShoppingCart &&
                productVariant.CallForPrice)
            {
                warnings.Add(_localizationService.GetResource("Products.CallForPrice"));
            }

            if (productVariant.CustomerEntersPrice)
            {
                if (customerEnteredPrice < productVariant.MinimumCustomerEnteredPrice ||
                    customerEnteredPrice > productVariant.MaximumCustomerEnteredPrice)
                {
                    decimal minimumCustomerEnteredPrice = _currencyService.ConvertFromPrimaryStoreCurrency(productVariant.MinimumCustomerEnteredPrice, _workContext.WorkingCurrency);
                    decimal maximumCustomerEnteredPrice = _currencyService.ConvertFromPrimaryStoreCurrency(productVariant.MaximumCustomerEnteredPrice, _workContext.WorkingCurrency);
                    warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.CustomerEnteredPrice.RangeError"),
                                               _priceFormatter.FormatPrice(minimumCustomerEnteredPrice, false, false),
                                               _priceFormatter.FormatPrice(maximumCustomerEnteredPrice, false, false)));
                }
            }

            if (quantity < productVariant.OrderMinimumQuantity)
            {
                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MinimumQuantity"), productVariant.OrderMinimumQuantity));
            }

            if (quantity > productVariant.OrderMaximumQuantity)
            {
                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MaximumQuantity"), productVariant.OrderMaximumQuantity));
            }

            switch (productVariant.ManageInventoryMethod)
            {
            case ManageInventoryMethod.DontManageStock:
            {
            }
            break;

            case ManageInventoryMethod.ManageStock:
            {
                if ((BackorderMode)productVariant.BackorderMode == BackorderMode.NoBackorders)
                {
                    if (productVariant.StockQuantity < quantity)
                    {
                        int maximumQuantityCanBeAdded = productVariant.StockQuantity;
                        if (maximumQuantityCanBeAdded <= 0)
                        {
                            warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock"));
                        }
                        else
                        {
                            warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.QuantityExceedsStock"), maximumQuantityCanBeAdded));
                        }
                    }
                }
            }
            break;

            case ManageInventoryMethod.ManageStockByAttributes:
            {
                var combinations = productVariant.ProductVariantAttributeCombinations;
                ProductVariantAttributeCombination combination = null;
                foreach (var comb1 in combinations)
                {
                    if (_productAttributeParser.AreProductAttributesEqual(comb1.AttributesXml, selectedAttributes))
                    {
                        combination = comb1;
                    }
                }
                if (combination != null)
                {
                    if (!combination.AllowOutOfStockOrders)
                    {
                        if (combination.StockQuantity < quantity)
                        {
                            int maximumQuantityCanBeAdded = combination.StockQuantity;
                            if (maximumQuantityCanBeAdded <= 0)
                            {
                                warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock"));
                            }
                            else
                            {
                                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.QuantityExceedsStock"), maximumQuantityCanBeAdded));
                            }
                        }
                    }
                }
            }
            break;

            default:
                break;
            }

            //availability dates
            bool availableStartDateError = false;

            if (productVariant.AvailableStartDateTimeUtc.HasValue)
            {
                DateTime now = DateTime.UtcNow;
                DateTime availableStartDateTime = DateTime.SpecifyKind(productVariant.AvailableStartDateTimeUtc.Value, DateTimeKind.Utc);
                if (availableStartDateTime.CompareTo(now) > 0)
                {
                    warnings.Add("Product is not available");
                    availableStartDateError = true;
                }
            }
            if (productVariant.AvailableEndDateTimeUtc.HasValue && !availableStartDateError)
            {
                DateTime now = DateTime.UtcNow;
                DateTime availableEndDateTime = DateTime.SpecifyKind(productVariant.AvailableEndDateTimeUtc.Value, DateTimeKind.Utc);
                if (availableEndDateTime.CompareTo(now) < 0)
                {
                    warnings.Add("Product is not available");
                }
            }

            //selected attributes
            warnings.AddRange(GetShoppingCartItemAttributeWarnings(shoppingCartType, productVariant, selectedAttributes));

            //gift cards
            warnings.AddRange(GetShoppingCartItemGiftCardWarnings(shoppingCartType, productVariant, selectedAttributes));

            //required product variants
            warnings.AddRange(GetRequiredProductVariantWarnings(customer, shoppingCartType, productVariant, automaticallyAddRequiredProductVariantsIfEnabled));

            return(warnings);
        }
예제 #21
0
 public static ProductVariantAttributeCombination ToEntity(this ProductVariantAttributeCombinationModel model, ProductVariantAttributeCombination destination)
 {
     return(Mapper.Map(model, destination));
 }
예제 #22
0
        /// <summary>
        /// Creates a copy of product with all depended data
        /// </summary>
        /// <param name="productId">The product identifier</param>
        /// <param name="newName">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 CopyProduct(int productId, string newName, bool isPublished, bool copyImages)
        {
            var product = _productService.GetProductById(productId);

            if (product == null)
            {
                throw new ArgumentException("No product found with the specified id", "productId");
            }

            Product productCopy = null;

            //uncomment this line to support transactions
            //using (var scope = new System.Transactions.TransactionScope())
            {
                // product
                productCopy = new Product()
                {
                    Name                 = newName,
                    ShortDescription     = product.ShortDescription,
                    FullDescription      = product.FullDescription,
                    ProductTemplateId    = product.ProductTemplateId,
                    AdminComment         = product.AdminComment,
                    ShowOnHomePage       = product.ShowOnHomePage,
                    MetaKeywords         = product.MetaKeywords,
                    MetaDescription      = product.MetaDescription,
                    MetaTitle            = product.MetaTitle,
                    AllowCustomerReviews = product.AllowCustomerReviews,
                    Published            = isPublished,
                    Deleted              = product.Deleted,
                    CreatedOnUtc         = DateTime.UtcNow,
                    UpdatedOnUtc         = DateTime.UtcNow
                };

                //validate search engine name
                _productService.InsertProduct(productCopy);

                //search engine name
                _urlRecordService.SaveSlug(productCopy, productCopy.ValidateSeName("", productCopy.Name, true), 0);

                var languages = _languageService.GetAllLanguages(true);

                //localization
                foreach (var lang in languages)
                {
                    var name = product.GetLocalized(x => x.Name, lang.Id, false, false);
                    if (!String.IsNullOrEmpty(name))
                    {
                        _localizedEntityService.SaveLocalizedValue(productCopy, x => x.Name, name, lang.Id);
                    }

                    var shortDescription = product.GetLocalized(x => x.ShortDescription, lang.Id, false, false);
                    if (!String.IsNullOrEmpty(shortDescription))
                    {
                        _localizedEntityService.SaveLocalizedValue(productCopy, x => x.ShortDescription, shortDescription, lang.Id);
                    }

                    var fullDescription = product.GetLocalized(x => x.FullDescription, lang.Id, false, false);
                    if (!String.IsNullOrEmpty(fullDescription))
                    {
                        _localizedEntityService.SaveLocalizedValue(productCopy, x => x.FullDescription, fullDescription, lang.Id);
                    }

                    var metaKeywords = product.GetLocalized(x => x.MetaKeywords, lang.Id, false, false);
                    if (!String.IsNullOrEmpty(metaKeywords))
                    {
                        _localizedEntityService.SaveLocalizedValue(productCopy, x => x.MetaKeywords, metaKeywords, lang.Id);
                    }

                    var metaDescription = product.GetLocalized(x => x.MetaDescription, lang.Id, false, false);
                    if (!String.IsNullOrEmpty(metaDescription))
                    {
                        _localizedEntityService.SaveLocalizedValue(productCopy, x => x.MetaDescription, metaDescription, lang.Id);
                    }

                    var metaTitle = product.GetLocalized(x => x.MetaTitle, lang.Id, false, false);
                    if (!String.IsNullOrEmpty(metaTitle))
                    {
                        _localizedEntityService.SaveLocalizedValue(productCopy, x => x.MetaTitle, metaTitle, lang.Id);
                    }

                    //search engine name
                    _urlRecordService.SaveSlug(productCopy, productCopy.ValidateSeName("", name, false), lang.Id);
                }

                //product tags
                foreach (var productTag in product.ProductTags)
                {
                    productCopy.ProductTags.Add(productTag);
                }
                //ensure product is saved before updating totals
                _productService.UpdateProduct(product);
                foreach (var productTag in product.ProductTags)
                {
                    _productTagService.UpdateProductTagTotals(productTag);
                }

                // product pictures
                if (copyImages)
                {
                    foreach (var productPicture in product.ProductPictures)
                    {
                        var picture     = productPicture.Picture;
                        var pictureCopy = _pictureService.InsertPicture(
                            _pictureService.LoadPictureBinary(picture),
                            picture.MimeType,
                            _pictureService.GetPictureSeName(newName),
                            true);
                        _productService.InsertProductPicture(new ProductPicture()
                        {
                            ProductId    = productCopy.Id,
                            PictureId    = pictureCopy.Id,
                            DisplayOrder = productPicture.DisplayOrder
                        });
                    }
                }

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

                    _categoryService.InsertProductCategory(productCategoryCopy);
                }

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

                    _manufacturerService.InsertProductManufacturer(productManufacturerCopy);
                }

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

                // product <-> cross sells mappings
                foreach (var csProduct in _productService.GetCrossSellProductsByProductId1(product.Id, true))
                {
                    _productService.InsertCrossSellProduct(
                        new CrossSellProduct()
                    {
                        ProductId1 = productCopy.Id,
                        ProductId2 = csProduct.ProductId2,
                    });
                }

                // product specifications
                foreach (var productSpecificationAttribute in product.ProductSpecificationAttributes)
                {
                    var psaCopy = new ProductSpecificationAttribute()
                    {
                        ProductId = productCopy.Id,
                        SpecificationAttributeOptionId = productSpecificationAttribute.SpecificationAttributeOptionId,
                        AllowFiltering    = productSpecificationAttribute.AllowFiltering,
                        ShowOnProductPage = productSpecificationAttribute.ShowOnProductPage,
                        DisplayOrder      = productSpecificationAttribute.DisplayOrder
                    };
                    _specificationAttributeService.InsertProductSpecificationAttribute(psaCopy);
                }

                // product variants
                var productVariants = product.ProductVariants;
                foreach (var productVariant in productVariants)
                {
                    // product variant picture
                    int pictureId = 0;
                    if (copyImages)
                    {
                        var picture = _pictureService.GetPictureById(productVariant.PictureId);
                        if (picture != null)
                        {
                            var pictureCopy = _pictureService.InsertPicture(
                                _pictureService.LoadPictureBinary(picture),
                                picture.MimeType,
                                _pictureService.GetPictureSeName(productVariant.Name),
                                true);
                            pictureId = pictureCopy.Id;
                        }
                    }

                    // product variant download & sample download
                    int downloadId       = productVariant.DownloadId;
                    int sampleDownloadId = productVariant.SampleDownloadId;
                    if (productVariant.IsDownload)
                    {
                        var download = _downloadService.GetDownloadById(productVariant.DownloadId);
                        if (download != null)
                        {
                            var downloadCopy = new Download()
                            {
                                DownloadGuid   = Guid.NewGuid(),
                                UseDownloadUrl = download.UseDownloadUrl,
                                DownloadUrl    = download.DownloadUrl,
                                DownloadBinary = download.DownloadBinary,
                                ContentType    = download.ContentType,
                                Filename       = download.Filename,
                                Extension      = download.Extension,
                                IsNew          = download.IsNew,
                            };
                            _downloadService.InsertDownload(downloadCopy);
                            downloadId = downloadCopy.Id;
                        }

                        if (productVariant.HasSampleDownload)
                        {
                            var sampleDownload = _downloadService.GetDownloadById(productVariant.SampleDownloadId);
                            if (sampleDownload != null)
                            {
                                var sampleDownloadCopy = new Download()
                                {
                                    DownloadGuid   = Guid.NewGuid(),
                                    UseDownloadUrl = sampleDownload.UseDownloadUrl,
                                    DownloadUrl    = sampleDownload.DownloadUrl,
                                    DownloadBinary = sampleDownload.DownloadBinary,
                                    ContentType    = sampleDownload.ContentType,
                                    Filename       = sampleDownload.Filename,
                                    Extension      = sampleDownload.Extension,
                                    IsNew          = sampleDownload.IsNew
                                };
                                _downloadService.InsertDownload(sampleDownloadCopy);
                                sampleDownloadId = sampleDownloadCopy.Id;
                            }
                        }
                    }

                    // product variant
                    var productVariantCopy = new ProductVariant()
                    {
                        ProductId                 = productCopy.Id,
                        Name                      = productVariant.Name,
                        Sku                       = productVariant.Sku,
                        Description               = productVariant.Description,
                        AdminComment              = productVariant.AdminComment,
                        ManufacturerPartNumber    = productVariant.ManufacturerPartNumber,
                        Gtin                      = productVariant.Gtin,
                        IsGiftCard                = productVariant.IsGiftCard,
                        GiftCardType              = productVariant.GiftCardType,
                        RequireOtherProducts      = productVariant.RequireOtherProducts,
                        RequiredProductVariantIds = productVariant.RequiredProductVariantIds,
                        AutomaticallyAddRequiredProductVariants = productVariant.AutomaticallyAddRequiredProductVariants,
                        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,
                        RecurringCycleLength          = productVariant.RecurringCycleLength,
                        RecurringCyclePeriod          = productVariant.RecurringCyclePeriod,
                        RecurringTotalCycles          = productVariant.RecurringTotalCycles,
                        IsShipEnabled                 = productVariant.IsShipEnabled,
                        IsFreeShipping                = productVariant.IsFreeShipping,
                        AdditionalShippingCharge      = productVariant.AdditionalShippingCharge,
                        IsTaxExempt                   = productVariant.IsTaxExempt,
                        TaxCategoryId                 = productVariant.TaxCategoryId,
                        ManageInventoryMethod         = productVariant.ManageInventoryMethod,
                        StockQuantity                 = productVariant.StockQuantity,
                        DisplayStockAvailability      = productVariant.DisplayStockAvailability,
                        DisplayStockQuantity          = productVariant.DisplayStockQuantity,
                        MinStockQuantity              = productVariant.MinStockQuantity,
                        LowStockActivityId            = productVariant.LowStockActivityId,
                        NotifyAdminForQuantityBelow   = productVariant.NotifyAdminForQuantityBelow,
                        BackorderMode                 = productVariant.BackorderMode,
                        AllowBackInStockSubscriptions = productVariant.AllowBackInStockSubscriptions,
                        OrderMinimumQuantity          = productVariant.OrderMinimumQuantity,
                        OrderMaximumQuantity          = productVariant.OrderMaximumQuantity,
                        AllowedQuantities             = productVariant.AllowedQuantities,
                        DisableBuyButton              = productVariant.DisableBuyButton,
                        DisableWishlistButton         = productVariant.DisableWishlistButton,
                        CallForPrice                  = productVariant.CallForPrice,
                        Price        = productVariant.Price,
                        OldPrice     = productVariant.OldPrice,
                        ProductCost  = productVariant.ProductCost,
                        SpecialPrice = productVariant.SpecialPrice,
                        SpecialPriceStartDateTimeUtc = productVariant.SpecialPriceStartDateTimeUtc,
                        SpecialPriceEndDateTimeUtc   = productVariant.SpecialPriceEndDateTimeUtc,
                        CustomerEntersPrice          = productVariant.CustomerEntersPrice,
                        MinimumCustomerEnteredPrice  = productVariant.MinimumCustomerEnteredPrice,
                        MaximumCustomerEnteredPrice  = productVariant.MaximumCustomerEnteredPrice,
                        Weight    = productVariant.Weight,
                        Length    = productVariant.Length,
                        Width     = productVariant.Width,
                        Height    = productVariant.Height,
                        PictureId = pictureId,
                        AvailableStartDateTimeUtc = productVariant.AvailableStartDateTimeUtc,
                        AvailableEndDateTimeUtc   = productVariant.AvailableEndDateTimeUtc,
                        Published    = productVariant.Published,
                        Deleted      = productVariant.Deleted,
                        DisplayOrder = productVariant.DisplayOrder,
                        CreatedOnUtc = DateTime.UtcNow,
                        UpdatedOnUtc = DateTime.UtcNow
                    };

                    _productService.InsertProductVariant(productVariantCopy);

                    //localization
                    foreach (var lang in languages)
                    {
                        var name = productVariant.GetLocalized(x => x.Name, lang.Id, false, false);
                        if (!String.IsNullOrEmpty(name))
                        {
                            _localizedEntityService.SaveLocalizedValue(productVariantCopy, x => x.Name, name, lang.Id);
                        }

                        var description = productVariant.GetLocalized(x => x.Description, lang.Id, false, false);
                        if (!String.IsNullOrEmpty(description))
                        {
                            _localizedEntityService.SaveLocalizedValue(productVariantCopy, x => x.Description, description, lang.Id);
                        }
                    }

                    // product variant <-> attributes mappings
                    var associatedAttributes      = new Dictionary <int, int>();
                    var associatedAttributeValues = new Dictionary <int, int>();
                    foreach (var productVariantAttribute in _productAttributeService.GetProductVariantAttributesByProductVariantId(productVariant.Id))
                    {
                        var productVariantAttributeCopy = new ProductVariantAttribute()
                        {
                            ProductVariantId       = productVariantCopy.Id,
                            ProductAttributeId     = productVariantAttribute.ProductAttributeId,
                            TextPrompt             = productVariantAttribute.TextPrompt,
                            IsRequired             = productVariantAttribute.IsRequired,
                            AttributeControlTypeId = productVariantAttribute.AttributeControlTypeId,
                            DisplayOrder           = productVariantAttribute.DisplayOrder
                        };
                        _productAttributeService.InsertProductVariantAttribute(productVariantAttributeCopy);
                        //save associated value (used for combinations copying)
                        associatedAttributes.Add(productVariantAttribute.Id, productVariantAttributeCopy.Id);

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

                            //save associated value (used for combinations copying)
                            associatedAttributeValues.Add(productVariantAttributeValue.Id, pvavCopy.Id);

                            //localization
                            foreach (var lang in languages)
                            {
                                var name = productVariantAttributeValue.GetLocalized(x => x.Name, lang.Id, false, false);
                                if (!String.IsNullOrEmpty(name))
                                {
                                    _localizedEntityService.SaveLocalizedValue(pvavCopy, x => x.Name, name, lang.Id);
                                }
                            }
                        }
                    }
                    foreach (var combination in _productAttributeService.GetAllProductVariantAttributeCombinations(productVariant.Id))
                    {
                        //generate new AttributesXml according to new value IDs
                        string newAttributesXml = "";
                        var    parsedProductVariantAttributes = _productAttributeParser.ParseProductVariantAttributes(combination.AttributesXml);
                        foreach (var oldPva in parsedProductVariantAttributes)
                        {
                            if (associatedAttributes.ContainsKey(oldPva.Id))
                            {
                                int newPvaId = associatedAttributes[oldPva.Id];
                                var newPva   = _productAttributeService.GetProductVariantAttributeById(newPvaId);
                                if (newPva != null)
                                {
                                    var oldPvaValuesStr = _productAttributeParser.ParseValues(combination.AttributesXml, oldPva.Id);
                                    foreach (var oldPvaValueStr in oldPvaValuesStr)
                                    {
                                        if (newPva.ShouldHaveValues())
                                        {
                                            //attribute values
                                            int oldPvaValue = int.Parse(oldPvaValueStr);
                                            if (associatedAttributeValues.ContainsKey(oldPvaValue))
                                            {
                                                int newPvavId = associatedAttributeValues[oldPvaValue];
                                                var newPvav   = _productAttributeService.GetProductVariantAttributeValueById(newPvavId);
                                                if (newPvav != null)
                                                {
                                                    newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml,
                                                                                                                   newPva, newPvav.Id.ToString());
                                                }
                                            }
                                        }
                                        else
                                        {
                                            //just a text
                                            newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml,
                                                                                                           newPva, oldPvaValueStr);
                                        }
                                    }
                                }
                            }
                        }
                        var combinationCopy = new ProductVariantAttributeCombination()
                        {
                            ProductVariantId      = productVariantCopy.Id,
                            AttributesXml         = newAttributesXml,
                            StockQuantity         = combination.StockQuantity,
                            AllowOutOfStockOrders = combination.AllowOutOfStockOrders
                        };
                        _productAttributeService.InsertProductVariantAttributeCombination(combinationCopy);
                    }

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

                    // product variant <-> discounts mapping
                    foreach (var discount in productVariant.AppliedDiscounts)
                    {
                        productVariantCopy.AppliedDiscounts.Add(discount);
                        _productService.UpdateProductVariant(productVariantCopy);
                    }


                    //update "HasTierPrices" and "HasDiscountsApplied" properties
                    _productService.UpdateHasTierPricesProperty(productVariantCopy);
                    _productService.UpdateHasDiscountsApplied(productVariantCopy);
                }

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

            return(productCopy);
        }
예제 #23
0
        public void WriteProduct(dynamic product, string node)
        {
            if (product == null)
            {
                return;
            }

            Product entity = product.Entity;

            if (node.HasValue())
            {
                _writer.WriteStartElement(node);
            }

            decimal?basePriceAmount                 = product.BasePriceAmount;
            int?    basePriceBaseAmount             = product.BasePriceBaseAmount;
            decimal?lowestAttributeCombinationPrice = product.LowestAttributeCombinationPrice;

            _writer.Write("Id", entity.Id.ToString());
            _writer.Write("Name", (string)product.Name);
            _writer.Write("SeName", (string)product.SeName);
            _writer.Write("ShortDescription", (string)product.ShortDescription);
            _writer.Write("FullDescription", (string)product.FullDescription);
            _writer.Write("AdminComment", (string)product.AdminComment);
            _writer.Write("ProductTemplateId", entity.ProductTemplateId.ToString());
            _writer.Write("ProductTemplateViewPath", (string)product._ProductTemplateViewPath);
            _writer.Write("ShowOnHomePage", entity.ShowOnHomePage.ToString());
            _writer.Write("HomePageDisplayOrder", entity.HomePageDisplayOrder.ToString());
            _writer.Write("MetaKeywords", (string)product.MetaKeywords);
            _writer.Write("MetaDescription", (string)product.MetaDescription);
            _writer.Write("MetaTitle", (string)product.MetaTitle);
            _writer.Write("AllowCustomerReviews", entity.AllowCustomerReviews.ToString());
            _writer.Write("ApprovedRatingSum", entity.ApprovedRatingSum.ToString());
            _writer.Write("NotApprovedRatingSum", entity.NotApprovedRatingSum.ToString());
            _writer.Write("ApprovedTotalReviews", entity.ApprovedTotalReviews.ToString());
            _writer.Write("NotApprovedTotalReviews", entity.NotApprovedTotalReviews.ToString());
            _writer.Write("Published", entity.Published.ToString());
            _writer.Write("CreatedOnUtc", entity.CreatedOnUtc.ToString(_culture));
            _writer.Write("UpdatedOnUtc", entity.UpdatedOnUtc.ToString(_culture));
            _writer.Write("SubjectToAcl", entity.SubjectToAcl.ToString());
            _writer.Write("LimitedToStores", entity.LimitedToStores.ToString());
            _writer.Write("ProductTypeId", entity.ProductTypeId.ToString());
            _writer.Write("ParentGroupedProductId", entity.ParentGroupedProductId.ToString());
            _writer.Write("Sku", (string)product.Sku);
            _writer.Write("ManufacturerPartNumber", (string)product.ManufacturerPartNumber);
            _writer.Write("Gtin", (string)product.Gtin);
            _writer.Write("IsGiftCard", entity.IsGiftCard.ToString());
            _writer.Write("GiftCardTypeId", entity.GiftCardTypeId.ToString());
            _writer.Write("RequireOtherProducts", entity.RequireOtherProducts.ToString());
            _writer.Write("RequiredProductIds", entity.RequiredProductIds);
            _writer.Write("AutomaticallyAddRequiredProducts", entity.AutomaticallyAddRequiredProducts.ToString());
            _writer.Write("IsDownload", entity.IsDownload.ToString());
            _writer.Write("DownloadId", entity.DownloadId.ToString());
            _writer.Write("UnlimitedDownloads", entity.UnlimitedDownloads.ToString());
            _writer.Write("MaxNumberOfDownloads", entity.MaxNumberOfDownloads.ToString());
            _writer.Write("DownloadExpirationDays", entity.DownloadExpirationDays.HasValue ? entity.DownloadExpirationDays.Value.ToString() : "");
            _writer.Write("DownloadActivationTypeId", entity.DownloadActivationTypeId.ToString());
            _writer.Write("HasSampleDownload", entity.HasSampleDownload.ToString());
            _writer.Write("SampleDownloadId", entity.SampleDownloadId.HasValue ? entity.SampleDownloadId.Value.ToString() : "");
            _writer.Write("HasUserAgreement", entity.HasUserAgreement.ToString());
            _writer.Write("UserAgreementText", entity.UserAgreementText);
            _writer.Write("IsRecurring", entity.IsRecurring.ToString());
            _writer.Write("RecurringCycleLength", entity.RecurringCycleLength.ToString());
            _writer.Write("RecurringCyclePeriodId", entity.RecurringCyclePeriodId.ToString());
            _writer.Write("RecurringTotalCycles", entity.RecurringTotalCycles.ToString());
            _writer.Write("IsShipEnabled", entity.IsShipEnabled.ToString());
            _writer.Write("IsFreeShipping", entity.IsFreeShipping.ToString());
            _writer.Write("AdditionalShippingCharge", entity.AdditionalShippingCharge.ToString(_culture));
            _writer.Write("IsTaxExempt", entity.IsTaxExempt.ToString());
            _writer.Write("TaxCategoryId", entity.TaxCategoryId.ToString());
            _writer.Write("ManageInventoryMethodId", entity.ManageInventoryMethodId.ToString());
            _writer.Write("StockQuantity", entity.StockQuantity.ToString());
            _writer.Write("DisplayStockAvailability", entity.DisplayStockAvailability.ToString());
            _writer.Write("DisplayStockQuantity", entity.DisplayStockQuantity.ToString());
            _writer.Write("MinStockQuantity", entity.MinStockQuantity.ToString());
            _writer.Write("LowStockActivityId", entity.LowStockActivityId.ToString());
            _writer.Write("NotifyAdminForQuantityBelow", entity.NotifyAdminForQuantityBelow.ToString());
            _writer.Write("BackorderModeId", entity.BackorderModeId.ToString());
            _writer.Write("AllowBackInStockSubscriptions", entity.AllowBackInStockSubscriptions.ToString());
            _writer.Write("OrderMinimumQuantity", entity.OrderMinimumQuantity.ToString());
            _writer.Write("OrderMaximumQuantity", entity.OrderMaximumQuantity.ToString());
            _writer.Write("HideQuantityControl", entity.HideQuantityControl.ToString());
            _writer.Write("AllowedQuantities", entity.AllowedQuantities);
            _writer.Write("DisableBuyButton", entity.DisableBuyButton.ToString());
            _writer.Write("DisableWishlistButton", entity.DisableWishlistButton.ToString());
            _writer.Write("AvailableForPreOrder", entity.AvailableForPreOrder.ToString());
            _writer.Write("CallForPrice", entity.CallForPrice.ToString());
            _writer.Write("Price", entity.Price.ToString(_culture));
            _writer.Write("OldPrice", entity.OldPrice.ToString(_culture));
            _writer.Write("ProductCost", entity.ProductCost.ToString(_culture));
            _writer.Write("SpecialPrice", entity.SpecialPrice.HasValue ? entity.SpecialPrice.Value.ToString(_culture) : "");
            _writer.Write("SpecialPriceStartDateTimeUtc", entity.SpecialPriceStartDateTimeUtc.HasValue ? entity.SpecialPriceStartDateTimeUtc.Value.ToString(_culture) : "");
            _writer.Write("SpecialPriceEndDateTimeUtc", entity.SpecialPriceEndDateTimeUtc.HasValue ? entity.SpecialPriceEndDateTimeUtc.Value.ToString(_culture) : "");
            _writer.Write("CustomerEntersPrice", entity.CustomerEntersPrice.ToString());
            _writer.Write("MinimumCustomerEnteredPrice", entity.MinimumCustomerEnteredPrice.ToString(_culture));
            _writer.Write("MaximumCustomerEnteredPrice", entity.MaximumCustomerEnteredPrice.ToString(_culture));
            _writer.Write("HasTierPrices", entity.HasTierPrices.ToString());
            _writer.Write("HasDiscountsApplied", entity.HasDiscountsApplied.ToString());
            _writer.Write("Weight", ((decimal)product.Weight).ToString(_culture));
            _writer.Write("Length", ((decimal)product.Length).ToString(_culture));
            _writer.Write("Width", ((decimal)product.Width).ToString(_culture));
            _writer.Write("Height", ((decimal)product.Height).ToString(_culture));
            _writer.Write("AvailableStartDateTimeUtc", entity.AvailableStartDateTimeUtc.HasValue ? entity.AvailableStartDateTimeUtc.Value.ToString(_culture) : "");
            _writer.Write("AvailableEndDateTimeUtc", entity.AvailableEndDateTimeUtc.HasValue ? entity.AvailableEndDateTimeUtc.Value.ToString(_culture) : "");
            _writer.Write("BasePriceEnabled", ((bool)product.BasePriceEnabled).ToString());
            _writer.Write("BasePriceMeasureUnit", (string)product.BasePriceMeasureUnit);
            _writer.Write("BasePriceAmount", basePriceAmount.HasValue ? basePriceAmount.Value.ToString(_culture) : "");
            _writer.Write("BasePriceBaseAmount", basePriceBaseAmount.HasValue ? basePriceBaseAmount.Value.ToString() : "");
            _writer.Write("BasePriceHasValue", ((bool)product.BasePriceHasValue).ToString());
            _writer.Write("BasePriceInfo", (string)product._BasePriceInfo);
            _writer.Write("VisibleIndividually", entity.VisibleIndividually.ToString());
            _writer.Write("DisplayOrder", entity.DisplayOrder.ToString());
            _writer.Write("BundleTitleText", entity.BundleTitleText);
            _writer.Write("BundlePerItemPricing", entity.BundlePerItemPricing.ToString());
            _writer.Write("BundlePerItemShipping", entity.BundlePerItemShipping.ToString());
            _writer.Write("BundlePerItemShoppingCart", entity.BundlePerItemShoppingCart.ToString());
            _writer.Write("LowestAttributeCombinationPrice", lowestAttributeCombinationPrice.HasValue ? lowestAttributeCombinationPrice.Value.ToString(_culture) : "");
            _writer.Write("IsEsd", entity.IsEsd.ToString());
            _writer.Write("CustomsTariffNumber", entity.CustomsTariffNumber);

            WriteLocalized(product);

            WriteDeliveryTime(product.DeliveryTime, "DeliveryTime");

            WriteQuantityUnit(product.QuantityUnit, "QuantityUnit");

            WriteCountry(product.CountryOfOrigin, "CountryOfOrigin");

            if (product.AppliedDiscounts != null)
            {
                _writer.WriteStartElement("AppliedDiscounts");
                foreach (dynamic discount in product.AppliedDiscounts)
                {
                    Discount entityDiscount = discount.Entity;

                    _writer.WriteStartElement("AppliedDiscount");
                    _writer.Write("Id", entityDiscount.Id.ToString());
                    _writer.Write("Name", (string)discount.Name);
                    _writer.Write("DiscountTypeId", entityDiscount.DiscountTypeId.ToString());
                    _writer.Write("UsePercentage", entityDiscount.UsePercentage.ToString());
                    _writer.Write("DiscountPercentage", entityDiscount.DiscountPercentage.ToString(_culture));
                    _writer.Write("DiscountAmount", entityDiscount.DiscountAmount.ToString(_culture));
                    _writer.Write("StartDateUtc", entityDiscount.StartDateUtc.HasValue ? entityDiscount.StartDateUtc.Value.ToString(_culture) : "");
                    _writer.Write("EndDateUtc", entityDiscount.EndDateUtc.HasValue ? entityDiscount.EndDateUtc.Value.ToString(_culture) : "");
                    _writer.Write("RequiresCouponCode", entityDiscount.RequiresCouponCode.ToString());
                    _writer.Write("CouponCode", entityDiscount.CouponCode);
                    _writer.Write("DiscountLimitationId", entityDiscount.DiscountLimitationId.ToString());
                    _writer.Write("LimitationTimes", entityDiscount.LimitationTimes.ToString());
                    _writer.WriteEndElement();                  // AppliedDiscount
                }
                _writer.WriteEndElement();                      // AppliedDiscounts
            }

            if (product.TierPrices != null)
            {
                _writer.WriteStartElement("TierPrices");
                foreach (dynamic tierPrice in product.TierPrices)
                {
                    TierPrice entityTierPrice = tierPrice.Entity;

                    _writer.WriteStartElement("TierPrice");
                    _writer.Write("Id", entityTierPrice.Id.ToString());
                    _writer.Write("ProductId", entityTierPrice.ProductId.ToString());
                    _writer.Write("StoreId", entityTierPrice.StoreId.ToString());
                    _writer.Write("CustomerRoleId", entityTierPrice.CustomerRoleId.HasValue ? entityTierPrice.CustomerRoleId.Value.ToString() : "");
                    _writer.Write("Quantity", entityTierPrice.Quantity.ToString());
                    _writer.Write("Price", entityTierPrice.Price.ToString(_culture));
                    _writer.Write("CalculationMethod", ((int)entityTierPrice.CalculationMethod).ToString());
                    _writer.WriteEndElement();  // TierPrice
                }
                _writer.WriteEndElement();      // TierPrices
            }

            if (product.ProductTags != null)
            {
                _writer.WriteStartElement("ProductTags");
                foreach (dynamic tag in product.ProductTags)
                {
                    _writer.WriteStartElement("ProductTag");
                    _writer.Write("Id", ((int)tag.Id).ToString());
                    _writer.Write("Name", (string)tag.Name);
                    _writer.Write("SeName", (string)tag.SeName);

                    WriteLocalized(tag);

                    _writer.WriteEndElement();                  // ProductTag
                }
                _writer.WriteEndElement();                      // ProductTags
            }

            if (product.ProductAttributes != null)
            {
                _writer.WriteStartElement("ProductAttributes");
                foreach (dynamic pva in product.ProductAttributes)
                {
                    ProductVariantAttribute entityPva = pva.Entity;

                    _writer.WriteStartElement("ProductAttribute");
                    _writer.Write("Id", entityPva.Id.ToString());
                    _writer.Write("TextPrompt", (string)pva.TextPrompt);
                    _writer.Write("IsRequired", entityPva.IsRequired.ToString());
                    _writer.Write("AttributeControlTypeId", entityPva.AttributeControlTypeId.ToString());
                    _writer.Write("DisplayOrder", entityPva.DisplayOrder.ToString());

                    _writer.WriteStartElement("Attribute");
                    _writer.Write("Id", ((int)pva.Attribute.Id).ToString());
                    _writer.Write("Alias", (string)pva.Attribute.Alias);
                    _writer.Write("Name", (string)pva.Attribute.Name);
                    _writer.Write("Description", (string)pva.Attribute.Description);

                    WriteLocalized(pva.Attribute);

                    _writer.WriteEndElement();                          // Attribute

                    _writer.WriteStartElement("AttributeValues");
                    foreach (dynamic value in pva.Attribute.Values)
                    {
                        ProductVariantAttributeValue entityPvav = value.Entity;

                        _writer.WriteStartElement("AttributeValue");
                        _writer.Write("Id", entityPvav.Id.ToString());
                        _writer.Write("Alias", (string)value.Alias);
                        _writer.Write("Name", (string)value.Name);
                        _writer.Write("Color", (string)value.Color);
                        _writer.Write("PriceAdjustment", ((decimal)value.PriceAdjustment).ToString(_culture));
                        _writer.Write("WeightAdjustment", ((decimal)value.WeightAdjustment).ToString(_culture));
                        _writer.Write("IsPreSelected", entityPvav.IsPreSelected.ToString());
                        _writer.Write("DisplayOrder", entityPvav.DisplayOrder.ToString());
                        _writer.Write("ValueTypeId", entityPvav.ValueTypeId.ToString());
                        _writer.Write("LinkedProductId", entityPvav.LinkedProductId.ToString());
                        _writer.Write("Quantity", entityPvav.Quantity.ToString());

                        WriteLocalized(value);

                        _writer.WriteEndElement();              // AttributeValue
                    }
                    _writer.WriteEndElement();                  // AttributeValues

                    _writer.WriteEndElement();                  // ProductAttribute
                }
                _writer.WriteEndElement();                      // ProductAttributes
            }

            if (product.ProductAttributeCombinations != null)
            {
                _writer.WriteStartElement("ProductAttributeCombinations");
                foreach (dynamic combination in product.ProductAttributeCombinations)
                {
                    ProductVariantAttributeCombination entityPvac = combination.Entity;

                    _writer.WriteStartElement("ProductAttributeCombination");
                    _writer.Write("Id", entityPvac.Id.ToString());
                    _writer.Write("StockQuantity", entityPvac.StockQuantity.ToString());
                    _writer.Write("AllowOutOfStockOrders", entityPvac.AllowOutOfStockOrders.ToString());
                    _writer.Write("AttributesXml", entityPvac.AttributesXml);
                    _writer.Write("Sku", entityPvac.Sku);
                    _writer.Write("Gtin", entityPvac.Gtin);
                    _writer.Write("ManufacturerPartNumber", entityPvac.ManufacturerPartNumber);
                    _writer.Write("Price", entityPvac.Price.HasValue ? entityPvac.Price.Value.ToString(_culture) : "");
                    _writer.Write("Length", entityPvac.Length.HasValue ? entityPvac.Length.Value.ToString(_culture) : "");
                    _writer.Write("Width", entityPvac.Width.HasValue ? entityPvac.Width.Value.ToString(_culture) : "");
                    _writer.Write("Height", entityPvac.Height.HasValue ? entityPvac.Height.Value.ToString(_culture) : "");
                    _writer.Write("BasePriceAmount", entityPvac.BasePriceAmount.HasValue ? entityPvac.BasePriceAmount.Value.ToString(_culture) : "");
                    _writer.Write("BasePriceBaseAmount", entityPvac.BasePriceBaseAmount.HasValue ? entityPvac.BasePriceBaseAmount.Value.ToString() : "");
                    _writer.Write("AssignedPictureIds", entityPvac.AssignedPictureIds);
                    _writer.Write("DeliveryTimeId", entityPvac.DeliveryTimeId.HasValue ? entityPvac.DeliveryTimeId.Value.ToString() : "");
                    _writer.Write("IsActive", entityPvac.IsActive.ToString());

                    WriteDeliveryTime(combination.DeliveryTime, "DeliveryTime");

                    WriteQuantityUnit(combination.QuantityUnit, "QuantityUnit");

                    _writer.WriteStartElement("Pictures");
                    foreach (dynamic assignedPicture in combination.Pictures)
                    {
                        WritePicture(assignedPicture, "Picture");
                    }
                    _writer.WriteEndElement();             // Pictures

                    _writer.WriteEndElement();             // ProductAttributeCombination
                }
                _writer.WriteEndElement();                 // ProductAttributeCombinations
            }

            if (product.ProductPictures != null)
            {
                _writer.WriteStartElement("ProductPictures");
                foreach (dynamic productPicture in product.ProductPictures)
                {
                    ProductPicture entityProductPicture = productPicture.Entity;

                    _writer.WriteStartElement("ProductPicture");
                    _writer.Write("Id", entityProductPicture.Id.ToString());
                    _writer.Write("DisplayOrder", entityProductPicture.DisplayOrder.ToString());

                    WritePicture(productPicture.Picture, "Picture");

                    _writer.WriteEndElement();                  // ProductPicture
                }
                _writer.WriteEndElement();                      // ProductPictures
            }

            if (product.ProductCategories != null)
            {
                _writer.WriteStartElement("ProductCategories");
                foreach (dynamic productCategory in product.ProductCategories)
                {
                    ProductCategory entityProductCategory = productCategory.Entity;

                    _writer.WriteStartElement("ProductCategory");
                    _writer.Write("Id", entityProductCategory.Id.ToString());
                    _writer.Write("DisplayOrder", entityProductCategory.DisplayOrder.ToString());
                    _writer.Write("IsFeaturedProduct", entityProductCategory.IsFeaturedProduct.ToString());

                    WriteCategory(productCategory.Category, "Category");

                    _writer.WriteEndElement();                  // ProductCategory
                }
                _writer.WriteEndElement();                      // ProductCategories
            }

            if (product.ProductManufacturers != null)
            {
                _writer.WriteStartElement("ProductManufacturers");
                foreach (dynamic productManu in product.ProductManufacturers)
                {
                    ProductManufacturer entityProductManu = productManu.Entity;

                    _writer.WriteStartElement("ProductManufacturer");

                    _writer.Write("Id", entityProductManu.Id.ToString());
                    _writer.Write("DisplayOrder", entityProductManu.DisplayOrder.ToString());
                    _writer.Write("IsFeaturedProduct", entityProductManu.IsFeaturedProduct.ToString());

                    WriteManufacturer(productManu.Manufacturer, "Manufacturer");

                    _writer.WriteEndElement();                  // ProductManufacturer
                }
                _writer.WriteEndElement();                      // ProductManufacturers
            }

            if (product.ProductSpecificationAttributes != null)
            {
                _writer.WriteStartElement("ProductSpecificationAttributes");
                foreach (dynamic psa in product.ProductSpecificationAttributes)
                {
                    ProductSpecificationAttribute entityPsa = psa.Entity;

                    _writer.WriteStartElement("ProductSpecificationAttribute");

                    _writer.Write("Id", entityPsa.Id.ToString());
                    _writer.Write("ProductId", entityPsa.ProductId.ToString());
                    _writer.Write("SpecificationAttributeOptionId", entityPsa.SpecificationAttributeOptionId.ToString());
                    _writer.Write("AllowFiltering", entityPsa.AllowFiltering.ToString());
                    _writer.Write("ShowOnProductPage", entityPsa.ShowOnProductPage.ToString());
                    _writer.Write("DisplayOrder", entityPsa.DisplayOrder.ToString());

                    dynamic option = psa.SpecificationAttributeOption;
                    SpecificationAttributeOption entitySao = option.Entity;
                    SpecificationAttribute       entitySa  = option.SpecificationAttribute.Entity;

                    _writer.WriteStartElement("SpecificationAttributeOption");
                    _writer.Write("Id", entitySao.Id.ToString());
                    _writer.Write("SpecificationAttributeId", entitySao.SpecificationAttributeId.ToString());
                    _writer.Write("DisplayOrder", entitySao.DisplayOrder.ToString());
                    _writer.Write("Name", (string)option.Name);
                    _writer.Write("Alias", (string)option.Alias);

                    WriteLocalized(option);

                    _writer.WriteStartElement("SpecificationAttribute");
                    _writer.Write("Id", entitySa.Id.ToString());
                    _writer.Write("Name", (string)option.SpecificationAttribute.Name);
                    _writer.Write("Alias", (string)option.SpecificationAttribute.Alias);
                    _writer.Write("DisplayOrder", entitySa.DisplayOrder.ToString());
                    _writer.Write("AllowFiltering", entitySa.AllowFiltering.ToString());
                    _writer.Write("ShowOnProductPage", entitySa.ShowOnProductPage.ToString());
                    _writer.Write("FacetSorting", ((int)entitySa.FacetSorting).ToString());
                    _writer.Write("FacetTemplateHint", ((int)entitySa.FacetTemplateHint).ToString());

                    WriteLocalized(option.SpecificationAttribute);

                    _writer.WriteEndElement();                  // SpecificationAttribute
                    _writer.WriteEndElement();                  // SpecificationAttributeOption

                    _writer.WriteEndElement();                  // ProductSpecificationAttribute
                }
                _writer.WriteEndElement();                      // ProductSpecificationAttributes
            }

            if (product.ProductBundleItems != null)
            {
                _writer.WriteStartElement("ProductBundleItems");
                foreach (dynamic bundleItem in product.ProductBundleItems)
                {
                    ProductBundleItem entityPbi = bundleItem.Entity;

                    _writer.WriteStartElement("ProductBundleItem");
                    _writer.Write("Id", entityPbi.Id.ToString());
                    _writer.Write("ProductId", entityPbi.ProductId.ToString());
                    _writer.Write("BundleProductId", entityPbi.BundleProductId.ToString());
                    _writer.Write("Quantity", entityPbi.Quantity.ToString());
                    _writer.Write("Discount", entityPbi.Discount.HasValue ? entityPbi.Discount.Value.ToString(_culture) : "");
                    _writer.Write("DiscountPercentage", entityPbi.DiscountPercentage.ToString());
                    _writer.Write("Name", (string)bundleItem.Name);
                    _writer.Write("ShortDescription", (string)bundleItem.ShortDescription);
                    _writer.Write("FilterAttributes", entityPbi.FilterAttributes.ToString());
                    _writer.Write("HideThumbnail", entityPbi.HideThumbnail.ToString());
                    _writer.Write("Visible", entityPbi.Visible.ToString());
                    _writer.Write("Published", entityPbi.Published.ToString());
                    _writer.Write("DisplayOrder", ((int)bundleItem.DisplayOrder).ToString());
                    _writer.Write("CreatedOnUtc", entityPbi.CreatedOnUtc.ToString(_culture));
                    _writer.Write("UpdatedOnUtc", entityPbi.UpdatedOnUtc.ToString(_culture));

                    WriteLocalized(bundleItem);

                    _writer.WriteEndElement();                  // ProductBundleItem
                }
                _writer.WriteEndElement();                      // ProductBundleItems
            }

            if (node.HasValue())
            {
                _writer.WriteEndElement();
            }
        }
예제 #24
0
 public static ProductVariantAttributeCombinationModel ToModel(this ProductVariantAttributeCombination entity)
 {
     return(Mapper.Map <ProductVariantAttributeCombination, ProductVariantAttributeCombinationModel>(entity));
 }
예제 #25
0
        public virtual void CreateAllProductVariantAttributeCombinations(Product product)
        {
            // delete all existing combinations
            _pvacRepository.DeleteAll(x => x.ProductId == product.Id);

            var attributes = GetProductVariantAttributesByProductId(product.Id);

            if (attributes == null || attributes.Count <= 0)
            {
                return;
            }

            var toCombine    = new List <List <ProductVariantAttributeValue> >();
            var resultMatrix = new List <List <ProductVariantAttributeValue> >();
            var tmp          = new List <ProductVariantAttributeValue>();

            foreach (var attr in attributes)
            {
                var attributeValues = attr.ProductVariantAttributeValues.ToList();
                if (attributeValues.Count > 0)
                {
                    toCombine.Add(attributeValues);
                }
            }

            if (toCombine.Count > 0)
            {
                CombineAll(toCombine, resultMatrix, 0, tmp);

                using (var scope = new DbContextScope(ctx: _pvacRepository.Context, autoCommit: false, autoDetectChanges: false, validateOnSave: false, hooksEnabled: false))
                {
                    ProductVariantAttributeCombination combination = null;

                    var idx = 0;
                    foreach (var values in resultMatrix)
                    {
                        idx++;

                        string attrXml = "";
                        for (var i = 0; i < values.Count; ++i)
                        {
                            var value = values[i];
                            attrXml = attributes[i].AddProductAttribute(attrXml, value.Id.ToString());
                        }

                        combination = new ProductVariantAttributeCombination
                        {
                            ProductId             = product.Id,
                            AttributesXml         = attrXml,
                            StockQuantity         = 10000,
                            AllowOutOfStockOrders = true,
                            IsActive = true
                        };

                        _pvacRepository.Insert(combination);
                    }

                    scope.Commit();

                    if (combination != null)
                    {
                        // Perf: publish event for last one only
                        _eventPublisher.EntityInserted(combination);
                    }
                }
            }

            //foreach (var y in resultMatrix) {
            //	StringBuilder sb = new StringBuilder();
            //	foreach (var x in y) {
            //		sb.AppendFormat("{0} ", x.Name);
            //	}
            //	sb.ToString().Dump();
            //}
        }
        public static void MergeWithCombination(this Product product, ProductVariantAttributeCombination combination)
        {
            Guard.NotNull(product, "product");

            var values = product.MergedDataValues;

            if (values != null)
            {
                values.Clear();
            }

            if (combination == null)
            {
                return;
            }

            if (values == null)
            {
                product.MergedDataValues = values = new Dictionary <string, object>();
            }

            if (ManageInventoryMethod.ManageStockByAttributes == (ManageInventoryMethod)product.ManageInventoryMethodId)
            {
                values.Add("StockQuantity", combination.StockQuantity);
                values.Add("BackorderModeId", combination.AllowOutOfStockOrders ? (int)BackorderMode.AllowQtyBelow0 : (int)BackorderMode.NoBackorders);
            }

            if (combination.Sku.HasValue())
            {
                values.Add("Sku", combination.Sku);
            }
            if (combination.Gtin.HasValue())
            {
                values.Add("Gtin", combination.Gtin);
            }
            if (combination.ManufacturerPartNumber.HasValue())
            {
                values.Add("ManufacturerPartNumber", combination.ManufacturerPartNumber);
            }

            if (combination.Price.HasValue)
            {
                values.Add("Price", combination.Price.Value);
            }

            if (combination.DeliveryTimeId.HasValue && combination.DeliveryTimeId.Value > 0)
            {
                values.Add("DeliveryTimeId", combination.DeliveryTimeId);
            }

            if (combination.QuantityUnitId.HasValue && combination.QuantityUnitId.Value > 0)
            {
                values.Add("QuantityUnitId", combination.QuantityUnitId);
            }

            if (combination.Length.HasValue)
            {
                values.Add("Length", combination.Length.Value);
            }
            if (combination.Width.HasValue)
            {
                values.Add("Width", combination.Width.Value);
            }
            if (combination.Height.HasValue)
            {
                values.Add("Height", combination.Height.Value);
            }

            if (combination.BasePriceAmount.HasValue)
            {
                values.Add("BasePriceAmount", combination.BasePriceAmount);
            }
            if (combination.BasePriceBaseAmount.HasValue)
            {
                values.Add("BasePriceBaseAmount", combination.BasePriceBaseAmount);
            }
        }
예제 #27
0
        /// <summary>
        /// Validates a product variant for standard properties
        /// </summary>
        /// <param name="customer">Customer</param>
        /// <param name="shoppingCartType">Shopping cart type</param>
        /// <param name="productVariant">Product variant</param>
        /// <param name="selectedAttributes">Selected attributes</param>
        /// <param name="customerEnteredPrice">Customer entered price</param>
        /// <param name="quantity">Quantity</param>
        /// <returns>Warnings</returns>
        public virtual IList <string> GetStandardWarnings(Customer customer, ShoppingCartType shoppingCartType,
                                                          ProductVariant productVariant, string selectedAttributes, decimal customerEnteredPrice,
                                                          int quantity)
        {
            if (customer == null)
            {
                throw new ArgumentNullException("customer");
            }

            if (productVariant == null)
            {
                throw new ArgumentNullException("productVariant");
            }

            var warnings = new List <string>();

            var product = productVariant.Product;

            if (product == null)
            {
                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.CannotLoadProduct"), productVariant.ProductId));
                return(warnings);
            }

            //deleted?
            if (product.Deleted || productVariant.Deleted)
            {
                warnings.Add(_localizationService.GetResource("ShoppingCart.ProductDeleted"));
                return(warnings);
            }

            //published?
            if (!product.Published || !productVariant.Published)
            {
                warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished"));
            }

            //ACL
            if (!_aclService.Authorize(product, customer))
            {
                warnings.Add(_localizationService.GetResource("ShoppingCart.ProductUnpublished"));
            }

            //disabled "add to cart" button
            if (shoppingCartType == ShoppingCartType.ShoppingCart && productVariant.DisableBuyButton)
            {
                warnings.Add(_localizationService.GetResource("ShoppingCart.BuyingDisabled"));
            }

            //disabled "add to wishlist" button
            if (shoppingCartType == ShoppingCartType.Wishlist && productVariant.DisableWishlistButton)
            {
                warnings.Add(_localizationService.GetResource("ShoppingCart.WishlistDisabled"));
            }

            //call for price
            if (shoppingCartType == ShoppingCartType.ShoppingCart && productVariant.CallForPrice)
            {
                warnings.Add(_localizationService.GetResource("Products.CallForPrice"));
            }

            //customer entered price
            if (productVariant.CustomerEntersPrice)
            {
                if (customerEnteredPrice < productVariant.MinimumCustomerEnteredPrice ||
                    customerEnteredPrice > productVariant.MaximumCustomerEnteredPrice)
                {
                    decimal minimumCustomerEnteredPrice = _currencyService.ConvertFromPrimaryStoreCurrency(productVariant.MinimumCustomerEnteredPrice, _workContext.WorkingCurrency);
                    decimal maximumCustomerEnteredPrice = _currencyService.ConvertFromPrimaryStoreCurrency(productVariant.MaximumCustomerEnteredPrice, _workContext.WorkingCurrency);
                    warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.CustomerEnteredPrice.RangeError"),
                                               _priceFormatter.FormatPrice(minimumCustomerEnteredPrice, false, false),
                                               _priceFormatter.FormatPrice(maximumCustomerEnteredPrice, false, false)));
                }
            }

            //quantity validation
            var hasQtyWarnings = false;

            if (quantity < productVariant.OrderMinimumQuantity)
            {
                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MinimumQuantity"), productVariant.OrderMinimumQuantity));
                hasQtyWarnings = true;
            }
            if (quantity > productVariant.OrderMaximumQuantity)
            {
                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MaximumQuantity"), productVariant.OrderMaximumQuantity));
                hasQtyWarnings = true;
            }
            var allowedQuantities = productVariant.ParseAllowedQuatities();

            if (allowedQuantities.Length > 0 && !allowedQuantities.Contains(quantity))
            {
                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.AllowedQuantities"), string.Join(", ", allowedQuantities)));
            }

            var validateOutOfStock = shoppingCartType == ShoppingCartType.ShoppingCart || !_shoppingCartSettings.AllowOutOfStockItemsToBeAddedToWishlist;

            if (validateOutOfStock && !hasQtyWarnings)
            {
                switch (productVariant.ManageInventoryMethod)
                {
                case ManageInventoryMethod.DontManageStock:
                {
                }
                break;

                case ManageInventoryMethod.ManageStock:
                {
                    if ((BackorderMode)productVariant.BackorderMode == BackorderMode.NoBackorders)
                    {
                        if (productVariant.StockQuantity < quantity)
                        {
                            int maximumQuantityCanBeAdded = productVariant.StockQuantity;
                            if (maximumQuantityCanBeAdded <= 0)
                            {
                                warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock"));
                            }
                            else
                            {
                                warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.QuantityExceedsStock"), maximumQuantityCanBeAdded));
                            }
                        }
                    }
                }
                break;

                case ManageInventoryMethod.ManageStockByAttributes:
                {
                    var combinations = productVariant.ProductVariantAttributeCombinations;
                    ProductVariantAttributeCombination combination = null;
                    foreach (var comb1 in combinations)
                    {
                        if (_productAttributeParser.AreProductAttributesEqual(comb1.AttributesXml, selectedAttributes))
                        {
                            combination = comb1;
                        }
                    }
                    if (combination != null)
                    {
                        if (!combination.AllowOutOfStockOrders)
                        {
                            if (combination.StockQuantity < quantity)
                            {
                                int maximumQuantityCanBeAdded = combination.StockQuantity;
                                if (maximumQuantityCanBeAdded <= 0)
                                {
                                    warnings.Add(_localizationService.GetResource("ShoppingCart.OutOfStock"));
                                }
                                else
                                {
                                    warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.QuantityExceedsStock"), maximumQuantityCanBeAdded));
                                }
                            }
                        }
                    }
                }
                break;

                default:
                    break;
                }
            }

            //availability dates
            bool availableStartDateError = false;

            if (productVariant.AvailableStartDateTimeUtc.HasValue)
            {
                DateTime now = DateTime.UtcNow;
                DateTime availableStartDateTime = DateTime.SpecifyKind(productVariant.AvailableStartDateTimeUtc.Value, DateTimeKind.Utc);
                if (availableStartDateTime.CompareTo(now) > 0)
                {
                    warnings.Add(_localizationService.GetResource("ShoppingCart.NotAvailable"));
                    availableStartDateError = true;
                }
            }
            if (productVariant.AvailableEndDateTimeUtc.HasValue && !availableStartDateError)
            {
                DateTime now = DateTime.UtcNow;
                DateTime availableEndDateTime = DateTime.SpecifyKind(productVariant.AvailableEndDateTimeUtc.Value, DateTimeKind.Utc);
                if (availableEndDateTime.CompareTo(now) < 0)
                {
                    warnings.Add(_localizationService.GetResource("ShoppingCart.NotAvailable"));
                }
            }
            return(warnings);
        }
예제 #28
0
        /// <summary>
        /// Creates all variant attribute combinations
        /// </summary>
        /// <param name="product">The product</param>
        public virtual void CreateAllProductVariantAttributeCombinations(Product product)
        {
            // delete all existing combinations
            foreach (var itm in GetAllProductVariantAttributeCombinations(product.Id))
            {
                DeleteProductVariantAttributeCombination(itm);
            }

            var attributes = GetProductVariantAttributesByProductId(product.Id);

            if (attributes == null || attributes.Count <= 0)
            {
                return;
            }

            var toCombine    = new List <List <ProductVariantAttributeValue> >();
            var resultMatrix = new List <List <ProductVariantAttributeValue> >();
            var tmp          = new List <ProductVariantAttributeValue>();

            foreach (var attr in attributes)
            {
                var attributeValues = attr.ProductVariantAttributeValues.ToList();
                if (attributeValues.Count > 0)
                {
                    toCombine.Add(attributeValues);
                }
            }

            if (toCombine.Count > 0)
            {
                CombineAll(toCombine, resultMatrix, 0, tmp);

                foreach (var values in resultMatrix)
                {
                    string attrXml = "";
                    foreach (var x in values)
                    {
                        attrXml = attributes[values.IndexOf(x)].AddProductAttribute(attrXml, x.Id.ToString());
                    }

                    var combination = new ProductVariantAttributeCombination()
                    {
                        ProductId             = product.Id,
                        AttributesXml         = attrXml,
                        StockQuantity         = 10000,
                        AllowOutOfStockOrders = true,
                        IsActive = true
                    };

                    _productVariantAttributeCombinationRepository.Insert(combination);
                    _eventPublisher.EntityInserted(combination);
                }
            }

            //foreach (var y in resultMatrix) {
            //	StringBuilder sb = new StringBuilder();
            //	foreach (var x in y) {
            //		sb.AppendFormat("{0} ", x.Name);
            //	}
            //	sb.ToString().Dump();
            //}
        }
예제 #29
0
        /// <summary>
        /// Create a copy of product variant with all depended data
        /// </summary>
        /// <param name="productVariant">The product variant to copy</param>
        /// <param name="productId">The product identifier</param>
        /// <param name="newName">The name of product variant duplicate</param>
        /// <param name="isPublished">A value indicating whether the product variant duplicate should be published</param>
        /// <param name="copyImage">A value indicating whether the product variant image should be copied</param>
        /// <returns>Product variant copy</returns>
        public virtual ProductVariant CopyProductVariant(ProductVariant productVariant, int productId,
                                                         string newName, bool isPublished, bool copyImage)
        {
            if (productVariant == null)
            {
                throw new ArgumentNullException("productVariant");
            }

            var languages = _languageService.GetAllLanguages(true);

            // product variant picture
            int pictureId = 0;

            if (copyImage)
            {
                var picture = _pictureService.GetPictureById(productVariant.PictureId);
                if (picture != null)
                {
                    var pictureCopy = _pictureService.InsertPicture(
                        _pictureService.LoadPictureBinary(picture),
                        picture.MimeType,
                        _pictureService.GetPictureSeName(productVariant.Name),
                        true);
                    pictureId = pictureCopy.Id;
                }
            }

            // product variant download & sample download
            int downloadId       = productVariant.DownloadId;
            int sampleDownloadId = productVariant.SampleDownloadId;

            if (productVariant.IsDownload)
            {
                var download = _downloadService.GetDownloadById(productVariant.DownloadId);
                if (download != null)
                {
                    var downloadCopy = new Download()
                    {
                        DownloadGuid   = Guid.NewGuid(),
                        UseDownloadUrl = download.UseDownloadUrl,
                        DownloadUrl    = download.DownloadUrl,
                        DownloadBinary = download.DownloadBinary,
                        ContentType    = download.ContentType,
                        Filename       = download.Filename,
                        Extension      = download.Extension,
                        IsNew          = download.IsNew,
                    };
                    _downloadService.InsertDownload(downloadCopy);
                    downloadId = downloadCopy.Id;
                }

                if (productVariant.HasSampleDownload)
                {
                    var sampleDownload = _downloadService.GetDownloadById(productVariant.SampleDownloadId);
                    if (sampleDownload != null)
                    {
                        var sampleDownloadCopy = new Download()
                        {
                            DownloadGuid   = Guid.NewGuid(),
                            UseDownloadUrl = sampleDownload.UseDownloadUrl,
                            DownloadUrl    = sampleDownload.DownloadUrl,
                            DownloadBinary = sampleDownload.DownloadBinary,
                            ContentType    = sampleDownload.ContentType,
                            Filename       = sampleDownload.Filename,
                            Extension      = sampleDownload.Extension,
                            IsNew          = sampleDownload.IsNew
                        };
                        _downloadService.InsertDownload(sampleDownloadCopy);
                        sampleDownloadId = sampleDownloadCopy.Id;
                    }
                }
            }

            // product variant
            var productVariantCopy = new ProductVariant()
            {
                ProductId                 = productId,
                Name                      = newName,
                Sku                       = productVariant.Sku,
                Description               = productVariant.Description,
                AdminComment              = productVariant.AdminComment,
                ManufacturerPartNumber    = productVariant.ManufacturerPartNumber,
                Gtin                      = productVariant.Gtin,
                IsGiftCard                = productVariant.IsGiftCard,
                GiftCardType              = productVariant.GiftCardType,
                RequireOtherProducts      = productVariant.RequireOtherProducts,
                RequiredProductVariantIds = productVariant.RequiredProductVariantIds,
                AutomaticallyAddRequiredProductVariants = productVariant.AutomaticallyAddRequiredProductVariants,
                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,
                RecurringCycleLength          = productVariant.RecurringCycleLength,
                RecurringCyclePeriod          = productVariant.RecurringCyclePeriod,
                RecurringTotalCycles          = productVariant.RecurringTotalCycles,
                IsShipEnabled                 = productVariant.IsShipEnabled,
                IsFreeShipping                = productVariant.IsFreeShipping,
                AdditionalShippingCharge      = productVariant.AdditionalShippingCharge,
                IsTaxExempt                   = productVariant.IsTaxExempt,
                TaxCategoryId                 = productVariant.TaxCategoryId,
                ManageInventoryMethod         = productVariant.ManageInventoryMethod,
                StockQuantity                 = productVariant.StockQuantity,
                DisplayStockAvailability      = productVariant.DisplayStockAvailability,
                DisplayStockQuantity          = productVariant.DisplayStockQuantity,
                MinStockQuantity              = productVariant.MinStockQuantity,
                LowStockActivityId            = productVariant.LowStockActivityId,
                NotifyAdminForQuantityBelow   = productVariant.NotifyAdminForQuantityBelow,
                BackorderMode                 = productVariant.BackorderMode,
                AllowBackInStockSubscriptions = productVariant.AllowBackInStockSubscriptions,
                OrderMinimumQuantity          = productVariant.OrderMinimumQuantity,
                OrderMaximumQuantity          = productVariant.OrderMaximumQuantity,
                AllowedQuantities             = productVariant.AllowedQuantities,
                DisableBuyButton              = productVariant.DisableBuyButton,
                DisableWishlistButton         = productVariant.DisableWishlistButton,
                CallForPrice                  = productVariant.CallForPrice,
                Price        = productVariant.Price,
                OldPrice     = productVariant.OldPrice,
                ProductCost  = productVariant.ProductCost,
                SpecialPrice = productVariant.SpecialPrice,
                SpecialPriceStartDateTimeUtc = productVariant.SpecialPriceStartDateTimeUtc,
                SpecialPriceEndDateTimeUtc   = productVariant.SpecialPriceEndDateTimeUtc,
                CustomerEntersPrice          = productVariant.CustomerEntersPrice,
                MinimumCustomerEnteredPrice  = productVariant.MinimumCustomerEnteredPrice,
                MaximumCustomerEnteredPrice  = productVariant.MaximumCustomerEnteredPrice,
                Weight    = productVariant.Weight,
                Length    = productVariant.Length,
                Width     = productVariant.Width,
                Height    = productVariant.Height,
                PictureId = pictureId,
                AvailableStartDateTimeUtc = productVariant.AvailableStartDateTimeUtc,
                AvailableEndDateTimeUtc   = productVariant.AvailableEndDateTimeUtc,
                Published    = isPublished,
                Deleted      = productVariant.Deleted,
                DisplayOrder = productVariant.DisplayOrder,
                CreatedOnUtc = DateTime.UtcNow,
                UpdatedOnUtc = DateTime.UtcNow
            };

            _productService.InsertProductVariant(productVariantCopy);

            //localization
            foreach (var lang in languages)
            {
                var name = productVariant.GetLocalized(x => x.Name, lang.Id, false, false);
                if (!String.IsNullOrEmpty(name))
                {
                    _localizedEntityService.SaveLocalizedValue(productVariantCopy, x => x.Name, name, lang.Id);
                }

                var description = productVariant.GetLocalized(x => x.Description, lang.Id, false, false);
                if (!String.IsNullOrEmpty(description))
                {
                    _localizedEntityService.SaveLocalizedValue(productVariantCopy, x => x.Description, description, lang.Id);
                }
            }

            // product variant <-> attributes mappings
            var associatedAttributes      = new Dictionary <int, int>();
            var associatedAttributeValues = new Dictionary <int, int>();

            foreach (var productVariantAttribute in _productAttributeService.GetProductVariantAttributesByProductVariantId(productVariant.Id))
            {
                var productVariantAttributeCopy = new ProductVariantAttribute()
                {
                    ProductVariantId       = productVariantCopy.Id,
                    ProductAttributeId     = productVariantAttribute.ProductAttributeId,
                    TextPrompt             = productVariantAttribute.TextPrompt,
                    IsRequired             = productVariantAttribute.IsRequired,
                    AttributeControlTypeId = productVariantAttribute.AttributeControlTypeId,
                    DisplayOrder           = productVariantAttribute.DisplayOrder
                };
                _productAttributeService.InsertProductVariantAttribute(productVariantAttributeCopy);
                //save associated value (used for combinations copying)
                associatedAttributes.Add(productVariantAttribute.Id, productVariantAttributeCopy.Id);

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

                    //save associated value (used for combinations copying)
                    associatedAttributeValues.Add(productVariantAttributeValue.Id, pvavCopy.Id);

                    //localization
                    foreach (var lang in languages)
                    {
                        var name = productVariantAttributeValue.GetLocalized(x => x.Name, lang.Id, false, false);
                        if (!String.IsNullOrEmpty(name))
                        {
                            _localizedEntityService.SaveLocalizedValue(pvavCopy, x => x.Name, name, lang.Id);
                        }
                    }
                }
            }
            foreach (var combination in _productAttributeService.GetAllProductVariantAttributeCombinations(productVariant.Id))
            {
                //generate new AttributesXml according to new value IDs
                string newAttributesXml = "";
                var    parsedProductVariantAttributes = _productAttributeParser.ParseProductVariantAttributes(combination.AttributesXml);
                foreach (var oldPva in parsedProductVariantAttributes)
                {
                    if (associatedAttributes.ContainsKey(oldPva.Id))
                    {
                        int newPvaId = associatedAttributes[oldPva.Id];
                        var newPva   = _productAttributeService.GetProductVariantAttributeById(newPvaId);
                        if (newPva != null)
                        {
                            var oldPvaValuesStr = _productAttributeParser.ParseValues(combination.AttributesXml, oldPva.Id);
                            foreach (var oldPvaValueStr in oldPvaValuesStr)
                            {
                                if (newPva.ShouldHaveValues())
                                {
                                    //attribute values
                                    int oldPvaValue = int.Parse(oldPvaValueStr);
                                    if (associatedAttributeValues.ContainsKey(oldPvaValue))
                                    {
                                        int newPvavId = associatedAttributeValues[oldPvaValue];
                                        var newPvav   = _productAttributeService.GetProductVariantAttributeValueById(newPvavId);
                                        if (newPvav != null)
                                        {
                                            newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml,
                                                                                                           newPva, newPvav.Id.ToString());
                                        }
                                    }
                                }
                                else
                                {
                                    //just a text
                                    newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml,
                                                                                                   newPva, oldPvaValueStr);
                                }
                            }
                        }
                    }
                }
                var combinationCopy = new ProductVariantAttributeCombination()
                {
                    ProductVariantId      = productVariantCopy.Id,
                    AttributesXml         = newAttributesXml,
                    StockQuantity         = combination.StockQuantity,
                    AllowOutOfStockOrders = combination.AllowOutOfStockOrders,
                    Sku = combination.Sku,
                    ManufacturerPartNumber = combination.ManufacturerPartNumber,
                    Gtin = combination.Gtin
                };
                _productAttributeService.InsertProductVariantAttributeCombination(combinationCopy);
            }

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

            // product variant <-> discounts mapping
            foreach (var discount in productVariant.AppliedDiscounts)
            {
                productVariantCopy.AppliedDiscounts.Add(discount);
                _productService.UpdateProductVariant(productVariantCopy);
            }


            //update "HasTierPrices" and "HasDiscountsApplied" properties
            _productService.UpdateHasTierPricesProperty(productVariantCopy);
            _productService.UpdateHasDiscountsApplied(productVariantCopy);


            return(productVariantCopy);
        }