コード例 #1
0
 public CatalogSearchQuery IsProductType(ProductType type)
 {
     return(WithFilter(SearchFilter.ByField("typeid", (int)type).Mandatory().ExactMatch().NotAnalyzed()));
 }
コード例 #2
0
 public CatalogSearchQuery AvailableOnly(bool value)
 {
     return(WithFilter(SearchFilter.ByField("available", value).Mandatory().ExactMatch().NotAnalyzed()));
 }
コード例 #3
0
 public CatalogSearchQuery VisibleIndividuallyOnly(bool value)
 {
     return(WithFilter(SearchFilter.ByField("visibleindividually", value).Mandatory().ExactMatch().NotAnalyzed()));
 }
コード例 #4
0
 public CatalogSearchQuery HomePageProductsOnly(bool value)
 {
     return(WithFilter(SearchFilter.ByField("showonhomepage", value).Mandatory().ExactMatch().NotAnalyzed()));
 }
コード例 #5
0
        protected override async Task <IEnumerable <RuleDescriptor> > LoadDescriptorsAsync()
        {
            var language   = _services.WorkContext.WorkingLanguage;
            var oneStarStr = T("Search.Facet.1StarAndMore").Value;
            var xStarsStr  = T("Search.Facet.XStarsAndMore").Value;

            var stores = _services.StoreContext.GetAllStores()
                         .Select(x => new RuleValueSelectListOption {
                Value = x.Id.ToString(), Text = x.Name
            })
                         .ToArray();

            var visibilities = ((ProductVisibility[])Enum.GetValues(typeof(ProductVisibility)))
                               .Select(x => new RuleValueSelectListOption {
                Value = ((int)x).ToString(), Text = _localizedEntityHelper.GetLocalizedEnum(x)
            })
                               .ToArray();

            var productTypes = ((ProductType[])Enum.GetValues(typeof(ProductType)))
                               .Select(x => new RuleValueSelectListOption {
                Value = ((int)x).ToString(), Text = _localizedEntityHelper.GetLocalizedEnum(x)
            })
                               .ToArray();

            var ratings = FacetUtility.GetRatings()
                          .Reverse()
                          .Skip(1)
                          .Select(x => new RuleValueSelectListOption
            {
                Value = ((double)x.Value).ToString(CultureInfo.InvariantCulture),
                Text  = (double)x.Value == 1 ? oneStarStr : xStarsStr.FormatInvariant(x.Value)
            })
                          .ToArray();

            var categoryTree = _catalogSettings.ShowProductsFromSubcategories
                ? await _categoryService.GetCategoryTreeAsync(includeHidden : true)
                : null;

            #region Special filters

            CatalogSearchQuery categoryFilter(SearchFilterContext ctx, int[] x)
            {
                if (x?.Any() ?? false)
                {
                    var ids = new HashSet <int>(x);

                    if (_catalogSettings.ShowProductsFromSubcategories)
                    {
                        foreach (var id in x)
                        {
                            var node = categoryTree.SelectNodeById(id);
                            if (node != null)
                            {
                                ids.AddRange(node.Flatten(false).Select(y => y.Id));
                            }
                        }
                    }

                    return(ctx.Query.WithCategoryIds(_catalogSettings.IncludeFeaturedProductsInNormalLists ? (bool?)null : false, ids.ToArray()));
                }

                return(ctx.Query);
            };

            CatalogSearchQuery stockQuantityFilter(SearchFilterContext ctx, int x)
            {
                if (ctx.Expression.Operator == RuleOperator.IsEqualTo || ctx.Expression.Operator == RuleOperator.IsNotEqualTo)
                {
                    return(ctx.Query.WithStockQuantity(x, x, ctx.Expression.Operator == RuleOperator.IsEqualTo, ctx.Expression.Operator == RuleOperator.IsEqualTo));
                }
                else if (ctx.Expression.Operator == RuleOperator.GreaterThanOrEqualTo || ctx.Expression.Operator == RuleOperator.GreaterThan)
                {
                    return(ctx.Query.WithStockQuantity(x, null, ctx.Expression.Operator == RuleOperator.GreaterThanOrEqualTo, null));
                }
                else if (ctx.Expression.Operator == RuleOperator.LessThanOrEqualTo || ctx.Expression.Operator == RuleOperator.LessThan)
                {
                    return(ctx.Query.WithStockQuantity(null, x, null, ctx.Expression.Operator == RuleOperator.LessThanOrEqualTo));
                }

                return(ctx.Query);
            };

            CatalogSearchQuery priceFilter(SearchFilterContext ctx, decimal x)
            {
                if (ctx.Expression.Operator == RuleOperator.IsEqualTo || ctx.Expression.Operator == RuleOperator.IsNotEqualTo)
                {
                    return(ctx.Query.PriceBetween(x, x, ctx.Expression.Operator == RuleOperator.IsEqualTo, ctx.Expression.Operator == RuleOperator.IsEqualTo));
                }
                else if (ctx.Expression.Operator == RuleOperator.GreaterThanOrEqualTo || ctx.Expression.Operator == RuleOperator.GreaterThan)
                {
                    return(ctx.Query.PriceBetween(x, null, ctx.Expression.Operator == RuleOperator.GreaterThanOrEqualTo, null));
                }
                else if (ctx.Expression.Operator == RuleOperator.LessThanOrEqualTo || ctx.Expression.Operator == RuleOperator.LessThan)
                {
                    return(ctx.Query.PriceBetween(null, x, null, ctx.Expression.Operator == RuleOperator.LessThanOrEqualTo));
                }

                return(ctx.Query);
            };

            CatalogSearchQuery createdFilter(SearchFilterContext ctx, DateTime x)
            {
                if (ctx.Expression.Operator == RuleOperator.IsEqualTo || ctx.Expression.Operator == RuleOperator.IsNotEqualTo)
                {
                    return(ctx.Query.CreatedBetween(x, x, ctx.Expression.Operator == RuleOperator.IsEqualTo, ctx.Expression.Operator == RuleOperator.IsEqualTo));
                }
                else if (ctx.Expression.Operator == RuleOperator.GreaterThanOrEqualTo || ctx.Expression.Operator == RuleOperator.GreaterThan)
                {
                    return(ctx.Query.CreatedBetween(x, null, ctx.Expression.Operator == RuleOperator.GreaterThanOrEqualTo, null));
                }
                else if (ctx.Expression.Operator == RuleOperator.LessThanOrEqualTo || ctx.Expression.Operator == RuleOperator.LessThan)
                {
                    return(ctx.Query.CreatedBetween(null, x, null, ctx.Expression.Operator == RuleOperator.LessThanOrEqualTo));
                }

                return(ctx.Query);
            };

            #endregion

            var descriptors = new List <SearchFilterDescriptor>
            {
                new SearchFilterDescriptor <int>((ctx, x) => ctx.Query.HasStoreId(x))
                {
                    Name        = "Store",
                    DisplayName = T("Admin.Rules.FilterDescriptor.Store"),
                    RuleType    = RuleType.Int,
                    SelectList  = new LocalRuleValueSelectList(stores),
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <int[]>((ctx, x) => ctx.Query.AllowedCustomerRoles(x))
                {
                    Name        = "CustomerRole",
                    DisplayName = T("Admin.Rules.FilterDescriptor.IsInCustomerRole"),
                    RuleType    = RuleType.IntArray,
                    SelectList  = new RemoteRuleValueSelectList("CustomerRole")
                    {
                        Multiple = true
                    },
                    Operators = new RuleOperator[] { RuleOperator.In }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.PublishedOnly(x))
                {
                    Name        = "Published",
                    DisplayName = T("Admin.Catalog.Products.Fields.Published"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.AvailableOnly(x))
                {
                    Name        = "AvailableByStock",
                    DisplayName = T("Products.Availability.InStock"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.AvailableByDate(x))
                {
                    Name        = "AvailableByDate",
                    DisplayName = T("Admin.Rules.FilterDescriptor.AvailableByDate"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <int>((ctx, x) => ctx.Query.WithVisibility((ProductVisibility)x))
                {
                    Name        = "Visibility",
                    DisplayName = T("Admin.Catalog.Products.Fields.Visibility"),
                    RuleType    = RuleType.Int,
                    SelectList  = new LocalRuleValueSelectList(visibilities),
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <int[]>((ctx, x) => ctx.Query.WithProductIds(x))
                {
                    Name        = "Product",
                    DisplayName = T("Common.Entity.Product"),
                    RuleType    = RuleType.IntArray,
                    SelectList  = new RemoteRuleValueSelectList("Product")
                    {
                        Multiple = true
                    },
                    Operators = new RuleOperator[] { RuleOperator.In }
                },
                new SearchFilterDescriptor <int>((ctx, x) => ctx.Query.IsProductType((ProductType)x))
                {
                    Name        = "ProductType",
                    DisplayName = T("Admin.Catalog.Products.Fields.ProductType"),
                    RuleType    = RuleType.Int,
                    SelectList  = new LocalRuleValueSelectList(productTypes),
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <int[]>(categoryFilter)
                {
                    Name        = "Category",
                    DisplayName = T("Common.Entity.Category"),
                    RuleType    = RuleType.IntArray,
                    SelectList  = new RemoteRuleValueSelectList("Category")
                    {
                        Multiple = true
                    },
                    Operators = new RuleOperator[] { RuleOperator.In }
                },
                new SearchFilterDescriptor <int[]>((ctx, x) => ctx.Query.WithManufacturerIds(null, x))
                {
                    Name        = "Manufacturer",
                    DisplayName = T("Common.Entity.Manufacturer"),
                    RuleType    = RuleType.IntArray,
                    SelectList  = new RemoteRuleValueSelectList("Manufacturer")
                    {
                        Multiple = true
                    },
                    Operators = new RuleOperator[] { RuleOperator.In }
                },
                // Same logic as the filter above product list.
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.HasAnyCategory(!x))
                {
                    Name        = "WithoutCategory",
                    DisplayName = T("Admin.Catalog.Products.List.SearchWithoutCategories"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.HasAnyManufacturer(!x))
                {
                    Name        = "WithoutManufacturer",
                    DisplayName = T("Admin.Catalog.Products.List.SearchWithoutManufacturers"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <int[]>((ctx, x) => ctx.Query.WithProductTagIds(x))
                {
                    Name        = "ProductTag",
                    DisplayName = T("Admin.Catalog.Products.Fields.ProductTags"),
                    RuleType    = RuleType.IntArray,
                    SelectList  = new RemoteRuleValueSelectList("ProductTag")
                    {
                        Multiple = true
                    },
                    Operators = new RuleOperator[] { RuleOperator.In }
                },
                new SearchFilterDescriptor <int[]>((ctx, x) => ctx.Query.WithDeliveryTimeIds(x))
                {
                    Name        = "DeliveryTime",
                    DisplayName = T("Admin.Catalog.Products.Fields.DeliveryTime"),
                    RuleType    = RuleType.IntArray,
                    Operators   = new RuleOperator[] { RuleOperator.In },
                    SelectList  = new RemoteRuleValueSelectList("DeliveryTime")
                    {
                        Multiple = true
                    }
                },
                new SearchFilterDescriptor <int>(stockQuantityFilter)
                {
                    Name        = "StockQuantity",
                    DisplayName = T("Admin.Catalog.Products.Fields.StockQuantity"),
                    RuleType    = RuleType.Int
                },
                new SearchFilterDescriptor <decimal>(priceFilter)
                {
                    Name        = "Price",
                    DisplayName = T("Admin.Catalog.Products.Fields.Price"),
                    RuleType    = RuleType.Money
                },
                new SearchFilterDescriptor <DateTime>(createdFilter)
                {
                    Name        = "CreatedOn",
                    DisplayName = T("Common.CreatedOn"),
                    RuleType    = RuleType.DateTime
                },
                new SearchFilterDescriptor <double>((ctx, x) => ctx.Query.WithRating(x, null))
                {
                    Name        = "Rating",
                    DisplayName = T("Admin.Catalog.ProductReviews.Fields.Rating"),
                    RuleType    = RuleType.Float,
                    Operators   = new RuleOperator[] { RuleOperator.GreaterThanOrEqualTo },
                    SelectList  = new LocalRuleValueSelectList(ratings)
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.HomePageProductsOnly(x))
                {
                    Name        = "HomepageProduct",
                    DisplayName = T("Admin.Catalog.Products.Fields.ShowOnHomePage"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.DownloadOnly(x))
                {
                    Name        = "Download",
                    DisplayName = T("Admin.Catalog.Products.Fields.IsDownload"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.RecurringOnly(x))
                {
                    Name        = "Recurring",
                    DisplayName = T("Admin.Catalog.Products.Fields.IsRecurring"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.ShipEnabledOnly(x))
                {
                    Name        = "ShipEnabled",
                    DisplayName = T("Admin.Catalog.Products.Fields.IsShipEnabled"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.FreeShippingOnly(x))
                {
                    Name        = "FreeShipping",
                    DisplayName = T("Admin.Catalog.Products.Fields.IsFreeShipping"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.TaxExemptOnly(x))
                {
                    Name        = "TaxExempt",
                    DisplayName = T("Admin.Catalog.Products.Fields.IsTaxExempt"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.EsdOnly(x))
                {
                    Name        = "Esd",
                    DisplayName = T("Admin.Catalog.Products.Fields.IsEsd"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                },
                new SearchFilterDescriptor <bool>((ctx, x) => ctx.Query.HasDiscount(x))
                {
                    Name        = "Discount",
                    DisplayName = T("Admin.Catalog.Products.Fields.HasDiscountsApplied"),
                    RuleType    = RuleType.Boolean,
                    Operators   = new RuleOperator[] { RuleOperator.IsEqualTo }
                }
            };

            if (_services.ApplicationContext.ModuleCatalog.GetModuleByName("SmartStore.MegaSearchPlus") != null)
            {
                ISearchFilter[] filters(string fieldName, int parentId, int[] valueIds)
                {
                    return(valueIds.Select(id => SearchFilter.ByField(fieldName, id).ExactMatch().NotAnalyzed().HasParent(parentId)).ToArray());
                }

                // Sort by display order!
                var pageIndex     = -1;
                var variantsQuery = _services.DbContext.ProductAttributes
                                    .AsNoTracking()
                                    .Where(x => x.AllowFiltering)
                                    .OrderBy(x => x.DisplayOrder);

                while (true)
                {
                    var variants = await PagedList.Create(variantsQuery, ++pageIndex, 1000).LoadAsync();

                    foreach (var variant in variants)
                    {
                        var descriptor = new SearchFilterDescriptor <int[]>((ctx, x) => ctx.Query.WithFilter(SearchFilter.Combined(filters("variantvalueid", variant.Id, x))))
                        {
                            Name        = $"Variant{variant.Id}",
                            DisplayName = variant.GetLocalized(x => x.Name, language, true, false),
                            GroupKey    = "Admin.Catalog.Attributes.ProductAttributes",
                            RuleType    = RuleType.IntArray,
                            SelectList  = new RemoteRuleValueSelectList("VariantValue")
                            {
                                Multiple = true
                            },
                            Operators = new RuleOperator[] { RuleOperator.In }
                        };
                        descriptor.Metadata["ParentId"] = variant.Id;

                        descriptors.Add(descriptor);
                    }
                    if (!variants.HasNextPage)
                    {
                        break;
                    }
                }

                pageIndex = -1;
                var attributesQuery = _services.DbContext.SpecificationAttributes
                                      .AsNoTracking()
                                      .Where(x => x.AllowFiltering)
                                      .OrderBy(x => x.DisplayOrder);

                while (true)
                {
                    var attributes = await PagedList.Create(attributesQuery, ++pageIndex, 1000).LoadAsync();

                    foreach (var attribute in attributes)
                    {
                        var descriptor = new SearchFilterDescriptor <int[]>((ctx, x) => ctx.Query.WithFilter(SearchFilter.Combined(filters("attrvalueid", attribute.Id, x))))
                        {
                            Name        = $"Attribute{attribute.Id}",
                            DisplayName = attribute.GetLocalized(x => x.Name, language, true, false),
                            GroupKey    = "Admin.Catalog.Attributes.SpecificationAttributes",
                            RuleType    = RuleType.IntArray,
                            SelectList  = new RemoteRuleValueSelectList("AttributeOption")
                            {
                                Multiple = true
                            },
                            Operators = new RuleOperator[] { RuleOperator.In }
                        };
                        descriptor.Metadata["ParentId"] = attribute.Id;

                        descriptors.Add(descriptor);
                    }
                    if (!attributes.HasNextPage)
                    {
                        break;
                    }
                }
            }

            descriptors
            .Where(x => x.RuleType == RuleType.Money)
            .Each(x => x.Metadata["postfix"] = _services.StoreContext.CurrentStore.PrimaryStoreCurrency.CurrencyCode);

            return(descriptors.Cast <RuleDescriptor>());
        }
コード例 #6
0
 public CatalogSearchQuery PublishedOnly(bool value)
 {
     return(WithFilter(SearchFilter.ByField("published", value).Mandatory().ExactMatch().NotAnalyzed()));
 }
コード例 #7
0
 public CatalogSearchQuery HasDiscount(bool value)
 {
     return(WithFilter(SearchFilter.ByField("discount", value).Mandatory().ExactMatch().NotAnalyzed()));
 }
コード例 #8
0
 public CatalogSearchQuery TaxExemptOnly(bool value)
 {
     return(WithFilter(SearchFilter.ByField("taxexempt", value).Mandatory().ExactMatch().NotAnalyzed()));
 }
コード例 #9
0
 public CatalogSearchQuery FreeShippingOnly(bool value)
 {
     return(WithFilter(SearchFilter.ByField("shipfree", value).Mandatory().ExactMatch().NotAnalyzed()));
 }
コード例 #10
0
 public CatalogSearchQuery RecurringOnly(bool value)
 {
     return(WithFilter(SearchFilter.ByField("recurring", value).Mandatory().ExactMatch().NotAnalyzed()));
 }
コード例 #11
0
 public CatalogSearchQuery WithVisibility(ProductVisibility value)
 {
     return(WithFilter(SearchFilter.ByField("visibility", (int)value).Mandatory().ExactMatch().NotAnalyzed()));
 }