/// <summary> /// Load sales transactions using the search criteria. /// </summary> /// <param name="request">Request containing the criteria used to retrieve sales transactions.</param> /// <returns>Instance of <see cref="GetSalesTransactionsServiceResponse"/>.</returns> private static GetSalesTransactionsServiceResponse GetSalesTransactions(GetSalesTransactionsServiceRequest request) { ThrowIf.Null(request, "request"); IDictionary <string, IList <SalesLine> > linesWithUnavailableProducts; // Try to load the transaction GetCartsDataRequest getSalesTransactionDatasetDataRequest = new GetCartsDataRequest(request.SearchCriteria, request.QueryResultSettings); PagedResult <SalesTransaction> salesTransactions = request.RequestContext.Execute <EntityDataServiceResponse <SalesTransaction> >(getSalesTransactionDatasetDataRequest).PagedEntityCollection; if (salesTransactions != null) { // Only search remote in case of customer order. SearchLocation productSearchLocation = salesTransactions.Results.Any(t => t.CartType == CartType.CustomerOrder) ? SearchLocation.All : SearchLocation.Local; linesWithUnavailableProducts = PopulateProductOnSalesLines(request.RequestContext, salesTransactions.Results, request.MustRemoveUnavailableProductLines, productSearchLocation); } else { salesTransactions = PagedResult <SalesTransaction> .Empty(); linesWithUnavailableProducts = new Dictionary <string, IList <SalesLine> >(); } GetSalesTransactionsServiceResponse response = new GetSalesTransactionsServiceResponse(salesTransactions, linesWithUnavailableProducts); return(response); }
/// <summary> /// Executes the workflow to resume suspended cart. /// </summary> /// <param name="request">Instance of <see cref="ResumeCartRequest"/>.</param> /// <returns>Instance of <see cref="ResumeCartResponse"/>.</returns> protected override ResumeCartResponse Process(ResumeCartRequest request) { ThrowIf.Null(request, "request"); var getSalesTransactionServiceRequest = new GetSalesTransactionsServiceRequest( new CartSearchCriteria { CartId = request.CartId }, QueryResultSettings.SingleRecord, mustRemoveUnavailableProductLines: true); var getSalesTransactionServiceResponse = this.Context.Execute <GetSalesTransactionsServiceResponse>(getSalesTransactionServiceRequest); SalesTransaction transaction = null; if (getSalesTransactionServiceResponse.SalesTransactions != null) { transaction = getSalesTransactionServiceResponse.SalesTransactions.FirstOrDefault(); } if (!transaction.IsSuspended) { throw new CartValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidStatus, request.CartId, "Cart is not suspended."); } // Resume the suspended transaction to normal state. transaction.EntryStatus = TransactionStatus.Normal; transaction.IsSuspended = false; transaction.TerminalId = this.Context.GetTerminal().TerminalId; transaction.BeginDateTime = this.Context.GetNowInChannelTimeZone(); CartWorkflowHelper.Calculate(this.Context, transaction, null); CartWorkflowHelper.SaveSalesTransaction(this.Context, transaction); if (getSalesTransactionServiceResponse.LinesWithUnavailableProducts.Any()) { // Send notification to decide if caller should be notified about discontinued products. var notification = new ProductDiscontinuedFromChannelNotification(getSalesTransactionServiceResponse.LinesWithUnavailableProducts); this.Context.Notify(notification); } Cart cart = CartWorkflowHelper.ConvertToCart(this.Context, transaction); CartWorkflowHelper.RemoveHistoricalTenderLines(cart); return(new ResumeCartResponse(cart)); }
/// <summary> /// Gets the shopping cart specified by cart identifier and optionally calculates the totals on the cart. /// </summary> /// <param name="request">The request.</param> /// <returns><see cref="GetCartResponse"/> object containing the shopping cart or a new one if the flag to create is set and no cart was found.</returns> protected override GetCartResponse Process(GetCartRequest request) { ThrowIf.Null(request, "request"); var validateCustomerAccountRequest = new GetValidatedCustomerAccountNumberServiceRequest(request.SearchCriteria.CustomerAccountNumber, throwOnValidationFailure: false); var validateCustomerAccountResponse = this.Context.Execute <GetValidatedCustomerAccountNumberServiceResponse>(validateCustomerAccountRequest); if (validateCustomerAccountResponse.IsCustomerAccountNumberInContextDifferent) { request.SearchCriteria.CustomerAccountNumber = validateCustomerAccountResponse.ValidatedAccountNumber; request.SearchCriteria.IncludeAnonymous = true; } if (!request.SearchCriteria.SuspendedOnly && string.IsNullOrEmpty(request.SearchCriteria.CartId) && string.IsNullOrEmpty(request.SearchCriteria.CustomerAccountNumber)) { throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidRequest, "SearchCriteria requires one of the following fields to be set: SuspendedOnly, CartId, CustomerAccountNumber."); } if (!string.IsNullOrEmpty(request.SearchCriteria.CustomerAccountNumber) && string.IsNullOrWhiteSpace(request.SearchCriteria.CartId) && !request.SearchCriteria.SuspendedOnly) { // If the only search criteria set is that of customer account number, then anonymous carts should not be fetched. request.SearchCriteria.IncludeAnonymous = false; } // User query result settings provided by caller. If not available and cart identifier is set retrieve one row, otherwise do not apply paging. QueryResultSettings queryResultSettings = request.QueryResultSettings ?? (string.IsNullOrEmpty(request.SearchCriteria.CartId) ? QueryResultSettings.AllRecords : QueryResultSettings.SingleRecord); bool removeUnassortedProducts = !request.SearchCriteria.SuspendedOnly; var getCartsServiceRequest = new GetSalesTransactionsServiceRequest(request.SearchCriteria, queryResultSettings, removeUnassortedProducts); var getCartsServiceResponse = this.Context.Execute <GetSalesTransactionsServiceResponse>(getCartsServiceRequest); PagedResult <SalesTransaction> salesTransactions = getCartsServiceResponse.SalesTransactions; IDictionary <string, IList <SalesLine> > linesWithUnavailableProducts = getCartsServiceResponse.LinesWithUnavailableProducts; IEnumerable <SalesTransaction> transactionWithUnassortedProducts = salesTransactions.Results.Where(t => linesWithUnavailableProducts.Keys.Contains(t.Id)); if (removeUnassortedProducts && linesWithUnavailableProducts.Any()) { foreach (SalesTransaction transaction in transactionWithUnassortedProducts) { // Recalculate totals (w/o unassorted products and save cart). CartWorkflowHelper.Calculate(this.Context, transaction, requestedMode: null); CartWorkflowHelper.SaveSalesTransaction(this.Context, transaction); } if (!request.IgnoreProductDiscontinuedNotification) { // Send notification to decide if caller should be notified about discontinued products. var notification = new ProductDiscontinuedFromChannelNotification(linesWithUnavailableProducts); this.Context.Notify(notification); } // Reload to cart to avoid version mismatch. var reloadCartsServiceRequest = new GetSalesTransactionsServiceRequest(request.SearchCriteria, queryResultSettings, mustRemoveUnavailableProductLines: false); salesTransactions = this.Context.Execute <GetSalesTransactionsServiceResponse>(reloadCartsServiceRequest).SalesTransactions; } PagedResult <Cart> carts = salesTransactions.ConvertTo(transaction => ConvertTransactionToCart(this.Context, transaction, request.IncludeHistoricalTenderLines)); return(new GetCartResponse(carts, salesTransactions)); }