using System.Collections.Generic; using System.Threading.Tasks; using Ardalis.GuardClauses; using Microsoft.eShopWeb.ApplicationCore.Entities.BasketAggregate; using Microsoft.eShopWeb.ApplicationCore.Interfaces; using Microsoft.eShopWeb.ApplicationCore.Specifications; namespace Microsoft.eShopWeb.ApplicationCore.Services; public class BasketService : IBasketService { private readonly IRepository<Basket> _basketRepository; private readonly IAppLogger<BasketService> _logger; public BasketService(IRepository<Basket> basketRepository, IAppLogger<BasketService> logger) { _basketRepository = basketRepository; _logger = logger; } public async Task<Basket> AddItemToBasket(string username, int catalogItemId, decimal price, int quantity = 1) { var basketSpec = new BasketWithItemsSpecification(username); var basket = await _basketRepository.GetBySpecAsync(basketSpec); if (basket == null) { basket = new Basket(username); await _basketRepository.AddAsync(basket); } basket.AddItem(catalogItemId, price, quantity); await _basketRepository.UpdateAsync(basket); return basket; } public async Task DeleteBasketAsync(int basketId) { var basket = await _basketRepository.GetByIdAsync(basketId); await _basketRepository.DeleteAsync(basket); } public async Task<Basket> SetQuantities(int basketId, Dictionary<string, int> quantities) { Guard.Against.Null(quantities, nameof(quantities)); var basketSpec = new BasketWithItemsSpecification(basketId); var basket = await _basketRepository.GetBySpecAsync(basketSpec); Guard.Against.NullBasket(basketId, basket); foreach (var item in basket.Items) { if (quantities.TryGetValue(item.Id.ToString(), out var quantity)) { if (_logger != null) _logger.LogInformation($"Updating quantity of item ID:{item.Id} to {quantity}."); item.SetQuantity(quantity); } } basket.RemoveEmptyItems(); await _basketRepository.UpdateAsync(basket); return basket; } public async Task TransferBasketAsync(string anonymousId, string userName) { Guard.Against.NullOrEmpty(anonymousId, nameof(anonymousId)); Guard.Against.NullOrEmpty(userName, nameof(userName)); var anonymousBasketSpec = new BasketWithItemsSpecification(anonymousId); var anonymousBasket = await _basketRepository.GetBySpecAsync(anonymousBasketSpec); if (anonymousBasket == null) return; var userBasketSpec = new BasketWithItemsSpecification(userName); var userBasket = await _basketRepository.GetBySpecAsync(userBasketSpec); if (userBasket == null) { userBasket = new Basket(userName); await _basketRepository.AddAsync(userBasket); } foreach (var item in anonymousBasket.Items) { userBasket.AddItem(item.CatalogItemId, item.UnitPrice, item.Quantity); } await _basketRepository.UpdateAsync(userBasket); await _basketRepository.DeleteAsync(anonymousBasket); } }