Example #1
0
        public async Task <IIdentifierResult> HandleAsync(ICreateOffer command, ICorrelationContext context)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            await Task.WhenAll(
                _posVerifier.AssertExists(command.PointOfSaleId),
                _productVerifier.AssertExists(command.ProductId),
                command.StockItemId != null?_stockItemVerifier.AssertExists(command.StockItemId.Value) : Task.CompletedTask
                );

            var offer = new Domain.Offer(command.Id, command.PointOfSaleId, command.ProductId, command.RecommendedPrice, command.StockItemId, command.ValidSince, command.ValidUntil);
            await _repository.AddAsync(offer);

            try
            {
                await _repository.SaveChanges();
            }
            catch (EntityAlreadyExistsException)
            {
                throw new BaristaException("offer_already_exists", $"An offer with the ID '{command.Id}' already exists.");
            }


            await _busPublisher.Publish(new OfferCreated(offer.Id, offer.PointOfSaleId, offer.ProductId,
                                                         offer.RecommendedPrice, offer.StockItemId, offer.ValidSince, offer.ValidUntil));

            return(new IdentifierResult(offer.Id));
        }
Example #2
0
        public void DeletesOfferFromRepository_RaisesIntegrationEvent()
        {
            var offer      = new Domain.Offer(Id, Guid.Empty, Guid.Empty, null, null, null, null);
            var repository = new Mock <IOfferRepository>(MockBehavior.Strict);

            repository.Setup(r => r.GetAsync(offer.Id)).Returns(Task.FromResult(offer)).Verifiable();
            repository.Setup(r => r.DeleteAsync(offer)).Returns(Task.CompletedTask).Verifiable();
            repository.Setup(r => r.SaveChanges()).Returns(Task.CompletedTask).Verifiable();

            var busPublisher = new Mock <IBusPublisher>(MockBehavior.Strict);

            busPublisher.Setup(p => p.Publish <IOfferDeleted>(It.Is <IOfferDeleted>(e => ValidateEquality(e)))).Returns(Task.CompletedTask).Verifiable();

            var handler = new DeleteOfferHandler(repository.Object, busPublisher.Object);
            var result  = handler.HandleAsync(Cmd, new Mock <ICorrelationContext>().Object).GetAwaiter().GetResult();

            Assert.IsTrue(result.Successful);
            repository.Verify();
            busPublisher.Verify();
        }
        public void UpdatesOfferInRepository_RaisesIntegrationEvent()
        {
            var offer      = new Domain.Offer(Id, PointOfSaleId, ProductId, RecommendedPrice, StockItemId, ValidSince, ValidUntil);
            var repository = new Mock <IOfferRepository>(MockBehavior.Strict);

            repository.Setup(r => r.GetAsync(offer.Id)).Returns(Task.FromResult(offer)).Verifiable();
            repository.Setup(r => r.UpdateAsync(offer)).Returns(Task.CompletedTask).Verifiable();
            repository.Setup(r => r.SaveChanges()).Returns(Task.CompletedTask).Verifiable();

            var busPublisher = new Mock <IBusPublisher>(MockBehavior.Strict);

            busPublisher.Setup(p => p.Publish <IOfferUpdated>(It.Is <IOfferUpdated>(e => ValidateEquality(e)))).Returns(Task.CompletedTask).Verifiable();

            var handler = new UnsetOfferStockItemReferenceHandler(repository.Object, busPublisher.Object);
            var result  = handler.HandleAsync(Cmd, new Mock <ICorrelationContext>().Object).GetAwaiter().GetResult();

            Assert.IsTrue(result.Successful);
            ValidateEquality(offer);
            repository.Verify();
            busPublisher.Verify();
        }
Example #4
0
        public void UpdatesOfferInRepository_RaisesIntegrationEvent()
        {
            var offer      = new Domain.Offer(Id, Guid.Empty, Guid.Empty, null, null, null, null);
            var repository = new Mock <IOfferRepository>(MockBehavior.Strict);

            repository.Setup(r => r.GetAsync(offer.Id)).Returns(Task.FromResult(offer)).Verifiable();
            repository.Setup(r => r.UpdateAsync(offer)).Returns(Task.CompletedTask).Verifiable();
            repository.Setup(r => r.SaveChanges()).Returns(Task.CompletedTask).Verifiable();

            var busPublisher = new Mock <IBusPublisher>(MockBehavior.Strict);

            busPublisher.Setup(p => p.Publish <IOfferUpdated>(It.Is <IOfferUpdated>(e => ValidateEquality(e)))).Returns(Task.CompletedTask).Verifiable();

            var posVerifier = new Mock <IPointOfSaleVerifier>(MockBehavior.Strict);

            posVerifier.Setup(v => v.AssertExists(PointOfSaleId)).Returns(Task.CompletedTask).Verifiable();

            var productVerifier = new Mock <IProductVerifier>(MockBehavior.Strict);

            productVerifier.Setup(v => v.AssertExists(ProductId)).Returns(Task.CompletedTask).Verifiable();

            var stockItemVerifier = new Mock <IStockItemVerifier>(MockBehavior.Strict);

            stockItemVerifier.Setup(v => v.AssertExists(StockItemId)).Returns(Task.CompletedTask).Verifiable();

            var handler = new UpdateOfferHandler(repository.Object, busPublisher.Object, posVerifier.Object, productVerifier.Object, stockItemVerifier.Object);
            var result  = handler.HandleAsync(Cmd, new Mock <ICorrelationContext>().Object).GetAwaiter().GetResult();

            Assert.IsTrue(result.Successful);
            ValidateEquality(offer);
            repository.Verify();
            busPublisher.Verify();
            posVerifier.Verify();
            productVerifier.Verify();
            stockItemVerifier.Verify();
        }
Example #5
0
        public (bool, Book) ProcessOffer(Domain.Offer of)
        {
            var transact     = TransactManager;
            var dic          = Dictionary;
            var result       = false;
            var offers       = new List <Offer>();
            var trades       = new List <Trade>();
            var resultOffers = new List <Offer>();
            var resultTrades = new List <Trade>();

            if (!dic.ContainsKey(of.Asset))
            {
                dic = dic.Add(of.Asset, new OfferBook(of.Asset));
            }


            var sourceQuantity = of.Quantity;
            var asset          = of.Asset;

            if (of.Type == OfferType.Bid)
            {
                sourceQuantity = of.Quantity * of.Price;
                asset          = "BIZ";
            }

            if (transact.HasBalance(of.Wallet, asset, sourceQuantity))
            {
                transact = transact.ChangeBalance(of.Wallet, asset, -sourceQuantity);
                var book = dic[of.Asset];

                if (of.Type == OfferType.Bid)
                {
                    (book, resultTrades, resultOffers) = book.AddBid(of);
                }
                else
                {
                    (book, resultTrades, resultOffers) = book.AddAsk(of);
                }

                dic = dic.SetItem(of.Asset, book);
                offers.AddRange(resultOffers);
                trades.AddRange(resultTrades);

                result = true;
                foreach (var trade in resultTrades)
                {
                    transact = transact.ChangeBalance(trade.BuyerWallet, trade.Asset, trade.Quantity);
                    transact = transact.ChangeBalance(trade.SellerWallet, "BIZ", trade.Quantity * trade.Price);
                }
            }
            else
            {
                Log.Error("Wallet has no balance to send offer.");
            }

            if (result)
            {
                return(true, new Book(this, transact, dic, ProcessedOffers.AddRange(offers), Trades.AddRange(trades)));
            }
            else
            {
                return(false, this);
            }
        }
Example #6
0
 public async Task <bool> Contains(Domain.Offer of) =>
 await OfferPool.Contains(of);
Example #7
0
 public async Task <bool> Add(Domain.Offer of) =>
 await OfferPool.Add(of);