private static EntityDataServiceResponse <ProductVariant> GetVariantsByDimensionIds(GetVariantsByDimensionIdsDataRequest request) { IEnumerable <string> inventoryDimensionIds = request.InventoryDimensionIds; RequestContext context = request.RequestContext; ThrowIf.Null(inventoryDimensionIds, "inventoryDimensionIds"); ThrowIf.Null(context, "context"); ItemL2CacheDataStoreAccessor level2CacheDataAccessor = GetCacheAccessor(context); bool found; bool updateL2Cache; ReadOnlyCollection <ProductVariant> result = DataManager.GetDataFromCache(() => level2CacheDataAccessor.GetVariantsByDimensionIds(inventoryDimensionIds), out found, out updateL2Cache); if (!found) { if (inventoryDimensionIds.Any()) { var settings = new QueryResultSettings(PagingInfo.CreateWithExactCount(inventoryDimensionIds.Count(), 0)); var query = new SqlPagedQuery(settings) { Select = new ColumnSet(), From = InventDimViewName, Where = string.Format("{0} = {1}", DataAreaIdColumnName, DataAreaIdVariableName) }; query.Parameters[DataAreaIdVariableName] = context.GetChannelConfiguration().InventLocationDataAreaId; using (StringIdTableType type = new StringIdTableType(inventoryDimensionIds, InventDimIdColumnName)) { query.Parameters[ItemIdTableTypeVariableName] = type; using (DatabaseContext databaseContext = new DatabaseContext(context)) { result = databaseContext.ReadEntity <ProductVariant>(query).Results; } } } else { result = new ReadOnlyCollection <ProductVariant>(new ProductVariant[0]); } updateL2Cache &= result != null && result.Count < MaxCachedCollectionSize; } if (updateL2Cache) { level2CacheDataAccessor.PutVariantDimensionsByItemIds(inventoryDimensionIds, result); } return(new EntityDataServiceResponse <ProductVariant>(result.AsPagedResult())); }
/// <summary> /// Executes the workflow to retrieve active product prices for given product ids. /// </summary> /// <param name="request">The request.</param> /// <returns>The response.</returns> protected override GetActiveProductPriceResponse Process(GetActiveProductPriceRequest request) { ThrowIf.Null(request, "request"); var validateCustomerAccountRequest = new GetValidatedCustomerAccountNumberServiceRequest(request.CustomerAccountNumber, throwOnValidationFailure: true); var validateCustomerAccountResponse = this.Context.Execute <GetValidatedCustomerAccountNumberServiceResponse>(validateCustomerAccountRequest); if (validateCustomerAccountResponse.IsCustomerAccountNumberInContextDifferent) { request.CustomerAccountNumber = validateCustomerAccountResponse.ValidatedAccountNumber; } bool downloadedProductsFilter = false; if (request.Context.ChannelId != this.Context.GetPrincipal().ChannelId) { downloadedProductsFilter = true; } var settings = new QueryResultSettings(PagingInfo.CreateWithExactCount(request.ProductIds.Count(), 0)); var productsRequest = new GetProductsDataRequest(request.ProductIds, settings, downloadedProductsFilter); var products = this.Context.Execute <EntityDataServiceResponse <SimpleProduct> >(productsRequest).PagedEntityCollection.Results; var activePrices = new List <ProductPrice>(products.Count); // package sales lines to calculate var salesLines = new List <SalesLine>(products.Count); foreach (var product in products) { salesLines.Add(new SalesLine { ItemId = product.ItemId, InventoryDimensionId = product.InventoryDimensionId, SalesOrderUnitOfMeasure = product.DefaultUnitOfMeasure, LineId = System.Guid.NewGuid().ToString("N"), Quantity = 1, ProductId = product.RecordId, CatalogId = request.Context.CatalogId.GetValueOrDefault() }); } // set the catalogIds on the sales lines if (request.Context.CatalogId != null) { if (request.Context.CatalogId.Value > 0) { // If a specific catalogId is set on the context, add it to the catalogIds on the sales lines. foreach (var sl in salesLines) { sl.CatalogIds.Add(request.Context.CatalogId.Value); } } else { // If catalogId is 0, add all active catalogs to the catalogIds on the sales lines. foreach (var sl in salesLines) { var productCatalogAssociationRequest = new GetProductCatalogAssociationsDataRequest(salesLines.Select(p => p.ProductId)) { QueryResultSettings = QueryResultSettings.AllRecords }; var productCatalogs = request.RequestContext.Runtime.Execute <GetProductCatalogAssociationsDataResponse>( productCatalogAssociationRequest, request.RequestContext).CatalogAssociations; sl.CatalogIds.UnionWith(productCatalogs.Where(pc => pc.ProductRecordId == sl.ProductId).Select(pc => pc.CatalogRecordId)); } } } Customer customer = null; if (!string.IsNullOrWhiteSpace(request.CustomerAccountNumber)) { var getCustomerDataRequest = new GetCustomerDataRequest(request.CustomerAccountNumber); SingleEntityDataServiceResponse <Customer> getCustomerDataResponse = this.Context.Runtime.Execute <SingleEntityDataServiceResponse <Customer> >(getCustomerDataRequest, this.Context); customer = getCustomerDataResponse.Entity; } string priceGroup = customer != null ? customer.PriceGroup : string.Empty; // calculate prices for sales lines var itemPriceServiceRequest = new GetPricesServiceRequest(salesLines, request.DateWhenActive, request.CustomerAccountNumber, priceGroup, PricingCalculationMode.Independent, request.AffiliationLoyaltyTiers); var itemPriceServiceResponse = this.Context.Execute <GetPricesServiceResponse>(itemPriceServiceRequest); var salesLineDictionary = itemPriceServiceResponse.SalesLines.Results.ToDictionary(sl => sl.ProductId); foreach (var product in products) { SalesLine salesLine; if (!salesLineDictionary.TryGetValue(product.RecordId, out salesLine)) { salesLine = new SalesLine(); } ProductPrice activePrice = GetActiveProductPriceRequestHandler.ActivePriceFromSalesLine(product.RecordId, salesLine); activePrice.ProductId = product.RecordId; activePrice.ValidFrom = request.DateWhenActive; activePrice.CurrencyCode = itemPriceServiceResponse.CurrencyCode; activePrice.ChannelId = request.Context.ChannelId.GetValueOrDefault(); activePrice.CatalogId = request.Context.CatalogId.GetValueOrDefault(); activePrices.Add(activePrice); } return(new GetActiveProductPriceResponse(activePrices.AsPagedResult())); }
private static PagedResult <SimpleProduct> PopulateComplexProductProperties(long channelId, PagedResult <SimpleProduct> products, RequestContext context, SearchLocation searchLocation, bool?downloadedProductsFilter, bool calculatePrices) { // Retrieving all id collections needed to query the Data Service for complex properties. var productIds = products.Results.Select(p => p.RecordId); var masterTypeProductIds = products.Results.Where(p => p.ProductType == ProductType.Master).Select(p => p.RecordId); var kitVariantTypeProductIds = products.Results.Where(p => p.ProductType == ProductType.KitVariant).Select(v => v.RecordId); var kitMasterTypeProductIds = products.Results.Where(p => p.ProductType == ProductType.KitMaster).Select(v => v.RecordId); var variantTypeProductIds = products.Results.Where(p => p.ProductType == ProductType.Variant).Select(v => v.RecordId); // Products of types Master and KitMaster have dimensions that need to be retrieved. var idsOfProductsContainingDimensions = masterTypeProductIds.Concat(kitMasterTypeProductIds); IEnumerable <ProductComponent> components = new List <ProductComponent>(); IEnumerable <ProductDimension> productDimensions = new List <ProductDimension>(); IEnumerable <ProductDimensionValue> dimensionValues = new List <ProductDimensionValue>(); // Products of type KitVariant have components that need to be retrieved. if (kitVariantTypeProductIds.Any()) { var getProductComponentsDataRequestColummnSet = ProductComponent.DefaultColumnSet; getProductComponentsDataRequestColummnSet.Add("VARIANTPRODUCTID"); var getProductComponentsDataRequestSettings = new QueryResultSettings(getProductComponentsDataRequestColummnSet, PagingInfo.AllRecords); var getProductComponentsDataRequest = new GetProductComponentsForVariantProductsDataRequest(kitVariantTypeProductIds, getProductComponentsDataRequestSettings, downloadedProductsFilter); components = context.Execute <EntityDataServiceResponse <ProductComponent> >(getProductComponentsDataRequest).PagedEntityCollection.Results; } if (idsOfProductsContainingDimensions.Any()) { var getDimensionsDataRequest = new GetProductDimensionsDataRequest(idsOfProductsContainingDimensions, QueryResultSettings.AllRecords); productDimensions = context.Execute <EntityDataServiceResponse <ProductDimension> >(getDimensionsDataRequest).PagedEntityCollection.Results; } // Products of types Variant and KitVariant have dimension values that need to be retrieved. // This collection is populated after retrieving components so that dimension values of Variant type products can also be retrieved in the same transaction. var idsOfProductsContainingDimensionValues = variantTypeProductIds.Concat(kitVariantTypeProductIds).Concat(components.Where(c => c.ProductType == ProductType.Variant).Select(c => c.ProductId).Distinct()); if (idsOfProductsContainingDimensionValues.Any()) { var getDimensionValuesDataRequest = new GetProductDimensionValuesForVariantProductsDataRequest(idsOfProductsContainingDimensionValues, QueryResultSettings.AllRecords, downloadedProductsFilter); dimensionValues = context.Execute <EntityDataServiceResponse <ProductDimensionValue> >(getDimensionValuesDataRequest).PagedEntityCollection.Results; } var productIdsToFetchBehavior = productIds.Concat(components.Select(c => c.ProductId).Distinct()); var productBehaviorSettings = new QueryResultSettings(ProductBehavior.DefaultColumnSet, PagingInfo.CreateWithExactCount(productIdsToFetchBehavior.Count(), skip: 0)); var productsBehaviorDataRequest = new GetProductBehaviorDataRequest(productIdsToFetchBehavior, productBehaviorSettings, downloadedProductsFilter); PagedResult <ProductBehavior> productsBehavior = context.Execute <EntityDataServiceResponse <ProductBehavior> >(productsBehaviorDataRequest).PagedEntityCollection; var getLinkedProductRelationsDataRequest = new GetLinkedProductRelationsDataRequest(productIds, QueryResultSettings.AllRecords, downloadedProductsFilter); PagedResult <LinkedProductRelation> linkedProductRelations = context.Execute <EntityDataServiceResponse <LinkedProductRelation> >(getLinkedProductRelationsDataRequest).PagedEntityCollection; var linkedProductIds = linkedProductRelations.Results.Select(r => r.LinkedProductId).Distinct(); var getLinkedProductsDataRequest = new GetProductsServiceRequest(channelId, linkedProductIds, QueryResultSettings.AllRecords); getLinkedProductsDataRequest.SearchLocation = searchLocation; PagedResult <SimpleProduct> linkedProducts = context.Execute <GetProductsServiceResponse>(getLinkedProductsDataRequest).Products; PagedResult <ProductPrice> productPrices = PagedResult <ProductPrice> .Empty(); if (calculatePrices) { // Pricing APIs currently take Product instead of SimpleProduct. We manually build a Product object // and populate the required field in the interim until uptake of SimpleProduct in pricing service. List <Product> productsTransformedForPricing = ConvertSimpleProductsToProducts(products.Results).ToList(); var priceRequest = new GetProductPricesServiceRequest(productsTransformedForPricing); productPrices = context.Execute <GetProductPricesServiceResponse>(priceRequest).ProductPrices; } return(InsertProductPropertiesIntoProduct(products, productsBehavior, productPrices, linkedProductRelations, linkedProducts, components, productDimensions, dimensionValues)); }
private static SearchProductsRealtimeResponse RemoteSearchProducts(RemoteSearchProductsRealtimeRequest request) { var client = new TransactionServiceClient(request.RequestContext); PagedResult <ProductSearchResult> searchResults = null; long currentChannelId = request.RequestContext.GetPrincipal().ChannelId; var retrieveAttributeSchemaEntriesDataRequest = new GetProductMediaAttributeSchemaEntriesDataRequest(); retrieveAttributeSchemaEntriesDataRequest.QueryResultSettings = new QueryResultSettings(new ColumnSet(new string[] { "ATTRIBUTE", "DATATYPE" }), PagingInfo.CreateWithExactCount(2, 0), new SortingInfo("DATATYPE")); var attributeSchemaEntries = request.RequestContext.Execute <EntityDataServiceResponse <ProductAttributeSchemaEntry> >(retrieveAttributeSchemaEntriesDataRequest).PagedEntityCollection.Results; var imageAttributeId = attributeSchemaEntries.Single(r => r.DataType == AttributeDataType.Image).RecordId; var attributesValuesToRetrieve = Convert.ToString(imageAttributeId); if (request.CategoryId.HasValue) { searchResults = new PagedResult <ProductSearchResult>(client.SearchProductsByCategoryId(currentChannelId, (long)request.CategoryId, request.RequestContext.LanguageId, request.ChannelId, request.CatalogId, attributesValuesToRetrieve, request.QueryResultSettings), request.QueryResultSettings.Paging); } else if (!string.IsNullOrWhiteSpace(request.SearchText)) { searchResults = new PagedResult <ProductSearchResult>(client.SearchProductsByText(currentChannelId, request.SearchText, request.ChannelId, request.CatalogId, attributesValuesToRetrieve, request.QueryResultSettings), request.QueryResultSettings.Paging); } else { throw new ArgumentOutOfRangeException("request", "A valid category identfier or search text must be provided to search products."); } return(new SearchProductsRealtimeResponse(searchResults)); }