Order CreateNewOrder(OrderDTO dto, Customer associatedCustomer)
        {
            //Create a new order entity from factory
            Order newOrder = OrderFactory.CreateOrder(associatedCustomer,
                                                     dto.ShippingName,
                                                     dto.ShippingCity,
                                                     dto.ShippingAddress,
                                                     dto.ShippingZipCode);

            //if have lines..add
            if (dto.OrderLines != null)
            {
                foreach (var line in dto.OrderLines) //add order lines
                    newOrder.AddNewOrderLine(line.ProductId, line.Amount, line.UnitPrice, line.Discount / 100);
            }

            return newOrder;
        }
        /// <summary>
        /// <see cref="Microsoft.Samples.NLayerApp.Application.MainBoundedContext.ERPModule.Services.ISalesAppService"/>
        /// </summary>
        /// <param name="orderDto"><see cref="Microsoft.Samples.NLayerApp.Application.MainBoundedContext.ERPModule.Services.ISalesAppService"/></param>
        public OrderDTO AddNewOrder(OrderDTO orderDto)
        {
            //if orderdto data is not valid
            if (orderDto == null || orderDto.CustomerId == Guid.Empty)
                throw new ArgumentException(Messages.warning_CannotAddOrderWithNullInformation);
            
            var customer = _customerRepository.Get(orderDto.CustomerId);

            if (customer != null)
            {
                //Create a new order entity
                var newOrder = CreateNewOrder(orderDto, customer);

                if (newOrder.IsCreditValidForOrder()) //if total order is less than credit 
                {
                    //save order
                    SaveOrder(newOrder);

                    return newOrder.ProjectedAs<OrderDTO>();
                }
                else //total order is greater than credit
                {
                    LoggerFactory.CreateLog().LogInfo(Messages.info_OrderTotalIsGreaterCustomerCredit);
                    return null;
                }
            }
            else
            {
                LoggerFactory.CreateLog().LogWarning(Messages.warning_CannotCreateOrderForNonExistingCustomer);
                return null;
            }
        }
        public void AddNewOrderWithTotalGreaterCustomerCreditReturnNull()
        {
            //Arrange 
            var productRepository = new SIProductRepository();
            var orderRepository = new SIOrderRepository();
            var customerRepository = new SICustomerRepository();
            var country = new Country("spain", "es-ES");
            country.GenerateNewIdentity();

            customerRepository.GetGuid = (guid) =>
            {
                //default credit limit is 1000
                var customer = CustomerFactory.CreateCustomer("Jhon", "El rojo","+34343","company", country, new Address("city", "zipCode", "addressline1", "addressline2"));

                return customer;
            };


            orderRepository.UnitOfWorkGet = () =>
            {
                var uow = new SIUnitOfWork();
                uow.Commit = () => { };

                return uow;
            };
            orderRepository.AddOrder = (order) => { };

            var salesManagement = new SalesAppService(productRepository, orderRepository, customerRepository);

            var dto = new OrderDTO()
            {
                CustomerId = Guid.NewGuid(),
                ShippingAddress = "Address",
                ShippingCity = "city",
                ShippingName = "name",
                ShippingZipCode = "zipcode",
                OrderLines = new List<OrderLineDTO>()
                {
                    new OrderLineDTO(){ProductId = Guid.NewGuid(),Amount = 1,Discount = 0,UnitPrice = 2000}
                }
            };

            //act
            var result = salesManagement.AddNewOrder(dto);

            //assert
            Assert.IsNull(result);
        }
 /// <summary>
 /// <see cref="Microsoft.Samples.NLayerApp.Application.MainBoundedContext.BankingModule.Services.IMainBoundedContextService"/>
 /// </summary>
 /// <param name="order"><see cref="Microsoft.Samples.NLayerApp.Application.MainBoundedContext.BankingModule.Services.IMainBoundedContextService"/></param>
 /// <returns><see cref="Microsoft.Samples.NLayerApp.Application.MainBoundedContext.BankingModule.Services.IMainBoundedContextService"/></returns>
 public OrderDTO AddNewOrder(OrderDTO order)
 {
     return _salesAppService.AddNewOrder(order);
 }
        public void AddNewOrderWithoutCustomerIdThrowArgumentException()
        {
            //Arrange 
            
            var customerRepository = new SICustomerRepository();
            var productRepository = new SIProductRepository();
            var orderRepository = new SIOrderRepository();

            var salesManagement = new SalesAppService(productRepository, orderRepository, customerRepository);

            var order = new OrderDTO() // order is not valid when customer id is empty
            {
                CustomerId = Guid.Empty
            };

            //act
            var result = salesManagement.AddNewOrder(order);

            //assert
            Assert.IsNull(result);
        }