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); }
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)); }
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; })); }
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(); })); }
/// <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)); }