public IEnumerable <AggregateEvent> TransferMoney(TransferMoneyCommand command) { if (this.CurrentBalance < command.Amount) { throw new InvalidOperationException($"Account {AccountNumber} does not have enough balance to execute the transaction."); } if (this.AccountState != AccountState.Created) { throw new InvalidOperationException($"Account {AccountNumber} is not available."); } var destinationAccountEvents = this.EventStore.GetAggregateEvents(CreateAggregateId(command.DestinationAccountNumber)); var destinationAccount = new Account(this.EventStore, destinationAccountEvents); if (destinationAccount.AccountState != AccountState.Created) { throw new InvalidOperationException($"Account {destinationAccount.AccountNumber} is not available."); } var aggregateEvent = new BalanceIncreased(command.DestinationAccountNumber, ++destinationAccount.SequenceNumber, command.Amount); Handle(aggregateEvent); return(new AggregateEvent[] { aggregateEvent, new BalanceDecreased(command.SourceAccountNumber, ++this.SequenceNumber, command.Amount) }); }
public async Task TransferMoneyAsync(TransferMoneyCommand command) { var sourceAccount = BuildAccountFromDomainEvents(command.SourceAccountNumber); var events = sourceAccount.TransferMoney(command); await this.EventStore.AddEventsAsync(events); }
public ActionResult TransferMoney(TransferMoneyCommand transferMoney) { var fromAccountBalance = this.accountRepository.GetBalance(transferMoney.FromAccountId); var toAccountBalance = this.accountRepository.GetBalance(transferMoney.ToAccountId); if (fromAccountBalance < transferMoney.Amount) { throw new InsufficientFundsException(); } this.accountRepository.UpdateBalance(transferMoney.FromAccountId, fromAccountBalance - transferMoney.Amount); this.accountRepository.UpdateBalance(transferMoney.ToAccountId, toAccountBalance + transferMoney.Amount); return(this.RedirectToAction("TransferMoney")); }
public ActionResult TransferMoney(TransferMoneyCommand transferMoney) { var fromAccount = accounts.Get(transferMoney.FromAccountId); var toAccount = accounts.Get(transferMoney.ToAccountId); if (fromAccount.CurrentBalance < transferMoney.Amount) { throw new InsufficientFundsException(); } fromAccount.CurrentBalance = fromAccount.CurrentBalance - transferMoney.Amount; toAccount.CurrentBalance = toAccount.CurrentBalance + transferMoney.Amount; return(this.RedirectToAction("TransferMoney")); }
public bool Execute(TransferMoneyCommand command) { var balanceSpec = new EnoughBalanceAmountSpecification(); var minimumTransferSpec = new MinimumTransferAmountSpecification(); var andSpec = balanceSpec.And(minimumTransferSpec); if (andSpec.IsSatisfiedBy(State)) { var sentEvent = new MoneySentEvent(command.Transaction); var feeEvent = new FeesDeductedEvent(new Money(0.25m)); EmitAll(sentEvent, feeEvent); } return(true); }
public static async Task Main(string[] args) { //initialize actor system CreateActorSystem(); //create send receiver identifiers var senderId = AccountId.New; var receiverId = AccountId.New; //create mock opening balances var senderOpeningBalance = new Money(509.23m); var receiverOpeningBalance = new Money(30.45m); //create commands for opening the sender and receiver accounts var openSenderAccountCommand = new OpenNewAccountCommand(senderId, senderOpeningBalance); var openReceiverAccountCommand = new OpenNewAccountCommand(receiverId, receiverOpeningBalance); //send the command to be handled by the account aggregate AccountManager.Tell(openReceiverAccountCommand); AccountManager.Tell(openSenderAccountCommand); //create command to initiate money transfer var amountToSend = new Money(125.23m); var transaction = new Transaction(senderId, receiverId, amountToSend); var transferMoneyCommand = new TransferMoneyCommand(senderId, transaction); //send the command to initiate the money transfer AccountManager.Tell(transferMoneyCommand); //fake 'wait' to let the saga process the chain of events await Task.Delay(TimeSpan.FromSeconds(1)); Console.WriteLine("Walkthrough operations complete.\n\n"); Console.WriteLine("Press Enter to get the revenue:"); Console.ReadLine(); //get the revenue stored in the repository var revenue = RevenueRepository.Ask <RevenueReadModel>(new GetRevenueQuery(), TimeSpan.FromMilliseconds(500)).Result; //print the results Console.WriteLine($"The Revenue is: {revenue.Revenue.Value}."); Console.WriteLine($"From: {revenue.Transactions} transaction(s)."); Console.ReadLine(); }
public void ExampleCommandHandler() { /* ************************************************************* * This test demonstrates the action that might be taken in the * TransferMoneyCommand command handler * *************************************************************/ // arrange var repository = GetFakeRepo(); // simulating a command coming in to transfer from account A to B TransferMoneyCommand command = GetTransferRequest(); // act var source = repository.Get(command.SourceAccountId); var destination = repository.Get(command.DestinationAccount); var amount = new Money(command.Amount); source.TransferOut(amount, destination, DateTimeOffset.UtcNow); repository.Save(source, destination); }
public async Task TransferMoney([FromBody] TransferMoneyCommand command) { await this.AccountCommands.TransferMoneyAsync(command); }
public async Task TransferMoney([FromBody] TransferMoneyDto request) { var command = new TransferMoneyCommand(request.SourceAccountNumber, request.DestinationAccountNumber, request.Amount); await this.AccountCommands.TransferMoneyAsync(command); }
public ActionResult Transfer(Guid? SourceAccount, Guid? SinkAccount, decimal? amount) { var transferMoneyCommand = new TransferMoneyCommand { SourceAccountId = SourceAccount.Value, SinkAccountId = SinkAccount.Value, Amount = amount.Value }; _cmdBus.Send(transferMoneyCommand); return RedirectToAction("Success"); }