using Ardalis.GuardClauses; using Microsoft.eShopWeb.ApplicationCore.Entities; using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate; using Microsoft.eShopWeb.ApplicationCore.Entities.OrderAggregate; using Microsoft.eShopWeb.ApplicationCore.Interfaces; using Microsoft.eShopWeb.ApplicationCore.Specifications; using System.Linq; using System.Threading.Tasks; using Microsoft.eShopWeb.Features.PlaceOrder; using NServiceBus; namespace Microsoft.eShopWeb.ApplicationCore.Services { public class OrderService : IOrderService { private readonly IAsyncRepository<Order> _orderRepository; private readonly IUriComposer _uriComposer; private readonly IEmailSender _emailSender; private readonly IMessageSession _messageSession; private readonly IAsyncRepository<Basket> _basketRepository; private readonly IAsyncRepository<CatalogItem> _itemRepository; public OrderService(IAsyncRepository<Basket> basketRepository, IAsyncRepository<CatalogItem> itemRepository, IAsyncRepository<Order> orderRepository, IUriComposer uriComposer, IEmailSender emailSender, IMessageSession messageSession) { _orderRepository = orderRepository; _uriComposer = uriComposer; _emailSender = emailSender; _messageSession = messageSession; _basketRepository = basketRepository; _itemRepository = itemRepository; } public async Task CreateOrderAsync(int basketId, Address shippingAddress, CreditCard creditCard) { var basketSpec = new BasketWithItemsSpecification(basketId); var basket = await _basketRepository.FirstOrDefaultAsync(basketSpec); Guard.Against.NullBasket(basketId, basket); Guard.Against.EmptyBasketOnCheckout(basket.Items); var catalogItemsSpecification = new CatalogItemsSpecification(basket.Items.Select(item => item.CatalogItemId).ToArray()); var catalogItems = await _itemRepository.ListAsync(catalogItemsSpecification); var items = basket.Items.Select(basketItem => { var catalogItem = catalogItems.First(c => c.Id == basketItem.CatalogItemId); var itemOrdered = new CatalogItemOrdered(catalogItem.Id, catalogItem.Name, _uriComposer.ComposePicUri(catalogItem.PictureUri)); var orderItem = new OrderItem(itemOrdered, basketItem.UnitPrice, basketItem.Quantity); return orderItem; }).ToList(); await _messageSession.Send(new PlaceOrderCommand { BuyerId = basket.BuyerId, Address = shippingAddress, Items = items, CreditCard = new PlaceOrderCommand.CreditCardEncrypted { Number = creditCard.Number, Expiry = creditCard.Expiry, Cvv = creditCard.Cvv } }); } } }