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)); }
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(); }
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(); }
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); } }
public async Task <bool> Contains(Domain.Offer of) => await OfferPool.Contains(of);
public async Task <bool> Add(Domain.Offer of) => await OfferPool.Add(of);