public OrderEntity Create(ProductEntity product, int quantity, CampaignEntity campaign, int currentTime)
        {
            if (product.Stock < quantity)
            {
                throw new InsufficientStockException();
            }

            OrderEntity order;

            if (campaign != null)
            {
                var sellingPrice = _productPriceService.CalculateDiscountedPrice(campaign, product.Price, currentTime);

                order = new OrderEntity(product.ProductCode, quantity, sellingPrice, campaign.Id);

                campaign.NotifyOrderCreation(quantity, order.Price);
            }
            else
            {
                order = new OrderEntity(product.ProductCode, quantity, product.Price);
            }

            product.DecreaseStock(quantity);

            return(order);
        }
        public async Task <GetProductInfoResponse> Handle(GetProductInfoQuery request, CancellationToken cancellationToken)
        {
            var product = await _productRepository.FindOneAsync(x => x.ProductCode == request.ProductCode);

            if (product == null)
            {
                throw new ProductNotFoundException();
            }

            var productCampaigns = await _campaignRepository.FindAsync(x => x.ProductCode == request.ProductCode);

            var productActiveCampaign = productCampaigns.FirstOrDefault(x => x.IsActive(_timeService.CurrentTime));

            var sellingPrice = _productPriceService.CalculateDiscountedPrice(productActiveCampaign, product.Price, _timeService.CurrentTime);

            return(new GetProductInfoResponse(product, sellingPrice));
        }
        public void CalculateDiscountedPrice_Should_Return_listingPrice_If_Campaign_Null_Or_Ended(decimal price)
        {
            var sellingPrice = _productPriceService.CalculateDiscountedPrice(null, price, 0);

            Assert.Equal(price, sellingPrice);
        }