public RuleOptionsContext(RuleOptionsRequestReason reason, IRuleExpression expression)
            : this(reason, expression?.Descriptor)
        {
            Guard.NotNull(expression, nameof(expression));

            Value = expression.RawValue;
        }
        // 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 virtual RuleOptionsResult GetOptions(
            RuleOptionsRequestReason reason,
            IRuleExpression expression,
            int pageIndex,
            int pageSize,
            string searchTerm)
        {
            Guard.NotNull(expression, nameof(expression));

            return(GetOptions(reason, expression.Descriptor, expression.RawValue, pageIndex, pageSize, searchTerm));
        }
        public RuleOptionsContext(RuleOptionsRequestReason reason, RuleDescriptor descriptor)
        {
            Guard.NotNull(descriptor, nameof(descriptor));
            Guard.NotNull(reason, nameof(reason));

            Descriptor = descriptor;
            Reason     = reason;

            if (descriptor.SelectList is RemoteRuleValueSelectList list)
            {
                DataSource = list.DataSource;
            }

            Guard.NotEmpty(DataSource, nameof(DataSource));
        }
        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);
        }
Example #6
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);
        }