public void Can_add_and_parse_productAttributes() { string attributes = ""; //color: green attributes = _productAttributeParser.AddProductAttribute(attributes, pva1_1, pvav1_1.Id.ToString()); //custom option: option 1, option 2 attributes = _productAttributeParser.AddProductAttribute(attributes, pva2_1, pvav2_1.Id.ToString()); attributes = _productAttributeParser.AddProductAttribute(attributes, pva2_1, pvav2_2.Id.ToString()); //custom text attributes = _productAttributeParser.AddProductAttribute(attributes, pva3_1, "Some custom text goes here"); var parsed_pvaValues = _productAttributeParser.ParseProductVariantAttributeValues(attributes); parsed_pvaValues.Contains(pvav1_1).ShouldEqual(true); parsed_pvaValues.Contains(pvav1_2).ShouldEqual(false); parsed_pvaValues.Contains(pvav2_1).ShouldEqual(true); parsed_pvaValues.Contains(pvav2_2).ShouldEqual(true); parsed_pvaValues.Contains(pvav2_2).ShouldEqual(true); var parsedValues = _productAttributeParser.ParseValues(attributes, pva3_1.Id); parsedValues.Count.ShouldEqual(1); parsedValues.Contains("Some custom text goes here").ShouldEqual(true); parsedValues.Contains("Some other custom text").ShouldEqual(false); }
public void Can_add_and_parse_productAttributes() { string attributes = ""; //color: green attributes = _productAttributeParser.AddProductAttribute(attributes, pam1_1, pav1_1.Id.ToString()); //custom option: option 1, option 2 attributes = _productAttributeParser.AddProductAttribute(attributes, pam2_1, pav2_1.Id.ToString()); attributes = _productAttributeParser.AddProductAttribute(attributes, pam2_1, pav2_2.Id.ToString()); //custom text attributes = _productAttributeParser.AddProductAttribute(attributes, pam3_1, "Some custom text goes here"); var parsed_attributeValues = _productAttributeParser.ParseProductAttributeValues(_product, attributes);//! Assert.IsTrue(parsed_attributeValues.Contains(pav1_1)); Assert.IsFalse(parsed_attributeValues.Contains(pav1_2)); Assert.IsTrue(parsed_attributeValues.Contains(pav2_1)); Assert.IsTrue(parsed_attributeValues.Contains(pav2_2)); Assert.IsTrue(parsed_attributeValues.Contains(pav2_2)); var parsedValues = _productAttributeParser.ParseValues(attributes, pam3_1.Id); Assert.AreEqual(1, parsedValues.Count); Assert.IsTrue(parsedValues.Contains("Some custom text goes here")); Assert.IsFalse(parsedValues.Contains("Some other custom text")); }
public async Task CanAddAndParseProductAttributes() { var attributes = string.Empty; foreach (var productAttributeMapping in _productAttributeMappings) { var skip = true; foreach (var productAttributeValue in productAttributeMapping.Value.OrderBy(p => p.Id)) { if (skip) { skip = false; continue; } attributes = _productAttributeParser.AddProductAttribute(attributes, productAttributeMapping.Key, productAttributeValue.Id.ToString()); } } var attributeValues = await _productAttributeParser.ParseProductAttributeValuesAsync(attributes); var parsedAttributeValues = attributeValues.Select(p => p.Id).ToList(); foreach (var productAttributeMapping in _productAttributeMappings) { var skip = true; foreach (var productAttributeValue in productAttributeMapping.Value.OrderBy(p => p.Id)) { if (skip) { parsedAttributeValues.Contains(productAttributeValue.Id).Should().BeFalse(); skip = false; continue; } parsedAttributeValues.Contains(productAttributeValue.Id).Should().BeTrue(); } } }
public async Task <string> InsertPickupAttributeAsync( Product product, StockResponse stockResponse, string attributes, Shop customerShop = null ) { Shop shop = customerShop ?? await GetCustomerShop(); string shopName = shop != null ? shop.Name : "Select Store"; ProductAttribute pickupAttribute = await GetPickupAttributeAsync(); // current product potential attribute mappings var pams = await _productAttributeService.GetProductAttributeMappingsByProductIdAsync(product.Id); var pickupAttributeMapping = pams .Where(pam => pam.ProductAttributeId == pickupAttribute.Id) .Select(pam => pam).FirstOrDefault(); if (pickupAttributeMapping != null) { string pickupMsg = stockResponse.ProductStocks .Where(ps => ps.Shop.Id == shop.Id) .Select(ps => ps.Message).FirstOrDefault(); attributes = _productAttributeParser.AddProductAttribute(attributes, pickupAttributeMapping, shop.Name + "\nAvailable: " + pickupMsg); // remove home delivery attributes var homeDeliveryAttributeMapping = await GetHomeDeliveryAttributeMappingAsync(attributes); if (homeDeliveryAttributeMapping != null) { attributes = _productAttributeParser.RemoveProductAttribute(attributes, homeDeliveryAttributeMapping); } } return(attributes); }
/// <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); }
/// <summary> /// Copy attributes mapping /// </summary> /// <param name="product">Product</param> /// <param name="productCopy">New product</param> /// <param name="originalNewPictureIdentifiers">Identifiers of pictures</param> protected virtual void CopyAttributesMapping(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 = _languageService.GetAllLanguages(true); foreach (var productAttributeMapping in _productAttributeService.GetProductAttributeMappingsByProductId(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 }; _productAttributeService.InsertProductAttributeMapping(productAttributeMappingCopy); //localization foreach (var lang in languages) { var textPrompt = _localizationService.GetLocalized(productAttributeMapping, x => x.TextPrompt, lang.Id, false, false); if (!string.IsNullOrEmpty(textPrompt)) { _localizedEntityService.SaveLocalizedValue(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 = _productAttributeService.GetProductAttributeValues(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 = _pictureService.GetPictureById(productAttributeValue.ImageSquaresPictureId); if (origImageSquaresPicture != null) { //copy the picture var imageSquaresPictureCopy = _pictureService.InsertPicture( _pictureService.LoadPictureBinary(origImageSquaresPicture), origImageSquaresPicture.MimeType, origImageSquaresPicture.SeoFilename, origImageSquaresPicture.AltAttribute, origImageSquaresPicture.TitleAttribute); attributeValueCopy.ImageSquaresPictureId = imageSquaresPictureCopy.Id; } } _productAttributeService.InsertProductAttributeValue(attributeValueCopy); //save associated value (used for combinations copying) associatedAttributeValues.Add(productAttributeValue.Id, attributeValueCopy.Id); //localization foreach (var lang in languages) { var name = _localizationService.GetLocalized(productAttributeValue, x => x.Name, lang.Id, false, false); if (!string.IsNullOrEmpty(name)) { _localizedEntityService.SaveLocalizedValue(attributeValueCopy, x => x.Name, name, lang.Id); } } } } //copy attribute conditions foreach (var productAttributeMapping in oldCopyWithConditionAttributes) { var oldConditionAttributeMapping = _productAttributeParser .ParseProductAttributeMappings(productAttributeMapping.ConditionAttributeXml).FirstOrDefault(); if (oldConditionAttributeMapping == null) { continue; } var oldConditionValues = _productAttributeParser.ParseProductAttributeValues(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; _productAttributeService.UpdateProductAttributeMapping(conditionAttribute); } //attribute combinations foreach (var combination in _productAttributeService.GetAllProductAttributeCombinations(product.Id)) { //generate new AttributesXml according to new value IDs var newAttributesXml = string.Empty; var parsedProductAttributes = _productAttributeParser.ParseProductAttributeMappings(combination.AttributesXml); foreach (var oldAttribute in parsedProductAttributes) { if (!associatedAttributes.ContainsKey(oldAttribute.Id)) { continue; } var newAttribute = _productAttributeService.GetProductAttributeMappingById(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 = _productAttributeService.GetProductAttributeValueById(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, AllowOutOfStockOrders = combination.AllowOutOfStockOrders, Sku = combination.Sku, ManufacturerPartNumber = combination.ManufacturerPartNumber, Gtin = combination.Gtin, OverriddenPrice = combination.OverriddenPrice, NotifyAdminForQuantityBelow = combination.NotifyAdminForQuantityBelow, PictureId = combinationPictureId }; _productAttributeService.InsertProductAttributeCombination(combinationCopy); //quantity change history _productService.AddStockQuantityHistoryEntry(productCopy, combination.StockQuantity, combination.StockQuantity, message: string.Format(_localizationService.GetResource("Admin.StockQuantityHistory.Messages.CopyProduct"), product.Id), combinationId: combination.Id); } }
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(); }
/// <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 IActionResult CustomLogoAdd(LogoModel logo) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageWidgets)) { return(AccessDeniedView()); } if (!ModelState.IsValid) { return(Json(new { Result = false, Errors = GetErrorsFromModelState() })); } //Get 1st product picture we use 1st picture of product to combine with logo ProductPicture productPicture = _productPictureModifierService .GetFirstProductPicture(logo.ProductId); if (productPicture == null) { throw new Exception("Product does not have any image"); } byte[] logoBinary = _pictureService.LoadPictureBinary(_pictureService.GetPictureById(logo.PictureId)); //Get new product image which has been merged with the logo uploaded (int, string)mergedPicture = _logoService.MergeProductPictureWithLogo( logoBinary, logo.PictureId, logo.ProductId, ProductPictureModifierUploadType.Predefined, logo.Size, logo.Opacity, logo.XCoordinate, logo.YCoordinate, overrideThumb: true); if (logo.AttributeValueId > 0) { var existingAttributeValue = _productAttributeService. GetProductAttributeValueById(logo.AttributeValueId); var existingProductPicture = _productService.GetProductPicturesByProductId(logo.ProductId) .First(x => x.PictureId == existingAttributeValue.PictureId); //update product attribute value existingAttributeValue.PictureId = mergedPicture.Item1; existingAttributeValue.ImageSquaresPictureId = logo.PictureId; _productAttributeService.UpdateProductAttributeValue(existingAttributeValue); //update product picture existingProductPicture.PictureId = mergedPicture.Item1; _productService.UpdateProductPicture(existingProductPicture); return(Json(new { Result = true, AttributeId = logo.AttributeValueId })); } //Insert the image as product picture _productService.InsertProductPicture(new ProductPicture { ProductId = logo.ProductId, PictureId = mergedPicture.Item1, DisplayOrder = ProductPictureModifierDefault.MergedPictureDisplayOrder }); ProductAttribute logoAttribute = _productPictureModifierService .GetProductAttributeByName(ProductPictureModifierDefault.ProductAttributeNameForLogo) .FirstOrDefault() ?? throw new ArgumentException("Product Attribute Not Found"); //get product's attribute for predefined logo attributes ProductAttributeMapping logoProductMapping = _productAttributeService .GetProductAttributeMappingsByProductId(logo.ProductId) .FirstOrDefault(x => x.ProductAttributeId == logoAttribute.Id); //create the mapping if it does not exist if (logoProductMapping == null) { logoProductMapping = new ProductAttributeMapping { ProductAttributeId = logoAttribute.Id, ProductId = logo.ProductId, AttributeControlTypeId = (int)AttributeControlType.ImageSquares }; _productAttributeService.InsertProductAttributeMapping(logoProductMapping); ////no logo attribute ////todo find a way to use the picture for this //_productAttributeService.InsertProductAttributeValue(new ProductAttributeValue //{ // ProductAttributeMappingId = logoProductMapping.Id, // AttributeValueType = AttributeValueType.Simple, // Name = _localizationService.GetResource("Widgets.ProductPictureModifier.Attributes.NoLogo"), // ImageSquaresPictureId = 1, // PictureId = productPicture.PictureId, //}); //provision for manual upload by user Setting customUploadIconSetting = _settingService .GetSetting(ProductPictureModifierDefault.UploadIconPictureIdSetting); var customUploadForLogoAttribute = new ProductAttributeValue { ProductAttributeMappingId = logoProductMapping.Id, AttributeValueType = AttributeValueType.Simple, Name = _localizationService.GetResource("Widgets.ProductPictureModifier.Attributes.Upload"), ImageSquaresPictureId = int.Parse(customUploadIconSetting.Value), }; _productAttributeService.InsertProductAttributeValue(customUploadForLogoAttribute); ProductAttribute productAttributeForCustomUpload = _productPictureModifierService .GetProductAttributeByName(ProductPictureModifierDefault.ProductAttributeNameForLogoUpload) .FirstOrDefault() ?? throw new ArgumentException("Product Attribute Not Found for Custom Upload"); //custom upload attribute mapping with product based on condition var customUploadProductAttributeMapping = new ProductAttributeMapping { ProductAttributeId = productAttributeForCustomUpload.Id, ProductId = logo.ProductId, AttributeControlTypeId = (int)AttributeControlType.FileUpload, ValidationFileAllowedExtensions = "png", ConditionAttributeXml = _productAttributeParser.AddProductAttribute(null, logoProductMapping, customUploadForLogoAttribute.Id.ToString()) }; _productAttributeService.InsertProductAttributeMapping(customUploadProductAttributeMapping); } //save the actual logo attribute var productAttributeValue = new ProductAttributeValue { ProductAttributeMappingId = logoProductMapping.Id, AttributeValueType = AttributeValueType.Simple, Name = "Custom Logo", ImageSquaresPictureId = logo.PictureId, PictureId = mergedPicture.Item1, }; _productAttributeService.InsertProductAttributeValue(productAttributeValue); //Logo Position for custom upload LogoPosition logoPosition = _logoPositionService.GetByProductId(logo.ProductId); if (logo.MarkAsDefault || IsLogoSettingNew(logoPosition)) { logoPosition.Size = logo.Size; logoPosition.XCoordinate = logo.XCoordinate; logoPosition.YCoordinate = logo.YCoordinate; logoPosition.Opacity = logo.Opacity; _logoPositionService.Update(logoPosition); } return(Json(new { Result = true, AttributeId = productAttributeValue.Id })); }
/// <summary>Takes selected elements from collection and creates a attribute XML string from it.</summary> /// <param name="formatWithProductId">how the name of the controls are formatted. frontend includes productId, backend does not.</param> public static string CreateSelectedAttributesXml(this NameValueCollection collection, int productId, IList <ProductVariantAttribute> variantAttributes, IProductAttributeParser productAttributeParser, ILocalizationService localizationService, IDownloadService downloadService, CatalogSettings catalogSettings, HttpRequestBase request, List <string> warnings, bool formatWithProductId = true, int bundleItemId = 0) { if (collection == null) { return(""); } string controlId; string selectedAttributes = ""; foreach (var attribute in variantAttributes) { controlId = AttributeFormatedName(attribute.ProductAttributeId, attribute.Id, formatWithProductId ? productId : 0, bundleItemId); switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.ColorSquares: { var ctrlAttributes = collection[controlId]; if (ctrlAttributes.HasValue()) { int selectedAttributeId = int.Parse(ctrlAttributes); if (selectedAttributeId > 0) { selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, selectedAttributeId.ToString()); } } } break; case AttributeControlType.Checkboxes: { var cblAttributes = collection[controlId]; if (cblAttributes.HasValue()) { foreach (var item in cblAttributes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { int selectedAttributeId = int.Parse(item); if (selectedAttributeId > 0) { selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, selectedAttributeId.ToString()); } } } } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: { var txtAttribute = collection[controlId]; if (txtAttribute.HasValue()) { string enteredText = txtAttribute.Trim(); selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, enteredText); } } break; case AttributeControlType.Datepicker: { var date = collection[controlId + "_day"]; var month = collection[controlId + "_month"]; var year = collection[controlId + "_year"]; DateTime?selectedDate = null; try { selectedDate = new DateTime(Int32.Parse(year), Int32.Parse(month), Int32.Parse(date)); } catch { } if (selectedDate.HasValue) { selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, selectedDate.Value.ToString("D")); } } break; case AttributeControlType.FileUpload: if (request == null) { Guid downloadGuid; Guid.TryParse(collection[controlId], out downloadGuid); var download = downloadService.GetDownloadByGuid(downloadGuid); if (download != null) { selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, download.DownloadGuid.ToString()); } } else { var httpPostedFile = request.Files[controlId]; if (httpPostedFile != null && httpPostedFile.FileName.HasValue()) { int fileMaxSize = catalogSettings.FileUploadMaximumSizeBytes; if (httpPostedFile.ContentLength > fileMaxSize) { warnings.Add(string.Format(localizationService.GetResource("ShoppingCart.MaximumUploadedFileSize"), (int)(fileMaxSize / 1024))); } else { //save an uploaded file var download = new Download { DownloadGuid = Guid.NewGuid(), UseDownloadUrl = false, DownloadUrl = "", DownloadBinary = httpPostedFile.GetDownloadBits(), ContentType = httpPostedFile.ContentType, Filename = System.IO.Path.GetFileNameWithoutExtension(httpPostedFile.FileName), Extension = System.IO.Path.GetExtension(httpPostedFile.FileName), IsNew = true }; downloadService.InsertDownload(download); //save attribute selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, download.DownloadGuid.ToString()); } } } break; default: break; } } return(selectedAttributes); }
// TODO // use it from ShoppingCartController private string ParseProductAttributes(Product product, IFormCollection form, List <string> errors) { var attributesXml = string.Empty; var productAttributes = _productAttributeService.GetProductAttributeMappingsByProductId(product.Id); foreach (var attribute in productAttributes) { var controlId = $"product_attribute_{attribute.Id}"; switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.ColorSquares: case AttributeControlType.ImageSquares: { var ctrlAttributes = form[controlId]; if (!StringValues.IsNullOrEmpty(ctrlAttributes)) { var selectedAttributeId = int.Parse(ctrlAttributes); if (selectedAttributeId > 0) { //get quantity entered by customer var quantity = 1; var quantityStr = form[$"product_attribute_{attribute.Id}_{selectedAttributeId}_qty"]; if (!StringValues.IsNullOrEmpty(quantityStr) && (!int.TryParse(quantityStr, out quantity) || quantity < 1)) { errors.Add(_localizationService.GetResource("ShoppingCart.QuantityShouldPositive")); } attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttributeId.ToString(), quantity > 1 ? (int?)quantity : null); } } } break; case AttributeControlType.Checkboxes: { var ctrlAttributes = form[controlId]; if (!StringValues.IsNullOrEmpty(ctrlAttributes)) { foreach (var item in ctrlAttributes.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { var selectedAttributeId = int.Parse(item); if (selectedAttributeId > 0) { //get quantity entered by customer var quantity = 1; var quantityStr = form[$"product_attribute_{attribute.Id}_{item}_qty"]; if (!StringValues.IsNullOrEmpty(quantityStr) && (!int.TryParse(quantityStr, out quantity) || quantity < 1)) { errors.Add(_localizationService.GetResource("ShoppingCart.QuantityShouldPositive")); } attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttributeId.ToString(), quantity > 1 ? (int?)quantity : null); } } } } break; case AttributeControlType.ReadonlyCheckboxes: { //load read-only (already server-side selected) values var attributeValues = _productAttributeService.GetProductAttributeValues(attribute.Id); foreach (var selectedAttributeId in attributeValues .Where(v => v.IsPreSelected) .Select(v => v.Id) .ToList()) { //get quantity entered by customer var quantity = 1; var quantityStr = form[$"product_attribute_{attribute.Id}_{selectedAttributeId}_qty"]; if (!StringValues.IsNullOrEmpty(quantityStr) && (!int.TryParse(quantityStr, out quantity) || quantity < 1)) { errors.Add(_localizationService.GetResource("ShoppingCart.QuantityShouldPositive")); } attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttributeId.ToString(), quantity > 1 ? (int?)quantity : null); } } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: { var ctrlAttributes = form[controlId]; if (!StringValues.IsNullOrEmpty(ctrlAttributes)) { var enteredText = ctrlAttributes.ToString().Trim(); attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, enteredText); } } break; case AttributeControlType.Datepicker: { var day = form[controlId + "_day"]; var month = form[controlId + "_month"]; var year = form[controlId + "_year"]; DateTime?selectedDate = null; try { selectedDate = new DateTime(Int32.Parse(year), Int32.Parse(month), Int32.Parse(day)); } catch { } if (selectedDate.HasValue) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedDate.Value.ToString("D")); } } break; case AttributeControlType.FileUpload: { Guid.TryParse(form[controlId], out Guid downloadGuid); var download = _downloadService.GetDownloadByGuid(downloadGuid); if (download != null) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, download.DownloadGuid.ToString()); } } break; default: break; } } //validate conditional attributes (if specified) foreach (var attribute in productAttributes) { var conditionMet = _productAttributeParser.IsConditionMet(attribute, attributesXml); if (conditionMet.HasValue && !conditionMet.Value) { attributesXml = _productAttributeParser.RemoveProductAttribute(attributesXml, attribute); } } return(attributesXml); }
public static string CreateSelectedAttributesXml( this ProductVariantQuery query, int productId, int bundleItemId, IEnumerable <ProductVariantAttribute> variantAttributes, IProductAttributeParser productAttributeParser, ILocalizationService localization, IDownloadService downloadService, CatalogSettings catalogSettings, HttpRequestBase request, List <string> warnings) { var result = string.Empty; foreach (var pva in variantAttributes) { var selectedItems = query.Variants.Where(x => x.ProductId == productId && x.BundleItemId == bundleItemId && x.AttributeId == pva.ProductAttributeId && x.VariantAttributeId == pva.Id); switch (pva.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.Boxes: { var firstItemValue = selectedItems.FirstOrDefault()?.Value; if (firstItemValue.HasValue()) { var selectedAttributeId = firstItemValue.SplitSafe(",").SafeGet(0).ToInt(); if (selectedAttributeId > 0) { result = productAttributeParser.AddProductAttribute(result, pva, selectedAttributeId.ToString()); } } } break; case AttributeControlType.Checkboxes: foreach (var item in selectedItems) { var selectedAttributeId = item.Value.SplitSafe(",").SafeGet(0).ToInt(); if (selectedAttributeId > 0) { result = productAttributeParser.AddProductAttribute(result, pva, selectedAttributeId.ToString()); } } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: { var selectedValue = string.Join(",", selectedItems.Select(x => x.Value)); if (selectedValue.HasValue()) { result = productAttributeParser.AddProductAttribute(result, pva, selectedValue); } } break; case AttributeControlType.Datepicker: { var firstItemDate = selectedItems.FirstOrDefault()?.Date; if (firstItemDate.HasValue) { result = productAttributeParser.AddProductAttribute(result, pva, firstItemDate.Value.ToString("D")); } } break; case AttributeControlType.FileUpload: if (request == null) { var firstItemValue = selectedItems.FirstOrDefault()?.Value; Guid.TryParse(firstItemValue, out var downloadGuid); var download = downloadService.GetDownloadByGuid(downloadGuid); if (download != null) { if (download.IsTransient) { download.IsTransient = false; downloadService.UpdateDownload(download); } result = productAttributeParser.AddProductAttribute(result, pva, download.DownloadGuid.ToString()); } } else { var postedFile = request.Files[ProductVariantQueryItem.CreateKey(productId, bundleItemId, pva.ProductAttributeId, pva.Id)]; if (postedFile != null && postedFile.FileName.HasValue()) { if (postedFile.ContentLength > catalogSettings.FileUploadMaximumSizeBytes) { warnings.Add(localization.GetResource("ShoppingCart.MaximumUploadedFileSize").FormatInvariant((int)(catalogSettings.FileUploadMaximumSizeBytes / 1024))); } else { var download = new Download { DownloadGuid = Guid.NewGuid(), UseDownloadUrl = false, DownloadUrl = "", UpdatedOnUtc = DateTime.UtcNow, EntityId = productId, EntityName = "ProductAttribute" }; downloadService.InsertDownload(download, postedFile.InputStream, postedFile.FileName); result = productAttributeParser.AddProductAttribute(result, pva, download.DownloadGuid.ToString()); } } } break; } } return(result); }
/// <summary> /// Create a copy of product with all depended data /// </summary> /// <param name="product">The product to copy</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 copy</returns> public virtual Product CopyProduct(Product product, string newName, bool isPublished = true, bool copyImages = true, bool copyAssociatedProducts = true) { if (product == null) { throw new ArgumentNullException("product"); } if (String.IsNullOrEmpty(newName)) { throw new ArgumentException("Product name is required"); } //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); 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 var productCopy = new Product { ProductTypeId = product.ProductTypeId, ParentGroupedProductId = product.ParentGroupedProductId, VisibleIndividually = product.VisibleIndividually, Name = newName, ShortDescription = product.ShortDescription, FullDescription = product.FullDescription, VendorId = product.VendorId, 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, OverriddenGiftCardAmount = product.OverriddenGiftCardAmount, 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, IsRental = product.IsRental, RentalPriceLength = product.RentalPriceLength, RentalPricePeriod = product.RentalPricePeriod, IsShipEnabled = product.IsShipEnabled, IsFreeShipping = product.IsFreeShipping, ShipSeparately = product.ShipSeparately, AdditionalShippingCharge = product.AdditionalShippingCharge, DeliveryDateId = product.DeliveryDateId, IsTaxExempt = product.IsTaxExempt, TaxCategoryId = product.TaxCategoryId, IsTelecommunicationsOrBroadcastingOrElectronicServices = product.IsTelecommunicationsOrBroadcastingOrElectronicServices, ManageInventoryMethod = product.ManageInventoryMethod, ProductAvailabilityRangeId = product.ProductAvailabilityRangeId, UseMultipleWarehouses = product.UseMultipleWarehouses, WarehouseId = product.WarehouseId, 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, AllowAddingOnlyExistingAttributeCombinations = product.AllowAddingOnlyExistingAttributeCombinations, NotReturnable = product.NotReturnable, DisableBuyButton = product.DisableBuyButton, DisableWishlistButton = product.DisableWishlistButton, AvailableForPreOrder = product.AvailableForPreOrder, PreOrderAvailabilityStartDateTimeUtc = product.PreOrderAvailabilityStartDateTimeUtc, 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, BasepriceEnabled = product.BasepriceEnabled, BasepriceAmount = product.BasepriceAmount, BasepriceUnitId = product.BasepriceUnitId, BasepriceBaseAmount = product.BasepriceBaseAmount, BasepriceBaseUnitId = product.BasepriceBaseUnitId, MarkAsNew = product.MarkAsNew, MarkAsNewStartDateTimeUtc = product.MarkAsNewStartDateTimeUtc, MarkAsNewEndDateTimeUtc = product.MarkAsNewEndDateTimeUtc, 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 = 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); } _productService.UpdateProduct(productCopy); //product pictures //variable to store original and new picture identifiers var originalNewPictureIdentifiers = new Dictionary <int, int>(); if (copyImages) { foreach (var productPicture in product.ProductPictures) { var picture = productPicture.Picture; var pictureCopy = _pictureService.InsertPicture( _pictureService.LoadPictureBinary(picture), picture.MimeType, _pictureService.GetPictureSeName(newName), picture.AltAttribute, picture.TitleAttribute); _productService.InsertProductPicture(new ProductPicture { ProductId = productCopy.Id, PictureId = pictureCopy.Id, DisplayOrder = productPicture.DisplayOrder }); originalNewPictureIdentifiers.Add(picture.Id, pictureCopy.Id); } } // product <-> warehouses mappings foreach (var pwi in product.ProductWarehouseInventory) { var pwiCopy = new ProductWarehouseInventory { ProductId = productCopy.Id, WarehouseId = pwi.WarehouseId, StockQuantity = pwi.StockQuantity, ReservedQuantity = 0, }; productCopy.ProductWarehouseInventory.Add(pwiCopy); } _productService.UpdateProduct(productCopy); // 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, AttributeTypeId = productSpecificationAttribute.AttributeTypeId, SpecificationAttributeOptionId = productSpecificationAttribute.SpecificationAttributeOptionId, CustomValue = productSpecificationAttribute.CustomValue, 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 productAttributeMapping in _productAttributeService.GetProductAttributeMappingsByProductId(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, //UNDONE copy ConditionAttributeXml (we should replace attribute IDs with new values) }; _productAttributeService.InsertProductAttributeMapping(productAttributeMappingCopy); //save associated value (used for combinations copying) associatedAttributes.Add(productAttributeMapping.Id, productAttributeMappingCopy.Id); // product attribute values var productAttributeValues = _productAttributeService.GetProductAttributeValues(productAttributeMapping.Id); foreach (var productAttributeValue in productAttributeValues) { int 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, 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 = _pictureService.GetPictureById(productAttributeValue.ImageSquaresPictureId); if (origImageSquaresPicture != null) { //copy the picture var imageSquaresPictureCopy = _pictureService.InsertPicture( _pictureService.LoadPictureBinary(origImageSquaresPicture), origImageSquaresPicture.MimeType, origImageSquaresPicture.SeoFilename, origImageSquaresPicture.AltAttribute, origImageSquaresPicture.TitleAttribute); attributeValueCopy.ImageSquaresPictureId = imageSquaresPictureCopy.Id; } } _productAttributeService.InsertProductAttributeValue(attributeValueCopy); //save associated value (used for combinations copying) associatedAttributeValues.Add(productAttributeValue.Id, attributeValueCopy.Id); //localization foreach (var lang in languages) { var name = productAttributeValue.GetLocalized(x => x.Name, lang.Id, false, false); if (!String.IsNullOrEmpty(name)) { _localizedEntityService.SaveLocalizedValue(attributeValueCopy, x => x.Name, name, lang.Id); } } } } //attribute combinations foreach (var combination in _productAttributeService.GetAllProductAttributeCombinations(product.Id)) { //generate new AttributesXml according to new value IDs string newAttributesXml = ""; var parsedProductAttributes = _productAttributeParser.ParseProductAttributeMappings(combination.AttributesXml); foreach (var oldAttribute in parsedProductAttributes) { if (associatedAttributes.ContainsKey(oldAttribute.Id)) { var newAttribute = _productAttributeService.GetProductAttributeMappingById(associatedAttributes[oldAttribute.Id]); if (newAttribute != null) { var oldAttributeValuesStr = _productAttributeParser.ParseValues(combination.AttributesXml, oldAttribute.Id); foreach (var oldAttributeValueStr in oldAttributeValuesStr) { if (newAttribute.ShouldHaveValues()) { //attribute values int oldAttributeValue = int.Parse(oldAttributeValueStr); if (associatedAttributeValues.ContainsKey(oldAttributeValue)) { var newAttributeValue = _productAttributeService.GetProductAttributeValueById(associatedAttributeValues[oldAttributeValue]); if (newAttributeValue != null) { newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml, newAttribute, newAttributeValue.Id.ToString()); } } } else { //just a text newAttributesXml = _productAttributeParser.AddProductAttribute(newAttributesXml, newAttribute, oldAttributeValueStr); } } } } } var combinationCopy = new ProductAttributeCombination { ProductId = productCopy.Id, AttributesXml = newAttributesXml, StockQuantity = combination.StockQuantity, AllowOutOfStockOrders = combination.AllowOutOfStockOrders, Sku = combination.Sku, ManufacturerPartNumber = combination.ManufacturerPartNumber, Gtin = combination.Gtin, OverriddenPrice = combination.OverriddenPrice, NotifyAdminForQuantityBelow = combination.NotifyAdminForQuantityBelow }; _productAttributeService.InsertProductAttributeCombination(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.UpdateHasDiscountsApplied(productCopy); //associated products if (copyAssociatedProducts) { var associatedProducts = _productService.GetAssociatedProducts(product.Id, showHidden: true); foreach (var associatedProduct in associatedProducts) { var associatedProductCopy = CopyProduct(associatedProduct, string.Format("Copy of {0}", associatedProduct.Name), isPublished, copyImages, false); associatedProductCopy.ParentGroupedProductId = productCopy.Id; _productService.UpdateProduct(productCopy); } } return(productCopy); }
/// <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); }
public async Task <string> ConvertToXmlAsync(List <ProductItemAttributeDto> attributeDtos, int productId) { var attributesXml = ""; if (attributeDtos == null) { return(attributesXml); } var productAttributes = await _productAttributeService.GetProductAttributeMappingsByProductIdAsync(productId); foreach (var attribute in productAttributes) { switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.ColorSquares: case AttributeControlType.ImageSquares: { // there should be only one selected value for this attribute var selectedAttribute = attributeDtos.Where(x => x.Id == attribute.Id).FirstOrDefault(); if (selectedAttribute != null) { int selectedAttributeValue; var isInt = int.TryParse(selectedAttribute.Value, out selectedAttributeValue); if (isInt && selectedAttributeValue > 0) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttributeValue.ToString()); } } } break; case AttributeControlType.Checkboxes: { // there could be more than one selected value for this attribute var selectedAttributes = attributeDtos.Where(x => x.Id == attribute.Id); foreach (var selectedAttribute in selectedAttributes) { int selectedAttributeValue; var isInt = int.TryParse(selectedAttribute.Value, out selectedAttributeValue); if (isInt && selectedAttributeValue > 0) { // currently there is no support for attribute quantity var quantity = 1; attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttributeValue.ToString(), quantity); } } } break; case AttributeControlType.ReadonlyCheckboxes: { //load read-only(already server - side selected) values var attributeValues = await _productAttributeService.GetProductAttributeValuesAsync(attribute.Id); foreach (var selectedAttributeId in attributeValues .Where(v => v.IsPreSelected) .Select(v => v.Id) .ToList()) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttributeId.ToString()); } } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: { var selectedAttribute = attributeDtos.Where(x => x.Id == attribute.Id).FirstOrDefault(); if (selectedAttribute != null) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttribute.Value); } } break; case AttributeControlType.Datepicker: { var selectedAttribute = attributeDtos.Where(x => x.Id == attribute.Id).FirstOrDefault(); if (selectedAttribute != null) { DateTime selectedDate; // Since nopCommerce uses this format to keep the date in the database to keep it consisten we will expect the same format to be passed var validDate = DateTime.TryParseExact(selectedAttribute.Value, "D", CultureInfo.CurrentCulture, DateTimeStyles.None, out selectedDate); if (validDate) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedDate.ToString("D")); } } } break; case AttributeControlType.FileUpload: { var selectedAttribute = attributeDtos.Where(x => x.Id == attribute.Id).FirstOrDefault(); if (selectedAttribute != null) { Guid downloadGuid; Guid.TryParse(selectedAttribute.Value, out downloadGuid); var download = await _downloadService.GetDownloadByGuidAsync(downloadGuid); if (download != null) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, download.DownloadGuid.ToString()); } } } break; } } // No Gift Card attributes support yet return(attributesXml); }
public void Can_add_and_parse_productAttributes() { var attributes = ""; //color: green attributes = _productAttributeParser.AddProductAttribute(attributes, pam1_1, pav1_1.Id.ToString()); //custom option: option 1, option 2 attributes = _productAttributeParser.AddProductAttribute(attributes, pam2_1, pav2_1.Id.ToString()); attributes = _productAttributeParser.AddProductAttribute(attributes, pam2_1, pav2_2.Id.ToString()); //custom text attributes = _productAttributeParser.AddProductAttribute(attributes, pam3_1, "Some custom text goes here"); RunWithTestServiceProvider(() => { var parsedAttributeValues = _productAttributeParser.ParseProductAttributeValues(attributes); parsedAttributeValues.Contains(pav1_1).Should().BeTrue(); parsedAttributeValues.Contains(pav1_2).Should().BeFalse(); parsedAttributeValues.Contains(pav2_1).Should().BeTrue(); parsedAttributeValues.Contains(pav2_2).Should().BeTrue(); parsedAttributeValues.Contains(pav2_2).Should().BeTrue(); }); var parsedValues = _productAttributeParser.ParseValues(attributes, pam3_1.Id); parsedValues.Count.Should().Be(1); parsedValues.Contains("Some custom text goes here").Should().BeTrue(); parsedValues.Contains("Some other custom text").Should().BeFalse(); }
private void UpdateProductAttributeCombinations(Product product, List <ProductAttributeCombinationDto> productAttributeCombinations) { if (productAttributeCombinations == null) { return; } // REMOVE OLD ProductAttributeCombinations! // IF ID IS NOT IN LIST THEN REMOVE! if (product.ProductAttributeCombinations.Count > 0) { var ids = productAttributeCombinations.Select(c => c.Id).ToList(); var dataCombinations = new ProductAttributeCombination[product.ProductAttributeCombinations.Count]; product.ProductAttributeCombinations.CopyTo(dataCombinations, 0); foreach (var combi in dataCombinations.Where(t => !ids.Contains(t.Id))) { _productAttributeService.DeleteProductAttributeCombination(combi); } } var attributesXml = ""; foreach (var combi in productAttributeCombinations) { attributesXml = string.Empty; if (combi.Id == 0) { for (int i = 0; i < combi.Records.Count; i++) { foreach (var mapping in product.ProductAttributeMappings) { if (mapping.ProductAttributeValues.Count == 0) { var productAttributeValues = _productAttributeService.GetProductAttributeValues(mapping.Id); } var mappingValue = mapping.ProductAttributeValues.Where(v => _genericAttributeService.GetAttribute <int>(v, "nop.product.attributevalue.recordid") == combi.Records[i]).FirstOrDefault(); if (mappingValue != null) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, mapping, mappingValue.Id.ToString()); } } } // OPRET NY COMBINATION var attributeCombi = new ProductAttributeCombination() { ProductId = product.Id, AttributesXml = attributesXml, Sku = combi.Sku, Gtin = combi.Gtin, StockQuantity = combi.StockQuantity, AllowOutOfStockOrders = combi.AllowOutOfStockOrders, ManufacturerPartNumber = combi.ManufacturerPartNumber, NotifyAdminForQuantityBelow = combi.NotifyAdminForQuantityBelow, OverriddenPrice = combi.OverriddenPrice }; _productAttributeService.InsertProductAttributeCombination(attributeCombi); _genericAttributeService.SaveAttribute(attributeCombi, "nop.product.attribute.combination.records", combi.Records); _genericAttributeService.SaveAttribute(attributeCombi, "nop.product.attribute.combination.admind_id", combi.AdmindCombinationId); } else { // OPDATERE COMBINATION var currentCombi = _productAttributeService.GetProductAttributeCombinationById(combi.Id); currentCombi.Gtin = combi.Gtin != currentCombi.Gtin ? combi.Gtin : currentCombi.Gtin; currentCombi.Sku = combi.Sku != currentCombi.Sku ? combi.Sku : currentCombi.Sku; currentCombi.StockQuantity = combi.StockQuantity != currentCombi.StockQuantity ? combi.StockQuantity : currentCombi.StockQuantity; currentCombi.AllowOutOfStockOrders = combi.AllowOutOfStockOrders != currentCombi.AllowOutOfStockOrders ? combi.AllowOutOfStockOrders : currentCombi.AllowOutOfStockOrders; currentCombi.ManufacturerPartNumber = combi.ManufacturerPartNumber != currentCombi.ManufacturerPartNumber ? combi.ManufacturerPartNumber : currentCombi.ManufacturerPartNumber; currentCombi.NotifyAdminForQuantityBelow = combi.NotifyAdminForQuantityBelow != currentCombi.NotifyAdminForQuantityBelow ? combi.NotifyAdminForQuantityBelow : currentCombi.NotifyAdminForQuantityBelow; currentCombi.OverriddenPrice = combi.OverriddenPrice != currentCombi.OverriddenPrice ? combi.OverriddenPrice : currentCombi.OverriddenPrice; _productAttributeService.UpdateProductAttributeCombination(currentCombi); } } }
/// <summary>Takes selected elements from collection and creates a attribute XML string from it.</summary> /// <param name="formatWithProductId">how the name of the controls are formatted. frontend includes productId, backend does not.</param> public static string CreateSelectedAttributesXml(this NameValueCollection collection, int productId, IList<ProductVariantAttribute> variantAttributes, IProductAttributeParser productAttributeParser, ILocalizationService localizationService, IDownloadService downloadService, CatalogSettings catalogSettings, HttpRequestBase request, List<string> warnings, bool formatWithProductId = true, int bundleItemId = 0) { if (collection == null) return ""; string controlId; string selectedAttributes = ""; foreach (var attribute in variantAttributes) { controlId = AttributeFormatedName(attribute.ProductAttributeId, attribute.Id, formatWithProductId ? productId : 0, bundleItemId); switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.ColorSquares: { var ctrlAttributes = collection[controlId]; if (ctrlAttributes.HasValue()) { int selectedAttributeId = int.Parse(ctrlAttributes); if (selectedAttributeId > 0) selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, selectedAttributeId.ToString()); } } break; case AttributeControlType.Checkboxes: { var cblAttributes = collection[controlId]; if (cblAttributes.HasValue()) { foreach (var item in cblAttributes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { int selectedAttributeId = int.Parse(item); if (selectedAttributeId > 0) selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, selectedAttributeId.ToString()); } } } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: { var txtAttribute = collection[controlId]; if (txtAttribute.HasValue()) { string enteredText = txtAttribute.Trim(); selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, enteredText); } } break; case AttributeControlType.Datepicker: { var date = collection[controlId + "_day"]; var month = collection[controlId + "_month"]; var year = collection[controlId + "_year"]; DateTime? selectedDate = null; try { selectedDate = new DateTime(Int32.Parse(year), Int32.Parse(month), Int32.Parse(date)); } catch { } if (selectedDate.HasValue) { selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, selectedDate.Value.ToString("D")); } } break; case AttributeControlType.FileUpload: if (request == null) { Guid downloadGuid; Guid.TryParse(collection[controlId], out downloadGuid); var download = downloadService.GetDownloadByGuid(downloadGuid); if (download != null) { selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, download.DownloadGuid.ToString()); } } else { var httpPostedFile = request.Files[controlId]; if (httpPostedFile != null && httpPostedFile.FileName.HasValue()) { int fileMaxSize = catalogSettings.FileUploadMaximumSizeBytes; if (httpPostedFile.ContentLength > fileMaxSize) { warnings.Add(string.Format(localizationService.GetResource("ShoppingCart.MaximumUploadedFileSize"), (int)(fileMaxSize / 1024))); } else { //save an uploaded file var download = new Download() { DownloadGuid = Guid.NewGuid(), UseDownloadUrl = false, DownloadUrl = "", DownloadBinary = httpPostedFile.GetDownloadBits(), ContentType = httpPostedFile.ContentType, Filename = System.IO.Path.GetFileNameWithoutExtension(httpPostedFile.FileName), Extension = System.IO.Path.GetExtension(httpPostedFile.FileName), IsNew = true }; downloadService.InsertDownload(download); //save attribute selectedAttributes = productAttributeParser.AddProductAttribute(selectedAttributes, attribute, download.DownloadGuid.ToString()); } } } break; default: break; } } return selectedAttributes; }
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(); }
public async Task <string> Handle(GetParseProductAttributes request, CancellationToken cancellationToken) { string attributesXml = ""; #region Product attributes var productAttributes = request.Product.ProductAttributeMappings.ToList(); if (request.Product.ProductType == ProductType.BundledProduct) { foreach (var bundle in request.Product.BundleProducts) { var bp = await _productService.GetProductById(bundle.ProductId); if (bp.ProductAttributeMappings.Any()) { productAttributes.AddRange(bp.ProductAttributeMappings); } } } foreach (var attribute in productAttributes) { string controlId = string.Format("product_attribute_{0}", attribute.Id); switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.ColorSquares: case AttributeControlType.ImageSquares: { var ctrlAttributes = request.Form[controlId]; if (!String.IsNullOrEmpty(ctrlAttributes)) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, ctrlAttributes); } } break; case AttributeControlType.Checkboxes: { var ctrlAttributes = request.Form[controlId].ToString(); if (!String.IsNullOrEmpty(ctrlAttributes)) { foreach (var item in ctrlAttributes.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { if (!String.IsNullOrEmpty(item)) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, item); } } } } break; case AttributeControlType.ReadonlyCheckboxes: { //load read-only (already server-side selected) values var attributeValues = attribute.ProductAttributeValues; foreach (var selectedAttributeId in attributeValues .Where(v => v.IsPreSelected) .Select(v => v.Id) .ToList()) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttributeId); } } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: { var ctrlAttributes = request.Form[controlId].ToString(); if (!String.IsNullOrEmpty(ctrlAttributes)) { string enteredText = ctrlAttributes.Trim(); attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, enteredText); } } break; case AttributeControlType.Datepicker: { var day = request.Form[controlId + "_day"]; var month = request.Form[controlId + "_month"]; var year = request.Form[controlId + "_year"]; DateTime?selectedDate = null; try { selectedDate = new DateTime(Int32.Parse(year), Int32.Parse(month), Int32.Parse(day)); } catch { } if (selectedDate.HasValue) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedDate.Value.ToString("D")); } } break; case AttributeControlType.FileUpload: { Guid downloadGuid; Guid.TryParse(request.Form[controlId], out downloadGuid); var download = await _downloadService.GetDownloadByGuid(downloadGuid); if (download != null) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, download.DownloadGuid.ToString()); } } break; default: break; } } //validate conditional attributes (if specified) foreach (var attribute in productAttributes) { var conditionMet = _productAttributeParser.IsConditionMet(request.Product, attribute, attributesXml); if (conditionMet.HasValue && !conditionMet.Value) { attributesXml = _productAttributeParser.RemoveProductAttribute(attributesXml, attribute); } } #endregion #region Gift cards if (request.Product.IsGiftCard) { string recipientName = ""; string recipientEmail = ""; string senderName = ""; string senderEmail = ""; string giftCardMessage = ""; foreach (string formKey in request.Form.Keys) { if (formKey.Equals(string.Format("giftcard_{0}.RecipientName", request.Product.Id), StringComparison.OrdinalIgnoreCase)) { recipientName = request.Form[formKey]; continue; } if (formKey.Equals(string.Format("giftcard_{0}.RecipientEmail", request.Product.Id), StringComparison.OrdinalIgnoreCase)) { recipientEmail = request.Form[formKey]; continue; } if (formKey.Equals(string.Format("giftcard_{0}.SenderName", request.Product.Id), StringComparison.OrdinalIgnoreCase)) { senderName = request.Form[formKey]; continue; } if (formKey.Equals(string.Format("giftcard_{0}.SenderEmail", request.Product.Id), StringComparison.OrdinalIgnoreCase)) { senderEmail = request.Form[formKey]; continue; } if (formKey.Equals(string.Format("giftcard_{0}.Message", request.Product.Id), StringComparison.OrdinalIgnoreCase)) { giftCardMessage = request.Form[formKey]; continue; } } attributesXml = _productAttributeParser.AddGiftCardAttribute(attributesXml, recipientName, recipientEmail, senderName, senderEmail, giftCardMessage); } #endregion return(attributesXml); }
private async Task SaveWarranty(IList <ShoppingCartItem> cart, IFormCollection form) { foreach (var keyValue in await GetWarrantiesAsync(cart)) { var value = form[keyValue.Key.Id.ToString()]; var sci = keyValue.Key; //Remove currently selected warranty var pavs = await _productAttributeParser.ParseProductAttributeValuesAsync(sci.AttributesXml); List <ProductAttributeValue> warranties = new List <ProductAttributeValue>(); foreach (var pav in pavs) { var pam = await _productAttributeService.GetProductAttributeMappingByIdAsync(pav.ProductAttributeMappingId); var pa = await _productAttributeService.GetProductAttributeByIdAsync(pam.ProductAttributeId); var isWarranty = pa.Name == "Warranty"; if (isWarranty) { warranties.Add(pav); } } if (warranties.Count > 0) { var pams = (await _productAttributeService.GetProductAttributeMappingsByProductIdAsync( (await _productService.GetProductByIdAsync(sci.ProductId)).Id)); ProductAttributeMapping warrantyPam = null; foreach (var pam in pams) { var isWarranty = (await _productAttributeService.GetProductAttributeByIdAsync(pam.ProductAttributeId)).Name == "Warranty"; if (isWarranty) { warrantyPam = pam; continue; } } sci.AttributesXml = _productAttributeParser.RemoveProductAttribute(sci.AttributesXml, warrantyPam); } if (value != "NoWarranty") { var pav = await _productAttributeService.GetProductAttributeValueByIdAsync( int.Parse(value)); sci.AttributesXml = _productAttributeParser.AddProductAttribute( sci.AttributesXml, await _productAttributeService.GetProductAttributeMappingByIdAsync(pav.ProductAttributeMappingId), pav.Id.ToString()); } // get checkout state before it gets deleted // hold OfferedShippingOptions var shippingOptions = await _genericAttributeService.GetAttributeAsync <List <ShippingOption> >( await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.OfferedShippingOptionsAttribute, (await _storeContext.GetCurrentStoreAsync()).Id); // hold selected shipping option var selectedShippingOption = await _genericAttributeService.GetAttributeAsync <ShippingOption>( await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.SelectedShippingOptionAttribute, (await _storeContext.GetCurrentStoreAsync()).Id); // hold SelectedPaymentMethod //find a selected (previously) payment method var selectedPaymentMethodSystemName = await _genericAttributeService.GetAttributeAsync <string>( await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.SelectedPaymentMethodAttribute, (await _storeContext.GetCurrentStoreAsync()).Id); // updating shopping cart resets the order state, so we are going to save the state, and re-initialize it after the reset await _shoppingCartService.UpdateShoppingCartItemAsync( await _customerService.GetCustomerByIdAsync(sci.CustomerId), sci.Id, sci.AttributesXml, sci.CustomerEnteredPrice, sci.RentalStartDateUtc, sci.RentalEndDateUtc, sci.Quantity); // re-add shopping cart state to what it was before // OfferedShippingOptions await _genericAttributeService.SaveAttributeAsync(await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.OfferedShippingOptionsAttribute, shippingOptions, (await _storeContext.GetCurrentStoreAsync()).Id); // SelectedShippingOption await _genericAttributeService.SaveAttributeAsync(await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.SelectedShippingOptionAttribute, selectedShippingOption, (await _storeContext.GetCurrentStoreAsync()).Id); // SelectedPaymentMethod await _genericAttributeService.SaveAttributeAsync(await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.SelectedPaymentMethodAttribute, selectedPaymentMethodSystemName, (await _storeContext.GetCurrentStoreAsync()).Id); } }