예제 #1
0
        public virtual async Task EvaluateProductInventoriesAsync(IEnumerable <Product> products, WorkContext workContext)
        {
            if (products == null)
            {
                throw new ArgumentNullException(nameof(products));
            }
            var productIds  = products.Select(x => x.Id).ToList();
            var cacheKey    = CacheKey.With(GetType(), "EvaluateProductInventoriesAsync", string.Join("-", productIds.OrderBy(x => x)));
            var inventories = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.SetAbsoluteExpiration(TimeSpan.FromMinutes(1));
                cacheEntry.AddExpirationToken(InventoryCacheRegion.CreateChangeToken());
                cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken());

                return(await _inventoryApi.GetProductsInventoriesByPlentyIdsAsync(productIds));
            });

            var availFullfilmentCentersIds = workContext.CurrentStore.AvailFulfillmentCenterIds;

            foreach (var item in products)
            {
                //TODO: Change these conditions to DDD specification
                item.InventoryAll = inventories.Where(x => x.ProductId == item.Id).Select(x => x.ToInventory()).Where(x => availFullfilmentCentersIds.Contains(x.FulfillmentCenterId)).ToList();
                item.Inventory    = item.InventoryAll.OrderByDescending(x => Math.Max(0, (x.InStockQuantity ?? 0L) - (x.ReservedQuantity ?? 0L))).FirstOrDefault();

                if (workContext.CurrentStore.DefaultFulfillmentCenterId != null)
                {
                    item.Inventory = item.InventoryAll.FirstOrDefault(x => x.FulfillmentCenterId == workContext.CurrentStore.DefaultFulfillmentCenterId)
                                     ?? item.Inventory;
                }
            }
        }
예제 #2
0
        public virtual async Task <Contact> GetContactByIdAsync(string contactId)
        {
            if (contactId == null)
            {
                throw new ArgumentNullException(nameof(contactId));
            }

            Contact result   = null;
            var     cacheKey = CacheKey.With(GetType(), "GetContactByIdAsync", contactId);
            var     dto      = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                var contactDto = await _customerApi.GetContactByIdAsync(contactId);
                if (contactDto != null)
                {
                    cacheEntry.AddExpirationToken(CustomerCacheRegion.CreateChangeToken(contactDto.Id));
                    cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken());
                }
                return(contactDto);
            });

            if (dto != null)
            {
                result = dto.ToContact();
                if (!dto.Organizations.IsNullOrEmpty())
                {
                    //Load contact organization
                    result.Organization = await GetOrganizationByIdAsync(dto.Organizations.FirstOrDefault());
                }
            }
            return(result);
        }
        public async Task <IList <PaymentPlan> > GetPaymentPlansByIdsAsync(string[] ids)
        {
            var cacheKey = CacheKey.With(GetType(), "GetPaymentPlansByIdsAsync", string.Join("-", ids.OrderBy(x => x)));

            return(await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(PaymentPlanCacheRegion.CreateChangeToken());
                return (await _subscriptionApi.GetPaymentPlansByPlentyIdsAsync(ids)).Select(x => x.ToPaymentPlan()).ToList();
            }));
        }
예제 #4
0
        public async Task <Model.Stores.Store[]> GetAllStoresAsync()
        {
            var cacheKey = CacheKey.With(GetType(), "GetAllStoresAsync");

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

                var storeDtos = await _storeApi.GetStoresAsync();
                return await Task.WhenAll(storeDtos.Select(x => ConvertStoreAndLoadDependeciesAsync(x)));
            }, cacheNullValue : false));
        }
예제 #5
0
        public async Task <IPagedList <Model.CustomerReviews.CustomerReview> > GetCustomerReviewsAsync(CustomerReviewSearchCriteria criteria)
        {
            var workContext = _workContextAccessor.WorkContext;
            var cacheKey    = CacheKey.With(GetType(), nameof(GetCustomerReviewsAsync), criteria.GetCacheKey(), workContext.CurrentLanguage.CultureName);

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

                var result = await _customerReviewsApi.SearchCustomerReviewsAsync(criteria.ToSearchCriteriaDto());
                return new StaticPagedList <Model.CustomerReviews.CustomerReview>(result.Results.Select(x => x.ToCustomerReview()), criteria.PageNumber, criteria.PageSize, result.TotalCount.Value);
            }));
        }
        public async Task <IPagedList <CutomerReviewModel> > SearchReviewAsync(CustomerReviewSearchCriteria criteria)
        {
            var cacheKey = CacheKey.With(GetType(), nameof(SearchReviewAsync), criteria.GetCacheKey());

            return(await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.ExpirationTokens.Add(CustomerReviewCacheRegion.CreateChangeToken(criteria.ProductIds.FirstOrDefault()));
                cacheEntry.ExpirationTokens.Add(_apiChangesWatcher.CreateChangeToken());

                var result = await _customerReviews.SearchCustomerReviewsAsync(criteria.ToSearchCriteriaDto());
                return new StaticPagedList <CutomerReviewModel>(result.Results.Select(c => c.ToCustomerReview()),
                                                                criteria.PageNumber, criteria.PageSize, result.TotalCount.Value);
            }
                                                                ));
        }
        public async Task Invoke(HttpContext context)
        {
            var cacheKey = CacheKey.With(GetType(), "GetAllPlatformRoles");

            try
            {
                await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
                {
                    cacheEntry.AddExpirationToken(SecurityCacheRegion.CreateChangeToken());
                    var allRolesIds = (await _platformSecurityApi.SearchRolesAsync(new RoleSearchCriteria {
                        Take = int.MaxValue
                    })).Roles.Select(x => x.Id).ToArray();
                    foreach (var role in SecurityConstants.Roles.AllRoles)
                    {
                        if (!allRolesIds.Contains(role.Id))
                        {
                            await _platformSecurityApi.UpdateRoleAsync(role.ToRoleDto());
                        }
                    }
                    return(allRolesIds);
                }, cacheNullValue : false);
            }
            catch (Exception ex)
            {
                _looger.LogError(ex, ex.Message);
            }

            await _next(context);
        }
        private async Task <Dictionary <string, AuthorizationPolicy> > GetDynamicAuthorizationPoliciesFromPlatformPermissions()
        {
            var cacheKey = CacheKey.With(GetType(), "GetDynamicAuthorizationPoliciesFromPlatformPermissions");
            var result   = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(SecurityCacheRegion.CreateChangeToken());

                var resultLookup = new Dictionary <string, AuthorizationPolicy>();
                foreach (var permission in await _platformSecurityApi.GetAllRegisteredPermissionsAsync())
                {
                    resultLookup[permission.Id] = new AuthorizationPolicyBuilder().AddRequirements(new PermissionAuthorizationRequirement {
                        Permission = permission.Id
                    }).Build();
                }

                //Register storefront permissions
                foreach (var permission in SecurityConstants.Permissions.AllPermissions)
                {
                    resultLookup[permission] = new AuthorizationPolicyBuilder().AddRequirements(new PermissionAuthorizationRequirement {
                        Permission = permission
                    }).Build();
                }

                return(resultLookup);
            });

            return(result);
        }
예제 #9
0
        public virtual async Task <Category[]> GetCategoriesAsync(string[] ids, CategoryResponseGroup responseGroup = CategoryResponseGroup.Info)
        {
            var workContext   = _workContextAccessor.WorkContext;
            var cacheKey      = CacheKey.With(GetType(), "GetCategoriesAsync", string.Join("-", ids.OrderBy(x => x)), responseGroup.ToString());
            var categoriesDto = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(CatalogCacheRegion.CreateChangeToken());
                return(await _categoriesApi.GetCategoriesByPlentyIdsAsync(ids.ToList(), ((int)responseGroup).ToString()));
            });

            var result = categoriesDto.Select(x => x.ToCategory(workContext.CurrentLanguage, workContext.CurrentStore)).ToArray();

            //Set  lazy loading for child categories
            EstablishLazyDependenciesForCategories(result);
            return(result);
        }
예제 #10
0
        public virtual async Task LoadOrCreateNewTransientCartAsync(string cartName, Store store, User user, Language language, Currency currency, string type = null)
        {
            var cacheKey       = CacheKey.With(GetType(), "LoadOrCreateNewTransientCart", store.Id, cartName, user.Id, currency.Code, type);
            var needReevaluate = false;

            Cart = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                needReevaluate = true;

                var cartSearchCriteria = CreateCartSearchCriteria(cartName, store, user, language, currency, type);
                var cartSearchResult   = await _cartService.SearchCartsAsync(cartSearchCriteria);
                var cart = cartSearchResult.FirstOrDefault() ?? CreateCart(cartName, store, user, language, currency, type);

                //Load cart dependencies
                await PrepareCartAsync(cart, store);

                //Add expiration token for concrete cart instance
                cacheEntry.AddExpirationToken(CartCacheRegion.CreateChangeToken(cart));

                return(cart);
            });

            if (needReevaluate)
            {
                await EvaluatePromotionsAsync();
                await EvaluateTaxesAsync();
            }
        }
        public async Task <Product[]> GetRecommendationsAsync(RecommendationEvalContext context)
        {
            var dynamicAssociationsContext = context as DynamicAssociationsEvalContext;

            if (dynamicAssociationsContext == null)
            {
                throw new InvalidCastException(nameof(context));
            }

            var cacheKey = CacheKey.With(GetType(), nameof(GetRecommendationsAsync), context.GetCacheKey());

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

                var result = new List <Product>();
                var recommendedProductIds = await _associationsApi.EvaluateDynamicAssociationsAsync(dynamicAssociationsContext.ToContextDto());

                if (recommendedProductIds != null)
                {
                    result.AddRange(await _catalogService.GetProductsAsync(recommendedProductIds.ToArray(), ItemResponseGroup.Seo | ItemResponseGroup.Outlines | ItemResponseGroup.ItemWithPrices | ItemResponseGroup.ItemWithDiscounts | ItemResponseGroup.Inventory));
                }

                return result.ToArray();
            }));
        }
예제 #12
0
        public virtual async Task <string> GetDynamicContentHtmlAsync(string storeId, string placeholderName)
        {
            string htmlContent = null;

            //TODO: make full context
            var evaluationContext = new DynamicContentEvaluationContext
            {
                StoreId   = storeId,
                PlaceName = placeholderName
            };

            var cacheKey = CacheKey.With(GetType(), "GetDynamicContentHtmlAsync", storeId, placeholderName);

            return(await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(MarketingCacheRegion.CreateChangeToken());
                cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken());
                var dynamicContentItems = (await _dynamicContentApi.EvaluateDynamicContentAsync(evaluationContext)).Select(x => x.ToDynamicContentItem());

                if (dynamicContentItems != null)
                {
                    var htmlContentSpec = new HtmlDynamicContentSpecification();
                    var htmlDynamicContent = dynamicContentItems.FirstOrDefault(htmlContentSpec.IsSatisfiedBy);
                    if (htmlDynamicContent != null)
                    {
                        var dynamicProperty = htmlDynamicContent.DynamicProperties.FirstOrDefault(htmlContentSpec.IsSatisfiedBy);
                        if (dynamicProperty != null && dynamicProperty.Values.Any(v => v.Value != null))
                        {
                            htmlContent = dynamicProperty.Values.First().Value.ToString();
                        }
                    }
                }
                return htmlContent;
            }));
        }
예제 #13
0
        public async Task <IPagedList <ShoppingCart> > SearchCartsAsync(CartSearchCriteria criteria)
        {
            if (criteria == null)
            {
                throw new ArgumentNullException(nameof(criteria));
            }
            var cacheKey = CacheKey.With(GetType(), "SearchCartsAsync", criteria.GetCacheKey());

            return(await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(CartCacheRegion.CreateCustomerChangeToken(criteria.Customer?.Id));

                var resultDto = await _cartApi.SearchAsync(criteria.ToSearchCriteriaDto());
                var result = new List <ShoppingCart>();
                foreach (var cartDto in resultDto.Results)
                {
                    var currency = _workContextAccessor.WorkContext.AllCurrencies.FirstOrDefault(x => x.Equals(cartDto.Currency));
                    var language = string.IsNullOrEmpty(cartDto.LanguageCode) ? Language.InvariantLanguage : new Language(cartDto.LanguageCode);
                    var user = await _userManager.FindByIdAsync(cartDto.CustomerId) ?? criteria.Customer;
                    var cart = cartDto.ToShoppingCart(currency, language, user);
                    result.Add(cart);
                }
                return new StaticPagedList <ShoppingCart>(result, criteria.PageNumber, criteria.PageSize, resultDto.TotalCount.Value);
            }));
        }
예제 #14
0
        public async Task <IPagedList <CustomerReview> > SearchReviewsAsync(CustomerReviewSearchCriteria criteria)
        {
            var cacheKey = CacheKey.With(GetType(), nameof(SearchReviewsAsync), criteria.GetCacheKey());

            return(await _memoryCache.GetOrCreateExclusiveAsync(
                       cacheKey,
                       async cacheEntry =>
            {
                var reviewsChangeToken = CustomerReviewCacheRegion.CreateChangeToken();
                cacheEntry.AddExpirationToken(reviewsChangeToken);

                var apiChangeToken = _apiChangesWatcher.CreateChangeToken();
                cacheEntry.AddExpirationToken(apiChangeToken);

                var searchCriteriaDto = criteria.ToApiSearchCriteria();
                var foundCustomerReviews = await _customerReviewsApi.SearchCustomerReviewsAsync(searchCriteriaDto);
                var totalCount = foundCustomerReviews.TotalCount ?? 0;

                var customerReviews =
                    foundCustomerReviews.Results.Select(customerReview => customerReview.ToCustomerReview());
                return new StaticPagedList <CustomerReview>(
                    customerReviews,
                    criteria.PageNumber,
                    criteria.PageSize,
                    totalCount);
            }));
        }
        public async virtual Task <bool> PathExistsAsync(string path)
        {
            path = NormalizePath(path);
            var cacheKey = CacheKey.With(GetType(), "PathExistsAsync", path);

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

                // If requested path is a directory we should always return true because Azure blob storage does not support checking if directories exist
                var result = string.IsNullOrEmpty(Path.GetExtension(path));
                if (!result)
                {
                    var url = GetAbsoluteUrl(path);
                    try
                    {
                        result = await(await _cloudBlobClient.GetBlobReferenceFromServerAsync(new Uri(url))).ExistsAsync();
                    }
                    catch (Exception)
                    {
                        //Azure blob storage client does not provide method to check blob url exist without throwing exception
                    }
                }
                return result;
            }));
        }
예제 #16
0
        protected virtual async Task <IList <coreDto.SeoInfo> > GetAllSeoRecordsAsync(string slug)
        {
            var result = new List <coreDto.SeoInfo>();

            if (!string.IsNullOrEmpty(slug))
            {
                var cacheKey  = CacheKey.With(GetType(), "GetAllSeoRecords", slug);
                var apiResult = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
                {
                    cacheEntry.AddExpirationToken(RoutingCacheRegion.CreateChangeToken());
                    return(await _coreApi.GetSeoInfoBySlugAsync(slug));
                });

                result.AddRange(apiResult);
            }
            return(result);
        }
예제 #17
0
        public async Task <User> FindByIdAsync(string userId, CancellationToken cancellationToken)
        {
            var cacheKey = CacheKey.With(GetType(), "FindByIdAsync", userId);
            var result   = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                var userDto = await _platformSecurityApi.GetUserByIdAsync(userId);

                return(PrepareUserResult(cacheEntry, userDto));
            }, cacheNullValue : false);

            //Load user associated contact
            if (result != null && result.ContactId != null)
            {
                result.Contact = await _memberService.GetContactByIdAsync(result.ContactId);
            }
            return(result);
        }
예제 #18
0
        public async Task <Currency[]> GetAllCurrenciesAsync(Language language)
        {
            var cacheKey = CacheKey.With(GetType(), language.CultureName);

            return(await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                return (await _commerceApi.GetAllCurrenciesAsync()).Select(x => x.ToCurrency(language)).ToArray();
            }));
        }
예제 #19
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(), "EvaluatePricesLists", 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();
            }));
        }
        public async Task <Model.Stores.Store[]> GetAllStoresAsync()
        {
            var cacheKey = CacheKey.With(GetType(), "GetAllStoresAsync");

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

                return (await _storeApi.GetStoresAsync()).Select(x => x.ToStore()).ToArray();
            }, cacheNullValue : false));
        }
예제 #21
0
        public virtual async Task EvaluateDiscountsAsync(PromotionEvaluationContext context, IEnumerable <IDiscountable> owners)
        {
            var cacheKey = CacheKey.With(GetType(), "EvaluateDiscountsAsync", context.GetCacheKey());
            var rewards  = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(MarketingCacheRegion.CreateChangeToken());
                cacheEntry.SetAbsoluteExpiration(TimeSpan.FromMinutes(1));

                var contextDto = context.ToPromotionEvaluationContextDto();
                return(await _promiotionApi.EvaluatePromotionsAsync(contextDto));
            });

            ApplyRewards(rewards, owners);
        }
        public virtual async Task <IEnumerable <DynamicContentItem> > EvaluateDynamicContentItemsAsync(DynamicContentEvaluationContext evalContext)
        {
            var cacheKey = CacheKey.With(GetType(), "EvaluateDynamicContentItemsAsync", evalContext.GetCacheKey());

            return(await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(MarketingCacheRegion.CreateChangeToken());
                cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken());
                var evalContextDto = evalContext.ToDynamicContentEvaluationContextDto();
                var dynamicContentItems = (await _dynamicContentApi.EvaluateDynamicContentAsync(evalContextDto)).Select(x => x.ToDynamicContentItem());

                return dynamicContentItems;
            }));
        }
예제 #23
0
        public virtual async Task EvaluateDiscountsAsync(PromotionEvaluationContext context, IEnumerable <IDiscountable> owners)
        {
            var cacheKey = CacheKey.With(GetType(), "EvaluateDiscountsAsync", context.GetCacheKey());
            var rewards  = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(MarketingCacheRegion.CreateChangeToken());
                //Workaround: Use lifetime for promotions from ChangesPollingInterval setting to be able manage this value
                cacheEntry.SetAbsoluteExpiration(_storefrontOptions.ChangesPollingInterval);

                var contextDto = context.ToPromotionEvaluationContextDto();
                return(await _promiotionApi.EvaluatePromotionsAsync(contextDto));
            });

            ApplyRewards(rewards, owners);
        }
예제 #24
0
        public virtual async Task EvaluateTaxesAsync(TaxEvaluationContext context, IEnumerable <ITaxable> owners)
        {
            IList <coreService.TaxRate> taxRates = new List <coreService.TaxRate>();

            if (context.StoreTaxCalculationEnabled)
            {
                var cacheKey = CacheKey.With(GetType(), context.GetCacheKey());

                taxRates = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, (cacheEntry) =>
                {
                    cacheEntry.AddExpirationToken(TaxCacheRegion.CreateChangeToken());
                    return(_commerceApi.EvaluateTaxesAsync(context.StoreId, context.ToTaxEvaluationContextDto()));
                });
            }
            ApplyTaxRates(taxRates, owners);
        }
예제 #25
0
        public async Task <IDictionary <string, object> > GetMemberIndexByIdAsync(string memberId)
        {
            ValidateParameters(memberId);

            var cacheKey = CacheKey.With(GetType(), "GetMemberIndexByIdAsync", memberId);
            var result   = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                var indexDto = await _demoSearchApi.GetDocumentIndexAsyncAsync(nameof(Member), memberId);

                cacheEntry.AddExpirationToken(CustomerCacheRegion.CreateChangeToken(memberId));
                cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken());
                return(indexDto);
            });

            return(result);
        }
        public async Task <IQuoteRequestBuilder> GetOrCreateNewTransientQuoteRequestAsync(Store store, User user, Language language, Currency currency)
        {
            var cacheKey = CacheKey.With(GetType(), store.Id, user.Id);

            _quoteRequest = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                var activeQuoteSearchCriteria = new quoteModel.QuoteRequestSearchCriteria
                {
                    Tag        = "actual",
                    CustomerId = user.Id,
                    StoreId    = store.Id
                };

                var searchResult = await _quoteApi.SearchAsync(activeQuoteSearchCriteria);

                var quoteRequest = searchResult.QuoteRequests.Select(x => x.ToQuoteRequest(currency, language)).FirstOrDefault();
                if (quoteRequest == null)
                {
                    quoteRequest = new QuoteRequest(currency, language)
                    {
                        Currency   = currency,
                        CustomerId = user.Id,
                        Language   = language,
                        Status     = "New",
                        StoreId    = store.Id,
                        Tag        = "actual"
                    };

                    quoteRequest.CustomerName = user.UserName;
                }
                else
                {
                    quoteRequest = (await _quoteApi.GetByIdAsync(quoteRequest.Id)).ToQuoteRequest(currency, language);
                }
                //Add expiration token for concrete quote instance
                cacheEntry.AddExpirationToken(QuoteCacheRegion.CreateChangeToken(quoteRequest));
                quoteRequest.Customer = user;

                return(quoteRequest);
            });

            return(this);
        }
        public virtual async Task EvaluateTaxesAsync(TaxEvaluationContext context, IEnumerable <ITaxable> owners)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (owners == null)
            {
                throw new ArgumentNullException(nameof(owners));
            }
            IList <coreService.TaxRate> taxRates = new List <coreService.TaxRate>();

            if (context.StoreTaxCalculationEnabled)
            {
                //Do not execute platform API for tax evaluation if fixed tax rate is used
                if (context.FixedTaxRate != 0)
                {
                    foreach (var line in context.Lines ?? Enumerable.Empty <TaxLine>())
                    {
                        var rate = new coreService.TaxRate()
                        {
                            Rate     = (double)(line.Amount * context.FixedTaxRate * 0.01m).Amount,
                            Currency = context.Currency.Code,
                            Line     = line.ToTaxLineDto()
                        };
                        taxRates.Add(rate);
                    }
                }
                else
                {
                    var cacheKey = CacheKey.With(GetType(), context.GetCacheKey());
                    taxRates = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, (cacheEntry) =>
                    {
                        cacheEntry.AddExpirationToken(TaxCacheRegion.CreateChangeToken());
                        return(_commerceApi.EvaluateTaxesAsync(context.StoreId, context.ToTaxEvaluationContextDto()));
                    });
                }
            }
            ApplyTaxRates(taxRates, owners);
        }
        public async Task <ProductPart[]> GetProductPartsAsync(string productId)
        {
            var workContext = _workContextAccessor.WorkContext;
            var cacheKey    = CacheKey.With(GetType(), nameof(GetProductPartsAsync), productId);

            var searchResult = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(CatalogCacheRegion.CreateChangeToken());
                cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken());
                var searchPartsResultDto = await _demoCatalogApi.SearchAsync(new DemoProductPartSearchCriteria {
                    ConfiguredProductId = productId, Take = int.MaxValue
                });
                return(searchPartsResultDto);
            });

            var partItemIds = searchResult.Results?
                              .Where(x => x.PartItems != null).SelectMany(x => x.PartItems).Select(x => x.ItemId).Distinct()
                              .ToArray();

            var allPartItems = !partItemIds.IsNullOrEmpty() ? await GetProductsAsync(partItemIds) : null; // Potential recursion

            ProductPart ConvertDtoToProductPartAndAttachItsItems(DemoProductPart x, WorkContext workContext, Product[] allPartItems)
            {
                var productPart = x.ToProductPart(workContext.CurrentLanguage.CultureName);

                productPart.Items = x.PartItems?
                                    .OrderBy(partItemInfo => partItemInfo.Priority)
                                    .Select(partItemInfo => allPartItems?.FirstOrDefault(product => product.Id.EqualsInvariant(partItemInfo.ItemId)))
                                    .Where(product => product != null)
                                    .ToArray() ?? Array.Empty <Product>();
                return(productPart);
            }

            var productParts = searchResult.Results?.OrderBy(x => x.Priority).Select(x => ConvertDtoToProductPartAndAttachItsItems(x, workContext, allPartItems))
                               .ToArray <ProductPart>() ?? Array.Empty <ProductPart>();

            return(productParts);
        }
예제 #29
0
        public async virtual Task <bool> PathExistsAsync(string path)
        {
            path = NormalizePath(path);
            var cacheKey = CacheKey.With(GetType(), "PathExistsAsync", path);

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

                var isDirectory = string.IsNullOrEmpty(Path.GetExtension(path));
                var result = false;

                if (isDirectory)
                {
                    //There is only one way to check if the blob directory exists is to request its contents.
                    BlobContinuationToken token = null;
                    var operationContext = new OperationContext();
                    var directory = GetCloudBlobDirectory(path);
                    var resultSegment = await directory.ListBlobsSegmentedAsync(true, BlobListingDetails.Metadata, 1, token, _options.BlobRequestOptions, operationContext);
                    result = resultSegment.Results.Any();
                }
                else
                {
                    try
                    {
                        var url = GetAbsoluteUrl(path);
                        result = await(await _cloudBlobClient.GetBlobReferenceFromServerAsync(new Uri(url))).ExistsAsync();
                    }
                    catch (Exception)
                    {
                        //Azure blob storage client does not provide method to check blob url exist without throwing exception
                    }
                }

                return result;
            }));
        }
예제 #30
0
        public async Task <IList <MenuLinkList> > LoadAllStoreLinkListsAsync(Store store, Language language)
        {
            if (store == null)
            {
                throw new ArgumentNullException(nameof(store));
            }
            var cacheKey = CacheKey.With(GetType(), "LoadAllStoreLinkLists", store.Id, language.CultureName);

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

                var result = new List <MenuLinkList>();
                var listsDto = await _cmsApi.GetListsAsync(store.Id);
                if (listsDto != null)
                {
                    result.AddRange(listsDto.Select(x => x.ToMenuLinkList()));
                }

                result = result.GroupBy(x => x.Name).Select(x => x.FindWithLanguage(language)).Where(x => x != null).ToList().ToList();

                var allMenuLinks = result.SelectMany(x => x.MenuLinks).ToList();
                var productLinks = allMenuLinks.OfType <ProductMenuLink>().ToList();
                var categoryLinks = allMenuLinks.OfType <CategoryMenuLink>().ToList();

                Task <Product[]> productsLoadingTask = null;
                Task <Category[]> categoriesLoadingTask = null;

                //Parallel loading associated objects
                var productIds = productLinks.Select(x => x.AssociatedObjectId).ToArray();
                if (productIds.Any())
                {
                    productsLoadingTask = _catalogService.GetProductsAsync(productIds, ItemResponseGroup.ItemSmall);
                }
                var categoriesIds = categoryLinks.Select(x => x.AssociatedObjectId).ToArray();
                if (categoriesIds.Any())
                {
                    categoriesLoadingTask = _catalogService.GetCategoriesAsync(categoriesIds, CategoryResponseGroup.Info | CategoryResponseGroup.WithImages | CategoryResponseGroup.WithSeo | CategoryResponseGroup.WithOutlines);
                }
                //Populate link by associated product
                if (productsLoadingTask != null)
                {
                    var products = await productsLoadingTask;
                    foreach (var productLink in productLinks)
                    {
                        productLink.Product = products.FirstOrDefault(x => x.Id == productLink.AssociatedObjectId);
                    }
                }
                //Populate link by associated category
                if (categoriesLoadingTask != null)
                {
                    var categories = await categoriesLoadingTask;
                    foreach (var categoryLink in categoryLinks)
                    {
                        categoryLink.Category = categories.FirstOrDefault(x => x.Id == categoryLink.AssociatedObjectId);
                    }
                }

                return result.ToList();
            }));
        }