public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.Product)
            {
                if (context.Reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    var products = await _db.Products.GetManyAsync(context.Value.ToIntArray());

                    result.AddOptions(context, products.Select(x => new RuleValueSelectListOption
                    {
                        Value = x.Id.ToString(),
                        Text  = x.GetLocalized(y => y.Name, context.Language, true, false),
                        Hint  = x.Sku
                    }));
                }
                else
                {
                    var options = await SearchProducts(result, context.SearchTerm, context.PageIndex *context.PageSize, context.PageSize);

                    result.AddOptions(context, options);
                    result.IsPaged = true;
                }
            }
            else
            {
                return(null);
            }

            return(result);
        }
Esempio n. 2
0
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.VariantValue)
            {
                if (context.Reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    var variants = await _db.ProductVariantAttributeValues.GetManyAsync(context.Value.ToIntArray());

                    result.AddOptions(context, variants.Select(x => new RuleValueSelectListOption
                    {
                        Value = x.Id.ToString(),
                        Text  = x.GetLocalized(y => y.Name, context.Language, true, false)
                    }));
                }
                else if (context.Descriptor.Metadata.TryGetValue("ParentId", out var objParentId))
                {
                    var pIndex         = -1;
                    var existingValues = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase);
                    var options        = new List <RuleValueSelectListOption>();

                    var query = _db.ProductVariantAttributeValues
                                .AsNoTracking()
                                .Where(x => x.ProductVariantAttribute.ProductAttributeId == (int)objParentId &&
                                       x.ProductVariantAttribute.ProductAttribute.AllowFiltering &&
                                       x.ValueTypeId == (int)ProductVariantAttributeValueType.Simple)
                                .ApplyValueFilter(null, true);

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

                        foreach (var variant in variants)
                        {
                            var name = variant.GetLocalized(x => x.Name, context.Language, true, false);
                            if (!existingValues.Contains(name))
                            {
                                existingValues.Add(name);
                                options.Add(new RuleValueSelectListOption {
                                    Value = variant.Id.ToString(), Text = name
                                });
                            }
                        }
                        if (!variants.HasNextPage)
                        {
                            break;
                        }
                    }

                    result.AddOptions(context, options);
                }
            }
            else
            {
                return(null);
            }

            return(result);
        }
Esempio n. 3
0
        public Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.PaymentMethod)
            {
                // TODO: (mg) (core) Complete IPaymentMethodRuleOptionsProvider (IPaymentMethod required).
                //var options = await _providerManager.Value.GetAllProviders<IPaymentMethod>()
                //    .Select(x => x.Metadata)
                //    .SelectAsync(async x => new RuleValueSelectListOption
                //    {
                //        Value = x.SystemName,
                //        Text = await GetLocalized(x, "FriendlyName") ?? x.FriendlyName.NullEmpty() ?? x.SystemName,
                //        Hint = x.SystemName
                //    })
                //    .ToListAsync();
                //result.AddOptions(context, options.OrderBy(x => x.Text).ToList();
            }
            else
            {
                return(null);
            }

            return(Task.FromResult(result));
        }
Esempio n. 4
0
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.ShippingRateComputationMethod)
            {
                var options = await _providerManager.GetAllProviders <IShippingRateComputationMethod>()
                              .Select(x => x.Metadata)
                              .SelectAsync(async x => new RuleValueSelectListOption
                {
                    Value = x.SystemName,
                    Text  = await GetLocalized(context, x, "FriendlyName") ?? x.FriendlyName.NullEmpty() ?? x.SystemName,
                    Hint  = x.SystemName
                })
                              .ToListAsync();

                result.AddOptions(context, options.OrderBy(x => x.Text));
            }
            else
            {
                return(null);
            }

            return(result);
        }
        protected virtual List <RuleValueSelectListOption> SearchProducts(RuleOptionsResult result, string term, int skip, int take)
        {
            List <RuleValueSelectListOption> products;
            var fields = new List <string> {
                "name"
            };

            if (_searchSettings.Value.SearchFields.Contains("sku"))
            {
                fields.Add("sku");
            }
            if (_searchSettings.Value.SearchFields.Contains("shortdescription"))
            {
                fields.Add("shortdescription");
            }

            var searchQuery = new CatalogSearchQuery(fields.ToArray(), term);

            if (_searchSettings.Value.UseCatalogSearchInBackend)
            {
                searchQuery = searchQuery
                              .Slice(skip, take)
                              .SortBy(ProductSortingEnum.NameAsc);

                var searchResult = _catalogSearchService.Value.Search(searchQuery);
                result.HasMoreData = searchResult.Hits.HasNextPage;

                products = searchResult.Hits
                           .Select(x => new RuleValueSelectListOption
                {
                    Value = x.Id.ToString(),
                    Text  = x.Name,
                    Hint  = x.Sku
                })
                           .ToList();
            }
            else
            {
                var query = _catalogSearchService.Value.PrepareQuery(searchQuery);

                var pageIndex = take == 0 ? 0 : Math.Max(skip / take, 0);
                result.HasMoreData = (pageIndex + 1) * take < query.Count();

                products = query
                           .Select(x => new RuleValueSelectListOption
                {
                    Value = x.Id.ToString(),
                    Text  = x.Name,
                    Hint  = x.Sku
                })
                           .OrderBy(x => x.Text)
                           .Skip(() => skip)
                           .Take(() => take)
                           .ToList();
            }

            return(products);
        }
        // Ajax.
        public ActionResult RuleOptions(
            RuleOptionsRequestReason reason,
            int ruleId,
            int rootRuleSetId,
            string term,
            int? page)
        {
            var rule = _ruleStorage.GetRuleById(ruleId, false);
            if (rule == null)
            {
                throw new SmartException(T("Admin.Rules.NotFound", ruleId));
            }

            var provider = _ruleProvider(rule.RuleSet.Scope);
            var expression = provider.VisitRule(rule);

            RuleOptionsResult options = null;
            Func<RuleValueSelectListOption, bool> optionsPredicate = x => true;

            if (expression.Descriptor.SelectList is RemoteRuleValueSelectList list)
            {
                var optionsProvider = _ruleOptionsProviders.FirstOrDefault(x => x.Matches(list.DataSource));
                if (optionsProvider != null)
                {
                    options = optionsProvider.GetOptions(reason, expression, page ?? 0, 100, term);
                    if (list.DataSource == "CartRule" || list.DataSource == "TargetGroup")
                    {
                        optionsPredicate = x => x.Value != rootRuleSetId.ToString();
                    }
                }
            }

            if (options == null)
            {
                options = new RuleOptionsResult();
            }

            var data = options.Options
                .Where(optionsPredicate)
                .Select(x => new RuleSelectItem { Id = x.Value, Text = x.Text, Hint = x.Hint })
                .ToList();

            // Mark selected items.
            var selectedValues = expression.RawValue.SplitSafe(",");

            data.Each(x => x.Selected = selectedValues.Contains(x.Id));

            return new JsonResult
            {
                Data = new
                {
                    hasMoreData = options.HasMoreData,
                    results = data
                },
                MaxJsonLength = int.MaxValue,
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            switch (context.DataSource)
            {
            case KnownRuleOptionDataSourceNames.Country:
                var countries = await _db.Countries
                                .AsNoTracking()
                                .ApplyStandardFilter(true)
                                .ToListAsync();

                result.AddOptions(context, countries.Select(x => new RuleValueSelectListOption
                {
                    Value = context.OptionById ? x.Id.ToString() : x.TwoLetterIsoCode,
                    Text  = x.GetLocalized(y => y.Name, context.Language, true, false)
                }));
                break;

            case KnownRuleOptionDataSourceNames.Currency:
                var currencies = await _db.Currencies
                                 .AsNoTracking()
                                 .ApplyStandardFilter(true)
                                 .ToListAsync();

                result.AddOptions(context, currencies.Select(x => new RuleValueSelectListOption
                {
                    Value = context.OptionById ? x.Id.ToString() : x.CurrencyCode,
                    Text  = x.GetLocalized(y => y.Name, context.Language, true, false)
                }));
                break;

            case KnownRuleOptionDataSourceNames.DeliveryTime:
                var deliveryTimes = await _db.DeliveryTimes
                                    .AsNoTracking()
                                    .OrderBy(x => x.DisplayOrder)
                                    .ToListAsync();

                result.AddOptions(context, deliveryTimes.Select(x => new RuleValueSelectListOption
                {
                    Value = x.Id.ToString(),
                    Text  = x.GetLocalized(y => y.Name, context.Language, true, false)
                }));
                break;

            default:
                return(null);
            }

            return(result);
        }
Esempio n. 8
0
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.Category)
            {
                if (context.Reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    var categories = await _db.Categories.GetManyAsync(context.Value.ToIntArray());

                    var options = await categories
                                  .SelectAsync(async x => new RuleValueSelectListOption
                    {
                        Value = x.Id.ToString(),
                        Text  = (await _categoryService.GetCategoryPathAsync(x, context.Language.Id)).NullEmpty() ?? x.Name
                    })
                                  .ToListAsync();

                    result.AddOptions(context, options);
                }
                else
                {
                    var categories = await _categoryService.GetCategoryTreeAsync(0, true);

                    var options = await categories
                                  .Flatten(false)
                                  .SelectAsync(async x => new RuleValueSelectListOption
                    {
                        Value = x.Id.ToString(),
                        Text  = (await _categoryService.GetCategoryPathAsync(x, context.Language.Id)).NullEmpty() ?? x.Name
                    })
                                  .ToListAsync();

                    result.AddOptions(context, options);
                }
            }
            else
            {
                return(null);
            }

            return(result);
        }
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.AttributeOption)
            {
                if (context.Reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    var attributes = await _db.SpecificationAttributeOptions.GetManyAsync(context.Value.ToIntArray());

                    result.AddOptions(context, attributes.Select(x => new RuleValueSelectListOption
                    {
                        Value = x.Id.ToString(),
                        Text  = x.GetLocalized(y => y.Name, context.Language, true, false)
                    }));
                }
                else if (context.Descriptor.Metadata.TryGetValue("ParentId", out var objParentId))
                {
                    var attributes = await _db.SpecificationAttributeOptions
                                     .AsNoTracking()
                                     .Where(x => x.SpecificationAttributeId == (int)objParentId)
                                     .OrderBy(x => x.DisplayOrder)
                                     .ToPagedList(context.PageIndex, context.PageSize)
                                     .LoadAsync();

                    result.IsPaged     = true;
                    result.HasMoreData = attributes.HasNextPage;

                    result.AddOptions(context, attributes.AsQueryable().Select(x => new RuleValueSelectListOption
                    {
                        Value = x.Id.ToString(),
                        Text  = x.GetLocalized(y => y.Name, context.Language, true, false, false)
                    }));
                }
            }
            else
            {
                return(null);
            }

            return(result);
        }
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.CartRule || context.DataSource == KnownRuleOptionDataSourceNames.TargetGroup)
            {
                if (context.Reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    var ruleSets = await _db.RuleSets.GetManyAsync(context.Value.ToIntArray());

                    result.AddOptions(context, ruleSets.Select(x => new RuleValueSelectListOption
                    {
                        Value = x.Id.ToString(),
                        Text  = x.Name
                    }));
                }
                else
                {
                    var ruleSets = await _db.RuleSets
                                   .AsNoTracking()
                                   .ApplyStandardFilter(context.Descriptor.Scope, false, true)
                                   .ToPagedList(context.PageIndex, context.PageSize)
                                   .LoadAsync();

                    result.IsPaged     = true;
                    result.HasMoreData = ruleSets.HasNextPage;

                    result.AddOptions(context, ruleSets.Select(x => new RuleValueSelectListOption
                    {
                        Value = x.Id.ToString(),
                        Text  = x.Name
                    }));
                }
            }
            else
            {
                return(null);
            }

            return(result);
        }
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.ProductTag)
            {
                var productTags = await _db.ProductTags.AsNoTracking().ToListAsync();

                result.AddOptions(context, productTags
                                  .Select(x => new RuleValueSelectListOption
                {
                    Value = x.Id.ToString(),
                    Text  = x.GetLocalized(y => y.Name, context.Language, true, false)
                })
                                  .OrderBy(x => x.Text));
            }
            else
            {
                return(null);
            }

            return(result);
        }
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.Language)
            {
                var languages = await _db.Languages
                                .AsNoTracking()
                                .ApplyStandardFilter(true)
                                .ToListAsync();

                result.AddOptions(context, languages.Select(x => new RuleValueSelectListOption
                {
                    Value = x.Id.ToString(),
                    Text  = GetCultureDisplayName(x) ?? x.Name
                }));
            }
            else
            {
                return(null);
            }

            return(result);
        }
Esempio n. 13
0
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.ShippingMethod)
            {
                var shippingMethods = await _db.ShippingMethods
                                      .AsNoTracking()
                                      .OrderBy(x => x.DisplayOrder)
                                      .ToListAsync();

                result.AddOptions(context, shippingMethods.Select(x => new RuleValueSelectListOption
                {
                    Value = context.OptionById ? x.Id.ToString() : x.Name,
                    Text  = context.OptionById ? x.GetLocalized(y => y.Name, context.Language, true, false) : x.Name
                }));
            }
            else
            {
                return(null);
            }

            return(result);
        }
Esempio n. 14
0
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.CustomerRole)
            {
                var customerRoles = await _db.CustomerRoles
                                    .AsNoTracking()
                                    .OrderBy(x => x.Name)
                                    .ToListAsync();

                result.AddOptions(context, customerRoles.Select(x => new RuleValueSelectListOption
                {
                    Value = x.Id.ToString(),
                    Text  = x.Name
                }));
            }
            else
            {
                return(null);
            }

            return(result);
        }
Esempio n. 15
0
        public async Task <RuleOptionsResult> GetOptionsAsync(RuleOptionsContext context)
        {
            var result = new RuleOptionsResult();

            if (context.DataSource == KnownRuleOptionDataSourceNames.Manufacturer)
            {
                var manufacturers = await _db.Manufacturers
                                    .AsNoTracking()
                                    .ApplyStandardFilter(true)
                                    .ToListAsync();

                result.AddOptions(context, manufacturers.Select(x => new RuleValueSelectListOption
                {
                    Value = x.Id.ToString(),
                    Text  = x.GetLocalized(y => y.Name, context.Language, true, false)
                }));
            }
            else
            {
                return(null);
            }

            return(result);
        }
Esempio n. 16
0
        public virtual RuleOptionsResult GetOptions(
            RuleOptionsRequestReason reason,
            IRuleExpression expression,
            int pageIndex,
            int pageSize,
            string searchTerm)
        {
            Guard.NotNull(expression, nameof(expression));
            Guard.NotNull(expression.Descriptor, nameof(expression.Descriptor));

            var result = new RuleOptionsResult();
            var list   = expression.Descriptor.SelectList as RemoteRuleValueSelectList;

            if (list == null)
            {
                return(result);
            }

            var language = _services.WorkContext.WorkingLanguage;
            var byId     = expression.Descriptor.RuleType == RuleType.Int || expression.Descriptor.RuleType == RuleType.IntArray;
            List <RuleValueSelectListOption> options = null;

            switch (list.DataSource)
            {
            case "Product":
                if (reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    options = _productService.Value.GetProductsByIds(expression.RawValue.ToIntArray())
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.GetLocalized(y => y.Name, language, true, false), Hint = x.Sku
                    })
                              .ToList();
                }
                else
                {
                    result.IsPaged = true;
                    options        = SearchProducts(result, searchTerm, pageIndex * pageSize, pageSize);
                }
                break;

            case "Country":
                options = _countryService.Value.GetAllCountries(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = byId ? x.Id.ToString() : x.TwoLetterIsoCode, Text = x.GetLocalized(y => y.Name, language, true, false)
                })
                          .ToList();
                break;

            case "Currency":
                options = _currencyService.Value.GetAllCurrencies(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = byId ? x.Id.ToString() : x.CurrencyCode, Text = x.GetLocalized(y => y.Name, language, true, false)
                })
                          .ToList();
                break;

            case "CustomerRole":
                options = _customerService.Value.GetAllCustomerRoles(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.Id.ToString(), Text = x.Name
                })
                          .ToList();
                break;

            case "Language":
                options = _languageService.Value.GetAllLanguages(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.Id.ToString(), Text = GetCultureDisplayName(x) ?? x.Name
                })
                          .ToList();
                break;

            case "Store":
                options = _services.StoreService.GetAllStores()
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.Id.ToString(), Text = x.Name
                })
                          .ToList();
                break;

            case "CartRule":
            case "TargetGroup":
                if (reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    options = _ruleStorage.Value.GetRuleSetsByIds(expression.RawValue.ToIntArray(), false)
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.Name
                    })
                              .ToList();
                }
                else
                {
                    var ruleSets = _ruleStorage.Value.GetAllRuleSets(false, false, expression.Descriptor.Scope, pageIndex, pageSize, false, true);
                    result.IsPaged     = true;
                    result.HasMoreData = ruleSets.HasNextPage;

                    options = ruleSets
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.Name
                    })
                              .ToList();
                }
                break;

            case "Category":
                if (reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    options = _categoryService.Value.GetCategoriesByIds(expression.RawValue.ToIntArray())
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.GetCategoryPath(_categoryService.Value).NullEmpty() ?? x.Name
                    })
                              .ToList();
                }
                else
                {
                    var categories = _categoryService.Value.GetCategoryTree(0, true).Flatten(false);
                    options = categories
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.GetCategoryPath(_categoryService.Value).NullEmpty() ?? x.Name
                    })
                              .ToList();
                }
                break;

            case "Manufacturer":
                options = _manufacturerService.Value.GetAllManufacturers(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.Id.ToString(), Text = x.GetLocalized(y => y.Name, language, true, false)
                })
                          .ToList();
                break;

            case "PaymentMethod":
                options = _providerManager.Value.GetAllProviders <IPaymentMethod>()
                          .Select(x => x.Metadata)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.SystemName, Text = GetLocalized(x, "FriendlyName") ?? x.FriendlyName.NullEmpty() ?? x.SystemName, Hint = x.SystemName
                })
                          .OrderBy(x => x.Text)
                          .ToList();
                break;

            case "ShippingRateComputationMethod":
                options = _providerManager.Value.GetAllProviders <IShippingRateComputationMethod>()
                          .Select(x => x.Metadata)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.SystemName, Text = GetLocalized(x, "FriendlyName") ?? x.FriendlyName.NullEmpty() ?? x.SystemName, Hint = x.SystemName
                })
                          .OrderBy(x => x.Text)
                          .ToList();
                break;

            case "ShippingMethod":
                options = _shippingService.GetAllShippingMethods()
                          .Select(x => new RuleValueSelectListOption {
                    Value = byId ? x.Id.ToString() : x.Name, Text = byId ? x.GetLocalized(y => y.Name, language, true, false) : x.Name
                })
                          .ToList();
                break;

            default:
                throw new SmartException($"Unknown data source \"{list.DataSource.NaIfEmpty()}\".");
            }

            if (reason == RuleOptionsRequestReason.SelectedDisplayNames)
            {
                // Get display names of selected options.
                if (expression.RawValue.HasValue())
                {
                    var selectedValues = expression.RawValue.SplitSafe(",");
                    result.Options.AddRange(options.Where(x => selectedValues.Contains(x.Value)));
                }
            }
            else
            {
                // Get select list options.
                if (!result.IsPaged && searchTerm.HasValue() && options.Any())
                {
                    // Apply the search term if the options are not paged.
                    result.Options.AddRange(options.Where(x => (x.Text?.IndexOf(searchTerm, 0, StringComparison.CurrentCultureIgnoreCase) ?? -1) != -1));
                }
                else
                {
                    result.Options.AddRange(options);
                }
            }

            return(result);
        }
        public virtual RuleOptionsResult GetOptions(
            RuleOptionsRequestReason reason,
            IRuleExpression expression,
            int pageIndex,
            int pageSize,
            string searchTerm)
        {
            Guard.NotNull(expression, nameof(expression));
            Guard.NotNull(expression.Descriptor, nameof(expression.Descriptor));

            var result = new RuleOptionsResult();

            if (!(expression.Descriptor.SelectList is RemoteRuleValueSelectList list))
            {
                return(result);
            }

            var language = _services.WorkContext.WorkingLanguage;
            var byId     = expression.Descriptor.RuleType == RuleType.Int || expression.Descriptor.RuleType == RuleType.IntArray;
            List <RuleValueSelectListOption> options = null;

            switch (list.DataSource)
            {
            case "Product":
                if (reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    options = _productService.Value.GetProductsByIds(expression.RawValue.ToIntArray())
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.GetLocalized(y => y.Name, language, true, false), Hint = x.Sku
                    })
                              .ToList();
                }
                else
                {
                    result.IsPaged = true;
                    options        = SearchProducts(result, searchTerm, pageIndex * pageSize, pageSize);
                }
                break;

            case "Country":
                options = _countryService.Value.GetAllCountries(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = byId ? x.Id.ToString() : x.TwoLetterIsoCode, Text = x.GetLocalized(y => y.Name, language, true, false)
                })
                          .ToList();
                break;

            case "Currency":
                options = _currencyService.Value.GetAllCurrencies(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = byId ? x.Id.ToString() : x.CurrencyCode, Text = x.GetLocalized(y => y.Name, language, true, false)
                })
                          .ToList();
                break;

            case "DeliveryTime":
                options = _deliveryTimeService.Value.GetAllDeliveryTimes()
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.Id.ToString(), Text = x.GetLocalized(y => y.Name, language, true, false)
                })
                          .ToList();
                break;

            case "CustomerRole":
                options = _customerService.Value.GetAllCustomerRoles(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.Id.ToString(), Text = x.Name
                })
                          .ToList();
                break;

            case "Language":
                options = _languageService.Value.GetAllLanguages(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.Id.ToString(), Text = GetCultureDisplayName(x) ?? x.Name
                })
                          .ToList();
                break;

            case "Store":
                options = _services.StoreService.GetAllStores()
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.Id.ToString(), Text = x.Name
                })
                          .ToList();
                break;

            case "CartRule":
            case "TargetGroup":
                if (reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    options = _ruleStorage.Value.GetRuleSetsByIds(expression.RawValue.ToIntArray(), false)
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.Name
                    })
                              .ToList();
                }
                else
                {
                    var ruleSets = _ruleStorage.Value.GetAllRuleSets(false, false, expression.Descriptor.Scope, pageIndex, pageSize, false, true);
                    result.IsPaged     = true;
                    result.HasMoreData = ruleSets.HasNextPage;

                    options = ruleSets
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.Name
                    })
                              .ToList();
                }
                break;

            case "Category":
                if (reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    options = _categoryService.Value.GetCategoriesByIds(expression.RawValue.ToIntArray())
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.GetCategoryPath(_categoryService.Value).NullEmpty() ?? x.Name
                    })
                              .ToList();
                }
                else
                {
                    var categories = _categoryService.Value.GetCategoryTree(0, true).Flatten(false);
                    options = categories
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.GetCategoryPath(_categoryService.Value).NullEmpty() ?? x.Name
                    })
                              .ToList();
                }
                break;

            case "Manufacturer":
                options = _manufacturerService.Value.GetAllManufacturers(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.Id.ToString(), Text = x.GetLocalized(y => y.Name, language, true, false)
                })
                          .ToList();
                break;

            case "PaymentMethod":
                options = _providerManager.Value.GetAllProviders <IPaymentMethod>()
                          .Select(x => x.Metadata)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.SystemName, Text = GetLocalized(x, "FriendlyName") ?? x.FriendlyName.NullEmpty() ?? x.SystemName, Hint = x.SystemName
                })
                          .OrderBy(x => x.Text)
                          .ToList();
                break;

            case "ShippingRateComputationMethod":
                options = _providerManager.Value.GetAllProviders <IShippingRateComputationMethod>()
                          .Select(x => x.Metadata)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.SystemName, Text = GetLocalized(x, "FriendlyName") ?? x.FriendlyName.NullEmpty() ?? x.SystemName, Hint = x.SystemName
                })
                          .OrderBy(x => x.Text)
                          .ToList();
                break;

            case "ShippingMethod":
                options = _shippingService.Value.GetAllShippingMethods()
                          .Select(x => new RuleValueSelectListOption {
                    Value = byId ? x.Id.ToString() : x.Name, Text = byId ? x.GetLocalized(y => y.Name, language, true, false) : x.Name
                })
                          .ToList();
                break;

            case "ProductTag":
                options = _productTagService.Value.GetAllProductTags(true)
                          .Select(x => new RuleValueSelectListOption {
                    Value = x.Id.ToString(), Text = x.GetLocalized(y => y.Name, language, true, false)
                })
                          .OrderBy(x => x.Text)
                          .ToList();
                break;

            case "VariantValue":
                if (reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    var ids           = expression.RawValue.ToIntArray();
                    var variantValues = _variantValueRepository.Value.TableUntracked
                                        .Where(x => ids.Contains(x.Id))
                                        .ToList();

                    options = variantValues
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.GetLocalized(y => y.Name, language, true, false)
                    })
                              .ToList();
                }
                else if (expression.Descriptor.Metadata.TryGetValue("ParentId", out var objParentId))
                {
                    options = new List <RuleValueSelectListOption>();
                    var pIndex            = -1;
                    var existingValues    = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase);
                    var multiValueTypeIds = new int[] { (int)AttributeControlType.Checkboxes, (int)AttributeControlType.RadioList, (int)AttributeControlType.DropdownList, (int)AttributeControlType.Boxes };
                    var query             = _variantValueRepository.Value.TableUntracked
                                            .Where(x =>
                                                   x.ProductVariantAttribute.ProductAttributeId == (int)objParentId &&
                                                   x.ProductVariantAttribute.ProductAttribute.AllowFiltering &&
                                                   multiValueTypeIds.Contains(x.ProductVariantAttribute.AttributeControlTypeId) &&
                                                   x.ValueTypeId == (int)ProductVariantAttributeValueType.Simple
                                                   )
                                            .OrderBy(x => x.DisplayOrder);

                    while (true)
                    {
                        var variantValues = PagedList.Create(query, ++pIndex, 500);
                        foreach (var value in variantValues)
                        {
                            var name = value.GetLocalized(x => x.Name, language, true, false);
                            if (!existingValues.Contains(name))
                            {
                                existingValues.Add(name);
                                options.Add(new RuleValueSelectListOption {
                                    Value = value.Id.ToString(), Text = name
                                });
                            }
                        }
                        if (!variantValues.HasNextPage)
                        {
                            break;
                        }
                    }
                }
                break;

            case "AttributeOption":
                if (reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    var ids = expression.RawValue.ToIntArray();
                    var attributeOptions = _attrOptionRepository.Value.TableUntracked
                                           .Where(x => ids.Contains(x.Id))
                                           .ToList();

                    options = attributeOptions
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.GetLocalized(y => y.Name, language, true, false)
                    })
                              .ToList();
                }
                else if (expression.Descriptor.Metadata.TryGetValue("ParentId", out var objParentId))
                {
                    var query = _attrOptionRepository.Value.TableUntracked
                                .Where(x => x.SpecificationAttributeId == (int)objParentId)
                                .OrderBy(x => x.DisplayOrder);

                    var attributeOptions = PagedList.Create(query, pageIndex, pageSize);

                    result.IsPaged     = true;
                    result.HasMoreData = attributeOptions.HasNextPage;

                    options = attributeOptions
                              .Select(x => new RuleValueSelectListOption {
                        Value = x.Id.ToString(), Text = x.GetLocalized(y => y.Name, language, true, false)
                    })
                              .ToList();
                }
                break;

            default:
                throw new SmartException($"Unknown data source \"{list.DataSource.NaIfEmpty()}\".");
            }

            if (options != null)
            {
                if (reason == RuleOptionsRequestReason.SelectedDisplayNames)
                {
                    // Get display names of selected options.
                    if (expression.RawValue.HasValue())
                    {
                        var selectedValues = expression.RawValue.SplitSafe(",");
                        result.Options.AddRange(options.Where(x => selectedValues.Contains(x.Value)));
                    }
                }
                else
                {
                    // Get select list options.
                    if (!result.IsPaged && searchTerm.HasValue() && options.Any())
                    {
                        // Apply the search term if the options are not paged.
                        result.Options.AddRange(options.Where(x => (x.Text?.IndexOf(searchTerm, 0, StringComparison.CurrentCultureIgnoreCase) ?? -1) != -1));
                    }
                    else
                    {
                        result.Options.AddRange(options);
                    }
                }
            }

            return(result);
        }