public void ImportProductVariantsService_ImportVariants_ShouldSetProductVariantPrimaryProperties() { var productVariantDTO = new ProductVariantImportDataTransferObject { PreviousPrice = 2, Price = 1, SKU = "123", Name = "Test Product Variant", TrackingPolicy = TrackingPolicy.Track, Weight = 0, Barcode = "456", Stock = 5 }; var productDTO = new ProductImportDataTransferObject { UrlSegment = "test-url", ProductVariants = new List<ProductVariantImportDataTransferObject>() { productVariantDTO } }; var product = new Product() { Name = "Test Product" }; var result = _importProductVariantsService.ImportVariants(productDTO, product); result.First().PreviousPrice.ShouldBeEquivalentTo(2); result.First().BasePrice.ShouldBeEquivalentTo(1); result.First().SKU.ShouldBeEquivalentTo("123"); result.First().Name.ShouldBeEquivalentTo("Test Product Variant"); result.First().TrackingPolicy.ShouldBeEquivalentTo(TrackingPolicy.Track); result.First().Weight.ShouldBeEquivalentTo(0); result.First().Barcode.ShouldBeEquivalentTo("456"); result.First().StockRemaining.ShouldBeEquivalentTo(5); }
public void ImportProductsService_ImportProduct_ShouldSetProductPrimaryProperties() { var product = new ProductImportDataTransferObject { UrlSegment = "test-url", Name = "Test Product", Abstract = "Test Abstract", Description = "Test Description", SEODescription = "Test SEO Description", SEOKeywords = "Test, Thought", SEOTitle = "Test SEO Title" }; ProductContainer container = new ProductContainer().PersistTo(Session); A.CallTo(() => _uniquePageService.GetUniquePage<ProductContainer>()).Returns(container); MediaCategory category = new MediaCategory().PersistTo(Session); A.CallTo(() => _documentService.GetDocumentByUrl<MediaCategory>("product-galleries")).Returns(category); Product result = _importProductsService.ImportProduct(product); result.UrlSegment.ShouldBeEquivalentTo("test-url"); result.Name.ShouldBeEquivalentTo("Test Product"); result.ProductAbstract.ShouldBeEquivalentTo("Test Abstract"); result.BodyContent.ShouldBeEquivalentTo("Test Description"); result.MetaDescription.ShouldBeEquivalentTo("Test SEO Description"); result.MetaKeywords.ShouldBeEquivalentTo("Test, Thought"); result.MetaTitle.ShouldBeEquivalentTo("Test SEO Title"); }
public void ImportProductsService_ImportProduct_ShouldCallGetGetDocumentByUrlOfDocumentService() { var product = new ProductImportDataTransferObject { UrlSegment = "test-url", }; _importProductsService.ImportProduct(product); A.CallTo(() => _documentService.GetDocumentByUrl<Product>(product.UrlSegment)).MustHaveHappened(); }
public IEnumerable<string> GetErrors(ProductImportDataTransferObject product) { var value = Selector(product); if (!String.IsNullOrWhiteSpace(value)) { if (value.Length > Length) yield return string.Format( "{0} is too long - max length is {1} characters and your value is {2} characters in length.", DisplayName, Length, value.Length); } }
public void ImportProductsService_ImportProduct_ShouldTryToLoadTheCategoryFromTheDocumentService() { var product = new ProductImportDataTransferObject { UrlSegment = "test-url", Categories = new List<string> {"test-category"} }; _importProductsService.ImportProduct(product); A.CallTo(() => _documentService.GetDocumentByUrl<Category>("test-category")).MustHaveHappened(); }
public IEnumerable<ProductSpecificationValue> ImportSpecifications( ProductImportDataTransferObject dataTransferObject, Product product) { List<KeyValuePair<string, string>> specificationsToAdd = dataTransferObject.Specifications.Where( s => !product.SpecificationValues.Select(value => value.SpecificationName) .Contains(s.Key, StringComparer.InvariantCultureIgnoreCase)).ToList(); List<ProductSpecificationValue> specificationsToRemove = product.SpecificationValues.Where( value => !dataTransferObject.Specifications.Keys.Contains(value.SpecificationName, StringComparer.InvariantCultureIgnoreCase)) .ToList(); List<ProductSpecificationValue> specificationsToUpdate = product.SpecificationValues.Where(value => !specificationsToRemove.Contains(value)).ToList(); foreach (var item in specificationsToAdd) { ProductSpecificationAttribute attribute = _session.QueryOver<ProductSpecificationAttribute>() .Where( specificationAttribute => specificationAttribute.Name.IsInsensitiveLike(item.Key, MatchMode.Exact)) .Take(1) .SingleOrDefault(); if (attribute == null) { attribute = new ProductSpecificationAttribute {Name = item.Key}; _session.Transact(session => session.Save(attribute)); } SetValue(product, attribute, item.Value); } foreach (ProductSpecificationValue value in specificationsToRemove) { RemoveValue(product, value); } foreach (ProductSpecificationValue value in specificationsToUpdate) { ProductSpecificationAttribute attribute = value.ProductSpecificationAttributeOption.ProductSpecificationAttribute; RemoveValue(product, value); SetValue(product, attribute, dataTransferObject.Specifications[value.SpecificationName]); } return dataTransferObject.Specifications.Any() ? product.SpecificationValues : null; }
public void ImportSpecificationsService_ImportSpecifications_ShouldAddANewSpecificationAttributeIfItDoesntExist() { var productDTO = new ProductImportDataTransferObject() { UrlSegment = "test-url", Specifications = new Dictionary<string, string>() { {"Storage","16GB"} } }; var product = new Product() { Name = "Test Product" }; _importSpecificationsService.ImportSpecifications(productDTO, product); Session.Query<ProductSpecificationAttribute>().First().Options.Should().HaveCount(1); }
public IEnumerable<string> GetErrors(ProductImportDataTransferObject product) { var errors = new List<string>(); var mrCmsProduct = _productService.GetByUrl(product.UrlSegment); foreach (var pv in product.ProductVariants) { var mrCmsVariant = _productVariantService.GetProductVariantBySKU(pv.SKU); if (mrCmsVariant != null) { if (mrCmsProduct == null || (mrCmsVariant.Product.Id != mrCmsProduct.Id)) { errors.Add(string.Format("Product Variant with SKU {0} already exists on product with Url Segment {1}", pv.SKU, mrCmsVariant.Product.UrlSegment)); } } } return errors; }
public void ImportProductVariantsService_ImportVariants_ShouldSetProductVariantTaxRate() { var productVariantDTO = new ProductVariantImportDataTransferObject { SKU = "123", TaxRate = 1 }; var productDTO = new ProductImportDataTransferObject { UrlSegment = "test-url", ProductVariants = new List<ProductVariantImportDataTransferObject>() { productVariantDTO } }; var product = new Product { Name = "Test Product" }; var taxRate = new TaxRate() { Id = 1, Name = "GLOBAL" }; A.CallTo(() => _taxRateManager.Get(productVariantDTO.TaxRate.Value)).Returns(taxRate); var result = _importProductVariantsService.ImportVariants(productDTO, product); result.First().TaxRate.Name.ShouldBeEquivalentTo("GLOBAL"); }
public IEnumerable<string> GetErrors(ProductImportDataTransferObject product) { var errors=new List<string>(); try { foreach (var item in product.Images) { Uri testUri; var result = Uri.TryCreate(item, UriKind.Absolute, out testUri) && (testUri.Scheme == Uri.UriSchemeHttps || testUri.Scheme == Uri.UriSchemeHttp); if (!result) errors.Add(string.Format( "{0} is not valid Url.", item)); } } catch (Exception) { errors.Add("Some of Image Urls are not in correct format."); } return errors; }
public void ImportUrlHistory(ProductImportDataTransferObject productDto, Product product) { List<string> urlsToAdd = productDto.UrlHistory.Where( s => !product.Urls.Select(history => history.UrlSegment) .Contains(s, StringComparer.InvariantCultureIgnoreCase)).ToList(); //List<UrlHistory> urlsToRemove = // product.Urls.Where( // history => // !productDto.UrlHistory.Contains(history.UrlSegment, StringComparer.InvariantCultureIgnoreCase)) // .ToList(); foreach (string item in urlsToAdd) { UrlHistory history = _session.Query<UrlHistory>().FirstOrDefault(urlHistory => urlHistory.UrlSegment == item); bool isNew = history == null; if (isNew) { history = new UrlHistory { UrlSegment = item, Webpage = product }; _session.Transact(session => session.Save(history)); } else history.Webpage = product; if (!product.Urls.Contains(history)) product.Urls.Add(history); _session.Transact(session => session.Update(history)); } //foreach (UrlHistory history in urlsToRemove) //{ // product.Urls.Remove(history); // history.Webpage = null; // UrlHistory closureHistory = history; // _session.Transact(session => session.Update(closureHistory)); //} }
public void ImportProductVariantsService_ImportVariants_ShouldAddVariantsToProduct() { var productVariantDTO = new ProductVariantImportDataTransferObject { SKU = "123" }; var productDTO = new ProductImportDataTransferObject { UrlSegment = "test-url", ProductVariants = new List<ProductVariantImportDataTransferObject>() { productVariantDTO } }; var product = new Product() { Name = "Test Product" }; _importProductVariantsService.ImportVariants(productDTO, product); product.Variants.Should().HaveCount(1); }
public void ImportProductVariantsService_ImportVariants_ShouldCallImportVariantPriceBreaksOfImportProductVariantPriceBreaksService() { var productVariantDTO = new ProductVariantImportDataTransferObject { SKU = "123", PriceBreaks = new Dictionary<int, decimal>() { { 10, 299 } } }; var productDTO = new ProductImportDataTransferObject { UrlSegment = "test-url", ProductVariants = new List<ProductVariantImportDataTransferObject>() { productVariantDTO } }; var product = new Product(); var productVariant = new ProductVariant() { Name = "Test Product Variant" }; _importProductVariantsService.ImportVariants(productDTO, product); A.CallTo(() => _importProductVariantPriceBreaksService.ImportVariantPriceBreaks(productVariantDTO, productVariant)).MustHaveHappened(); }
public void ImportProductsService_ImportProducts_ShouldSetCategoriesIfTheyExist() { var productDTO = new ProductImportDataTransferObject { UrlSegment = "test-url", Categories = new List<string> {"test-category"} }; var category = new Category {Id = 1, Name = "Test Category"}; A.CallTo(() => _documentService.GetDocument<Category>(1)).Returns(category); var product = new Product {Name = "Test Product"}; A.CallTo(() => _documentService.GetDocumentByUrl<Product>(productDTO.UrlSegment)).Returns(product); Product importProduct = _importProductsService.ImportProduct(productDTO); importProduct.Categories.Should().HaveCount(1); }
public void ImportProductService_ImportProducts_ShouldCallImportUrlHistoryOfImportProductUrlHistoryService() { var productDTO = new ProductImportDataTransferObject { UrlSegment = "test-url", UrlHistory = new List<string> {"test-url-old"} }; var product = new Product {Name = "Test Product"}; A.CallTo(() => _documentService.GetDocumentByUrl<Product>(productDTO.UrlSegment)).Returns(product); _importProductsService.ImportProduct(productDTO); A.CallTo(() => _importProductUrlHistoryService.ImportUrlHistory(productDTO, product)).MustHaveHappened(); }
public void ImportProductsService_ImportProducts_ShouldSetProductBrandIfItAlreadyExists() { var product = new ProductImportDataTransferObject { UrlSegment = "test-url", Brand = "Test Brand" }; var brand = new Brand {Name = "Test BrandPage"}; Product importProduct = _importProductsService.ImportProduct(product); importProduct.BrandPage.Should().Be(brand); }
public void ImportProductsService_ImportProducts_ShouldSetTheBrandToOneWithTheCorrectNameIfItDoesNotExist() { var product = new ProductImportDataTransferObject { UrlSegment = "test-url", Brand = "Test Brand" }; Product importProduct = _importProductsService.ImportProduct(product); importProduct.BrandPage.Name.Should().Be("Test Brand"); }
/// <summary> /// Validate And Import Products With Variants /// </summary> /// <param name="spreadsheet"></param> /// <param name="parseErrors"></param> /// <returns></returns> public HashSet<ProductImportDataTransferObject> ValidateAndImportProductsWithVariants(ExcelPackage spreadsheet, ref Dictionary<string, List<string>> parseErrors) { var productsToImport = new HashSet<ProductImportDataTransferObject>(); if (!parseErrors.Any()) { if (spreadsheet != null) { if (spreadsheet.Workbook != null) { var worksheet = spreadsheet.Workbook.Worksheets.SingleOrDefault(x => x.Name == "Items"); if (worksheet != null) { var totalRows = worksheet.Dimension.End.Row; for (var rowId = 2; rowId <= totalRows; rowId++) { if (!worksheet.GetValue<string>(rowId, 1).HasValue() && !worksheet.GetValue<string>(rowId, 2).HasValue() && !worksheet.GetValue<string>(rowId, 3).HasValue()) continue; var product = new ProductImportDataTransferObject(); //Prepare handle name for storing and grouping errors string url = worksheet.GetValue<string>(rowId, 1), name = worksheet.GetValue<string>(rowId, 2); var handle = url.HasValue() ? url : SeoHelper.TidyUrl(name); if (!productsToImport.Any(x => x.Name == name || x.UrlSegment == url)) { if (parseErrors.All(x => x.Key != handle)) parseErrors.Add(handle, new List<string>()); product.UrlSegment = worksheet.GetValue<string>(rowId, 1).HasValue() ? worksheet.GetValue<string>(rowId, 1) : _urlService.Suggest(null, new SuggestParams { PageName = name, DocumentType = typeof (Product).FullName }); //skip duplicate url if (productsToImport.Any(x => x.UrlSegment == product.UrlSegment)) continue; GetBasicData(parseErrors, worksheet, rowId, product, handle); GetCategories(parseErrors, worksheet, rowId, product, handle); GetSpecifications(parseErrors, worksheet, rowId, handle, product); GetImages(worksheet, rowId, product); GetUrlHistory(parseErrors, worksheet, rowId, product, handle); productsToImport.Add(product); } else { product = !string.IsNullOrWhiteSpace(url) ? productsToImport.SingleOrDefault(x => x.Name == name && x.UrlSegment == url) : productsToImport.SingleOrDefault(x => x.Name == name); } //Variants if (product != null) { var productVariant = GetProductVariant(parseErrors, worksheet, rowId, handle); if (productVariant != null) { //Options GetProductVariantOptions(worksheet, rowId, productVariant); //Price Breaks GetPriceBreaks(parseErrors, worksheet, rowId, handle, productVariant); product.ProductVariants.Add(productVariant); } } } } } } //Remove handles with no errors parseErrors = parseErrors.Where(x => x.Value.Any()).ToDictionary(pair => pair.Key, pair => pair.Value); } var i = productsToImport.Where(x => x.ProductVariants.Count == 0).ToList(); return productsToImport; }
/// <summary> /// Import from DTOs /// </summary> /// <param name="dataTransferObject"></param> public Product ImportProduct(ProductImportDataTransferObject dataTransferObject) { var uniquePage = _uniquePageService.GetUniquePage<ProductContainer>(); var productGalleriesCategory = _documentService.GetDocumentByUrl<MediaCategory>("product-galleries"); if (productGalleriesCategory == null) { productGalleriesCategory = new MediaCategory { Name = "Product Galleries", UrlSegment = "product-galleries", IsGallery = true, HideInAdminNav = true }; _documentService.AddDocument(productGalleriesCategory); } Product product = _session.Query<Product>() .SingleOrDefault(x => x.UrlSegment == dataTransferObject.UrlSegment) ?? new Product(); product.Parent = uniquePage; product.UrlSegment = dataTransferObject.UrlSegment; product.Name = dataTransferObject.Name; product.BodyContent = dataTransferObject.Description; product.MetaTitle = dataTransferObject.SEOTitle; product.MetaDescription = dataTransferObject.SEODescription; product.MetaKeywords = dataTransferObject.SEOKeywords; product.ProductAbstract = dataTransferObject.Abstract; product.PublishOn = dataTransferObject.PublishDate; bool isNew = false; MediaCategory productGallery = product.Gallery ?? new MediaCategory(); if (product.Id == 0) { isNew = true; product.DisplayOrder = GetParentQuery(uniquePage).Any() ? GetParentQuery(uniquePage) .Select(Projections.Max<Webpage>(webpage => webpage.DisplayOrder)) .SingleOrDefault<int>() : 0; productGallery.Name = product.Name; productGallery.UrlSegment = "product-galleries/" + product.UrlSegment; productGallery.IsGallery = true; productGallery.Parent = productGalleriesCategory; productGallery.HideInAdminNav = true; product.Gallery = productGallery; } SetBrand(dataTransferObject, product); SetCategories(dataTransferObject, product); SetOptions(dataTransferObject, product); ////Url History _importUrlHistoryService.ImportUrlHistory(dataTransferObject, product); ////Specifications _importSpecificationsService.ImportSpecifications(dataTransferObject, product); ////Variants _importProductVariantsService.ImportVariants(dataTransferObject, product); if (isNew) { _session.Transact(session => session.Save(product)); _session.Transact(session => session.Save(productGallery)); } else { _session.Transact(session => session.Update(product)); _session.Transact(session => session.Update(productGallery)); } _importProductImagesService.ImportProductImages(dataTransferObject.Images, product.Gallery); return product; }
private static void GetSpecifications(Dictionary<string, List<string>> parseErrors, ExcelWorksheet worksheet, int rowId, string handle, ProductImportDataTransferObject product) { //Specifications var specificationsValue = worksheet.GetValue<string>(rowId, 10); if (!String.IsNullOrWhiteSpace(specificationsValue)) { try { if (!String.IsNullOrWhiteSpace(specificationsValue)) { if (!specificationsValue.Contains(":")) parseErrors[handle].Add( "Product Specifications field value contains illegal characters / not in correct format. Names and Values (Item) must be split with :, and items must be split by ;"); var specs = specificationsValue.Split(';'); foreach (var item in specs) { if (!String.IsNullOrWhiteSpace(item)) { string[] specificationValue = item.Split(':'); if (!String.IsNullOrWhiteSpace(specificationValue[0]) && !String.IsNullOrWhiteSpace(specificationValue[1]) && !product.Specifications.ContainsKey( specificationValue[0])) product.Specifications.Add(specificationValue[0], specificationValue[1]); } } } } catch (Exception) { parseErrors[handle].Add( "Product Specifications field value contains illegal characters / not in correct format. Names and Values (Item) must be split with :, and items must be split by ;"); } } }
private static void GetCategories(Dictionary<string, List<string>> parseErrors, ExcelWorksheet worksheet, int rowId, ProductImportDataTransferObject product, string handle) { //Categories try { var value = worksheet.GetValue<string>(rowId, 9); if (!String.IsNullOrWhiteSpace(value)) { var Cats = value.Split(';'); foreach (var item in Cats) { if (!String.IsNullOrWhiteSpace(item)) { if (!product.Categories.Any(x => x == item)) product.Categories.Add(item); else { parseErrors[handle].Add( "Product Categories field value contains duplicate values."); break; } } } } } catch (Exception) { parseErrors[handle].Add( "Product Categories field value contains illegal characters / not in correct format."); } }
private void SetOptions(ProductImportDataTransferObject dataTransferObject, Product product) { List<string> optionsToAdd = dataTransferObject.Options.Where( s => !product.Options.Select(option => option.Name).Contains(s, StringComparer.OrdinalIgnoreCase)) .ToList(); List<ProductOption> optionsToRemove = product.Options.Where(option => !dataTransferObject.Options.Contains(option.Name)).ToList(); foreach (string option in optionsToAdd) { ProductOption existingOption = _session.QueryOver<ProductOption>() .Where(productOption => productOption.Name.IsInsensitiveLike(option, MatchMode.Exact)) .Take(1).SingleOrDefault(); if (existingOption == null) { existingOption = new ProductOption { Name = option, }; _session.Transact(session => session.Save(existingOption)); } product.Options.Add(existingOption); existingOption.Products.Add(product); } foreach (ProductOption option in optionsToRemove) { product.Options.Remove(option); option.Products.Remove(product); } }
public IEnumerable<string> GetErrors(ProductImportDataTransferObject product) { return (from item in product.Categories where _documentService.GetDocumentByUrl<Category>(item) == null select string.Format("Category with url: {0} is not present within the system.", item)).ToList(); }
private static void GetBasicData(Dictionary<string, List<string>> parseErrors, ExcelWorksheet worksheet, int rowId, ProductImportDataTransferObject product, string handle) { if (worksheet.GetValue<string>(rowId, 2).HasValue()) product.Name = worksheet.GetValue<string>(rowId, 2); else parseErrors[handle].Add("Product Name is required."); product.Description = worksheet.GetValue<string>(rowId, 3); product.SEOTitle = worksheet.GetValue<string>(rowId, 4); product.SEODescription = worksheet.GetValue<string>(rowId, 5); product.SEOKeywords = worksheet.GetValue<string>(rowId, 6); product.Abstract = worksheet.GetValue<string>(rowId, 7); product.Brand = worksheet.GetValue<string>(rowId, 8); if (worksheet.GetValue<string>(rowId, 32).HasValue()) { if (!worksheet.GetValue<string>(rowId, 32).IsValidDateTime()) parseErrors[handle].Add("Publish Date is not a valid date."); else product.PublishDate = worksheet.GetValue<DateTime>(rowId, 32); } }
public void ImportProductVariantsService_ImportVariants_ShouldCallGetProductVariantBySKUOfProductVariantService() { var productVariant = new ProductVariantImportDataTransferObject { SKU = "123" }; var productDTO = new ProductImportDataTransferObject { UrlSegment = "test-url", ProductVariants = new List<ProductVariantImportDataTransferObject>() { productVariant } }; var product = new Product(); _importProductVariantsService.ImportVariants(productDTO, product); }
private void SetBrand(ProductImportDataTransferObject dataTransferObject, Product product) { //Brand if (!String.IsNullOrWhiteSpace(dataTransferObject.Brand)) { string dtoBrand = dataTransferObject.Brand.Trim(); Brand brand = _session.QueryOver<Brand>() .Where(b => b.Name.IsInsensitiveLike(dtoBrand, MatchMode.Exact)) .Take(1) .SingleOrDefault(); if (brand == null) { brand = _getNewBrandPage.Get(dtoBrand); _session.Transact(session => session.Save(brand)); } product.BrandPage = brand; } }
private static void GetUrlHistory(Dictionary<string, List<string>> parseErrors, ExcelWorksheet worksheet, int rowId, ProductImportDataTransferObject product, string handle) { //Url History try { var value = worksheet.GetValue<string>(rowId, 31); if (!String.IsNullOrWhiteSpace(value)) { var urlHistory = value.Split(','); foreach (var item in urlHistory) { if (!String.IsNullOrWhiteSpace(item)) { product.UrlHistory.Add(item); } } } } catch (Exception) { parseErrors[handle].Add( "Product Url History field value contains illegal characters / not in correct format."); } }
public void SetCategories(ProductImportDataTransferObject dataTransferObject, Product product) { //Categories List<string> categoriesToAdd = dataTransferObject.Categories.Where( s => !product.Categories.Select(category => category.UrlSegment) .Contains(s, StringComparer.OrdinalIgnoreCase)).ToList(); List<Category> categoriesToRemove = product.Categories.Where( category => !dataTransferObject.Categories.Contains(category.UrlSegment, StringComparer.OrdinalIgnoreCase)) .ToList(); foreach (string item in categoriesToAdd) { Category category = _session.QueryOver<Category>() .Where(c => c.UrlSegment.IsInsensitiveLike(item, MatchMode.Exact)) .Take(1) .SingleOrDefault(); if (category != null) { product.Categories.Add(category); if (!category.Products.Contains(product)) category.Products.Add(product); } } foreach (Category category in categoriesToRemove) { product.Categories.Remove(category); if (category.Products.Contains(product)) category.Products.Remove(product); } }
private static void GetImages(ExcelWorksheet worksheet, int rowId, ProductImportDataTransferObject product) { //Images if (worksheet.GetValue<string>(rowId, 27).HasValue()) product.Images.Add(worksheet.GetValue<string>(rowId, 27)); if (worksheet.GetValue<string>(rowId, 28).HasValue()) product.Images.Add(worksheet.GetValue<string>(rowId, 28)); if (worksheet.GetValue<string>(rowId, 29).HasValue()) product.Images.Add(worksheet.GetValue<string>(rowId, 29)); }
public void ImportSpecificationsService_ImportSpecifications_ShouldSetSpecifications() { var productDTO = new ProductImportDataTransferObject() { UrlSegment = "test-url", Specifications = new Dictionary<string, string>() { {"Storage","16GB"} } }; var product = new Product() { Name = "Test Product" }; _importSpecificationsService.ImportSpecifications(productDTO, product); product.SpecificationValues.Should().HaveCount(1); }