public void Percentage(decimal price, decimal percentage, decimal expected) { var product = new ProductEntity { Price = price }; var record = new BasketRecordEntity { Count = 1, Product = product }; var basket = new BasketEntity { Records = new[] { record } }; var percentageDiscount = new DiscountEntity { Type = DiscountEntityType.Percentage, Percentage = percentage, TargetProduct = product }; var dbPrice = _sut.CalculatePrice(basket); var basketModel = _sut.CalculatePriceWithDiscounts(basket, new[] { percentageDiscount }); var basketModelPrice = _sut.CalculatePrice(basketModel); dbPrice.Should().Be(price); basketModelPrice.Should().Be(expected); }
public void Remove_ShouldRemoveItemToBasket_AndCallUpdate() { // Given var basketId = Guid.NewGuid(); var basketEntity = new BasketEntity { BasketId = basketId }; var itemId = Guid.NewGuid(); var itemEntity = new ItemEntity { ItemId = itemId }; basketEntity.Items.Add(itemEntity); _basketStore.Setup(x => x.Get(basketId)).Returns(basketEntity); _itemStore.Setup(x => x.Get(itemId)).Returns(itemEntity); var basketViewModel = new BasketViewModel { BasketId = basketId }; _basketMapper.Setup(x => x.MapFrom(It.IsAny <BasketEntity>())).Returns(basketViewModel); // When var result = _basketService.Remove(basketId, itemId); // Then result.ShouldBe(basketViewModel); _basketStore.Verify(x => x.Update(It.Is <BasketEntity>(p => !p.Items.Any(y => y.ItemId == itemId)))); }
public async Task <IResult> Delete(int basketId) { try { BasketEntity basket = await UnitOfWork.Basket.GetAsync(basket => basket.Id == basketId); if (basket != null) { bool deleteResult = UnitOfWork.Basket.Delete(basket); if (deleteResult) { return(new Result(ResultStatus.Success, $"{basket.Id} numaralı sepet silindi")); } else { return(new Result(ResultStatus.Error, "Silme işlemi gerçekleşmedi")); } } return(new DataResult <BasketEntity>(ResultStatus.Error, "Böyle bir sepet bulunamadı", basket)); } catch (Exception ex) { //_logger.Log(LogLevel.Error, ex, ex.Message); throw; } }
public void BuyTwoGetOneFree(decimal price, int count, int expectedCount, decimal expectedPrice) { var product = new ProductEntity { Price = price }; var record = new BasketRecordEntity { Count = count, Product = product }; var basket = new BasketEntity { Records = new[] { record } }; var percentageDiscount = new DiscountEntity { Type = DiscountEntityType.BuyTwoGetOneForFree, TargetProduct = product, RewardProduct = product, }; var dbPrice = _sut.CalculatePrice(basket); var basketModel = _sut.CalculatePriceWithDiscounts(basket, new[] { percentageDiscount }); var basketModelPrice = _sut.CalculatePrice(basketModel); var basketModelProductCount = basketModel.Records[0].Count + basketModel.Records[0].FreeProducts.Count; dbPrice.Should().Be(price * record.Count); basketModelPrice.Should().Be(expectedPrice); basketModelProductCount.Should().Be(expectedCount); }
public void Update(BasketEntity basket) { var originalBasket = _baskets.SingleOrDefault(x => x.BasketId == basket.BasketId); _baskets.Remove(originalBasket); _baskets.Add(basket); }
public async Task <ActionResult <Wrapper <BasketEntity> > > PostBasketEntity(BasketEntity basketEntity) { _context.Baskets.Add(basketEntity); await _context.SaveChangesAsync(); return(new Wrapper <BasketEntity> { Data = basketEntity, Success = true }); }
public async Task <BasketEntity> UpdateBasketAsync(BasketEntity basketEntity) { var created = await _database.StringSetAsync(basketEntity.Id, JsonSerializer.Serialize(basketEntity), TimeSpan.FromDays(30)); if (!created) { return(null); } return(await GetBasketAsync(basketEntity.Id)); }
public async Task <BasketEntity> InsertOrUpdate(BasketEntity basket) { basket.Id = basket.Id ?? Guid.NewGuid().ToString(); var collection = database.GetCollection <BasketEntity>("commerce"); var filter = Builders <BasketEntity> .Filter.Eq("_id", basket.Id); await collection.ReplaceOneAsync(filter, basket, new UpdateOptions { IsUpsert = true }); return(basket); }
public Guid Create(Guid token) { var basket = new BasketEntity { BasketId = Guid.NewGuid(), Token = token }; _baskets.Add(basket); return(basket.BasketId); }
public BasketEntity BasketImporter(int id, List <ItemsEntity> itemsEntities, DateTime dateTime, CustomerEntity customer) { var basketOfCustomer = new BasketEntity(); basketOfCustomer.Id = id; basketOfCustomer.ItemsList = itemsEntities; basketOfCustomer.EnterDateTime = dateTime; basketOfCustomer.CustomerEntity = customer; // حذف اقلام مورد نیاز مشتری از فروشگاه پس از آنکه خریداری انجام گرفت DelItemFrmShop(itemsEntities); return(basketOfCustomer); }
public async Task <IResult> Update(BasketDto basketUpdateDto) { try { BasketEntity basket = Mapper.Map <BasketEntity>(basketUpdateDto); await UnitOfWork.Basket.UpdateAsync(basket); await UnitOfWork.SaveAsync(); BasketDto result = Mapper.Map <BasketEntity, BasketDto>(basket); return(new Result(ResultStatus.Success, $"{basket.Id} li sepet güncellendi")); } catch (Exception ex) { //_logger.Log(LogLevel.Error, ex, ex.Message); throw; } }
public async Task <IResult> Insert(BasketDto basketAddDto) { try { BasketEntity basket = Mapper.Map <BasketEntity>(basketAddDto); await UnitOfWork.Basket.AddAsync(basket); await UnitOfWork.SaveAsync(); BasketDto result = Mapper.Map <BasketEntity, BasketDto>(basket); return(new Result(ResultStatus.Success, $"{result.Id} eklendi")); } catch (Exception ex) { //_logger.Log(LogLevel.Error, ex, ex.Message); throw; } }
public async Task <BasketEntity> UpdateBasketAsync(BasketEntity basketEntity, string correlationToken, TelemetryClient telemetryClient) { // Telemetry variables var success = false; var startTime = DateTime.UtcNow; var timer = System.Diagnostics.Stopwatch.StartNew(); var returnValue = "Not Found"; try { var created = await _database.StringSetAsync(basketEntity.BasketId, JsonConvert.SerializeObject(basketEntity)); // _database.SetAdd() if (!created) { _logger.LogInformation("Redis cache could not persist an item."); return(null); } else { success = true; returnValue = basketEntity.BasketId; _logger.LogInformation("Redis cache persisted item succesfully."); } } catch (Exception ex) { telemetryClient.TrackException(ex); _logger.LogError(ex.ToString()); throw; } finally { telemetryClient.TrackDependency("RedisCache", "UpdateBasket", returnValue, startTime, timer.Elapsed, success); } return(await GetBasketAsync(returnValue)); //return null; }
public async Task <IDataResult <BasketDto> > Get(int basketId) { try { BasketEntity basketEntities = await UnitOfWork.Basket.GetAsync(basket => basket.Id == basketId); BasketDto basketDto = Mapper.Map <BasketEntity, BasketDto>(basketEntities); if (basketDto != null) { return(new DataResult <BasketDto>(ResultStatus.Success, basketDto)); } return(new DataResult <BasketDto>(ResultStatus.Error, "Böyle bir sepet bulunamadı", data: null)); } catch (Exception ex) { //_logger.Log(LogLevel.Error, ex, ex.Message); throw; } }
public BasketViewModel MapFrom(BasketEntity basketEntity) { var itemViewModels = new List <ItemViewModel>(); var items = basketEntity.Items.GroupBy(x => x.ItemId); foreach (var item in items) { var itemViewModel = _itemMapper.MapFrom(item.First()); itemViewModel.Quantity = item.Count(); itemViewModels.Add(itemViewModel); } return(new BasketViewModel { BasketId = basketEntity.BasketId, Token = basketEntity.Token, Items = itemViewModels, Total = basketEntity.Items.Sum(x => x.Cost) }); }
public void Get_ShouldFetchBasketDetailsFromBasketStore() { // Given var basketId = Guid.NewGuid(); var basketEntity = new BasketEntity { BasketId = basketId }; _basketStore.Setup(x => x.Get(basketId)).Returns(basketEntity); var basketViewModel = new BasketViewModel { BasketId = basketId }; _basketMapper.Setup(x => x.MapFrom(basketEntity)).Returns(basketViewModel); // When var result = _basketService.Get(basketId); // Then result.ShouldBe(basketViewModel); }
public void ShouldMapEntityToModel() { AutoMapperConfiguration.Configure(); const string Id = "My Id"; var entity = new BasketEntity { Id = Id, Items = new[] { new ProductEntity { Id = 42, Name = "Name", Cost = new MoneyEntity(4200, SE.ISOCurrencySymbol) } } }; var model = AutoMapperConfiguration.Mapper.Map <Basket>(entity); Assert.Equal(Id, model.Id); Assert.Single(model.Products); Assert.Equal(1, model.Count); Assert.Equal(new Money(42.0, SE), model.Total); }
public void ShowResult(BasketEntity basket) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"================= Basket Id is: {basket.Id} =================\n"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine($"Customer Id: {basket.CustomerEntity.Id}"); Console.WriteLine($"FullName: {basket.CustomerEntity.FullName}"); Console.WriteLine($"Gender: {basket.CustomerEntity.Gender}"); Console.WriteLine($"Date Entrance: {basket.EnterDateTime}"); foreach (var item in basket.ItemsList) { Console.WriteLine($"Name item is: {item.Stuff} and Quntity is: {item.Qnt}"); } Console.WriteLine("\n"); Console.ForegroundColor = ConsoleColor.DarkBlue; Console.WriteLine("########## Shop remaind ##########"); foreach (var item in Repository.UpdateShopItems) { Console.WriteLine($"Name item is: {item.Stuff} and Quntity is: {item.Qnt}"); } Console.ForegroundColor = default; Console.WriteLine("\n"); }
public BasketModel CalculatePriceWithDiscounts(BasketEntity basket, IEnumerable <DiscountEntity> discounts) { var basketModel = new BasketModel(); foreach (var discount in discounts) { var handler = _handlers.SingleOrDefault(x => x.CanHandle(discount)); foreach (var record in basket.Records) { if (handler != null && handler.IsApplicable(record, discount)) { basketModel.Records.Add(handler.Apply(record, discount)); } else { basketModel.Records.Add(new BasketRecordModel(record.Count, new ProductModel(record.Product.Price))); } } } return(basketModel); }
public async Task ShouldAddProductToBasket() { const string BasketId = "My basket id"; var entity = new BasketEntity { Id = BasketId }; var product = new Product(42, "What name?", new Money(13.76, SE)); var repositoryMock = new Mock <IRepository>(MockBehavior.Strict); repositoryMock .Setup(repository => repository.GetById(BasketId)) .ReturnsAsync(entity); repositoryMock .Setup(repository => repository.InsertOrUpdate(It.IsAny <BasketEntity>())) .ReturnsAsync(entity); var productServiceMock = new Mock <IProductService>(MockBehavior.Strict); productServiceMock.Setup(productService => productService.GetById(42)).ReturnsAsync(product); var service = new BasketService(productServiceMock.Object, repositoryMock.Object); await service.AddProductToBasket(BasketId, 42); repositoryMock.VerifyAll(); repositoryMock.Verify(repository => repository.InsertOrUpdate( It.Is <BasketEntity>(item => item.Id == BasketId && item.Items.Single().Cost.Units == product.Cost.Units && item.Items.Single().Id == 42)), Times.Once); productServiceMock.VerifyAll(); }
public void Clear_ShouldRemoveItemsFromBasket_AndCallUpdate() { // Given var basketId = Guid.NewGuid(); var basketEntity = new BasketEntity { BasketId = basketId, Items = new List <ItemEntity> { new ItemEntity(), new ItemEntity() } }; _basketStore.Setup(x => x.Get(basketId)).Returns(basketEntity); var basketViewModel = new BasketViewModel { BasketId = basketId }; _basketMapper.Setup(x => x.MapFrom(basketEntity)).Returns(basketViewModel); // When var result = _basketService.Clear(basketId); // Then result.ShouldBe(basketViewModel); _basketStore.Verify(x => x.Update(It.Is <BasketEntity>(p => p.Items.Count == 0))); }
public async Task ShouldCreateEmptyBasket() { const string BasketId = "My basket id"; var entity = new BasketEntity { Id = BasketId }; var repositoryMock = new Mock <IRepository>(MockBehavior.Strict); repositoryMock .Setup(repository => repository.InsertOrUpdate(It.IsAny <BasketEntity>())) .ReturnsAsync(entity); var productServiceMock = new Mock <IProductService>(MockBehavior.Strict); var service = new BasketService(productServiceMock.Object, repositoryMock.Object); var created = await service.CreateBasket(); Assert.Equal(0, created.Count); Assert.Equal(BasketId, created.Id); repositoryMock.VerifyAll(); }
public decimal CalculatePrice(BasketEntity basket) { return(basket.Records.Sum(x => x.Count * x.Product.Price)); }
/// <summary> /// Add single line item to shopping basket /// </summary> /// <param name="productId">Id of productEntity to add</param> /// <param name="correlationToken">Tracks request - can be any value</param> /// <param name="basketId">Id of shopping basket</param> /// <returns>BasketItemEntity</returns> public async Task <BasketEntity> AddItemToBasket(int productId, string correlationToken, string basketId) { //* Materialized View Pattern //* Fetch product entity data from a read-only store contained in shopping basket service. //* ProductEntity ID is row key in underlying Azure table. //* Returns a ProductTableEntity class var productTableEntity = await _productRepository.GetItem(ProductPartitionKey, productId.ToString(), correlationToken); // Fallback logic if (productTableEntity == null) { // Fallback: // If product not available from local read store, fetch it from catalog service by // making direct HTTP call to Catalog Service. var product = await _restClient.GetAsync <ProductEntity>(ServiceEnum.Catalog, $"api/Catalog/Music/{productId}", correlationToken); if (product == null) { throw new Exception( $"Cannot add item to shopping basket: ProductEntity #{productId} does not exist for Request {correlationToken}. Have you created the ProductEntity Read Model for the Shopping BasketEntity microservice?"); } // Transform product into an entity class for table storage productTableEntity = new ProductTableEntity { // parition key is constant PartitionKey = ProductPartitionKey, // row key is productId RowKey = product.Data.Id.ToString(), Title = product.Data.Title, Id = product.Data.Id, GenreName = product.Data.GenreName, ArtistName = product.Data.ArtistName, Price = product.Data.Price.ToString() }; // Add product entity tolocal read store, implementing a cache-aside pattern await _productRepository.Insert(productTableEntity, correlationToken); _logger.LogInformation( $"Added productEntity information for item {productId} for Request {correlationToken} to the read model."); } BasketEntity basket = null; // Does basketID exist? if (basketId == "-1") { basketId = SnowflakeIdGenerator.GenerateId(SnowflakeEnum.Basket); } else { basket = await _distributedCacheRepository.GetBasketAsync(basketId, correlationToken, _telemetryClient); } // Get basket from cache if (basket == null) { // BasketEntity is null, add new single item to it basket = new BasketEntity { BuyerId = "2", BasketId = basketId, CorrelationToken = correlationToken, Items = { new BasketItemEntity { CorrelationToken = correlationToken, //DateCreated = DateTime.Now, Title = productTableEntity.Title, UnitPrice = productTableEntity.Price.ToString(), Artist = productTableEntity.ArtistName, Genre = productTableEntity.GenreName, Quantity = 1, ProductId = productId, } } }; basket = await _distributedCacheRepository.UpdateBasketAsync(basket, correlationToken, _telemetryClient); _logger.LogInformation($"Created new shopping basket {basketId} and added productEntity {productTableEntity.Title} for Request {correlationToken} "); } else { // BasketEntity is not null // Determine if the same productEntity has already been added to the basket var itemInBasket = basket.Items.FirstOrDefault(x => x.ProductId == Int32.Parse(productTableEntity.RowKey)); if (itemInBasket == null) { // ProductEntity does not exist in basket, add it basket.Items.Add(new BasketItemEntity() { CorrelationToken = correlationToken, //DateCreated = DateTime.Now, Title = productTableEntity.Title, UnitPrice = productTableEntity.Price.ToString(), Artist = productTableEntity.ArtistName, Genre = productTableEntity.GenreName, Quantity = 1, ProductId = Int32.Parse(productTableEntity.RowKey) }); _logger.LogInformation($"Added productEntity Id {productId} to shopping basket {basketId} for request {correlationToken}"); } else { // Idempotency write-check // Ensure that update with same correlation token does not already exist. // This could happen if we've already committed the write, but have gotten caught-up in retry logic. if (itemInBasket.CorrelationToken != null && itemInBasket.CorrelationToken == correlationToken) { _logger.LogWarning($"ProductEntity Id {productId} already added to shopping basket {basketId} for Request {correlationToken}"); return(basket); } // ProductEntity already exists in basket. Increment its count. basket.Items.FirstOrDefault(x => x.ProductId == Int32.Parse(productTableEntity.RowKey)).Quantity++; _logger.LogInformation($"Added productEntity Id {productId} to existing shopping basket {basketId} for request {correlationToken}"); } basket = await _distributedCacheRepository.UpdateBasketAsync(basket, correlationToken, _telemetryClient); } return(basket); }