Exemplo n.º 1
0
        public GenericSearchResult <ListEntryBase> Search(CatalogListEntrySearchCriteria criteria)
        {
            var result = new GenericSearchResult <ListEntryBase>();

            using (var repository = _catalogRepositoryFactory())
            {
                //Optimize performance and CPU usage
                repository.DisableChangesTracking();

                var query = repository.Categories.Where(cat => cat.CatalogId == criteria.CatalogId && cat.ParentCategoryId == criteria.CategoryId).Select(cat => new { cat.Id, cat.Name, cat.Code })
                            .Union(repository.Items.Where(item => item.CatalogId == criteria.CatalogId && item.CategoryId == criteria.CategoryId).Select(item => new { item.Id, item.Name, item.Code }));

                var sortInfos = criteria.SortInfos;
                if (sortInfos.IsNullOrEmpty())
                {
                    sortInfos = new[] { new SortInfo {
                                            SortColumn = "Name"
                                        } };
                }
                query             = query.OrderBySortInfos(sortInfos);
                result.TotalCount = query.Count();
                var ids = query.Skip(criteria.Skip).Take(criteria.Take).Select(x => x.Id).ToList();
                var productsListEntries   = _itemService.GetByIds(ids, (ItemResponseGroup.ItemInfo | ItemResponseGroup.ItemAssets | ItemResponseGroup.Outlines).ToString()).Select(x => AbstractTypeFactory <ProductListEntry> .TryCreateInstance().FromModel(x));
                var categoriesListEntries = _categoryService.GetByIds(ids, (CategoryResponseGroup.Info | CategoryResponseGroup.WithImages | CategoryResponseGroup.WithOutlines).ToString()).Select(x => AbstractTypeFactory <CategoryListEntry> .TryCreateInstance().FromModel(x));;
                result.Results = productsListEntries.Concat(categoriesListEntries).OrderBy(x => ids.IndexOf(x.Id)).ToList();
            }
            return(result);
        }
Exemplo n.º 2
0
        public ActionResult ListItemsSearch([FromBody] CatalogListEntrySearchCriteria criteria)
        {
            //TODO:
            //ApplyRestrictionsForCurrentUser(coreModelCriteria);
            var result = _listEntrySearchService.Search(criteria);

            return(Ok(result));
        }
Exemplo n.º 3
0
        public async Task <ListEntrySearchResult> SearchAsync(CatalogListEntrySearchCriteria criteria)
        {
            if (criteria == null)
            {
                throw new ArgumentNullException(nameof(criteria));
            }

            criteria = criteria.Clone() as CatalogListEntrySearchCriteria;
            criteria.Normalize();
            var result = AbstractTypeFactory <ListEntrySearchResult> .TryCreateInstance();

            //Need search in children categories if user specify keyword
            if (!string.IsNullOrEmpty(criteria.Keyword))
            {
                criteria.SearchInChildren   = true;
                criteria.SearchInVariations = true;
            }

            var categorySkip = 0;
            var categoryTake = 0;

            //Because products and categories represent in search result as two separated collections for handle paging request
            //we should join two resulting collection artificially
            //search categories
            if (criteria.ObjectTypes.IsNullOrEmpty() || criteria.ObjectTypes.Contains(nameof(Category)))
            {
                var categoriesSearchResult = await SearchCategoriesAsync(criteria);

                var categoriesTotalCount = categoriesSearchResult.TotalCount;

                categorySkip = Math.Min(categoriesTotalCount, criteria.Skip);
                categoryTake = Math.Min(criteria.Take, Math.Max(0, categoriesTotalCount - criteria.Skip));
                var categoryListEntries = categoriesSearchResult.Results.Select(x => AbstractTypeFactory <CategoryListEntry> .TryCreateInstance().FromModel(x)).ToList();

                result.TotalCount = categoriesTotalCount;
                result.ListEntries.AddRange(categoryListEntries);
            }
            if (criteria.ObjectTypes.IsNullOrEmpty() || criteria.ObjectTypes.Contains(nameof(CatalogProduct)))
            {
                criteria.Skip -= categorySkip;
                criteria.Take -= categoryTake;
                var productsSearchResult = await SearchItemsAsync(criteria);

                var productListEntries = productsSearchResult.Results.Select(x => AbstractTypeFactory <ProductListEntry> .TryCreateInstance().FromModel(x)).ToList();

                result.TotalCount += productsSearchResult.TotalCount;
                result.ListEntries.AddRange(productListEntries);
            }

            return(result);
        }
Exemplo n.º 4
0
        protected virtual IList <SortInfo> BuildSortExpression(CatalogListEntrySearchCriteria criteria)
        {
            var sortInfos = criteria.SortInfos;

            if (sortInfos.IsNullOrEmpty())
            {
                sortInfos = new[]
                {
                    new SortInfo {
                        SortColumn = nameof(ItemEntity.Priority), SortDirection = SortDirection.Descending
                    },
                    new SortInfo {
                        SortColumn = nameof(CategoryEntity.Name)
                    }
                };
            }
            return(sortInfos);
        }
Exemplo n.º 5
0
        private async Task <ListEntrySearchResult> InnerListItemsSearchAsync(CatalogListEntrySearchCriteria criteria)
        {
            var result           = new ListEntrySearchResult();
            var useIndexedSearch = _settingsManager.GetValue(ModuleConstants.Settings.Search.UseCatalogIndexedSearchInManager.Name, true);

            if (useIndexedSearch && !string.IsNullOrEmpty(criteria.Keyword))
            {
                // TODO: create outline for category
                // TODO: implement sorting

                var categoryIndexedSearchCriteria = AbstractTypeFactory <CategoryIndexedSearchCriteria> .TryCreateInstance().FromListEntryCriteria(criteria) as CategoryIndexedSearchCriteria;

                const CategoryResponseGroup catResponseGroup = CategoryResponseGroup.Info | CategoryResponseGroup.WithOutlines;
                categoryIndexedSearchCriteria.ResponseGroup = catResponseGroup.ToString();

                var catIndexedSearchResult = await _categoryIndexedSearchService.SearchAsync(categoryIndexedSearchCriteria);

                var totalCount = catIndexedSearchResult.TotalCount;
                var skip       = Math.Min(totalCount, criteria.Skip);
                var take       = Math.Min(criteria.Take, Math.Max(0, totalCount - criteria.Skip));

                result.Results = catIndexedSearchResult.Items.Select(x => AbstractTypeFactory <CategoryListEntry> .TryCreateInstance().FromModel(x)).ToList();

                criteria.Skip -= (int)skip;
                criteria.Take -= (int)take;

                const ItemResponseGroup itemResponseGroup = ItemResponseGroup.ItemInfo | ItemResponseGroup.Outlines;

                var productIndexedSearchCriteria = AbstractTypeFactory <ProductIndexedSearchCriteria> .TryCreateInstance().FromListEntryCriteria(criteria) as ProductIndexedSearchCriteria;

                productIndexedSearchCriteria.ResponseGroup = itemResponseGroup.ToString();

                var indexedSearchResult = await _productIndexedSearchService.SearchAsync(productIndexedSearchCriteria);

                result.TotalCount += (int)indexedSearchResult.TotalCount;
                result.Results.AddRange(indexedSearchResult.Items.Select(x => AbstractTypeFactory <ProductListEntry> .TryCreateInstance().FromModel(x)));
            }
            else
            {
                result = await _listEntrySearchService.SearchAsync(criteria);
            }

            return(result);
        }
Exemplo n.º 6
0
        public async Task <ActionResult> Delete([FromBody] CatalogListEntrySearchCriteria criteria)
        {
            const int deleteBatchSize     = 20;
            var       authorizationResult = await _authorizationService.AuthorizeAsync(User, criteria, new CatalogAuthorizationRequirement(ModuleConstants.Security.Permissions.Delete));

            if (!authorizationResult.Succeeded)
            {
                return(Unauthorized());
            }

            var idsToDelete = criteria.ObjectIds?.ToList() ?? new List <string>();

            if (idsToDelete.IsNullOrEmpty())
            {
                var listEntries = await InnerListItemsSearchAsync(criteria);

                idsToDelete = listEntries.ListEntries
                              .Where(x => x.Type.EqualsInvariant(ProductListEntry.TypeName) || x.Type.EqualsInvariant(CategoryListEntry.TypeName))
                              .Select(x => x.Id)
                              .ToList();
            }

            for (var i = 0; i < idsToDelete.Count; i += deleteBatchSize)
            {
                var commonIds = idsToDelete.Skip(i).Take(deleteBatchSize).ToArray();

                var searchProductResult = await _itemService.GetByIdsAsync(commonIds, ItemResponseGroup.None.ToString());

                await _itemService.DeleteAsync(searchProductResult.Select(x => x.Id).ToArray());

                var searchCategoryResult = await _categoryService.GetByIdsAsync(commonIds, CategoryResponseGroup.None.ToString());

                await _categoryService.DeleteAsync(searchCategoryResult.Select(x => x.Id).ToArray());
            }

            return(StatusCode(StatusCodes.Status204NoContent));
        }
Exemplo n.º 7
0
        protected virtual async Task <GenericSearchResult <Category> > SearchCategoriesAsync(CatalogListEntrySearchCriteria criteria)
        {
            var result = new GenericSearchResult <Category>();

            using (var repository = _catalogRepositoryFactory())
            {
                //Optimize performance and CPU usage
                repository.DisableChangesTracking();

                var query = repository.Categories.Where(x => criteria.WithHidden || x.IsActive);

                //Get list of search in categories
                var searchCategoryIds = criteria.CategoryIds;

                if (!searchCategoryIds.IsNullOrEmpty())
                {
                    if (criteria.SearchInChildren)
                    {
                        searchCategoryIds = searchCategoryIds.Concat(await repository.GetAllChildrenCategoriesIdsAsync(searchCategoryIds)).ToArray();
                        //linked categories
                        var allLinkedCategories = repository.CategoryLinks.Where(x => searchCategoryIds.Contains(x.TargetCategoryId)).Select(x => x.SourceCategoryId).ToArray();
                        searchCategoryIds = searchCategoryIds.Concat(allLinkedCategories).Distinct().ToArray();
                    }

                    if (criteria.HideDirectLinkedCategories)
                    {
                        query = query.Where(x => searchCategoryIds.Contains(x.ParentCategoryId) || x.OutgoingLinks.Any(y => searchCategoryIds.Contains(y.TargetCategory.ParentCategoryId)));
                    }
                    else
                    {
                        query = query.Where(x => searchCategoryIds.Contains(x.ParentCategoryId) || x.OutgoingLinks.Any(y => searchCategoryIds.Contains(y.TargetCategoryId)));
                    }
                }
                else if (!criteria.CatalogIds.IsNullOrEmpty())
                {
                    if (criteria.SearchInChildren)
                    {
                        //need search in all catalog linked and children categories
                        //First need load all categories belong to searched catalogs
                        searchCategoryIds = repository.Categories.Where(x => criteria.CatalogIds.Contains(x.CatalogId)).Select(x => x.Id).ToArray();
                        //Then load all physical categories linked to catalog
                        var allCatalogLinkedCategories = repository.CategoryLinks.Where(x => criteria.CatalogIds.Contains(x.TargetCatalogId)).Select(x => x.SourceCategoryId).ToArray();
                        searchCategoryIds = searchCategoryIds.Concat(allCatalogLinkedCategories).Distinct().ToArray();
                        //Then expand all categories, get all children's
                        searchCategoryIds = searchCategoryIds.Concat(await repository.GetAllChildrenCategoriesIdsAsync(searchCategoryIds)).ToArray();
                        if (!searchCategoryIds.IsNullOrEmpty())
                        {
                            //find all categories belong searched catalogs and all categories direct or implicitly linked to catalogs
                            query = query.Where(x => searchCategoryIds.Contains(x.Id));
                        }
                    }
                    else
                    {
                        query = query.Where(x => (criteria.CatalogIds.Contains(x.CatalogId) && x.ParentCategoryId == null) || (x.OutgoingLinks.Any(y => y.TargetCategoryId == null && criteria.CatalogIds.Contains(y.TargetCatalogId))));
                    }
                }

                if (!string.IsNullOrEmpty(criteria.Keyword))
                {
                    query = query.Where(x => x.Name.Contains(criteria.Keyword) || x.Code.Contains(criteria.Keyword));
                }
                else if (!string.IsNullOrEmpty(criteria.Code))
                {
                    query = query.Where(x => x.Code == criteria.Code);
                }
                //Extension point
                query = BuildQuery(query, criteria);
                var sortInfos = BuildSortExpression(criteria);
                //Try to replace sorting columns names
                TryTransformSortingInfoColumnNames(_categorySortingAliases, sortInfos);

                result.TotalCount = await query.CountAsync();

                if (criteria.Take > 0 && result.TotalCount > 0)
                {
                    query = query.OrderBySortInfos(sortInfos).ThenBy(x => x.Id);

                    var categoryIds            = query.Select(x => x.Id).AsNoTracking().ToList();
                    var essentialResponseGroup = CategoryResponseGroup.Info | CategoryResponseGroup.WithImages | CategoryResponseGroup.WithSeo | CategoryResponseGroup.WithLinks | CategoryResponseGroup.WithParents | CategoryResponseGroup.WithProperties | CategoryResponseGroup.WithOutlines;
                    var respGroup = string.Concat(criteria.ResponseGroup, ",", essentialResponseGroup.ToString());
                    result.Results = (await _categoryService.GetByIdsAsync(categoryIds.ToArray(), respGroup, criteria.CatalogId)).OrderBy(x => categoryIds.IndexOf(x.Id)).ToList();
                }
            }

            return(result);
        }
Exemplo n.º 8
0
        protected virtual IQueryable <ItemEntity> BuildQuery(IQueryable <ItemEntity> query, CatalogListEntrySearchCriteria criteria, string[] searchCategoryIds)
        {
            query = query.Where(x => criteria.WithHidden || x.IsActive);

            if (!string.IsNullOrEmpty(criteria.MainProductId))
            {
                query = query.Where(x => x.ParentId == criteria.MainProductId);
            }
            else if (!criteria.SearchInVariations)
            {
                query = query.Where(x => x.ParentId == null);
            }

            if (!searchCategoryIds.IsNullOrEmpty())
            {
                query = query.Where(x => searchCategoryIds.Contains(x.CategoryId) || x.CategoryLinks.Any(link => searchCategoryIds.Contains(link.CategoryId)));
            }
            else if (!criteria.CatalogIds.IsNullOrEmpty())
            {
                query = query.Where(x => criteria.CatalogIds.Contains(x.CatalogId) && (criteria.SearchInChildren || x.CategoryId == null) ||
                                    x.CategoryLinks.Any(link => criteria.CatalogIds.Contains(link.CatalogId) && (criteria.SearchInChildren || link.CategoryId == null)));
            }

            if (!string.IsNullOrEmpty(criteria.Code))
            {
                query = query.Where(x => x.Code == criteria.Code);
            }
            else if (!string.IsNullOrEmpty(criteria.Keyword))
            {
                query = query.Where(x => x.Name.Contains(criteria.Keyword) || x.Code.Contains(criteria.Keyword) || x.ItemPropertyValues.Any(y => y.ShortTextValue == criteria.Keyword));
            }

            if (!criteria.VendorIds.IsNullOrEmpty())
            {
                query = query.Where(x => criteria.VendorIds.Contains(x.Vendor));
            }

            if (!criteria.ProductTypes.IsNullOrEmpty())
            {
                query = query.Where(x => criteria.ProductTypes.Contains(x.ProductType));
            }

            if (criteria.OnlyBuyable != null)
            {
                query = query.Where(x => x.IsBuyable == criteria.OnlyBuyable);
            }

            if (criteria.OnlyWithTrackingInventory != null)
            {
                query = query.Where(x => x.TrackInventory == criteria.OnlyWithTrackingInventory);
            }

            return(query);
        }
Exemplo n.º 9
0
 protected virtual IQueryable <CategoryEntity> BuildQuery(IQueryable <CategoryEntity> query, CatalogListEntrySearchCriteria criteria)
 {
     return(query);
 }
Exemplo n.º 10
0
        protected virtual async Task <GenericSearchResult <CatalogProduct> > SearchItemsAsync(CatalogListEntrySearchCriteria criteria)
        {
            var result = new GenericSearchResult <CatalogProduct>();

            using (var repository = _catalogRepositoryFactory())
            {
                //Optimize performance and CPU usage
                repository.DisableChangesTracking();

                //list of search categories
                var searchCategoryIds = criteria.CategoryIds;
                if (criteria.SearchInChildren)
                {
                    if (!searchCategoryIds.IsNullOrEmpty())
                    {
                        searchCategoryIds = searchCategoryIds.Concat(await repository.GetAllChildrenCategoriesIdsAsync(searchCategoryIds)).ToArray();
                        //linked categories
                        var allLinkedCategories = repository.CategoryLinks.Where(x => searchCategoryIds.Contains(x.TargetCategoryId)).Select(x => x.SourceCategoryId).ToArray();
                        searchCategoryIds = searchCategoryIds.Concat(allLinkedCategories).Distinct().ToArray();
                    }
                    else if (!criteria.CatalogIds.IsNullOrEmpty())
                    {
                        //If category not specified need search in all linked and children categories
                        searchCategoryIds = repository.Categories.Where(x => criteria.CatalogIds.Contains(x.CatalogId)).Select(x => x.Id).ToArray();
                        var allCatalogLinkedCategories = repository.CategoryLinks.Where(x => criteria.CatalogIds.Contains(x.TargetCatalogId)).Select(x => x.SourceCategoryId).ToArray();
                        searchCategoryIds = searchCategoryIds.Concat(allCatalogLinkedCategories).Distinct().ToArray();
                    }
                }

                // Build the query based on the search criteria
                var query     = BuildQuery(repository.Items, criteria, searchCategoryIds);
                var sortInfos = BuildSortExpression(criteria);
                //Try to replace sorting columns names
                TryTransformSortingInfoColumnNames(_productSortingAliases, sortInfos.ToArray());

                result.TotalCount = await query.CountAsync();

                if (criteria.Take > 0 && result.TotalCount > 0)
                {
                    query = query.OrderBySortInfos(sortInfos).ThenBy(x => x.Id);

                    var itemIds = query.Skip(criteria.Skip)
                                  .Take(criteria.Take)
                                  .Select(x => x.Id)
                                  .AsNoTracking()
                                  .ToList();

                    var essentialResponseGroup = ItemResponseGroup.ItemInfo | ItemResponseGroup.ItemAssets | ItemResponseGroup.Links | ItemResponseGroup.Seo | ItemResponseGroup.Outlines;
                    var responseGroup          = string.Concat(criteria.ResponseGroup, ",", essentialResponseGroup.ToString());
                    result.Results = (await _itemService.GetByIdsAsync(itemIds.ToArray(), responseGroup, criteria.CatalogId)).OrderBy(x => itemIds.IndexOf(x.Id)).ToList();
                }
            }

            return(result);
        }
Exemplo n.º 11
0
        public async Task <ActionResult <ListEntrySearchResult> > ListItemsSearchAsync([FromBody] CatalogListEntrySearchCriteria criteria)
        {
            var authorizationResult = await _authorizationService.AuthorizeAsync(User, criteria, new CatalogAuthorizationRequirement(ModuleConstants.Security.Permissions.Read));

            if (!authorizationResult.Succeeded)
            {
                return(Unauthorized());
            }

            var result = await InnerListItemsSearchAsync(criteria);

            return(Ok(result));
        }
Exemplo n.º 12
0
        public async Task <ActionResult <ListEntrySearchResult> > ListItemsSearchAsync([FromBody] CatalogListEntrySearchCriteria criteria)
        {
            //TODO:
            //ApplyRestrictionsForCurrentUser(coreModelCriteria);
            var result           = new ListEntrySearchResult();
            var useIndexedSearch = _settingsManager.GetValue(ModuleConstants.Settings.Search.UseCatalogIndexedSearchInManager.Name, true);

            if (useIndexedSearch && !string.IsNullOrEmpty(criteria.Keyword))
            {
                // TODO: create outline for category
                // TODO: implement sorting

                const ItemResponseGroup responseGroup = ItemResponseGroup.ItemInfo | ItemResponseGroup.Outlines;

                var productIndexedSearchCriteria = AbstractTypeFactory <ProductIndexedSearchCriteria> .TryCreateInstance();

                productIndexedSearchCriteria.ObjectType    = KnownDocumentTypes.Product;
                productIndexedSearchCriteria.Keyword       = criteria.Keyword;
                productIndexedSearchCriteria.CatalogId     = criteria.CatalogId;
                productIndexedSearchCriteria.Outline       = criteria.CategoryId;
                productIndexedSearchCriteria.WithHidden    = !criteria.HideDirectLinkedCategories;
                productIndexedSearchCriteria.Skip          = criteria.Skip;
                productIndexedSearchCriteria.Take          = criteria.Take;
                productIndexedSearchCriteria.ResponseGroup = responseGroup.ToString();
                productIndexedSearchCriteria.Sort          = criteria.Sort;

                var indexedSearchResult = await _productIndexedSearchService.SearchAsync(productIndexedSearchCriteria);

                result.TotalCount = (int)indexedSearchResult.TotalCount;
                result.Results    = indexedSearchResult.Items.Select(x => AbstractTypeFactory <ProductListEntry> .TryCreateInstance().FromModel(x)).ToList();
            }
            else
            {
                result = await _listEntrySearchService.SearchAsync(criteria);
            }
            return(Ok(result));
        }