Esempio n. 1
0
            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()));
            }
Esempio n. 3
0
            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));
            }