using Core.Entities; using Core.Entities.OrderAggregate; using Core.Interfaces; using Core.Specifications; namespace Infrastructure.Services { public class OrderService : IOrderService { private readonly IBasketRepository _basketRepo; private readonly IUnitOfWork _unitOfWork; private readonly IPaymentService _paymentService; public OrderService(IBasketRepository basketRepo, IUnitOfWork unitOfWork, IPaymentService paymentService) { _paymentService = paymentService; _unitOfWork = unitOfWork; _basketRepo = basketRepo; } public async Task CreateOrderAsync(string buyerEmail, int deliverMethodId, string basketId, Address shippingAddress) { var basket = await _basketRepo.GetBasketAsync(basketId); var items = new List(); foreach (var item in basket.Items) { var productItem = await _unitOfWork.Repository().GetByIdAsync(item.Id); var itemOrdered = new ProductItemOrdered(productItem.Id, productItem.Name, productItem.PictureUrl); var orderItem = new OrderItem(itemOrdered, productItem.Price, item.Quantity); items.Add(orderItem); } var deliveryMethod = await _unitOfWork.Repository().GetByIdAsync(deliverMethodId); var subtotal = items.Sum(item => item.Price * item.Quantity); var spec = new OrderByPaymentIntentIdWithItemsSpecification(basket.PaymentItentId); var existingOrder = await _unitOfWork.Repository().GetEntityWithSpec(spec); if(existingOrder != null) { _unitOfWork.Repository().Delete(existingOrder); await _paymentService.CreateOrUpdatePaymentIntent(basket.PaymentItentId); } var order = new Order(items, buyerEmail, shippingAddress, deliveryMethod, subtotal, basket.PaymentItentId); _unitOfWork.Repository().Add(order); var result = await _unitOfWork.Complete(); if(result <= 0) return null; return order; } public async Task> GetDeliveryMethodsAsync() { return await _unitOfWork.Repository().ListAllAsync(); } public async Task GetOrderByIdAsync(int id, string buyerEmail) { var spec = new OrdersWithItemsAndOrderingSpecification(id, buyerEmail); return await _unitOfWork.Repository().GetEntityWithSpec(spec); } public async Task> GetOrdersForUserAsync(string buyerEmail) { var spec = new OrdersWithItemsAndOrderingSpecification(buyerEmail); return await _unitOfWork.Repository().ListAsync(spec); } } }