Exemple #1
0
        protected async Task <RuleExpression> GetOtherExpressionAsync(RuleExpression expression)
        {
            var ruleSetId       = expression.Value.Convert <int>();
            var otherExpression = await _ruleService.CreateExpressionGroupAsync(ruleSetId, _cartRuleProvider) as RuleExpression;

            return(otherExpression);
        }
Exemple #2
0
        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 = _ruleService.CreateExpressionGroupAsync(ruleSetId, visitor).Await() 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));
        }
Exemple #3
0
 public async Task <SearchFilterExpressionGroup> CreateExpressionGroupAsync(int ruleSetId)
 {
     return(await _ruleService.CreateExpressionGroupAsync(ruleSetId, this) as SearchFilterExpressionGroup);
 }
        public async Task Run(TaskExecutionContext ctx, CancellationToken cancelToken = default)
        {
            //var count = 0;
            var numDeleted = 0;
            var numAdded   = 0;
            var rolesCount = 0;

            using (var scope = new DbContextScope(_db, autoDetectChanges: false, hooksEnabled: false, deferCommit: true))
            {
                // Delete existing system mappings.
                var deleteQuery = _db.CustomerRoleMappings.Where(x => x.IsSystemMapping);
                if (ctx.Parameters.ContainsKey("CustomerRoleIds"))
                {
                    var roleIds = ctx.Parameters["CustomerRoleIds"].ToIntArray();
                    deleteQuery = deleteQuery.Where(x => roleIds.Contains(x.CustomerRoleId));
                }

                numDeleted = await deleteQuery.BatchDeleteAsync(cancelToken);

                // Insert new customer role mappings.
                var roles = await _db.CustomerRoles
                            .Include(x => x.RuleSets)
                            .AsNoTracking()
                            .Where(x => x.Active && x.RuleSets.Any(y => y.IsActive))
                            .ToListAsync(cancelToken);

                rolesCount = roles.Count;

                foreach (var role in roles)
                {
                    var ruleSetCustomerIds = new HashSet <int>();

                    // TODO: (mg) (core) Complete TargetGroupEvaluatorTask (TaskExecutionContext required).
                    //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 (cancelToken.IsCancellationRequested)
                        {
                            return;
                        }

                        var expressionGroup = await _ruleService.CreateExpressionGroupAsync(ruleSet, _targetGroupService);

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

                            while ((await resultPager.ReadNextPageAsync(x => x.Id, x => x)).Out(out var customerIds))
                            {
                                ruleSetCustomerIds.AddRange(customerIds);
                            }
                        }
                    }

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

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

                                ++numAdded;
                            }

                            await scope.CommitAsync(cancelToken);
                        }

                        try
                        {
                            scope.DbContext.DetachEntities <CustomerRoleMapping>();
                        }
                        catch { }
                    }
                }
            }

            if (numAdded > 0 || numDeleted > 0)
            {
                await _cache.RemoveByPatternAsync(AclService.ACL_SEGMENT_PATTERN);
            }

            Debug.WriteLineIf(numDeleted > 0 || numAdded > 0, $"Deleted {numDeleted} and added {numAdded} customer assignments for {rolesCount} roles.");
        }
Exemple #5
0
        public async Task Run(TaskExecutionContext ctx, CancellationToken cancelToken = default)
        {
            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(_db, autoDetectChanges: false, hooksEnabled: true, deferCommit: true))
            {
                // Delete existing system mappings.
                var deleteQuery = _db.ProductCategories.Where(x => x.IsSystemMapping);
                if (categoryIds != null)
                {
                    deleteQuery = deleteQuery.Where(x => categoryIds.Contains(x.CategoryId));
                }

                numDeleted = await deleteQuery.BatchDeleteAsync(cancelToken);

                // Insert new product category mappings.
                var categoryQuery = _db.Categories
                                    .Include(x => x.RuleSets)
                                    .AsNoTracking();

                if (categoryIds != null)
                {
                    categoryQuery = categoryQuery.Where(x => categoryIds.Contains(x.Id));
                }

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

                numCategories = categories.Count;

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

                    await ctx.SetProgressAsync(++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 (cancelToken.IsCancellationRequested)
                        {
                            return;
                        }

                        var expressionGroup = await _ruleService.CreateExpressionGroupAsync(ruleSet, (IRuleVisitor)_productRuleProvider);

                        if (expressionGroup is SearchFilterExpression expression)
                        {
                            pageIndex = -1;
                            while (true)
                            {
                                // Do not touch searchResult.Hits. We only need the product identifiers.
                                var searchResult = await _productRuleProvider.SearchAsync(new[] { 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 (cancelToken.IsCancellationRequested)
                            {
                                return;
                            }

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

                                ++numAdded;
                            }

                            await scope.CommitAsync(cancelToken);
                        }

                        try
                        {
                            scope.DbContext.DetachEntities <ProductCategory>();
                        }
                        catch { }
                    }
                }
            }

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