public void ShouldCreateValidCupom()
 {
     _service.CalcDiscount("XPTO1", _order);
     Assert.AreEqual(_notifications.HasNotifications(), false);
 }
        public Task <bool> Handle(PlaceOrderCommand message, CancellationToken cancellationToken)
        {
            if (!message.IsValid())
            {
                NotifyValidationErrors(message);
                return(Task.FromResult(false));
            }

            // search the clinte on database
            var customer = _customerRepository.GetById(message.CustomerId);

            if (customer == null)
            {
                NotifyValidationError(new DomainNotification(message.MessageType, $"Cliente com o id {message.CustomerId} não foi localizado"));
                return(Task.FromResult(false));
            }

            // get range of products
            var products = _productRepository.GetById(message.OrderItems.Select(x => x.Product).ToArray())?.ToList();

            if (products == null || products.Count == 0)
            {
                NotifyValidationError(new DomainNotification(message.MessageType, $"nenhum produto foi encontrado"));
                return(Task.FromResult(false));
            }

            // create an order
            var order = Order.Factory.Create(customer, new CreditCard(message.CreditCard.Number, message.CreditCard.Cvv, message.CreditCard.Validate, message.CreditCard.PrintName));

            // after create then validate
            if (!order.IsValid())
            {
                NotifyValidationErrors(order);
                return(Task.FromResult(false));
            }

            // verify if some product wasn't found
            var ids = products.Select(x => x.Id).ToArray();

            message.OrderItems.ToList().ForEach((x) =>
            {
                if (ids.Contains(x.Product))
                {
                    var product = products.Where(y => y.Id == x.Product)?.First();
                    order.AddItem(product, x.Quantity);
                }
                else
                {
                    NotifyValidationError(new DomainNotification(message.MessageType, $"produto {x.Product} não foi encontrado"));
                }
            });

            // apply discount if has in command
            if (message.DiscountCupon != null)
            {
                order = _cupomService.CalcDiscount(message.DiscountCupon, order);
            }

            // place order
            order.Place();

            // if has notifications then notify the application
            if (order.HasNotifications)
            {
                DisparchNotifications(order);
            }

            // save a order
            _orderRepository.Add(order);

            // if already it´s ok then disparch all events
            if (Commit())
            {
                DisparchEvents(order.DomainEvents);
                return(Task.FromResult(true));
            }

            NotifyValidationError(new DomainNotification(message.MessageType, "houve algum problema ao criar o pedido"));
            return(Task.FromResult(false));
        }