protected async Task <RuleExpression> GetOtherExpressionAsync(RuleExpression expression) { var ruleSetId = expression.Value.Convert <int>(); var otherExpression = await _ruleService.CreateExpressionGroupAsync(ruleSetId, _cartRuleProvider) as RuleExpression; return(otherExpression); }
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)); }
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."); }
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."); }