private coreModel.CatalogProduct UpdateProduct(webModel.Product product) { var moduleProduct = product.ToModuleModel(_blobUrlResolver); if (moduleProduct.Id == null) { if (moduleProduct.SeoInfos == null || !moduleProduct.SeoInfos.Any()) { var slugUrl = GenerateProductDefaultSlugUrl(product); if (!string.IsNullOrEmpty(slugUrl)) { var catalog = _catalogService.GetById(product.CatalogId); var defaultLanguageCode = catalog.Languages.First(x => x.IsDefault).LanguageCode; var seoInfo = new SeoInfo { LanguageCode = defaultLanguageCode, SemanticUrl = slugUrl }; moduleProduct.SeoInfos = new SeoInfo[] { seoInfo }; } } base.CheckCurrentUserHasPermissionForObjects(CatalogPredefinedPermissions.Create, moduleProduct); return(_itemsService.Create(moduleProduct)); } else { base.CheckCurrentUserHasPermissionForObjects(CatalogPredefinedPermissions.Update, moduleProduct); _itemsService.Update(new[] { moduleProduct }); } return(null); }
// GET: /blogs/{blogname}/tag/{tag} public ActionResult GetArticlesByTag(string blogName, string tag) { var blog = WorkContext.Blogs.FirstOrDefault(b => b.Name.Equals(blogName, StringComparison.OrdinalIgnoreCase)); if (blog != null) { var blogClone = new Blog(); //Need to clone exist blog because it may be memory cached blogClone.InjectFrom <NullableAndEnumValueInjecter>(blog); var seoInfo = new SeoInfo { Language = blog.Language, MetaDescription = blog.Title, Slug = string.Format("/blogs/{0}/tag/{1}", blog, tag), Title = blog.Title }; var articles = blog.Articles.Where(a => a.Tags != null && a.Tags.Contains(tag, StringComparer.OrdinalIgnoreCase) && a.PublicationStatus != ContentPublicationStatus.Private); if (articles != null) { blogClone.Articles = new MutablePagedList <BlogArticle>(articles); } WorkContext.CurrentBlog = blogClone; WorkContext.CurrentPageSeo = seoInfo; } return(View("blog", blog.Layout, WorkContext)); }
public CsvProduct(CatalogProduct product, IBlobUrlResolver blobUrlResolver, Price price, InventoryInfo inventory, SeoInfo seoInfo) : this() { _blobUrlResolver = blobUrlResolver; this.InjectFrom(product); Properties = product.Properties; Images = product.Images; Assets = product.Assets; Links = product.Links; Variations = product.Variations; SeoInfos = product.SeoInfos; Reviews = product.Reviews; Associations = product.Associations; if (price != null) { Price = price; } if (inventory != null) { Inventory = inventory; } if (seoInfo != null) { SeoInfo = seoInfo; } }
public static SeoInfo ToWebModel(this VirtoCommerce.Client.Model.VirtoCommerceDomainCommerceModelSeoInfo seoDto) { var retVal = new SeoInfo(); retVal.InjectFrom(seoDto); retVal.Slug = seoDto.SemanticUrl; retVal.Title = seoDto.PageTitle; return retVal; }
public static SeoInfo ToWebModel(this VirtoCommerce.Client.Model.VirtoCommerceDomainCommerceModelSeoInfo seoDto) { var retVal = new SeoInfo(); retVal.InjectFrom(seoDto); retVal.Slug = seoDto.SemanticUrl; retVal.Title = seoDto.PageTitle; return(retVal); }
public static SeoInfo ToWebModel(this VirtoCommerce.Client.Model.VirtoCommerceDomainCommerceModelSeoInfo seoDto) { var retVal = new SeoInfo(); retVal.InjectFrom(seoDto); retVal.Slug = seoDto.SemanticUrl; retVal.Title = seoDto.PageTitle; retVal.Language = String.IsNullOrEmpty(seoDto.LanguageCode) ? Language.InvariantLanguage : new Language(seoDto.LanguageCode); return retVal; }
public static SeoInfo ToWebModel(this VirtoCommerce.Client.Model.VirtoCommerceDomainCommerceModelSeoInfo seoDto) { var retVal = new SeoInfo(); retVal.InjectFrom(seoDto); retVal.Slug = seoDto.SemanticUrl; retVal.Title = seoDto.PageTitle; retVal.Language = String.IsNullOrEmpty(seoDto.LanguageCode) ? Language.InvariantLanguage : new Language(seoDto.LanguageCode); return(retVal); }
public static webModel.SeoKeyword ToWebModel(this SeoInfo seoInfo) { var retVal = new webModel.SeoKeyword(); retVal.InjectFrom(seoInfo); retVal.Keyword = seoInfo.SemanticUrl; retVal.Language = seoInfo.LanguageCode; retVal.Title = seoInfo.PageTitle; return(retVal); }
public static SeoInfo ToSeoInfo(this coreDto.SeoInfo seoDto) { var retVal = new SeoInfo(); retVal.InjectFrom(seoDto); retVal.Slug = seoDto.SemanticUrl; retVal.Title = seoDto.PageTitle; retVal.Language = string.IsNullOrEmpty(seoDto.LanguageCode) ? Language.InvariantLanguage : new Language(seoDto.LanguageCode); return(retVal); }
public static SeoInfo ToSeoInfo(this coreDto.SeoInfo seoDto) { var retVal = new SeoInfo(); retVal.MetaDescription = seoDto.MetaDescription; retVal.MetaKeywords = seoDto.MetaKeywords; retVal.Slug = seoDto.SemanticUrl; retVal.Title = seoDto.PageTitle; retVal.Language = string.IsNullOrEmpty(seoDto.LanguageCode) ? Language.InvariantLanguage : new Language(seoDto.LanguageCode); return(retVal); }
public virtual void MergeFrom(SeoInfo source) { SemanticUrl = source.SemanticUrl; LanguageCode = source.LanguageCode; StoreId = source.StoreId; if (PageTitle.IsNullOrEmpty()) { PageTitle = source.PageTitle; } if (MetaDescription.IsNullOrEmpty()) { MetaDescription = source.MetaDescription; } }
public static SeoInfo ToWebModel(this storeModel.SeoInfo seoDto) { SeoInfo retVal = null; if (seoDto != null) { retVal = new SeoInfo(); retVal.InjectFrom(seoDto); retVal.Slug = seoDto.SemanticUrl; retVal.Title = seoDto.PageTitle; retVal.Language = string.IsNullOrEmpty(seoDto.LanguageCode) ? Language.InvariantLanguage : new Language(seoDto.LanguageCode); } return(retVal); }
private coreModel.CatalogProduct[] InnerSaveProducts(webModel.Product[] products) { var toUpdateList = new List <coreModel.CatalogProduct>(); var toCreateList = new List <coreModel.CatalogProduct>(); foreach (var product in products) { var moduleProduct = product.ToModuleModel(_blobUrlResolver); if (moduleProduct.IsTransient()) { if (moduleProduct.SeoInfos == null || !moduleProduct.SeoInfos.Any()) { var slugUrl = GenerateProductDefaultSlugUrl(product); if (!string.IsNullOrEmpty(slugUrl)) { var catalog = _catalogService.GetById(product.CatalogId); var defaultLanguageCode = catalog.Languages.First(x => x.IsDefault).LanguageCode; var seoInfo = new SeoInfo { LanguageCode = defaultLanguageCode, SemanticUrl = slugUrl }; moduleProduct.SeoInfos = new[] { seoInfo }; } } CheckCurrentUserHasPermissionForObjects(CatalogPredefinedPermissions.Create, moduleProduct); toCreateList.Add(moduleProduct); } else { CheckCurrentUserHasPermissionForObjects(CatalogPredefinedPermissions.Update, moduleProduct); toUpdateList.Add(moduleProduct); } } if (!toCreateList.IsNullOrEmpty()) { _itemsService.Create(toCreateList.ToArray()); } if (!toUpdateList.IsNullOrEmpty()) { _itemsService.Update(toUpdateList.ToArray()); } return(toCreateList.Concat(toUpdateList).ToArray()); }
public virtual SeoInfo ToModel(SeoInfo seoInfo) { seoInfo.Id = Id; seoInfo.CreatedBy = CreatedBy; seoInfo.CreatedDate = CreatedDate; seoInfo.ModifiedBy = ModifiedBy; seoInfo.ModifiedDate = ModifiedDate; seoInfo.LanguageCode = Language; seoInfo.SemanticUrl = Keyword; seoInfo.PageTitle = Title; seoInfo.ImageAltDescription = ImageAltDescription; seoInfo.IsActive = IsActive; seoInfo.MetaDescription = MetaDescription; seoInfo.MetaKeywords = MetaKeywords; seoInfo.ObjectId = ItemId ?? CategoryId; seoInfo.ObjectType = ItemId != null ? "CatalogProduct" : "Category"; seoInfo.StoreId = StoreId; return(seoInfo); }
public virtual SeoInfoEntity FromModel(SeoInfo seoInfo, PrimaryKeyResolvingMap pkMap) { pkMap.AddPair(seoInfo, this); Id = seoInfo.Id; CreatedBy = seoInfo.CreatedBy; CreatedDate = seoInfo.CreatedDate; ModifiedBy = seoInfo.ModifiedBy; ModifiedDate = seoInfo.ModifiedDate; Language = seoInfo.LanguageCode; Keyword = seoInfo.SemanticUrl; Title = seoInfo.PageTitle; ImageAltDescription = seoInfo.ImageAltDescription; IsActive = seoInfo.IsActive; MetaDescription = seoInfo.MetaDescription; MetaKeywords = seoInfo.MetaKeywords; StoreId = seoInfo.StoreId; return(this); }
public virtual SeoInfo ToModel(SeoInfo seoInfo) { seoInfo.Id = Id; seoInfo.CreatedBy = CreatedBy; seoInfo.CreatedDate = CreatedDate; seoInfo.ModifiedBy = ModifiedBy; seoInfo.ModifiedDate = ModifiedDate; seoInfo.LanguageCode = Language; seoInfo.SemanticUrl = Keyword; seoInfo.PageTitle = Title; seoInfo.ImageAltDescription = ImageAltDescription; seoInfo.IsActive = IsActive; seoInfo.MetaDescription = MetaDescription; seoInfo.MetaKeywords = MetaKeywords; seoInfo.ObjectId = MemberId; seoInfo.ObjectType = "Member"; seoInfo.StoreId = StoreId; return(seoInfo); }
public CsvProduct() { SeoInfos = new List <SeoInfo>(); Reviews = new List <EditorialReview>(); PropertyValues = new List <PropertyValue>(); Images = new List <Image>(); Assets = new List <Asset>(); Price = new Price() { Currency = CurrencyCodes.USD }; Inventory = new InventoryInfo(); EditorialReview = new EditorialReview(); Reviews = new List <EditorialReview>(); Reviews.Add(EditorialReview); SeoInfo = new SeoInfo(); SeoInfos = new List <SeoInfo>(); SeoInfos.Add(SeoInfo); }
private async Task <CatalogProduct[]> InnerSaveProducts(CatalogProduct[] products) { var toSaveList = new List <CatalogProduct>(); var catalogs = await _catalogService.GetByIdsAsync(products.Select(pr => pr.CatalogId).Distinct().ToArray()); foreach (var product in products) { if (product.IsTransient()) { if (product.SeoInfos == null || !product.SeoInfos.Any()) { var slugUrl = GenerateProductDefaultSlugUrl(product); if (!string.IsNullOrEmpty(slugUrl)) { var catalog = catalogs.FirstOrDefault(c => c.Id.EqualsInvariant(product.CatalogId)); var defaultLanguageCode = catalog?.Languages.First(x => x.IsDefault).LanguageCode; var seoInfo = new SeoInfo { LanguageCode = defaultLanguageCode, SemanticUrl = slugUrl }; product.SeoInfos = new[] { seoInfo }; } } //CheckCurrentUserHasPermissionForObjects(CatalogPredefinedPermissions.Create, moduleProduct); } toSaveList.Add(product); } if (!toSaveList.IsNullOrEmpty()) { await _itemsService.SaveChangesAsync(toSaveList.ToArray()); } return(toSaveList.ToArray()); }
public CsvProduct() { SeoInfos = new List <SeoInfo>(); Reviews = new List <EditorialReview>(); PropertyValues = new List <PropertyValue>(); Images = new List <Image>(); Assets = new List <Asset>(); Price = new Price { Currency = "USD" }; Inventory = new InventoryInfo(); EditorialReview = new EditorialReview(); Reviews = new List <EditorialReview> { EditorialReview }; SeoInfo = new SeoInfo { ObjectType = typeof(CatalogProduct).Name }; SeoInfos = new List <SeoInfo> { SeoInfo }; }
/// <example> ///{ /// product(id: "f1b26974b7634abaa0900e575a99476f") /// { /// id /// code /// category{ id code name hasParent slug } /// name /// metaTitle /// metaDescription /// metaKeywords /// brandName /// slug /// imgSrc /// productType /// masterVariation { /// images{ id url name } /// assets{ id size url } /// prices(cultureName: "en-us"){ /// list { amount } /// currency /// } /// availabilityData{ /// availableQuantity /// inventories{ /// inStockQuantity /// fulfillmentCenterId /// fulfillmentCenterName /// allowPreorder /// allowBackorder /// } /// } /// properties{ id name valueType value valueId } /// } ///} /// </example> public ProductType(IMediator mediator, IDataLoaderContextAccessor dataLoader) { Name = "Product"; Description = "Products are the sellable goods in an e-commerce project."; Field(d => d.IndexedProduct.Id).Description("The unique ID of the product."); Field(d => d.IndexedProduct.Code, nullable: false).Description("The product SKU."); Field <StringGraphType>("catalogId", "The unique ID of the catalog", resolve: context => context.Source.IndexedProduct.CatalogId); Field(d => d.IndexedProduct.ProductType, nullable: true).Description("The type of product"); Field(d => d.IndexedProduct.MinQuantity, nullable: true).Description("Min. quantity"); Field(d => d.IndexedProduct.MaxQuantity, nullable: true).Description("Max. quantity"); FieldAsync <StringGraphType>("outline", resolve: async context => { var outlines = context.Source.IndexedProduct.Outlines; if (outlines.IsNullOrEmpty()) { return(null); } var loadRelatedCatalogOutlineQuery = context.GetCatalogQuery <LoadRelatedCatalogOutlineQuery>(); loadRelatedCatalogOutlineQuery.Outlines = outlines; var response = await mediator.Send(loadRelatedCatalogOutlineQuery); return(response.Outline); }, description: @"All parent categories ids relative to the requested catalog and concatenated with \ . E.g. (1/21/344)"); FieldAsync <StringGraphType>("slug", resolve: async context => { var outlines = context.Source.IndexedProduct.Outlines; if (outlines.IsNullOrEmpty()) { return(null); } var loadRelatedSlugPathQuery = context.GetCatalogQuery <LoadRelatedSlugPathQuery>(); loadRelatedSlugPathQuery.Outlines = outlines; var response = await mediator.Send(loadRelatedSlugPathQuery); return(response.Slug); }, description: "Request related slug for product"); Field(d => d.IndexedProduct.Name, nullable: false).Description("The name of the product."); Field <SeoInfoType>("seoInfo", resolve: context => { var source = context.Source; var storeId = context.GetArgumentOrValue <string>("storeId"); var cultureName = context.GetArgumentOrValue <string>("cultureName"); SeoInfo seoInfo = null; if (!source.IndexedProduct.SeoInfos.IsNullOrEmpty()) { seoInfo = source.IndexedProduct.SeoInfos.GetBestMatchingSeoInfo(storeId, cultureName); } return(seoInfo ?? GetFallbackSeoInfo(source, cultureName)); }, description: "Request related SEO info"); Field <ListGraphType <DescriptionType> >("descriptions", arguments: new QueryArguments(new QueryArgument <StringGraphType> { Name = "type" }), resolve: context => { var reviews = context.Source.IndexedProduct.Reviews; var cultureName = context.GetArgumentOrValue <string>("cultureName"); var type = context.GetArgumentOrValue <string>("type"); if (cultureName != null) { reviews = reviews.Where(x => string.IsNullOrEmpty(x.LanguageCode) || x.LanguageCode.EqualsInvariant(cultureName)).ToList(); } if (type != null) { reviews = reviews.Where(x => x.ReviewType?.EqualsInvariant(type) ?? true).ToList(); } return(reviews); }); Field <DescriptionType>("description", arguments: new QueryArguments(new QueryArgument <StringGraphType> { Name = "type" }), resolve: context => { var reviews = context.Source.IndexedProduct.Reviews; var type = context.GetArgumentOrValue <string>("type"); var cultureName = context.GetArgumentOrValue <string>("cultureName"); if (!reviews.IsNullOrEmpty()) { return(reviews.Where(x => x.ReviewType.EqualsInvariant(type ?? "FullReview")).FirstBestMatchForLanguage(cultureName) as EditorialReview ?? reviews.FirstBestMatchForLanguage(cultureName) as EditorialReview); } return(null); }); FieldAsync <CategoryType>( "category", resolve: async context => { var categoryId = context.Source.IndexedProduct.CategoryId; var loadCategoryQuery = context.GetCatalogQuery <LoadCategoryQuery>(); loadCategoryQuery.ObjectIds = new[] { categoryId }; loadCategoryQuery.IncludeFields = context.SubFields.Values.GetAllNodesPaths(); var responce = await mediator.Send(loadCategoryQuery); return(responce.Categories.FirstOrDefault()); }); Field <StringGraphType>( "imgSrc", description: "The product main image URL.", resolve: context => context.Source.IndexedProduct.ImgSrc); Field(d => d.IndexedProduct.OuterId, nullable: true).Description("The outer identifier"); Field <StringGraphType>( "brandName", description: "Get brandName for product.", resolve: context => { var brandName = context.Source.IndexedProduct.Properties ?.FirstOrDefault(x => x.Name.EqualsInvariant("Brand")) ?.Values ?.FirstOrDefault(x => x.Value != null) ?.Value; return(brandName?.ToString()); }); FieldAsync <VariationType>( "masterVariation", resolve: async context => { if (string.IsNullOrEmpty(context.Source.IndexedProduct.MainProductId)) { return(null); } var query = context.GetCatalogQuery <LoadProductsQuery>(); query.ObjectIds = new[] { context.Source.IndexedProduct.MainProductId }; query.IncludeFields = context.SubFields.Values.GetAllNodesPaths(); var response = await mediator.Send(query); return(response.Products.Select(expProduct => new ExpVariation(expProduct)).FirstOrDefault()); }); FieldAsync <ListGraphType <VariationType> >( "variations", resolve: async context => { var productIds = context.Source.IndexedVariationIds.ToArray(); if (productIds.IsNullOrEmpty()) { return(new List <ExpVariation>()); } var query = context.GetCatalogQuery <LoadProductsQuery>(); query.ObjectIds = context.Source.IndexedVariationIds.ToArray(); query.IncludeFields = context.SubFields.Values.GetAllNodesPaths(); var response = await mediator.Send(query); return(response.Products.Select(expProduct => new ExpVariation(expProduct))); }); Field <BooleanGraphType>( "hasVariations", resolve: context => { var result = context.Source.IndexedVariationIds?.Any() ?? false; return(result); }); Field( GraphTypeExtenstionHelper.GetActualType <AvailabilityDataType>(), "availabilityData", "Product availability data", resolve: context => new ExpAvailabilityData { AvailableQuantity = context.Source.AvailableQuantity, InventoryAll = context.Source.AllInventories, IsBuyable = context.Source.IsBuyable, IsAvailable = context.Source.IsAvailable, IsInStock = context.Source.IsInStock, IsActive = context.Source.IndexedProduct.IsActive ?? false, IsTrackInventory = context.Source.IndexedProduct.TrackInventory ?? false, }); Field <ListGraphType <ImageType> >( "images", "Product images", resolve: context => { var images = context.Source.IndexedProduct.Images; return(context.GetValue <string>("cultureName") switch { // Get images with null or current cultureName value if cultureName is passed string languageCode => images.Where(x => string.IsNullOrEmpty(x.LanguageCode) || x.LanguageCode.EqualsInvariant(languageCode)).ToList(), // CultureName is null _ => images });
/// <summary> /// Try to find (create if not) categories for products with Category.Path /// </summary> private void SaveCategoryTree(Catalog catalog, IEnumerable <CsvProduct> csvProducts, ExportImportProgressInfo progressInfo, Action <ExportImportProgressInfo> progressCallback) { int i = 1; var cachedCategoryMap = new Dictionary <string, Category>(); foreach (var csvProduct in csvProducts.Where(x => x.Category != null && !string.IsNullOrEmpty(x.Category.Path))) { var outline = ""; var productCategoryNames = csvProduct.Category.Path.Split(_categoryDelimiters); string parentCategoryId = null; foreach (var categoryName in productCategoryNames) { outline += "\\" + categoryName; Category category; if (!cachedCategoryMap.TryGetValue(outline, out category)) { var searchCriteria = new SearchCriteria { CatalogId = catalog.Id, CategoryId = parentCategoryId, ResponseGroup = SearchResponseGroup.WithCategories }; category = _searchService.Search(searchCriteria).Categories.FirstOrDefault(x => x.Name == categoryName); } if (category == null) { var seo = new SeoInfo(); var code = categoryName.GenerateSlug(); if (string.IsNullOrEmpty(code)) { code = Guid.NewGuid().ToString("N"); } // Adding SEO infos to categories. if (addedCategories.Any(s => s.EqualsInvariant(code))) { seo.SemanticUrl = code + i.ToString(); i++; } else { addedCategories.Add(code); seo.SemanticUrl = code; } seo.LanguageCode = csvProduct.SeoLanguage; seo.PageTitle = categoryName; seo.IsActive = true; seo.Name = code; category = _categoryService.Create(new Category() { Name = categoryName, Code = code, CatalogId = catalog.Id, ParentId = parentCategoryId, SeoInfos = new SeoInfo[] { seo } }); //Raise notification each notifyCategorySizeLimit category var count = progressInfo.ProcessedCount; progressInfo.Description = $"Creating categories: {++count} created"; progressCallback(progressInfo); } csvProduct.CategoryId = category.Id; csvProduct.Category = category; parentCategoryId = category.Id; cachedCategoryMap[outline] = category; } } }
public CategoryType(IMediator mediator, IDataLoaderContextAccessor dataLoader) { Name = "Category"; Field(x => x.Id, nullable: false).Description("Id of category."); Field(x => x.Category.ImgSrc, nullable: true).Description("The category image."); Field(x => x.Category.Code, nullable: false).Description("SKU of category."); Field(x => x.Category.Name, nullable: false).Description("Name of category."); Field(x => x.Level, nullable: true).Description(@"Level in hierarchy"); FieldAsync <StringGraphType>("outline", resolve: async context => { var outlines = context.Source.Category.Outlines; if (outlines.IsNullOrEmpty()) { return(null); } var loadRelatedCatalogOutlineQuery = context.GetCatalogQuery <LoadRelatedCatalogOutlineQuery>(); loadRelatedCatalogOutlineQuery.Outlines = outlines; var response = await mediator.Send(loadRelatedCatalogOutlineQuery); return(response.Outline); }, description: @"All parent categories ids relative to the requested catalog and concatenated with \ . E.g. (1/21/344)"); FieldAsync <StringGraphType>("slug", resolve: async context => { var outlines = context.Source.Category.Outlines; if (outlines.IsNullOrEmpty()) { return(null); } var loadRelatedSlugPathQuery = context.GetCatalogQuery <LoadRelatedSlugPathQuery>(); loadRelatedSlugPathQuery.Outlines = outlines; var response = await mediator.Send(loadRelatedSlugPathQuery); return(response.Slug); }, description: @"Request related slug for category"); Field(x => x.Category.Path, nullable: true).Description("Category path in to the requested catalog (all parent categories names concatenated. E.g. (parent1/parent2))"); Field <SeoInfoType>("seoInfo", resolve: context => { var source = context.Source; var storeId = context.GetArgumentOrValue <string>("storeId"); var cultureName = context.GetArgumentOrValue <string>("cultureName"); SeoInfo seoInfo = null; if (!source.Category.SeoInfos.IsNullOrEmpty()) { seoInfo = source.Category.SeoInfos.GetBestMatchingSeoInfo(storeId, cultureName); } return(seoInfo ?? GetFallbackSeoInfo(source, cultureName)); }, description: "Request related SEO info"); Field <ListGraphType <CategoryDescriptionType> >("descriptions", arguments: new QueryArguments(new QueryArgument <StringGraphType> { Name = "type" }), resolve: context => { var descriptions = context.Source.Category.Descriptions; var cultureName = context.GetArgumentOrValue <string>("cultureName"); var type = context.GetArgumentOrValue <string>("type"); if (cultureName != null) { descriptions = descriptions.Where(x => string.IsNullOrEmpty(x.LanguageCode) || x.LanguageCode.EqualsInvariant(cultureName)).ToList(); } if (type != null) { descriptions = descriptions.Where(x => x.DescriptionType?.EqualsInvariant(type) ?? true).ToList(); } return(descriptions); }); Field <CategoryDescriptionType>("description", arguments: new QueryArguments(new QueryArgument <StringGraphType> { Name = "type" }), resolve: context => { var descriptions = context.Source.Category.Descriptions; var type = context.GetArgumentOrValue <string>("type"); var cultureName = context.GetArgumentOrValue <string>("cultureName"); if (!descriptions.IsNullOrEmpty()) { return(descriptions.Where(x => x.DescriptionType.EqualsInvariant(type ?? "FullReview")).FirstBestMatchForLanguage(cultureName) as CategoryDescription ?? descriptions.FirstBestMatchForLanguage(cultureName) as CategoryDescription); } return(null); }); Field <CategoryType, ExpCategory>("parent").ResolveAsync(ctx => { var loader = dataLoader.Context.GetOrAddBatchLoader <string, ExpCategory>("parentsCategoryLoader", (ids) => LoadCategoriesAsync(mediator, ids, ctx)); if (TryGetCategoryParentId(ctx, out var parentCategoryId)) { return(loader.LoadAsync(parentCategoryId)); } return(null); }); Field <BooleanGraphType>("hasParent", "Have a parent", resolve: context => TryGetCategoryParentId(context, out _)); Field <ListGraphType <OutlineType> >("outlines", "Outlines", resolve: context => context.Source.Category.Outlines); Field <ListGraphType <ImageType> >("images", "Images", resolve: context => context.Source.Category.Images); Field <ListGraphType <BreadcrumbType> >("breadcrumbs", "Breadcrumbs", resolve: context => { var store = context.GetArgumentOrValue <Store>("store"); var cultureName = context.GetValue <string>("cultureName"); return(context.Source.Category.Outlines.GetBreadcrumbsFromOutLine(store, cultureName)); }); ExtendableField <ListGraphType <PropertyType> >("properties", arguments: new QueryArguments(new QueryArgument <ListGraphType <StringGraphType> > { Name = "names" }), resolve: context => { var names = context.GetArgument <string[]>("names"); var cultureName = context.GetValue <string>("cultureName"); var result = context.Source.Category.Properties.ExpandByValues(cultureName); if (!names.IsNullOrEmpty()) { result = result.Where(x => names.Contains(x.Name, StringComparer.InvariantCultureIgnoreCase)).ToList(); } return(result); }); }
public CatalogProduct Convert(ShopifyProduct shopifyProduct, ShopifyImportParams importParams, ShopifyData shopifyData, VirtoData virtoData) { var retVal = new CatalogProduct { Id = shopifyProduct.Handle + "-" + shopifyProduct.Id.ToString(), Name = shopifyProduct.Title, Code = shopifyProduct.Handle, StartDate = shopifyProduct.PublishedAt, IsActive = true, CatalogId = importParams.VirtoCatalogId, ProductType = shopifyProduct.ProductType, Vendor = shopifyProduct.Vendor }; //Images if (shopifyProduct.Image != null) { retVal.Images = new List <Image>(); retVal.Images.Add(Convert(shopifyProduct.Image, true)); } //Review if (shopifyProduct.BodyHtml != null) { retVal.Reviews = new List <EditorialReview>(); var review = new EditorialReview { Content = shopifyProduct.BodyHtml, LanguageCode = "en-US", }; retVal.Reviews.Add(review); } //Seo retVal.SeoInfos = new List <SeoInfo>(); var seoInfo = new SeoInfo { SemanticUrl = shopifyProduct.Title.GenerateSlug(), LanguageCode = "en-US" }; retVal.SeoInfos.Add(seoInfo); //TODO: Inventory //Variation if (shopifyProduct.Variants != null) { retVal.Variations = new List <CatalogProduct>(); var isFirst = true; foreach (var shopifyVariant in shopifyProduct.Variants) { var variation = isFirst ? retVal : new CatalogProduct(); variation.Name = String.Format("{0} ({1})", retVal.Name, shopifyVariant.Title); variation.Code = (shopifyProduct.Handle + "-" + shopifyVariant.Title).GenerateSlug(); variation.IsActive = true; variation.SeoInfos = new List <SeoInfo>(); seoInfo = new SeoInfo { SemanticUrl = variation.Name.GenerateSlug(), LanguageCode = "en-US" }; retVal.SeoInfos.Add(seoInfo); if (shopifyVariant.ImageId != null && shopifyProduct.Images != null) { variation.Images = new List <Image>(); var image = shopifyProduct.Images.Where(x => x.Id == shopifyVariant.ImageId).Select(x => Convert(x, true)).FirstOrDefault(); if (image != null) { variation.Images.Add(image); } } //Price variation.Prices = new List <Price>(); variation.Prices.Add(new Price { Sale = shopifyVariant.Price, List = shopifyVariant.Price, Currency = "USD" }); //Properties (need refactor) variation.PropertyValues = new List <PropertyValue>(); var orderedProperties = shopifyProduct.Options.OrderBy(option => option.Position).ToArray(); if (shopifyVariant.Option1 != null) { var propValue = new PropertyValue { PropertyName = orderedProperties[0].Name, Value = shopifyVariant.Option1, ValueType = PropertyValueType.ShortText, }; variation.PropertyValues.Add(propValue); } if (shopifyVariant.Option2 != null) { var propValue = new PropertyValue { PropertyName = orderedProperties[1].Name, Value = shopifyVariant.Option2, ValueType = PropertyValueType.ShortText }; variation.PropertyValues.Add(propValue); } if (shopifyVariant.Option3 != null) { var propValue = new PropertyValue { PropertyName = orderedProperties[2].Name, Value = shopifyVariant.Option3, ValueType = PropertyValueType.ShortText }; variation.PropertyValues.Add(propValue); } if (!isFirst) { retVal.Variations.Add(variation); } isFirst = false; } } if (importParams.ImportCollections) { var firstCollect = shopifyData.Collects.FirstOrDefault(collect => collect.ProductId == shopifyProduct.Id); if (firstCollect != null) { retVal.Category = new Category() { Code = shopifyData.Collections.First(collection => collection.Id == firstCollect.CollectionId) .Handle }; } } return(retVal); }
public CategoryType(IMediator mediator, IDataLoaderContextAccessor dataLoader) { Name = "Category"; Field(x => x.Id, nullable: false).Description("Id of category."); Field(x => x.Category.ImgSrc, nullable: true).Description("The category image."); Field(x => x.Category.Code, nullable: false).Description("SKU of category."); Field(x => x.Category.Name, nullable: false).Description("Name of category."); Field(x => x.Level, nullable: true).Description(@"Level in hierarchy"); FieldAsync <StringGraphType>("outline", resolve: async context => { var outlines = context.Source.Category.Outlines; if (outlines.IsNullOrEmpty()) { return(null); } var loadRelatedCatalogOutlineQuery = context.GetCatalogQuery <LoadRelatedCatalogOutlineQuery>(); loadRelatedCatalogOutlineQuery.Outlines = outlines; var response = await mediator.Send(loadRelatedCatalogOutlineQuery); return(response.Outline); }, description: @"All parent categories ids relative to the requested catalog and concatenated with \ . E.g. (1/21/344)"); FieldAsync <StringGraphType>("slug", resolve: async context => { var outlines = context.Source.Category.Outlines; if (outlines.IsNullOrEmpty()) { return(null); } var loadRelatedSlugPathQuery = context.GetCatalogQuery <LoadRelatedSlugPathQuery>(); loadRelatedSlugPathQuery.Outlines = outlines; var response = await mediator.Send(loadRelatedSlugPathQuery); return(response.Slug); }, description: @"Request related slug for category"); Field(x => x.Category.Path, nullable: true).Description("Category path in to the requested catalog (all parent categories names concatenated. E.g. (parent1/parent2))"); Field <SeoInfoType>("seoInfo", resolve: context => { var source = context.Source; var storeId = context.GetArgumentOrValue <string>("storeId"); var cultureName = context.GetArgumentOrValue <string>("cultureName"); SeoInfo seoInfo = null; if (!source.Category.SeoInfos.IsNullOrEmpty()) { seoInfo = source.Category.SeoInfos.GetBestMatchingSeoInfo(storeId, cultureName); } return(seoInfo ?? new SeoInfo { SemanticUrl = source.Id, LanguageCode = cultureName, Name = source.Category.Name }); }, description: "Request related SEO info"); Field <CategoryType, ExpCategory>("parent").ResolveAsync(ctx => { var loader = dataLoader.Context.GetOrAddBatchLoader <string, ExpCategory>("parentsCategoryLoader", (ids) => LoadCategoriesAsync(mediator, ids, ctx)); if (TryGetParentId(ctx, out var parentCategoryId)) { return(loader.LoadAsync(parentCategoryId)); } return(null); }); Field <BooleanGraphType>("hasParent", resolve: context => TryGetParentId(context, out _)); Field <ListGraphType <OutlineType> >("outlines", resolve: context => context.Source.Category.Outlines); Field <ListGraphType <ImageType> >("images", resolve: context => context.Source.Category.Images); }