/// <summary> /// Setup the variant data for the sale line. /// </summary> /// <param name="context">The CRT context.</param> /// <param name="inventDimensionId">The invent dimension identifier.</param> /// <param name="itemId">The item identifier.</param> /// <param name="lineItem">The sales line to update.</param> internal static void SetUpVariantAndProduct(RequestContext context, string inventDimensionId, string itemId, SalesLine lineItem) { // Get the product corresponding to this item. // It is expected to get product details // even if the product is not assorted, as long as // respected product exists on headquarters. long channelId = context.GetPrincipal().ChannelId; // Search product with itemId and InventDimensionId. var itemAndInventDimIdCombination = new List <ProductLookupClause> { new ProductLookupClause(itemId, inventDimensionId) }; var productsRequest = new GetProductsServiceRequest(channelId, itemAndInventDimIdCombination, QueryResultSettings.AllRecords) { SearchLocation = SearchLocation.All }; var product = context.Execute <GetProductsServiceResponse>(productsRequest).Products.Results.OrderBy(p => p.IsRemote).FirstOrDefault(); if (product == null) { throw new DataValidationException( DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_UnableToFindListing, string.Format("Unable to find listing for item {0}, variant {1}, channel {2}.", lineItem.ItemId, lineItem.InventoryDimensionId, context.GetPrincipal().ChannelId)); } // Populate variant information // Processing variants. if (!string.IsNullOrWhiteSpace(inventDimensionId)) { lineItem.Variant = null; if (product.IsDistinct) { lineItem.Variant = ProductVariant.ConvertFrom(product); } if (lineItem.Variant == null) { throw new DataValidationException( DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_UnableToFindVariant, string.Format("Unable to find variant for invent Dimension id {0}, channel {1}.", inventDimensionId, context.GetPrincipal().ChannelId)); } lineItem.InventoryDimensionId = lineItem.Variant.InventoryDimensionId; lineItem.ProductId = lineItem.Variant.DistinctProductVariantId; } else { lineItem.InventoryDimensionId = string.Empty; lineItem.ProductId = product.RecordId; } }
private static IEnumerable <Product> ConvertSimpleProductsToProducts(IEnumerable <SimpleProduct> simpleProducts) { List <Product> productsTransformedForPricing = new List <Product>(simpleProducts.Count()); foreach (SimpleProduct simpleProduct in simpleProducts) { Product product = null; if (simpleProduct.MasterProductId.HasValue) { product = (productsTransformedForPricing.Where(p => p.RecordId == simpleProduct.MasterProductId.Value).Count() == 1) ? productsTransformedForPricing.Single(p => p.RecordId == simpleProduct.MasterProductId.Value) : null; } if (product == null) { product = new Product { RecordId = simpleProduct.MasterProductId.HasValue ? simpleProduct.MasterProductId.Value : simpleProduct.RecordId, ItemId = simpleProduct.ItemId, DefaultUnitOfMeasure = simpleProduct.DefaultUnitOfMeasure, IsRemote = simpleProduct.IsRemote, IsMasterProduct = simpleProduct.ProductType == ProductType.Master || simpleProduct.ProductType == ProductType.KitMaster || simpleProduct.ProductType == ProductType.Variant || simpleProduct.ProductType == ProductType.KitVariant, }; } if (product.CompositionInformation == null) { product.CompositionInformation = new ProductCompositionInformation { VariantInformation = new ProductVariantInformation() }; } if (simpleProduct.ProductType == ProductType.Variant || simpleProduct.ProductType == ProductType.KitVariant) { product.CompositionInformation.VariantInformation.IndexedVariants.Add( simpleProduct.RecordId, ProductVariant.ConvertFrom(simpleProduct)); } if (!productsTransformedForPricing.Exists(p => p.RecordId == (simpleProduct.MasterProductId.HasValue ? simpleProduct.MasterProductId.Value : simpleProduct.RecordId))) { productsTransformedForPricing.Add(product); } } return(productsTransformedForPricing); }
/// <summary> /// Processes the create cart lines request. /// </summary> /// <param name="context">The context.</param> /// <param name="request">The request.</param> /// <param name="transaction">Current transaction.</param> /// <param name="returnTransaction">Return transaction.</param> /// <param name="productByRecordId">The mapping of products by record identifier.</param> private static void ProcessCreateCartLinesRequest(RequestContext context, SaveCartLinesRequest request, SalesTransaction transaction, SalesTransaction returnTransaction, IDictionary <long, SimpleProduct> productByRecordId) { // Create the new cart lines. var salesLines = new List <SalesLine>(); foreach (CartLine cartLine in request.CartLines) { var salesLine = new SalesLine(); if (!cartLine.LineData.IsReturnByReceipt) { // Creates a sales line base on the cart line salesLine.CopyPropertiesFrom(cartLine.LineData); // Set ItemId and VariantInventDimId of the sales line, if the cart line is constructed from listing. if (cartLine.LineData.IsProductLine) { long id = cartLine.LineData.ProductId; SimpleProduct product = productByRecordId[id]; salesLine.ItemId = product.ItemId; salesLine.ProductId = id; salesLine.InventoryDimensionId = product.InventoryDimensionId; salesLine.Variant = ProductVariant.ConvertFrom(product); } } else { // Creates a sales line base on the retuned sales line var returnedSalesLine = CartWorkflowHelper.GetSalesLineByNumber(returnTransaction, cartLine.LineData.ReturnLineNumber); CartWorkflowHelper.SetSalesLineBasedOnReturnedSalesLine(salesLine, returnedSalesLine, returnTransaction, cartLine.LineData.Quantity); // Calculate required reason code lines for return transaction. ReasonCodesWorkflowHelper.CalculateRequiredReasonCodesOnSalesLine(context, transaction, salesLine, ReasonCodeSourceType.ReturnItem); } // Assign sales line Id. Using format 'N' to remove dashes from the GUID. salesLine.LineId = Guid.NewGuid().ToString("N"); // Add sales lines to collection. salesLines.Add(salesLine); } // Set default attributes from order header. CartWorkflowHelper.SetDefaultDataOnSalesLines(context, transaction, salesLines); // Add sales lines to transation. transaction.SalesLines.AddRange(salesLines); }
/// <summary> /// Populates the product information on the sales lines. /// </summary> /// <param name="context">The request context.</param> /// <param name="salesTransactions">The list of sales transactions.</param> /// <param name="mustRemoveUnavailableProductLines">A flag indicating whether to remove cart lines with unavailable products.</param> /// <param name="productsSearchLocation">Products search location.</param> /// <returns>Collection of unavailable product identifiers.</returns> private static IDictionary <string, IList <SalesLine> > PopulateProductOnSalesLines(RequestContext context, IEnumerable <SalesTransaction> salesTransactions, bool mustRemoveUnavailableProductLines, SearchLocation productsSearchLocation) { var productIdToLineAndTransactionMapping = new Dictionary <long, List <Tuple <SalesLine, SalesTransaction> > >(); var linesWithUnavilableProducts = new Dictionary <string, IList <SalesLine> >(); foreach (SalesTransaction transaction in salesTransactions) { IEnumerable <SalesLine> productSalesLines = transaction.SalesLines.Where(line => line.ProductId != 0); foreach (SalesLine line in productSalesLines) { long productId = line.ProductId; if (!productIdToLineAndTransactionMapping.ContainsKey(productId)) { productIdToLineAndTransactionMapping.Add(productId, new List <Tuple <SalesLine, SalesTransaction> >()); } productIdToLineAndTransactionMapping[productId].Add(new Tuple <SalesLine, SalesTransaction>(line, transaction)); } } if (productIdToLineAndTransactionMapping.IsNullOrEmpty()) { return(linesWithUnavilableProducts); } // Get referenced productIds for CartLines to be created var productIds = productIdToLineAndTransactionMapping.Keys.ToList(); var request = new GetProductsServiceRequest(context.GetPrincipal().ChannelId, productIds, calculatePrice: false, settings: QueryResultSettings.AllRecords) { SearchLocation = productsSearchLocation }; var results = context.Runtime.Execute <GetProductsServiceResponse>(request, context).Products.Results.OrderBy(p => p.IsRemote); var productByRecordId = new Dictionary <long, SimpleProduct>(); foreach (var product in results) { if (!productByRecordId.ContainsKey(product.RecordId)) { productByRecordId[product.RecordId] = product; } } foreach (KeyValuePair <long, List <Tuple <SalesLine, SalesTransaction> > > mapping in productIdToLineAndTransactionMapping) { SimpleProduct product; bool productFound = productByRecordId.TryGetValue(mapping.Key, out product); foreach (Tuple <SalesLine, SalesTransaction> lineTransactionPair in mapping.Value) { SalesLine salesLine = lineTransactionPair.Item1; SalesTransaction transaction = lineTransactionPair.Item2; if (!productFound) { if (mustRemoveUnavailableProductLines) { transaction.SalesLines.Remove(salesLine); } else { salesLine.Variant = null; } if (!linesWithUnavilableProducts.ContainsKey(transaction.Id)) { linesWithUnavilableProducts.Add(transaction.Id, new List <SalesLine>()); } linesWithUnavilableProducts[transaction.Id].Add(salesLine); continue; } if (product.IsDistinct) { salesLine.Variant = ProductVariant.ConvertFrom(product); } } } return(linesWithUnavilableProducts); }