using System;
using System.Linq;
using System.Threading.Tasks;
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;
namespace Microsoft.eShopWeb.ApplicationCore.Services;
public class OrderService : IOrderService
{
private readonly IRepository<Order> _orderRepository;
private readonly IRepository<Basket> _basketRepository;
private readonly IRepository<CatalogItem> _itemRepository;
private readonly IUriComposer _uriComposer;
public OrderService(IRepository<Basket> basketRepository,
IRepository<CatalogItem> itemRepository,
IRepository<Order> orderRepository,
IUriComposer uriComposer)
{
_orderRepository = orderRepository;
_uriComposer = uriComposer;
_basketRepository = basketRepository;
_itemRepository = itemRepository;
}
public async Task<Order> CreateOrderAsync(int basketId, Address shippingAddress)
{
var basket = await _basketRepository.GetByIdAsync(basketId);
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();
var now = DateTime.UtcNow;
var order = new Order(basket.BuyerId, shippingAddress, items, now);
await _orderRepository.AddAsync(order);
return order;
}
}
public class OrderServiceWithInterface : IOrderService
{
private readonly IRepository<Order> _orderRepository;
private readonly IUriComposer _uriComposer;
private readonly IRepository<Basket> _basketRepository;
private readonly IRepository<CatalogItem> _itemRepository;
private readonly IDateTime _dateTime;
public OrderServiceWithInterface(IRepository<Basket> basketRepository,
IRepository<CatalogItem> itemRepository,
IRepository<Order> orderRepository,
IUriComposer uriComposer,
IDateTime dateTime)
{
_orderRepository = orderRepository;
_uriComposer = uriComposer;
_dateTime = dateTime;
_basketRepository = basketRepository;
_itemRepository = itemRepository;
}
public async Task<Order> CreateOrderAsync(int basketId, Address shippingAddress)
{
var basket = await _basketRepository.GetByIdAsync(basketId);
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();
var now = _dateTime.UtcNow();
var order = new Order(basket.BuyerId, shippingAddress, items, now);
await _orderRepository.AddAsync(order);
return order;
}
}
public class OrderServiceDelegate : IOrderService
{
private readonly IRepository<Order> _orderRepository;
private readonly IUriComposer _uriComposer;
private readonly UtcNow _utcNow;
private readonly IRepository<Basket> _basketRepository;
private readonly IRepository<CatalogItem> _itemRepository;
public OrderServiceDelegate(IRepository<Basket> basketRepository,
IRepository<CatalogItem> itemRepository,
IRepository<Order> orderRepository,
IUriComposer uriComposer,
UtcNow utcNow)
{
_orderRepository = orderRepository;
_uriComposer = uriComposer;
_utcNow = utcNow;
_basketRepository = basketRepository;
_itemRepository = itemRepository;
}
public async Task<Order> CreateOrderAsync(int basketId, Address shippingAddress)
{
var basket = await _basketRepository.GetByIdAsync(basketId);
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();
var now = _utcNow();
var order = new Order(basket.BuyerId, shippingAddress, items, now);
await _orderRepository.AddAsync(order);
return order;
}
}
public class OrderServiceValue : IOrderServiceValue
{
private readonly IRepository<Order> _orderRepository;
private readonly IUriComposer _uriComposer;
private readonly IRepository<Basket> _basketRepository;
private readonly IRepository<CatalogItem> _itemRepository;
public OrderServiceValue(IRepository<Basket> basketRepository,
IRepository<CatalogItem> itemRepository,
IRepository<Order> orderRepository,
IUriComposer uriComposer)
{
_orderRepository = orderRepository;
_uriComposer = uriComposer;
_basketRepository = basketRepository;
_itemRepository = itemRepository;
}
public async Task<Order> CreateOrderAsync(int basketId, Address shippingAddress, DateTimeOffset orderDate)
{
var basket = await _basketRepository.GetByIdAsync(basketId);
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();
var order = new Order(basket.BuyerId, shippingAddress, items, orderDate);
await _orderRepository.AddAsync(order);
return order;
}
}