public ActionResult Edit(int id /* ruleSetId */)
        {
            var entity = _ruleStorage.GetRuleSetById(id, false, true);

            if (entity == null || entity.IsSubGroup)
            {
                return(HttpNotFound());
            }

            var model = MiniMapper.Map <RuleSetEntity, RuleSetModel>(entity);

            model.ScopeName = entity.Scope.GetLocalizedEnum(Services.Localization, Services.WorkContext);

            var provider = _ruleProvider(entity.Scope);

            model.ExpressionGroup      = _ruleFactory.CreateExpressionGroup(entity, provider, true);
            model.AvailableDescriptors = _targetGroupService.RuleDescriptors;

            model.AssignedToDiscounts = entity.Discounts
                                        .Select(x => new RuleSetModel.AssignedToEntityModel {
                Id = x.Id, Name = x.Name.NullEmpty() ?? x.Id.ToString()
            })
                                        .ToList();

            model.AssignedToShippingMethods = entity.ShippingMethods
                                              .Select(x => new RuleSetModel.AssignedToEntityModel {
                Id = x.Id, Name = x.GetLocalized(y => y.Name)
            })
                                              .ToList();

            var paymentMethods = entity.PaymentMethods;

            if (paymentMethods.Any())
            {
                var paymentProviders = _paymentService.Value.LoadAllPaymentMethods().ToDictionarySafe(x => x.Metadata.SystemName);

                model.AssignedToPaymentMethods = paymentMethods
                                                 .Select(x =>
                {
                    string friendlyName = null;
                    if (paymentProviders.TryGetValue(x.PaymentMethodSystemName, out var paymentProvider))
                    {
                        friendlyName = _pluginMediator.Value.GetLocalizedFriendlyName(paymentProvider.Metadata);
                    }

                    return(new RuleSetModel.AssignedToEntityModel
                    {
                        Id = x.Id,
                        Name = friendlyName.NullEmpty() ?? x.PaymentMethodSystemName,
                        SystemName = x.PaymentMethodSystemName
                    });
                })
                                                 .ToList();
            }

            PrepareExpressions(model.ExpressionGroup);
            PrepareTemplateViewBag(entity.Id);

            return(View(model));
        }
        protected RuleExpression GetOtherExpression(RuleExpression expression)
        {
            var ruleSetId       = expression.Value.Convert <int>();
            var otherExpression = _ruleFactory.CreateExpressionGroup(ruleSetId, _cartRuleProvider) as RuleExpression;

            return(otherExpression);
        }
        public ActionResult Edit(int id /* ruleSetId */)
        {
            var entity = _ruleStorage.GetRuleSetById(id, false, true);

            if (entity == null || entity.IsSubGroup)
            {
                return(HttpNotFound());
            }

            var model = MiniMapper.Map <RuleSetEntity, RuleSetModel>(entity);

            model.ScopeName = entity.Scope.GetLocalizedEnum(Services.Localization, Services.WorkContext);

            var provider = _ruleProvider(entity.Scope);

            model.ExpressionGroup      = _ruleFactory.CreateExpressionGroup(entity, provider, true);
            model.AvailableDescriptors = _targetGroupService.RuleDescriptors;

            PrepareExpressions(model.ExpressionGroup);
            PrepareTemplateViewBag(entity.Id);

            return(View(model));
        }
        public override Expression GetExpression(RuleOperator op, Expression valueExpression, bool liftToNull)
        {
            var ruleSetId = ((ConstantExpression)valueExpression).Value.Convert <int>();

            // Get other expression group
            _ruleVisitor.TryGetTarget(out var visitor);
            var otherGroup = _ruleFactory.CreateExpressionGroup(ruleSetId, visitor) as FilterExpressionGroup;

            var otherPredicate = otherGroup?.ToPredicate(liftToNull);

            if (otherPredicate is Expression <Func <Customer, bool> > lambda)
            {
                MemberExpression = lambda;
            }

            return(base.GetExpression(op, Expression.Constant(true), liftToNull));
        }
 public RuleExpressionGroup CreateExpressionGroup(int ruleSetId)
 {
     return(_ruleFactory.CreateExpressionGroup(ruleSetId, this) as RuleExpressionGroup);
 }
Exemple #6
0
 public SearchFilterExpressionGroup CreateExpressionGroup(int ruleSetId)
 {
     return(_ruleFactory.CreateExpressionGroup(ruleSetId, this) as SearchFilterExpressionGroup);
 }
Exemple #7
0
        public ActionResult PreviewList(int id, GridCommand command)
        {
            var entity = _ruleStorage.GetRuleSetById(id, false, true);

            switch (entity.Scope)
            {
            case RuleScope.Customer:
            {
                var provider   = _ruleProvider(entity.Scope) as ITargetGroupService;
                var expression = _ruleFactory.CreateExpressionGroup(entity, provider, true) as FilterExpression;
                var customers  = provider.ProcessFilter(new[] { expression }, LogicalRuleOperator.And, command.Page - 1, command.PageSize);
                var guestStr   = T("Admin.Customers.Guest").Text;

                var model = new GridModel <CustomerModel>
                {
                    Total = customers.TotalCount
                };

                model.Data = customers.Select(x =>
                    {
                        var customerModel = new CustomerModel
                        {
                            Id               = x.Id,
                            Active           = x.Active,
                            Email            = x.Email.NullEmpty() ?? (x.IsGuest() ? guestStr : string.Empty),
                            Username         = x.Username,
                            FullName         = x.GetFullName(),
                            CreatedOn        = Services.DateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc),
                            LastActivityDate = Services.DateTimeHelper.ConvertToUserTime(x.LastActivityDateUtc, DateTimeKind.Utc)
                        };

                        return(customerModel);
                    })
                             .ToList();

                return(new JsonResult {
                        Data = model
                    });
            }

            case RuleScope.Product:
            {
                var provider     = _ruleProvider(entity.Scope) as IProductRuleProvider;
                var expression   = _ruleFactory.CreateExpressionGroup(entity, provider, true) as SearchFilterExpression;
                var searchResult = provider.Search(new[] { expression }, command.Page - 1, command.PageSize);

                var fileIds = searchResult.Hits
                              .Select(x => x.MainPictureId ?? 0)
                              .Where(x => x != 0)
                              .Distinct()
                              .ToArray();
                var files = _mediaService.Value.GetFilesByIds(fileIds).ToDictionarySafe(x => x.Id);

                var model = new GridModel <ProductModel>
                {
                    Total = searchResult.TotalHitsCount
                };

                model.Data = searchResult.Hits.Select(x =>
                    {
                        var productModel = new ProductModel
                        {
                            Id                   = x.Id,
                            Sku                  = x.Sku,
                            Published            = x.Published,
                            ProductTypeLabelHint = x.ProductTypeLabelHint,
                            ProductTypeName      = x.GetProductTypeLabel(Services.Localization),
                            Name                 = x.Name,
                            StockQuantity        = x.StockQuantity,
                            Price                = x.Price,
                            LimitedToStores      = x.LimitedToStores,
                            UpdatedOn            = Services.DateTimeHelper.ConvertToUserTime(x.UpdatedOnUtc, DateTimeKind.Utc),
                            CreatedOn            = Services.DateTimeHelper.ConvertToUserTime(x.CreatedOnUtc, DateTimeKind.Utc)
                        };

                        files.TryGetValue(x.MainPictureId ?? 0, out var file);

                        productModel.PictureThumbnailUrl = _mediaService.Value.GetUrl(file, _mediaSettings.Value.CartThumbPictureSize, null, true);
                        productModel.NoThumb             = file == null;

                        return(productModel);
                    })
                             .ToList();

                return(new JsonResult {
                        Data = model
                    });
            }
            }

            return(new JsonResult {
                Data = null
            });
        }
        public override async Task ExecuteAsync(TaskExecutionContext ctx)
        {
            var count      = 0;
            var clearCache = false;
            var roleQuery  = _customerRoleRepository.TableUntracked.Expand(x => x.RuleSets);

            if (ctx.Parameters.ContainsKey("CustomerRoleIds"))
            {
                var rolesIds = ctx.Parameters["CustomerRoleIds"].ToIntArray();
                roleQuery = roleQuery.Where(x => rolesIds.Contains(x.Id));
            }

            var roles = await roleQuery.ToListAsync();

            if (!roles.Any())
            {
                return;
            }

            using (var scope = new DbContextScope(ctx: _customerRoleMappingRepository.Context, autoDetectChanges: false, validateOnSave: false, hooksEnabled: false, autoCommit: false))

                foreach (var role in roles)
                {
                    try
                    {
                        ctx.SetProgress(++count, roles.Count, $"Sync customer assignments for role {role.SystemName.NaIfEmpty()}.");

                        _customerRoleMappingRepository.Context.DetachEntities(x => x is CustomerRoleMapping);
                    }
                    catch { }

                    var ruleSetCustomerIds  = new HashSet <int>();
                    var existingCustomerIds = new HashSet <int>();
                    var numDeleted          = 0;
                    var numAdded            = 0;

                    // Execute active rule sets and collect customer ids.
                    // Delete old mappings if the role is inactive or has no assigned rule sets.
                    if (role.Active)
                    {
                        foreach (var ruleSet in role.RuleSets.Where(x => x.IsActive))
                        {
                            if (ctx.CancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            var expression = _ruleFactory.CreateExpressionGroup(ruleSet, _targetGroupService) as FilterExpression;
                            if (expression != null)
                            {
                                var filterResult = _targetGroupService.ProcessFilter(expression, 0, 500);
                                var resultPager  = new FastPager <Customer>(filterResult.SourceQuery, 500);

                                for (var i = 0; i < 9999999; ++i)
                                {
                                    var customerIds = await resultPager.ReadNextPageAsync(x => x.Id, x => x);

                                    if (!(customerIds?.Any() ?? false))
                                    {
                                        break;
                                    }

                                    ruleSetCustomerIds.AddRange(customerIds);
                                }
                            }
                        }
                    }

                    // Sync mappings.
                    var query = _customerRoleMappingRepository.Table.Where(x => x.CustomerRoleId == role.Id && x.IsSystemMapping);
                    var pager = new FastPager <CustomerRoleMapping>(query, 500);

                    // Mappings to delete.
                    for (var i = 0; i < 9999999; ++i)
                    {
                        if (ctx.CancellationToken.IsCancellationRequested)
                        {
                            return;
                        }

                        var mappings = await pager.ReadNextPageAsync <CustomerRoleMapping>();

                        if (!(mappings?.Any() ?? false))
                        {
                            break;
                        }

                        foreach (var mapping in mappings)
                        {
                            if (!role.Active || !ruleSetCustomerIds.Contains(mapping.CustomerId))
                            {
                                _customerRoleMappingRepository.Delete(mapping);

                                ++numDeleted;
                                clearCache = true;
                            }
                            else
                            {
                                existingCustomerIds.Add(mapping.CustomerId);
                            }
                        }

                        await scope.CommitAsync();
                    }

                    // Mappings to add.
                    if (role.Active)
                    {
                        var toAdd = ruleSetCustomerIds.Except(existingCustomerIds).ToList();
                        if (toAdd.Any())
                        {
                            foreach (var chunk in toAdd.Slice(500))
                            {
                                if (ctx.CancellationToken.IsCancellationRequested)
                                {
                                    return;
                                }

                                foreach (var customerId in chunk)
                                {
                                    _customerRoleMappingRepository.Insert(new CustomerRoleMapping
                                    {
                                        CustomerId      = customerId,
                                        CustomerRoleId  = role.Id,
                                        IsSystemMapping = true
                                    });

                                    ++numAdded;
                                    clearCache = true;
                                }

                                await scope.CommitAsync();
                            }
                        }
                    }

                    Debug.WriteLineIf(numDeleted > 0 || numAdded > 0, $"Customer assignments for {role.SystemName.NaIfEmpty()}: deleted {numDeleted}, added {numAdded}.");
                }

            if (clearCache)
            {
                _cacheManager.RemoveByPattern(AclService.ACL_SEGMENT_PATTERN);
            }
        }
        public override async Task ExecuteAsync(TaskExecutionContext ctx)
        {
            var count      = 0;
            var numDeleted = 0;
            var numAdded   = 0;
            var roleQuery  = _customerRoleRepository.TableUntracked.Expand(x => x.RuleSets);

            if (ctx.Parameters.ContainsKey("CustomerRoleIds"))
            {
                var roleIds = ctx.Parameters["CustomerRoleIds"].ToIntArray();
                roleQuery = roleQuery.Where(x => roleIds.Contains(x.Id));

                numDeleted = _customerRoleMappingRepository.Context.ExecuteSqlCommand(
                    "Delete From [dbo].[CustomerRoleMapping] Where [CustomerRoleId] In ({0}) And [IsSystemMapping] = 1",
                    false,
                    null,
                    string.Join(",", roleIds));
            }
            else
            {
                numDeleted = _customerRoleMappingRepository.Context.ExecuteSqlCommand("Delete From [dbo].[CustomerRoleMapping] Where [IsSystemMapping] = 1");
            }

            var roles = await roleQuery
                        .Where(x => x.Active && x.RuleSets.Any(y => y.IsActive))
                        .ToListAsync();

            using (var scope = new DbContextScope(ctx: _customerRoleMappingRepository.Context, autoDetectChanges: false, validateOnSave: false, hooksEnabled: false, autoCommit: false))
            {
                foreach (var role in roles)
                {
                    var ruleSetCustomerIds = new HashSet <int>();

                    ctx.SetProgress(++count, roles.Count, $"Add customer assignments for role \"{role.SystemName.NaIfEmpty()}\".");

                    // Execute active rule sets and collect customer ids.
                    foreach (var ruleSet in role.RuleSets.Where(x => x.IsActive))
                    {
                        if (ctx.CancellationToken.IsCancellationRequested)
                        {
                            return;
                        }

                        if (_ruleFactory.CreateExpressionGroup(ruleSet, _targetGroupService) is FilterExpression expression)
                        {
                            var filterResult = _targetGroupService.ProcessFilter(expression, 0, 500);
                            var resultPager  = new FastPager <Customer>(filterResult.SourceQuery, 500);

                            while (true)
                            {
                                var customerIds = await resultPager.ReadNextPageAsync(x => x.Id, x => x);

                                if (!(customerIds?.Any() ?? false))
                                {
                                    break;
                                }

                                ruleSetCustomerIds.AddRange(customerIds);
                            }
                        }
                    }

                    // Add mappings.
                    if (ruleSetCustomerIds.Any())
                    {
                        foreach (var chunk in ruleSetCustomerIds.Slice(500))
                        {
                            if (ctx.CancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            foreach (var customerId in chunk)
                            {
                                _customerRoleMappingRepository.Insert(new CustomerRoleMapping
                                {
                                    CustomerId      = customerId,
                                    CustomerRoleId  = role.Id,
                                    IsSystemMapping = true
                                });

                                ++numAdded;
                            }

                            await scope.CommitAsync();
                        }

                        try
                        {
                            _customerRoleMappingRepository.Context.DetachEntities <CustomerRoleMapping>();
                        }
                        catch { }
                    }
                }
            }

            if (numAdded > 0 || numDeleted > 0)
            {
                _cacheManager.RemoveByPattern(AclService.ACL_SEGMENT_PATTERN);
            }

            Debug.WriteLineIf(numDeleted > 0 || numAdded > 0, $"Deleted {numDeleted} and added {numAdded} customer assignments for {roles.Count} roles.");
        }
Exemple #10
0
        public override async Task ExecuteAsync(TaskExecutionContext ctx)
        {
            var count         = 0;
            var numDeleted    = 0;
            var numAdded      = 0;
            var pageSize      = 500;
            var categoryQuery = _categoryRepository.TableUntracked.Expand(x => x.RuleSets);

            if (ctx.Parameters.ContainsKey("CategoryIds"))
            {
                var categoryIds = ctx.Parameters["CategoryIds"].ToIntArray();
                categoryQuery = categoryQuery.Where(x => categoryIds.Contains(x.Id));

                numDeleted = _productCategoryRepository.Context.ExecuteSqlCommand(
                    "Delete From [dbo].[Product_Category_Mapping] Where [CategoryId] In ({0}) And [IsSystemMapping] = 1",
                    false,
                    null,
                    string.Join(",", categoryIds));
            }
            else
            {
                numDeleted = _productCategoryRepository.Context.ExecuteSqlCommand("Delete From [dbo].[Product_Category_Mapping] Where [IsSystemMapping] = 1");
            }

            var categories = await categoryQuery
                             .Where(x => x.Published && !x.Deleted && x.RuleSets.Any(y => y.IsActive))
                             .ToListAsync();

            using (var scope = new DbContextScope(ctx: _productCategoryRepository.Context, autoDetectChanges: false, validateOnSave: false, hooksEnabled: false, autoCommit: false))
            {
                foreach (var category in categories)
                {
                    var ruleSetProductIds = new HashSet <int>();

                    ctx.SetProgress(++count, categories.Count, $"Add product mappings for category \"{category.Name.NaIfEmpty()}\".");

                    // Execute active rule sets and collect product ids.
                    foreach (var ruleSet in category.RuleSets.Where(x => x.IsActive))
                    {
                        if (ctx.CancellationToken.IsCancellationRequested)
                        {
                            return;
                        }

                        if (_ruleFactory.CreateExpressionGroup(ruleSet, _productRuleProvider) is SearchFilterExpression expression)
                        {
                            var pageIndex = -1;
                            while (true)
                            {
                                // Do not touch searchResult.Hits. We only need the product identifiers.
                                var searchResult = _productRuleProvider.Search(new SearchFilterExpression[] { expression }, ++pageIndex, pageSize);
                                ruleSetProductIds.AddRange(searchResult.HitsEntityIds);

                                if (pageIndex >= (searchResult.TotalHitsCount / pageSize))
                                {
                                    break;
                                }
                            }
                        }
                    }

                    // Add mappings.
                    if (ruleSetProductIds.Any())
                    {
                        foreach (var chunk in ruleSetProductIds.Slice(500))
                        {
                            if (ctx.CancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            foreach (var productId in chunk)
                            {
                                _productCategoryRepository.Insert(new ProductCategory
                                {
                                    ProductId       = productId,
                                    CategoryId      = category.Id,
                                    IsSystemMapping = true
                                });

                                ++numAdded;
                            }

                            await scope.CommitAsync();
                        }

                        try
                        {
                            _productCategoryRepository.Context.DetachEntities <ProductCategory>();
                        }
                        catch { }
                    }
                }
            }

            Debug.WriteLineIf(numDeleted > 0 || numAdded > 0, $"Deleted {numDeleted} and added {numAdded} product mappings for {categories.Count} categories.");
        }
Exemple #11
0
        public override async Task ExecuteAsync(TaskExecutionContext ctx)
        {
            var count         = 0;
            var numDeleted    = 0;
            var numAdded      = 0;
            var numCategories = 0;
            var pageSize      = 500;
            var pageIndex     = -1;

            var categoryIds = ctx.Parameters.ContainsKey("CategoryIds")
                ? ctx.Parameters["CategoryIds"].ToIntArray()
                : null;

            // Hooks are enabled because search index needs to be updated.
            using (var scope = new DbContextScope(ctx: _productCategoryRepository.Context, autoDetectChanges: false, validateOnSave: false, hooksEnabled: true, autoCommit: false))
            {
                // Delete existing system mappings.
                var deleteQuery = _productCategoryRepository.Table.Where(x => x.IsSystemMapping);
                if (categoryIds != null)
                {
                    deleteQuery = deleteQuery.Where(x => categoryIds.Contains(x.CategoryId));
                }

                var pager = new FastPager <ProductCategory>(deleteQuery, pageSize);

                while (pager.ReadNextPage(out var mappings))
                {
                    if (ctx.CancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    if (mappings.Any())
                    {
                        _productCategoryRepository.DeleteRange(mappings);
                        numDeleted += await scope.CommitAsync();
                    }
                }

                try
                {
                    _productCategoryRepository.Context.DetachEntities <ProductCategory>();
                }
                catch { }

                // Insert new product category mappings.
                var categoryQuery = _categoryRepository.TableUntracked.Expand(x => x.RuleSets);
                if (categoryIds != null)
                {
                    categoryQuery = categoryQuery.Where(x => categoryIds.Contains(x.Id));
                }

                var categories = await categoryQuery
                                 .Where(x => x.Published && !x.Deleted && x.RuleSets.Any(y => y.IsActive))
                                 .ToListAsync();

                numCategories = categories.Count;

                foreach (var category in categories)
                {
                    var ruleSetProductIds = new HashSet <int>();

                    ctx.SetProgress(++count, categories.Count, $"Add product mappings for category \"{category.Name.NaIfEmpty()}\".");

                    // Execute active rule sets and collect product ids.
                    foreach (var ruleSet in category.RuleSets.Where(x => x.IsActive))
                    {
                        if (ctx.CancellationToken.IsCancellationRequested)
                        {
                            return;
                        }

                        if (_ruleFactory.CreateExpressionGroup(ruleSet, _productRuleProvider) is SearchFilterExpression expression)
                        {
                            pageIndex = -1;
                            while (true)
                            {
                                // Do not touch searchResult.Hits. We only need the product identifiers.
                                var searchResult = _productRuleProvider.Search(new SearchFilterExpression[] { expression }, ++pageIndex, pageSize);
                                ruleSetProductIds.AddRange(searchResult.HitsEntityIds);

                                if (pageIndex >= (searchResult.TotalHitsCount / pageSize))
                                {
                                    break;
                                }
                            }
                        }
                    }

                    // Add mappings.
                    if (ruleSetProductIds.Any())
                    {
                        foreach (var chunk in ruleSetProductIds.Slice(500))
                        {
                            if (ctx.CancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            foreach (var productId in chunk)
                            {
                                _productCategoryRepository.Insert(new ProductCategory
                                {
                                    ProductId       = productId,
                                    CategoryId      = category.Id,
                                    IsSystemMapping = true
                                });

                                ++numAdded;
                            }

                            await scope.CommitAsync();
                        }

                        try
                        {
                            _productCategoryRepository.Context.DetachEntities <ProductCategory>();
                        }
                        catch { }
                    }
                }
            }

            Debug.WriteLineIf(numDeleted > 0 || numAdded > 0, $"Deleted {numDeleted} and added {numAdded} product mappings for {numCategories} categories.");
        }