public void Can_save_and_load_productVariantAttribute() { var pva = new ProductVariantAttribute { TextPrompt = "TextPrompt 1", IsRequired = true, AttributeControlType = AttributeControlType.DropdownList, DisplayOrder = 1, ProductVariant = new ProductVariant() { Name = "Product variant name 1", CreatedOnUtc = new DateTime(2010, 01, 03), UpdatedOnUtc = new DateTime(2010, 01, 04), Product = new Product() { Name = "Name 1", Published = true, Deleted = false, CreatedOnUtc = new DateTime(2010, 01, 01), UpdatedOnUtc = new DateTime(2010, 01, 02), } }, ProductAttribute = new ProductAttribute() { Name = "Name 1", Description = "Description 1", } }; var fromDb = SaveAndLoadEntity(pva); fromDb.ShouldNotBeNull(); fromDb.TextPrompt.ShouldEqual("TextPrompt 1"); fromDb.IsRequired.ShouldEqual(true); fromDb.AttributeControlType.ShouldEqual(AttributeControlType.DropdownList); fromDb.DisplayOrder.ShouldEqual(1); fromDb.ProductVariant.ShouldNotBeNull(); fromDb.ProductVariant.Name.ShouldEqual("Product variant name 1"); fromDb.ProductAttribute.ShouldNotBeNull(); fromDb.ProductAttribute.Name.ShouldEqual("Name 1"); }
public new void SetUp() { #region Test data //color (dropdownlist) pa1 = new ProductAttribute { Id = 1, Name = "Color", }; pva1_1 = new ProductVariantAttribute { Id = 11, ProductVariantId = 1, TextPrompt = "Select color:", IsRequired = true, AttributeControlType = AttributeControlType.DropdownList, DisplayOrder = 1, ProductAttribute = pa1, ProductAttributeId = pa1.Id }; pvav1_1 = new ProductVariantAttributeValue { Id = 11, Name = "Green", DisplayOrder = 1, ProductVariantAttribute = pva1_1, ProductVariantAttributeId = pva1_1.Id }; pvav1_2 = new ProductVariantAttributeValue { Id = 12, Name = "Red", DisplayOrder = 2, ProductVariantAttribute = pva1_1, ProductVariantAttributeId = pva1_1.Id }; pva1_1.ProductVariantAttributeValues.Add(pvav1_1); pva1_1.ProductVariantAttributeValues.Add(pvav1_2); //custom option (checkboxes) pa2 = new ProductAttribute { Id = 2, Name = "Some custom option", }; pva2_1 = new ProductVariantAttribute { Id = 21, ProductVariantId = 1, TextPrompt = "Select at least one option:", IsRequired = true, AttributeControlType = AttributeControlType.Checkboxes, DisplayOrder = 2, ProductAttribute = pa2, ProductAttributeId = pa2.Id }; pvav2_1 = new ProductVariantAttributeValue { Id = 21, Name = "Option 1", DisplayOrder = 1, ProductVariantAttribute = pva2_1, ProductVariantAttributeId = pva2_1.Id }; pvav2_2 = new ProductVariantAttributeValue { Id = 22, Name = "Option 2", DisplayOrder = 2, ProductVariantAttribute = pva2_1, ProductVariantAttributeId = pva2_1.Id }; pva2_1.ProductVariantAttributeValues.Add(pvav2_1); pva2_1.ProductVariantAttributeValues.Add(pvav2_2); //custom text pa3 = new ProductAttribute { Id = 3, Name = "Custom text", }; pva3_1 = new ProductVariantAttribute { Id = 31, ProductVariantId = 1, TextPrompt = "Enter custom text:", IsRequired = true, AttributeControlType = AttributeControlType.TextBox, DisplayOrder = 1, ProductAttribute = pa1, ProductAttributeId = pa3.Id }; #endregion _productAttributeRepo = MockRepository.GenerateMock<IRepository<ProductAttribute>>(); _productAttributeRepo.Expect(x => x.Table).Return(new List<ProductAttribute>() { pa1, pa2, pa3 }.AsQueryable()); _productAttributeRepo.Expect(x => x.GetById(pa1.Id)).Return(pa1); _productAttributeRepo.Expect(x => x.GetById(pa2.Id)).Return(pa2); _productAttributeRepo.Expect(x => x.GetById(pa3.Id)).Return(pa3); _productVariantAttributeRepo = MockRepository.GenerateMock<IRepository<ProductVariantAttribute>>(); _productVariantAttributeRepo.Expect(x => x.Table).Return(new List<ProductVariantAttribute>() { pva1_1, pva2_1, pva3_1 }.AsQueryable()); _productVariantAttributeRepo.Expect(x => x.GetById(pva1_1.Id)).Return(pva1_1); _productVariantAttributeRepo.Expect(x => x.GetById(pva2_1.Id)).Return(pva2_1); _productVariantAttributeRepo.Expect(x => x.GetById(pva3_1.Id)).Return(pva3_1); _productVariantAttributeCombinationRepo = MockRepository.GenerateMock<IRepository<ProductVariantAttributeCombination>>(); _productVariantAttributeCombinationRepo.Expect(x => x.Table).Return(new List<ProductVariantAttributeCombination>().AsQueryable()); _productVariantAttributeValueRepo = MockRepository.GenerateMock<IRepository<ProductVariantAttributeValue>>(); _productVariantAttributeValueRepo.Expect(x => x.Table).Return(new List<ProductVariantAttributeValue>() { pvav1_1, pvav1_2, pvav2_1, pvav2_2 }.AsQueryable()); _productVariantAttributeValueRepo.Expect(x => x.GetById(pvav1_1.Id)).Return(pvav1_1); _productVariantAttributeValueRepo.Expect(x => x.GetById(pvav1_2.Id)).Return(pvav1_2); _productVariantAttributeValueRepo.Expect(x => x.GetById(pvav2_1.Id)).Return(pvav2_1); _productVariantAttributeValueRepo.Expect(x => x.GetById(pvav2_2.Id)).Return(pvav2_2); _eventPublisher = MockRepository.GenerateMock<IEventPublisher>(); _eventPublisher.Expect(x => x.Publish(Arg<object>.Is.Anything)); var cacheManager = new NasNullCache(); _productAttributeService = new ProductAttributeService(cacheManager, _productAttributeRepo, _productVariantAttributeRepo, _productVariantAttributeCombinationRepo, _productVariantAttributeValueRepo, _eventPublisher); _productAttributeParser = new ProductAttributeParser(_productAttributeService); var workingLanguage = new Language(); _workContext = MockRepository.GenerateMock<IWorkContext>(); _workContext.Expect(x => x.WorkingLanguage).Return(workingLanguage); _currencyService = MockRepository.GenerateMock<ICurrencyService>(); _localizationService = MockRepository.GenerateMock<ILocalizationService>(); _localizationService.Expect(x => x.GetResource("GiftCardAttribute.For.Virtual")).Return("For: {0} <{1}>"); _localizationService.Expect(x => x.GetResource("GiftCardAttribute.From.Virtual")).Return("From: {0} <{1}>"); _localizationService.Expect(x => x.GetResource("GiftCardAttribute.For.Physical")).Return("For: {0}"); _localizationService.Expect(x => x.GetResource("GiftCardAttribute.From.Physical")).Return("From: {0}"); _taxService = MockRepository.GenerateMock<ITaxService>(); _priceFormatter = MockRepository.GenerateMock<IPriceFormatter>(); _downloadService = MockRepository.GenerateMock<IDownloadService>(); _webHelper = MockRepository.GenerateMock<IWebHelper>(); _productAttributeFormatter = new ProductAttributeFormatter(_workContext, _productAttributeService, _productAttributeParser, _currencyService, _localizationService, _taxService, _priceFormatter, _downloadService, _webHelper); }
/// <summary> /// Updates the product variant attribute mapping /// </summary> /// <param name="productVariantAttribute">The product variant attribute mapping</param> public virtual void UpdateProductVariantAttribute(ProductVariantAttribute productVariantAttribute) { if (productVariantAttribute == null) throw new ArgumentNullException("productVariantAttribute"); _productVariantAttributeRepository.Update(productVariantAttribute); _cacheManager.RemoveByPattern(PRODUCTATTRIBUTES_PATTERN_KEY); _cacheManager.RemoveByPattern(PRODUCTVARIANTATTRIBUTES_PATTERN_KEY); _cacheManager.RemoveByPattern(PRODUCTVARIANTATTRIBUTEVALUES_PATTERN_KEY); //event notification _eventPublisher.EntityUpdated(productVariantAttribute); }
/// <summary> /// Adds an attribute /// </summary> /// <param name="attributes">Attributes</param> /// <param name="pva">Product variant attribute</param> /// <param name="value">Value</param> /// <returns>Attributes</returns> public virtual string AddProductAttribute(string attributes, ProductVariantAttribute pva, string value) { string result = string.Empty; try { var xmlDoc = new XmlDocument(); if (String.IsNullOrEmpty(attributes)) { var element1 = xmlDoc.CreateElement("Attributes"); xmlDoc.AppendChild(element1); } else { xmlDoc.LoadXml(attributes); } var rootElement = (XmlElement)xmlDoc.SelectSingleNode(@"//Attributes"); XmlElement pvaElement = null; //find existing var nodeList1 = xmlDoc.SelectNodes(@"//Attributes/ProductVariantAttribute"); foreach (XmlNode node1 in nodeList1) { if (node1.Attributes != null && node1.Attributes["ID"] != null) { string str1 =node1.Attributes["ID"].InnerText.Trim(); int id = 0; if (int.TryParse(str1, out id)) { if (id == pva.Id) { pvaElement = (XmlElement)node1; break; } } } } //create new one if not found if (pvaElement == null) { pvaElement = xmlDoc.CreateElement("ProductVariantAttribute"); pvaElement.SetAttribute("ID", pva.Id.ToString()); rootElement.AppendChild(pvaElement); } var pvavElement = xmlDoc.CreateElement("ProductVariantAttributeValue"); pvaElement.AppendChild(pvavElement); var pvavVElement = xmlDoc.CreateElement("Value"); pvavVElement.InnerText = value; pvavElement.AppendChild(pvavVElement); result = xmlDoc.OuterXml; } catch (Exception exc) { Debug.Write(exc.ToString()); } return result; }
/// <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, ColorSquaresRgb = productVariantAttributeValue.ColorSquaresRgb, 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; }