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));
            }
示例#2
0
            /// <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));
            }