private static void NotifyProductDiscontinuedFromChannelNotification(ProductDiscontinuedFromChannelNotification notification) { IEnumerable <string> notAvailableItemIds = notification.LinesWithUnavailableProducts.Values.SelectMany(c => c.Select(l => l.ItemId)); throw new ItemDiscontinuedException( "Item(s) {0} have been discontinued from the channel or have not been synchronized to the channel database.", string.Join(", ", notAvailableItemIds)); }
/// <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)); }