Пример #1
0
        public virtual async Task EvaluateProductPricesAsync(IEnumerable <Product> products, WorkContext workContext)
        {
            if (products == null)
            {
                throw new ArgumentNullException(nameof(products));
            }
            if (workContext == null)
            {
                throw new ArgumentNullException(nameof(workContext));
            }

            //Evaluate products prices
            var evalContext    = workContext.ToPriceEvaluationContext(products);
            var cacheKey       = CacheKey.With(GetType(), "EvaluateProductPricesAsync", evalContext.GetCacheKey());
            var pricesResponse = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(PricingCacheRegion.CreateChangeToken());
                cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken());

                return(await _pricingApi.EvaluatePricesAsync(evalContext.ToPriceEvaluationContextDto()));
            });

            ApplyProductPrices(products, pricesResponse, workContext);

            //Evaluate product discounts
            //Fill product inventories for getting InStockQuantity data for promotion evaluation
            await _inventoryService.EvaluateProductInventoriesAsync(products.ToList(), workContext);

            var promoEvalContext = workContext.ToPromotionEvaluationContext(products);
            await _promotionEvaluator.EvaluateDiscountsAsync(promoEvalContext, products);

            //Evaluate product taxes
            var taxEvalContext = workContext.ToTaxEvaluationContext(products);
            await _taxEvaluator.EvaluateTaxesAsync(taxEvalContext, products);
        }
Пример #2
0
        public virtual async Task <PricelistAssignmentSearchResult> SearchPricelistAssignmentsAsync(PricelistAssignmentsSearchCriteria criteria)
        {
            var cacheKey = CacheKey.With(GetType(), nameof(SearchPricelistAssignmentsAsync), criteria.GetCacheKey());

            return(await _platformMemoryCache.GetOrCreateExclusiveAsync(cacheKey, async cacheEntry =>
            {
                cacheEntry.AddExpirationToken(PricingSearchCacheRegion.CreateChangeToken());
                cacheEntry.AddExpirationToken(PricingCacheRegion.CreateChangeToken());

                var result = AbstractTypeFactory <PricelistAssignmentSearchResult> .TryCreateInstance();
                using (var repository = _repositoryFactory())
                {
                    var query = BuildQuery(repository, criteria);
                    var sortInfos = BuildSortExpression(criteria);

                    result.TotalCount = await query.CountAsync();

                    if (criteria.Take > 0)
                    {
                        var pricelistAssignmentsIds = await query.OrderBySortInfos(sortInfos).ThenBy(x => x.Id)
                                                      .Select(x => x.Id)
                                                      .Skip(criteria.Skip).Take(criteria.Take)
                                                      .AsNoTracking()
                                                      .ToArrayAsync();
                        var unorderedResults = await _pricingService.GetPricelistAssignmentsByIdAsync(pricelistAssignmentsIds);
                        result.Results = unorderedResults.OrderBy(x => Array.IndexOf(pricelistAssignmentsIds, x.Id)).ToList();
                    }
                }
                return result;
            }));
        }
        /// <summary>
        /// Evaluate pricelists for special context. All resulting pricelists ordered by priority
        /// </summary>
        /// <param name="evalContext"></param>
        /// <returns></returns>
        public virtual async Task <IEnumerable <Pricelist> > EvaluatePriceListsAsync(PriceEvaluationContext evalContext)
        {
            var cacheKey             = CacheKey.With(GetType(), nameof(EvaluatePriceListsAsync));
            var priceListAssignments = await _platformMemoryCache.GetOrCreateExclusiveAsync(cacheKey, async cacheEntry =>
            {
                cacheEntry.AddExpirationToken(PricingCacheRegion.CreateChangeToken());

                return(await GetAllPricelistAssignments());
            });

            var query = priceListAssignments.AsQueryable();

            if (evalContext.CatalogId != null)
            {
                //filter by catalog
                query = query.Where(x => x.CatalogId == evalContext.CatalogId);
            }

            if (evalContext.Currency != null)
            {
                //filter by currency
                query = query.Where(x => x.Pricelist.Currency == evalContext.Currency.ToString());
            }

            if (evalContext.CertainDate != null)
            {
                //filter by date expiration
                query = query.Where(x => (x.StartDate == null || evalContext.CertainDate >= x.StartDate) && (x.EndDate == null || x.EndDate >= evalContext.CertainDate));
            }

            var assignments         = query.AsNoTracking().ToArray();
            var assignmentsToReturn = assignments.Where(x => x.DynamicExpression == null).ToList();

            foreach (var assignment in assignments.Where(x => x.DynamicExpression != null))
            {
                try
                {
                    if (assignment.DynamicExpression.IsSatisfiedBy(evalContext) && assignmentsToReturn.All(x => x.PricelistId != assignment.PricelistId))
                    {
                        assignmentsToReturn.Add(assignment);
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Failed to evaluate price assignment condition.");
                }
            }

            return(assignmentsToReturn.OrderByDescending(x => x.Priority).ThenByDescending(x => x.Name).Select(x => x.Pricelist));
        }
Пример #4
0
        public virtual async Task <PricelistAssignmentSearchResult> SearchPricelistAssignmentsAsync(PricelistAssignmentsSearchCriteria criteria)
        {
            var cacheKey = CacheKey.With(GetType(), nameof(SearchPricelistAssignmentsAsync), criteria.GetCacheKey());

            return(await _platformMemoryCache.GetOrCreateExclusiveAsync(cacheKey, async cacheEntry =>
            {
                cacheEntry.AddExpirationToken(PricingSearchCacheRegion.CreateChangeToken());
                cacheEntry.AddExpirationToken(PricingCacheRegion.CreateChangeToken());

                var retVal = AbstractTypeFactory <PricelistAssignmentSearchResult> .TryCreateInstance();
                using (var repository = _repositoryFactory())
                {
                    var query = repository.PricelistAssignments;

                    if (!criteria.PriceListIds.IsNullOrEmpty())
                    {
                        query = query.Where(x => criteria.PriceListIds.Contains(x.PricelistId));
                    }

                    if (!string.IsNullOrEmpty(criteria.Keyword))
                    {
                        query.Where(x => x.Name.Contains(criteria.Keyword) || x.Description.Contains(criteria.Keyword));
                    }

                    var sortInfos = criteria.SortInfos;
                    if (sortInfos.IsNullOrEmpty())
                    {
                        sortInfos = new[] { new SortInfo {
                                                SortColumn = ReflectionUtility.GetPropertyName <PricelistAssignment>(x => x.Priority)
                                            } };
                    }

                    query = query.OrderBySortInfos(sortInfos);

                    retVal.TotalCount = await query.CountAsync();

                    if (criteria.Take > 0)
                    {
                        query = query.Skip(criteria.Skip).Take(criteria.Take);

                        var pricelistAssignmentsIds = await query.Select(x => x.Id).ToListAsync();
                        retVal.Results =
                            (await _pricingService.GetPricelistAssignmentsByIdAsync(pricelistAssignmentsIds.ToArray()))
                            .OrderBy(x => pricelistAssignmentsIds.IndexOf(x.Id))
                            .ToList();
                    }
                }
                return retVal;
            }));
        }
Пример #5
0
        public virtual async Task <IList <Pricelist> > EvaluatePricesListsAsync(PriceEvaluationContext evalContext, WorkContext workContext)
        {
            if (evalContext == null)
            {
                throw new ArgumentNullException(nameof(evalContext));
            }
            if (workContext == null)
            {
                throw new ArgumentNullException(nameof(workContext));
            }
            var cacheKey = CacheKey.With(GetType(), "EvaluatePricesListsAsync", evalContext.GetCacheKey());

            return(await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(PricingCacheRegion.CreateChangeToken());
                cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken());

                return (await _pricingApi.EvaluatePriceListsAsync(evalContext.ToPriceEvaluationContextDto())).Select(x => x.ToPricelist(workContext.AllCurrencies, workContext.CurrentLanguage)).ToList();
            }));
        }
Пример #6
0
        public ActionResult ResetCache()
        {
            //TODO: Replace to some other (maybe with using reflection)
            ThemeEngineCacheRegion.ExpireRegion();
            CartCacheRegion.ExpireRegion();
            CatalogCacheRegion.ExpireRegion();
            ContentBlobCacheRegion.ExpireRegion();
            CustomerCacheRegion.ExpireRegion();
            MarketingCacheRegion.ExpireRegion();
            PricingCacheRegion.ExpireRegion();
            QuoteCacheRegion.ExpireRegion();
            RecommendationsCacheRegion.ExpireRegion();
            StaticContentCacheRegion.ExpireRegion();
            StoreCacheRegion.ExpireRegion();
            TaxCacheRegion.ExpireRegion();
            SubscriptionCacheRegion.ExpireRegion();
            SecurityCacheRegion.ExpireRegion();

            return(StoreFrontRedirect("~/"));
        }
 private void ResetCache()
 {
     //Clear cache (Smart cache implementation)
     PricingCacheRegion.ExpireRegion();
     PricingSearchCacheRegion.ExpireRegion();
 }
Пример #8
0
        /// <summary>
        /// Evaluate pricelists for special context. All resulting pricelists ordered by priority
        /// </summary>
        /// <param name="evalContext"></param>
        /// <returns></returns>
        public virtual async Task <IEnumerable <Pricelist> > EvaluatePriceListsAsync(PriceEvaluationContext evalContext)
        {
            var cacheKey             = CacheKey.With(GetType(), nameof(EvaluatePriceListsAsync));
            var priceListAssignments = await _platformMemoryCache.GetOrCreateExclusiveAsync(cacheKey, async cacheEntry =>
            {
                cacheEntry.AddExpirationToken(PricingCacheRegion.CreateChangeToken());

                using (var repository = _repositoryFactory())
                {
                    var allAssignments = (await repository.PricelistAssignments.Include(x => x.Pricelist).ToArrayAsync()).Select(x => x.ToModel(AbstractTypeFactory <PricelistAssignment> .TryCreateInstance())).ToArray();
                    foreach (var assignment in allAssignments.Where(x => !string.IsNullOrEmpty(x.ConditionExpression)))
                    {
                        try
                        {
                            //Deserialize conditions
                            assignment.Conditions = JsonConvert.DeserializeObject <IConditionTree[]>(assignment.ConditionExpression, new ConditionJsonConverter());
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, "Failed to deserialize an expression.");
                        }
                    }
                    return(allAssignments);
                }
            });

            var query = priceListAssignments.AsQueryable();

            if (evalContext.CatalogId != null)
            {
                //filter by catalog
                query = query.Where(x => x.CatalogId == evalContext.CatalogId);
            }

            if (evalContext.Currency != null)
            {
                //filter by currency
                query = query.Where(x => x.Pricelist.Currency == evalContext.Currency.ToString());
            }
            if (evalContext.CertainDate != null)
            {
                //filter by date expiration
                query = query.Where(x => (x.StartDate == null || evalContext.CertainDate >= x.StartDate) && (x.EndDate == null || x.EndDate >= evalContext.CertainDate));
            }

            var assignments         = query.ToArray();
            var assignmentsToReturn = assignments.Where(x => x.Conditions.IsNullOrEmpty()).ToList();

            foreach (var assignment in assignments.Where(x => !x.Conditions.IsNullOrEmpty()))
            {
                try
                {
                    if (assignment.Conditions.All(x => x.Evaluate(evalContext)))
                    {
                        if (assignmentsToReturn.All(x => x.PricelistId != assignment.PricelistId))
                        {
                            assignmentsToReturn.Add(assignment);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Failed to evaluate price assignment condition.");
                }
            }

            return(assignmentsToReturn.OrderByDescending(x => x.Priority).ThenByDescending(x => x.Name).Select(x => x.Pricelist));
        }