public async Task <bool> Handle(DeleteOrderCommand request, CancellationToken cancellationToken)
        {
            if (request.Order == null)
            {
                throw new ArgumentNullException("order");
            }

            //check whether the order wasn't cancelled before
            //if it already was cancelled, then there's no need to make the following adjustments
            //(such as reward points, inventory, recurring payments)
            //they already was done when cancelling the order
            if (request.Order.OrderStatus != OrderStatus.Cancelled)
            {
                //return (add) back redeemded reward points
                await _mediator.Send(new ReturnBackRedeemedRewardPointsCommand()
                {
                    Order = request.Order
                });

                //reduce (cancel) back reward points (previously awarded for this order)
                await _mediator.Send(new ReduceRewardPointsCommand()
                {
                    Order = request.Order
                });

                //cancel recurring payments
                var recurringPayments = await _orderService.SearchRecurringPayments(initialOrderId : request.Order.Id);

                foreach (var rp in recurringPayments)
                {
                    var errors = await _mediator.Send(new CancelRecurringPaymentCommand()
                    {
                        RecurringPayment = rp
                    });

                    //use "errors" variable?
                }

                //Adjust inventory for already shipped shipments
                //only products with "use multiple warehouses"
                foreach (var shipment in await _shipmentService.GetShipmentsByOrder(request.Order.Id))
                {
                    foreach (var shipmentItem in shipment.ShipmentItems)
                    {
                        var product = await _productService.GetProductById(shipmentItem.ProductId);

                        shipmentItem.ShipmentId = shipment.Id;
                        if (product != null)
                        {
                            await _inventoryManageService.ReverseBookedInventory(product, shipment, shipmentItem);
                        }
                    }
                }
                //Adjust inventory
                foreach (var orderItem in request.Order.OrderItems)
                {
                    var product = await _productService.GetProductById(orderItem.ProductId);

                    if (product != null)
                    {
                        await _inventoryManageService.AdjustInventory(product, orderItem.Quantity, orderItem.AttributesXml, orderItem.WarehouseId);
                    }
                }

                //cancel reservations
                await _productReservationService.CancelReservationsByOrderId(request.Order.Id);

                //cancel bid
                await _auctionService.CancelBidByOrder(request.Order.Id);
            }

            //deactivate gift cards
            if (_orderSettings.DeactivateGiftCardsAfterDeletingOrder)
            {
                await _mediator.Send(new ActivatedValueForPurchasedGiftCardsCommand()
                {
                    Order = request.Order, Activate = false
                });
            }

            request.Order.Deleted = true;
            //now delete an order
            await _orderService.UpdateOrder(request.Order);

            //cancel discounts
            await _discountService.CancelDiscount(request.Order.Id);

            return(true);
        }
        public async Task <bool> Handle(CancelOrderCommand request, CancellationToken cancellationToken)
        {
            if (request.Order == null)
            {
                throw new ArgumentNullException("order");
            }

            if (request.Order.OrderStatus == OrderStatus.Cancelled)
            {
                throw new Exception("Cannot do cancel for order.");
            }

            //Cancel order
            await _mediator.Send(new SetOrderStatusCommand()
            {
                Order            = request.Order,
                Os               = OrderStatus.Cancelled,
                NotifyCustomer   = request.NotifyCustomer,
                NotifyStoreOwner = request.NotifyStoreOwner
            });

            //add a note
            await _orderService.InsertOrderNote(new OrderNote {
                Note = "Order has been cancelled",
                DisplayToCustomer = false,
                CreatedOnUtc      = DateTime.UtcNow,
                OrderId           = request.Order.Id,
            });

            //return (add) back redeemded reward points
            await _mediator.Send(new ReturnBackRedeemedRewardPointsCommand()
            {
                Order = request.Order
            });

            //cancel recurring payments
            var recurringPayments = await _orderService.SearchRecurringPayments(initialOrderId : request.Order.Id);

            foreach (var rp in recurringPayments)
            {
                var errors = await _mediator.Send(new CancelRecurringPaymentCommand()
                {
                    RecurringPayment = rp
                });
            }

            //Adjust inventory for already shipped shipments
            //only products with "use multiple warehouses"
            var shipments = await _shipmentService.GetShipmentsByOrder(request.Order.Id);

            foreach (var shipment in shipments)
            {
                foreach (var shipmentItem in shipment.ShipmentItems)
                {
                    var product = await _productService.GetProductById(shipmentItem.ProductId);

                    shipmentItem.ShipmentId = shipment.Id;
                    await _inventoryManageService.ReverseBookedInventory(product, shipment, shipmentItem);
                }
            }
            //Adjust inventory
            foreach (var orderItem in request.Order.OrderItems)
            {
                var product = await _productService.GetProductById(orderItem.ProductId);

                await _inventoryManageService.AdjustInventory(product, orderItem.Quantity, orderItem.Attributes, orderItem.WarehouseId);
            }

            //cancel reservations
            await _productReservationService.CancelReservationsByOrderId(request.Order.Id);

            //cancel bid
            await _auctionService.CancelBidByOrder(request.Order.Id);

            //cancel discount
            await _discountService.CancelDiscount(request.Order.Id);

            //event notification
            await _mediator.Publish(new OrderCancelledEvent(request.Order));

            return(true);
        }