/// <summary>
        /// Finds a product attribute combination by attributes stored in XML
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="attributesXml">Attributes in XML format</param>
        /// <param name="ignoreNonCombinableAttributes">A value indicating whether we should ignore non-combinable attributes</param>
        /// <returns>
        /// A task that represents the asynchronous operation
        /// The task result contains the found product attribute combination
        /// </returns>
        public virtual async Task <ProductAttributeCombination> FindProductAttributeCombinationAsync(Product product,
                                                                                                     string attributesXml, bool ignoreNonCombinableAttributes = true)
        {
            if (product == null)
            {
                throw new ArgumentNullException(nameof(product));
            }

            //anyway combination cannot contains non combinable attributes
            if (string.IsNullOrEmpty(attributesXml))
            {
                return(null);
            }

            var combinations = await _productAttributeService.GetAllProductAttributeCombinationsAsync(product.Id);

            return(await combinations.FirstOrDefaultAwaitAsync(async x =>
                                                               await AreProductAttributesEqualAsync(x.AttributesXml, attributesXml, ignoreNonCombinableAttributes)));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Copy attributes mapping
        /// </summary>
        /// <param name="product">Product</param>
        /// <param name="productCopy">New product</param>
        /// <param name="originalNewPictureIdentifiers">Identifiers of pictures</param>
        /// <returns>A task that represents the asynchronous operation</returns>
        protected virtual async Task CopyAttributesMappingAsync(Product product, Product productCopy, Dictionary <int, int> originalNewPictureIdentifiers)
        {
            var associatedAttributes      = new Dictionary <int, int>();
            var associatedAttributeValues = new Dictionary <int, int>();

            //attribute mapping with condition attributes
            var oldCopyWithConditionAttributes = new List <ProductAttributeMapping>();

            //all product attribute mapping copies
            var productAttributeMappingCopies = new Dictionary <int, ProductAttributeMapping>();

            var languages = await _languageService.GetAllLanguagesAsync(true);

            foreach (var productAttributeMapping in await _productAttributeService.GetProductAttributeMappingsByProductIdAsync(product.Id))
            {
                var productAttributeMappingCopy = new ProductAttributeMapping
                {
                    ProductId                       = productCopy.Id,
                    ProductAttributeId              = productAttributeMapping.ProductAttributeId,
                    TextPrompt                      = productAttributeMapping.TextPrompt,
                    IsRequired                      = productAttributeMapping.IsRequired,
                    AttributeControlTypeId          = productAttributeMapping.AttributeControlTypeId,
                    DisplayOrder                    = productAttributeMapping.DisplayOrder,
                    ValidationMinLength             = productAttributeMapping.ValidationMinLength,
                    ValidationMaxLength             = productAttributeMapping.ValidationMaxLength,
                    ValidationFileAllowedExtensions = productAttributeMapping.ValidationFileAllowedExtensions,
                    ValidationFileMaximumSize       = productAttributeMapping.ValidationFileMaximumSize,
                    DefaultValue                    = productAttributeMapping.DefaultValue
                };
                await _productAttributeService.InsertProductAttributeMappingAsync(productAttributeMappingCopy);

                //localization
                foreach (var lang in languages)
                {
                    var textPrompt = await _localizationService.GetLocalizedAsync(productAttributeMapping, x => x.TextPrompt, lang.Id, false, false);

                    if (!string.IsNullOrEmpty(textPrompt))
                    {
                        await _localizedEntityService.SaveLocalizedValueAsync(productAttributeMappingCopy, x => x.TextPrompt, textPrompt,
                                                                              lang.Id);
                    }
                }

                productAttributeMappingCopies.Add(productAttributeMappingCopy.Id, productAttributeMappingCopy);

                if (!string.IsNullOrEmpty(productAttributeMapping.ConditionAttributeXml))
                {
                    oldCopyWithConditionAttributes.Add(productAttributeMapping);
                }

                //save associated value (used for combinations copying)
                associatedAttributes.Add(productAttributeMapping.Id, productAttributeMappingCopy.Id);

                // product attribute values
                var productAttributeValues = await _productAttributeService.GetProductAttributeValuesAsync(productAttributeMapping.Id);

                foreach (var productAttributeValue in productAttributeValues)
                {
                    var attributeValuePictureId = 0;
                    if (originalNewPictureIdentifiers.ContainsKey(productAttributeValue.PictureId))
                    {
                        attributeValuePictureId = originalNewPictureIdentifiers[productAttributeValue.PictureId];
                    }

                    var attributeValueCopy = new ProductAttributeValue
                    {
                        ProductAttributeMappingId = productAttributeMappingCopy.Id,
                        AttributeValueTypeId      = productAttributeValue.AttributeValueTypeId,
                        AssociatedProductId       = productAttributeValue.AssociatedProductId,
                        Name            = productAttributeValue.Name,
                        ColorSquaresRgb = productAttributeValue.ColorSquaresRgb,
                        PriceAdjustment = productAttributeValue.PriceAdjustment,
                        PriceAdjustmentUsePercentage = productAttributeValue.PriceAdjustmentUsePercentage,
                        WeightAdjustment             = productAttributeValue.WeightAdjustment,
                        Cost = productAttributeValue.Cost,
                        CustomerEntersQty = productAttributeValue.CustomerEntersQty,
                        Quantity          = productAttributeValue.Quantity,
                        IsPreSelected     = productAttributeValue.IsPreSelected,
                        DisplayOrder      = productAttributeValue.DisplayOrder,
                        PictureId         = attributeValuePictureId,
                    };
                    //picture associated to "iamge square" attribute type (if exists)
                    if (productAttributeValue.ImageSquaresPictureId > 0)
                    {
                        var origImageSquaresPicture =
                            await _pictureService.GetPictureByIdAsync(productAttributeValue.ImageSquaresPictureId);

                        if (origImageSquaresPicture != null)
                        {
                            //copy the picture
                            var imageSquaresPictureCopy = await _pictureService.InsertPictureAsync(
                                await _pictureService.LoadPictureBinaryAsync(origImageSquaresPicture),
                                origImageSquaresPicture.MimeType,
                                origImageSquaresPicture.SeoFilename,
                                origImageSquaresPicture.AltAttribute,
                                origImageSquaresPicture.TitleAttribute);

                            attributeValueCopy.ImageSquaresPictureId = imageSquaresPictureCopy.Id;
                        }
                    }

                    await _productAttributeService.InsertProductAttributeValueAsync(attributeValueCopy);

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

                    //localization
                    foreach (var lang in languages)
                    {
                        var name = await _localizationService.GetLocalizedAsync(productAttributeValue, x => x.Name, lang.Id, false, false);

                        if (!string.IsNullOrEmpty(name))
                        {
                            await _localizedEntityService.SaveLocalizedValueAsync(attributeValueCopy, x => x.Name, name, lang.Id);
                        }
                    }
                }
            }

            //copy attribute conditions
            foreach (var productAttributeMapping in oldCopyWithConditionAttributes)
            {
                var oldConditionAttributeMapping = (await _productAttributeParser
                                                    .ParseProductAttributeMappingsAsync(productAttributeMapping.ConditionAttributeXml)).FirstOrDefault();

                if (oldConditionAttributeMapping == null)
                {
                    continue;
                }

                var oldConditionValues = await _productAttributeParser.ParseProductAttributeValuesAsync(
                    productAttributeMapping.ConditionAttributeXml,
                    oldConditionAttributeMapping.Id);

                if (!oldConditionValues.Any())
                {
                    continue;
                }

                var newAttributeMappingId        = associatedAttributes[oldConditionAttributeMapping.Id];
                var newConditionAttributeMapping = productAttributeMappingCopies[newAttributeMappingId];

                var newConditionAttributeXml = string.Empty;

                foreach (var oldConditionValue in oldConditionValues)
                {
                    newConditionAttributeXml = _productAttributeParser.AddProductAttribute(newConditionAttributeXml,
                                                                                           newConditionAttributeMapping, associatedAttributeValues[oldConditionValue.Id].ToString());
                }

                var attributeMappingId = associatedAttributes[productAttributeMapping.Id];
                var conditionAttribute = productAttributeMappingCopies[attributeMappingId];
                conditionAttribute.ConditionAttributeXml = newConditionAttributeXml;

                await _productAttributeService.UpdateProductAttributeMappingAsync(conditionAttribute);
            }

            //attribute combinations
            foreach (var combination in await _productAttributeService.GetAllProductAttributeCombinationsAsync(product.Id))
            {
                //generate new AttributesXml according to new value IDs
                var newAttributesXml        = string.Empty;
                var parsedProductAttributes = await _productAttributeParser.ParseProductAttributeMappingsAsync(combination.AttributesXml);

                foreach (var oldAttribute in parsedProductAttributes)
                {
                    if (!associatedAttributes.ContainsKey(oldAttribute.Id))
                    {
                        continue;
                    }

                    var newAttribute = await _productAttributeService.GetProductAttributeMappingByIdAsync(associatedAttributes[oldAttribute.Id]);

                    if (newAttribute == null)
                    {
                        continue;
                    }

                    var oldAttributeValuesStr = _productAttributeParser.ParseValues(combination.AttributesXml, oldAttribute.Id);

                    foreach (var oldAttributeValueStr in oldAttributeValuesStr)
                    {
                        if (newAttribute.ShouldHaveValues())
                        {
                            //attribute values
                            var oldAttributeValue = int.Parse(oldAttributeValueStr);
                            if (!associatedAttributeValues.ContainsKey(oldAttributeValue))
                            {
                                continue;
                            }

                            var newAttributeValue = await _productAttributeService.GetProductAttributeValueByIdAsync(associatedAttributeValues[oldAttributeValue]);

                            if (newAttributeValue != null)
                            {
                                newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml,
                                                                                               newAttribute, newAttributeValue.Id.ToString());
                            }
                        }
                        else
                        {
                            //just a text
                            newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml,
                                                                                           newAttribute, oldAttributeValueStr);
                        }
                    }
                }

                //picture
                originalNewPictureIdentifiers.TryGetValue(combination.PictureId, out var combinationPictureId);

                var combinationCopy = new ProductAttributeCombination
                {
                    ProductId             = productCopy.Id,
                    AttributesXml         = newAttributesXml,
                    StockQuantity         = combination.StockQuantity,
                    MinStockQuantity      = combination.MinStockQuantity,
                    AllowOutOfStockOrders = combination.AllowOutOfStockOrders,
                    Sku = combination.Sku,
                    ManufacturerPartNumber = combination.ManufacturerPartNumber,
                    Gtin                        = combination.Gtin,
                    OverriddenPrice             = combination.OverriddenPrice,
                    NotifyAdminForQuantityBelow = combination.NotifyAdminForQuantityBelow,
                    PictureId                   = combinationPictureId
                };
                await _productAttributeService.InsertProductAttributeCombinationAsync(combinationCopy);

                //quantity change history
                await _productService.AddStockQuantityHistoryEntryAsync(productCopy, combination.StockQuantity,
                                                                        combination.StockQuantity,
                                                                        message : string.Format(await _localizationService.GetResourceAsync("Admin.StockQuantityHistory.Messages.CopyProduct"), product.Id), combinationId : combination.Id);
            }
        }