public void Can_save_and_load_productAttributeCombination() { var combination = new ProductAttributeCombination { AttributesXml = "Some XML", StockQuantity = 2, AllowOutOfStockOrders = true, Sku = "Sku1", ManufacturerPartNumber = "ManufacturerPartNumber1", Gtin = "Gtin1", OverriddenPrice = 0.01M, NotifyAdminForQuantityBelow = 3, Product = GetTestProduct() }; var fromDb = SaveAndLoadEntity(combination); fromDb.ShouldNotBeNull(); fromDb.AttributesXml.ShouldEqual("Some XML"); fromDb.StockQuantity.ShouldEqual(2); fromDb.AllowOutOfStockOrders.ShouldEqual(true); fromDb.Sku.ShouldEqual("Sku1"); fromDb.ManufacturerPartNumber.ShouldEqual("ManufacturerPartNumber1"); fromDb.Gtin.ShouldEqual("Gtin1"); fromDb.OverriddenPrice.ShouldEqual(0.01M); fromDb.NotifyAdminForQuantityBelow.ShouldEqual(3); }
/// <summary> /// Updates a product attribute combination /// </summary> /// <param name="combination">Product attribute combination</param> public virtual void UpdateProductAttributeCombination(ProductAttributeCombination combination) { if (combination == null) throw new ArgumentNullException("combination"); _productAttributeCombinationRepository.Update(combination); //cache _cacheManager.RemoveByPattern(PRODUCTATTRIBUTES_PATTERN_KEY); _cacheManager.RemoveByPattern(PRODUCTATTRIBUTEMAPPINGS_PATTERN_KEY); _cacheManager.RemoveByPattern(PRODUCTATTRIBUTEVALUES_PATTERN_KEY); _cacheManager.RemoveByPattern(PRODUCTATTRIBUTECOMBINATIONS_PATTERN_KEY); //event notification _eventPublisher.EntityUpdated(combination); }
public ActionResult AddAttributeCombinationPopup(string btnId, string formId, int productId, AddProductAttributeCombinationModel model, FormCollection form) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageProducts)) return AccessDeniedView(); var product = _productService.GetProductById(productId); if (product == null) //No product found with the specified id return RedirectToAction("List", "Product"); //a vendor should have access only to his products if (_workContext.CurrentVendor != null&& product.VendorId != _workContext.CurrentVendor.Id) return RedirectToAction("List", "Product"); ViewBag.btnId = btnId; ViewBag.formId = formId; //attributes string attributesXml = ""; var warnings = new List<string>(); #region Product attributes var attributes = _productAttributeService.GetProductAttributeMappingsByProductId(product.Id) //ignore non-combinable attributes for combinations .Where(x => !x.IsNonCombinable()) .ToList(); foreach (var attribute in attributes) { string controlId = string.Format("product_attribute_{0}_{1}", attribute.ProductAttributeId, attribute.Id); switch (attribute.AttributeControlType) { case AttributeControlType.DropdownList: case AttributeControlType.RadioList: case AttributeControlType.ColorSquares: { var ctrlAttributes = form[controlId]; if (!String.IsNullOrEmpty(ctrlAttributes)) { int selectedAttributeId = int.Parse(ctrlAttributes); if (selectedAttributeId > 0) attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttributeId.ToString()); } } break; case AttributeControlType.Checkboxes: { var cblAttributes = form[controlId]; if (!String.IsNullOrEmpty(cblAttributes)) { foreach (var item in cblAttributes.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { int selectedAttributeId = int.Parse(item); if (selectedAttributeId > 0) attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttributeId.ToString()); } } } 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()) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedAttributeId.ToString()); } } break; case AttributeControlType.TextBox: case AttributeControlType.MultilineTextbox: { var ctrlAttributes = form[controlId]; if (!String.IsNullOrEmpty(ctrlAttributes)) { string enteredText = ctrlAttributes.Trim(); attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, enteredText); } } break; case AttributeControlType.Datepicker: { var date = 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(date)); } catch { } if (selectedDate.HasValue) { attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, selectedDate.Value.ToString("D")); } } break; case AttributeControlType.FileUpload: { var httpPostedFile = this.Request.Files[controlId]; if ((httpPostedFile != null) && (!String.IsNullOrEmpty(httpPostedFile.FileName))) { var fileSizeOk = true; if (attribute.ValidationFileMaximumSize.HasValue) { //compare in bytes var maxFileSizeBytes = attribute.ValidationFileMaximumSize.Value * 1024; if (httpPostedFile.ContentLength > maxFileSizeBytes) { warnings.Add(string.Format(_localizationService.GetResource("ShoppingCart.MaximumUploadedFileSize"), attribute.ValidationFileMaximumSize.Value)); fileSizeOk = false; } } if (fileSizeOk) { //save an uploaded file var download = new Download { DownloadGuid = Guid.NewGuid(), UseDownloadUrl = false, DownloadUrl = "", DownloadBinary = httpPostedFile.GetDownloadBits(), ContentType = httpPostedFile.ContentType, Filename = Path.GetFileNameWithoutExtension(httpPostedFile.FileName), Extension = Path.GetExtension(httpPostedFile.FileName), IsNew = true }; _downloadService.InsertDownload(download); //save attribute attributesXml = _productAttributeParser.AddProductAttribute(attributesXml, attribute, download.DownloadGuid.ToString()); } } } break; default: break; } } #endregion warnings.AddRange(_shoppingCartService.GetShoppingCartItemAttributeWarnings(_workContext.CurrentCustomer, ShoppingCartType.ShoppingCart, product, 1, attributesXml, true)); if (warnings.Count == 0) { //save combination var combination = new ProductAttributeCombination { ProductId = product.Id, AttributesXml = attributesXml, StockQuantity = model.StockQuantity, AllowOutOfStockOrders = model.AllowOutOfStockOrders, Sku = model.Sku, ManufacturerPartNumber = model.ManufacturerPartNumber, Gtin = model.Gtin, OverriddenPrice = model.OverriddenPrice, NotifyAdminForQuantityBelow = model.NotifyAdminForQuantityBelow, }; _productAttributeService.InsertProductAttributeCombination(combination); ViewBag.RefreshPage = true; return View(model); } //If we got this far, something failed, redisplay form PrepareAddProductAttributeCombinationModel(model, product); model.Warnings = warnings; return View(model); }
public ActionResult GenerateAllAttributeCombinations(int productId) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageProducts)) return AccessDeniedView(); var product = _productService.GetProductById(productId); if (product == null) throw new ArgumentException("No product found with the specified id"); //a vendor should have access only to his products if (_workContext.CurrentVendor != null && product.VendorId != _workContext.CurrentVendor.Id) return Content("This is not your product"); var allAttributesXml = _productAttributeParser.GenerateAllCombinations(product, true); foreach (var attributesXml in allAttributesXml) { var existingCombination = _productAttributeParser.FindProductAttributeCombination(product, attributesXml); //already exists? if (existingCombination != null) continue; //new one var warnings = new List<string>(); warnings.AddRange(_shoppingCartService.GetShoppingCartItemAttributeWarnings(_workContext.CurrentCustomer, ShoppingCartType.ShoppingCart, product, 1, attributesXml, true)); if (warnings.Count != 0) continue; //save combination var combination = new ProductAttributeCombination { ProductId = product.Id, AttributesXml = attributesXml, StockQuantity = 10000, AllowOutOfStockOrders = false, Sku = null, ManufacturerPartNumber = null, Gtin = null, OverriddenPrice = null, NotifyAdminForQuantityBelow = 1 }; _productAttributeService.InsertProductAttributeCombination(combination); } return Json(new { Success = true }); }
/// <summary> /// Sends a "quantity below" notification to a store owner /// </summary> /// <param name="combination">Attribute combination</param> /// <param name="languageId">Message language identifier</param> /// <returns>Queued email identifier</returns> public virtual int SendQuantityBelowStoreOwnerNotification(ProductAttributeCombination combination, int languageId) { if (combination == null) throw new ArgumentNullException("combination"); var store = _storeContext.CurrentStore; languageId = EnsureLanguageIsActive(languageId, store.Id); var messageTemplate = GetActiveMessageTemplate("QuantityBelow.AttributeCombination.StoreOwnerNotification", store.Id); if (messageTemplate == null) return 0; //email account var emailAccount = GetEmailAccountOfMessageTemplate(messageTemplate, languageId); var product = combination.Product; var tokens = new List<Token>(); _messageTokenProvider.AddStoreTokens(tokens, store, emailAccount); _messageTokenProvider.AddProductTokens(tokens, product, languageId); _messageTokenProvider.AddAttributeCombinationTokens(tokens, combination, languageId); //event notification _eventPublisher.MessageTokensAdded(messageTemplate, tokens); var toEmail = emailAccount.Email; var toName = emailAccount.DisplayName; return SendNotification(messageTemplate, emailAccount, languageId, tokens, toEmail, toName); }
public virtual void AddAttributeCombinationTokens(IList<Token> tokens, ProductAttributeCombination combination, int languageId) { //attributes //we cannot inject IProductAttributeFormatter into constructor because it'll cause circular references. //that's why we resolve it here this way var productAttributeFormatter = EngineContext.Current.Resolve<IProductAttributeFormatter>(); string attributes = productAttributeFormatter.FormatAttributes(combination.Product, combination.AttributesXml, _workContext.CurrentCustomer, renderPrices: false); tokens.Add(new Token("AttributeCombination.Formatted", attributes, true)); tokens.Add(new Token("AttributeCombination.SKU", combination.Product.FormatSku(combination.AttributesXml, _productAttributeParser))); tokens.Add(new Token("AttributeCombination.StockQuantity", combination.StockQuantity.ToString())); //event notification _eventPublisher.EntityTokensAdded(combination, tokens); }
/// <summary> /// Updates a product attribute combination /// </summary> /// <param name="combination">Product attribute combination</param> public virtual void UpdateProductAttributeCombination(ProductAttributeCombination combination) { if (combination == null) throw new ArgumentNullException("combination"); //_productAttributeCombinationRepository.Update(combination); var builder = Builders<Product>.Filter; var filter = builder.Eq(x => x.Id, combination.ProductId); filter = filter & builder.ElemMatch(x => x.ProductAttributeCombinations, y => y.Id == combination.Id); var update = Builders<Product>.Update .Set("ProductAttributeCombinations.$.StockQuantity", combination.StockQuantity) .Set("ProductAttributeCombinations.$.AllowOutOfStockOrders", combination.AllowOutOfStockOrders) .Set("ProductAttributeCombinations.$.Sku", combination.Sku) .Set("ProductAttributeCombinations.$.ManufacturerPartNumber", combination.ManufacturerPartNumber) .Set("ProductAttributeCombinations.$.Gtin", combination.Gtin) .Set("ProductAttributeCombinations.$.OverriddenPrice", combination.OverriddenPrice) .Set("ProductAttributeCombinations.$.NotifyAdminForQuantityBelow", combination.NotifyAdminForQuantityBelow); var result = _productRepository.Collection.UpdateManyAsync(filter, update).Result; //cache _cacheManager.RemoveByPattern(string.Format(PRODUCTS_BY_ID_KEY, combination.ProductId)); //event notification _eventPublisher.EntityUpdated(combination); }
/// <summary> /// Inserts a product attribute combination /// </summary> /// <param name="combination">Product attribute combination</param> public virtual void InsertProductAttributeCombination(ProductAttributeCombination combination) { if (combination == null) throw new ArgumentNullException("combination"); var updatebuilder = Builders<Product>.Update; var update = updatebuilder.AddToSet(p => p.ProductAttributeCombinations, combination); _productRepository.Collection.UpdateOneAsync(new BsonDocument("Id", combination.ProductId), update); //cache _cacheManager.RemoveByPattern(string.Format(PRODUCTS_BY_ID_KEY, combination.ProductId)); //event notification _eventPublisher.EntityInserted(combination); }
/// <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, 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, 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, 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, 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, }; _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, Quantity = productAttributeValue.Quantity, IsPreSelected = productAttributeValue.IsPreSelected, DisplayOrder = productAttributeValue.DisplayOrder, PictureId = attributeValuePictureId, }; _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; }
public string GetReference(Product product, ProductAttributeCombination combination) { var reference = product.Sku; if (string.IsNullOrEmpty(reference)) { reference = product.Id.ToString(CultureInfo.InvariantCulture); } if (combination != null) { reference = combination.Sku; if (string.IsNullOrEmpty(reference)) { reference = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", product.Id, combination.Id); } } return reference; }