public async void Deposit_Valid_Amount(string accountId, double amount)
        {
            var account  = new Account();
            var customer = Substitute.For <Customer>();

            accountReadOnlyRepository
            .Get(Guid.Parse(accountId))
            .Returns(account);

            var output = Substitute.For <CustomPresenter <Application.UseCases.Deposit.DepositOutput> >();

            var depositUseCase = new Application.UseCases.Deposit.DepositInteractor(
                accountReadOnlyRepository,
                bus,
                output,
                converter
                );

            var request = new Application.UseCases.Deposit.DepositInput(
                Guid.Parse(accountId),
                amount
                );

            await depositUseCase.Process(request);

            Assert.Equal(request.Amount, output.Output.Transaction.Amount);
        }
Exemple #2
0
        public async Task <CustomerOutput> Execute(Guid customerId)
        {
            Customer customer = await _customerReadOnlyRepository.Get(customerId);

            if (customer == null)
            {
                throw new CustomerNotFoundException($"The customer {customerId} does not exists or is not processed yet.");
            }

            List <AccountOutput> accounts = new List <AccountOutput> ();

            foreach (Guid accountId in customer.Accounts.ToReadOnlyCollection())
            {
                Account account = await _accountReadOnlyRepository.Get(accountId);

                if (account != null)
                {
                    AccountOutput accountOutput = new AccountOutput(account);
                    accounts.Add(accountOutput);
                }
            }

            CustomerOutput output = new CustomerOutput(customer, accounts);

            return(output);
        }
Exemple #3
0
        public async Task <CloseResult> Process(CloseCommand command)
        {
            Account account = await accountReadOnlyRepository.Get(command.AccountId);

            account.Close();

            await accountWriteOnlyRepository.Delete(account);

            CloseResult result = resultConverter.Map <CloseResult>(account);

            return(result);
        }
        public async Task Process(CloseInput input)
        {
            Account account = await accountReadOnlyRepository.Get(input.AccountId);

            account.Close();

            await accountWriteOnlyRepository.Delete(account);

            CloseOutput output = outputConverter.Map <CloseOutput>(account);

            this.outputBoundary.Populate(output);
        }
Exemple #5
0
        public async void Deposit_Valid_Amount()
        {
            DepositMessage command = new DepositMessage()
            {
                AccountId = Guid.NewGuid(),
                Amount    = 600
            };

            accountReadOnlyRepository
            .Get(command.AccountId)
            .Returns(new Account());

            Deposit sut = new Deposit(
                accountReadOnlyRepository,
                accountWriteOnlyRepository);

            Credit credit = await sut.Handle(command);

            Assert.Equal(command.Amount, credit.Amount.Value);
            Assert.Equal("Credit", credit.Description);
            Assert.True(credit.Id != Guid.Empty);
        }
        public async Task <AccountOutput> Execute(Guid accountId)
        {
            Account account = await _accountReadOnlyRepository.Get(accountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {accountId} does not exists or is not processed yet.");
            }

            AccountOutput output = new AccountOutput(account);

            return(output);
        }
Exemple #7
0
        public async Task <Guid> Execute(CloseAccountCommand command)
        {
            Account account = await _accountReadOnlyRepository.Get(command.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {command.AccountId} does not exist or it is already closed");
            }
            account.Close();
            await _accountWriteOnlyRepository.Delete(account);

            return(account.Id);
        }
Exemple #8
0
        public async Task Process(GetAccountDetailsInput input)
        {
            Account account = await accountReadOnlyRepository.Get(input.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {input.AccountId} does not exists or is already closed.");
            }

            AccountOutput output = outputConverter.Map <AccountOutput>(account);

            outputBoundary.Populate(output);
        }
Exemple #9
0
        public async Task <CreateFinanceStatementResult> Execute <T>(Guid accountId, Title title, Amount amount = null) where T : class, IFinanceStatement
        {
            Account account = await _accountReadOnlyRepository.Get(accountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {accountId} does not exists!");
            }

            T financeStatement = (T)Activator.CreateInstance(typeof(T), title, amount);

            FinanceStatementCollection collection = account
                                                    .GetCollecion <T>();

            collection.Add(financeStatement);

            await _accountWriteOnlyRepository.Update(account, financeStatement);

            decimal totalIncomes     = account.Incomes.Total();
            decimal totalExpenses    = account.Expenses.Total();
            decimal totalInvestments = account.Investments.Total();

            CreateFinanceStatementResult result = new CreateFinanceStatementResult
            {
                Id            = financeStatement.Id,
                Total         = financeStatement.AmountRecords.Total(),
                Percentage    = financeStatement.AmountRecords.Percentage(collection.Total()),
                AmountRecords = financeStatement.AmountRecords.GetAmountRecords().Select(x => new Results.AmountRecordResult
                {
                    Id          = x.Id,
                    Amount      = x.Amount,
                    Description = x.Description
                }),
                Income = new Results.FinanceStatementResult
                {
                    Total = totalIncomes
                },
                Expense = new Results.FinanceStatementResult
                {
                    Total      = totalExpenses,
                    Percentage = account.Expenses.Percentage(totalIncomes)
                },
                Investment = new Results.FinanceStatementResult
                {
                    Total      = totalInvestments,
                    Percentage = account.Investments.Percentage(totalIncomes)
                },
            };

            return(result);
        }
        public async Task Process(GetAccountDetailsInput input)
        {
            var account = await accountReadOnlyRepository.Get(input.AccountId);

            if (account == null)
            {
                outputBoundary.Populate(null);
                return;
            }

            AccountOutput output = outputConverter.Map <AccountOutput>(account);

            outputBoundary.Populate(output);
        }
Exemple #11
0
        public async Task <SaveAmountRecordResult> Execute <T>(Guid accountId, Guid financeStatementId, IEnumerable <AmountRecord> amountRecords) where T : class, IFinanceStatement
        {
            Account account = await _accountReadOnlyRepository.Get(accountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {accountId} does not exists");
            }

            T financeStatement = (T)account.Get <T>(x => x.Id == financeStatementId);

            financeStatement
            .AmountRecords
            .Replace(amountRecords);

            await _accountWriteOnlyRepository.Update(account, financeStatement);

            decimal incomeTotal     = account.Incomes.Total();
            decimal expenseTotal    = account.Expenses.Total();
            decimal investmentTotal = account.Investments.Total();

            SaveAmountRecordResult result = new SaveAmountRecordResult
            {
                Id            = financeStatement.Id,
                Total         = financeStatement.AmountRecords.Total(),
                Percentage    = financeStatement.AmountRecords.Percentage(account.GetCollecion <T>().Total()),
                AmountRecords = financeStatement.AmountRecords
                                .GetAmountRecords()
                                .Select(x => new Results.AmountRecordResult {
                    Id = x.Id, Amount = x.Amount, Description = x.Description
                }),

                Income = new Results.FinanceStatementResult
                {
                    Total = incomeTotal,
                },
                Expense = new Results.FinanceStatementResult
                {
                    Total      = expenseTotal,
                    Percentage = account.Expenses.Percentage(incomeTotal)
                },
                Investment = new Results.FinanceStatementResult
                {
                    Total      = investmentTotal,
                    Percentage = account.Investments.Percentage(incomeTotal)
                }
            };

            return(result);
        }
Exemple #12
0
        public async Task Process(CloseInput input)
        {
            Account account = await accountReadOnlyRepository.Get(input.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {input.AccountId} does not exists or is already closed.");
            }

            account.Close();

            await accountWriteOnlyRepository.Delete(account);

            CloseOutput output = outputConverter.Map <CloseOutput>(account);

            this.outputBoundary.Populate(output);
        }
        public async Task <Transaction> Handle(DepositCommand command)
        {
            Account account = await accountReadOnlyRepository.Get(command.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {command.AccountId} does not exists or is already closed.");
            }

            Transaction transaction = Credit.Create(command.CustomerId, Amount.Create(command.Amount));

            account.Deposit(transaction);

            await accountWriteOnlyRepository.Update(account);

            return(transaction);
        }
        public async Task <CloseResult> Process(CloseCommand command)
        {
            Account account = await accountReadOnlyRepository.Get(command.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {command.AccountId} does not exists or is already closed.");
            }

            account.Close();

            await accountWriteOnlyRepository.Delete(account);

            CloseResult result = new CloseResult(account);

            return(result);
        }
Exemple #15
0
        public async Task <Credit> Handle(DepositMessage command)
        {
            Account account = await accountReadOnlyRepository.Get(command.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {command.AccountId} does not exists or is already closed.");
            }

            Credit credit = Credit.Create(Amount.Create(command.Amount));

            account.Deposit(credit);

            await accountWriteOnlyRepository.Update(account);

            return(credit);
        }
Exemple #16
0
        public async Task Process(CloseInput input)
        {
            Account account = await accountReadOnlyRepository.Get(input.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {input.AccountId} does not exists or is already closed.");
            }

            account.Close();

            var domainEvents = account.GetEvents();
            await bus.Publish(domainEvents);

            CloseOutput response = responseConverter.Map <CloseOutput>(account);

            this.outputBoundary.Populate(response);
        }
Exemple #17
0
        public async Task Process(DepositInput input)
        {
            Account account = await accountReadOnlyRepository.Get(input.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {input.AccountId} does not exists or is already closed.");
            }

            Credit credit = new Credit(account.Id, input.Amount);

            account.Deposit(credit);

            await accountWriteOnlyRepository.Update(account, credit);

            TransactionOutput transactionResponse = outputConverter.Map <TransactionOutput>(credit);
            DepositOutput     output = new DepositOutput(transactionResponse, account.GetCurrentBalance().Value);

            outputBoundary.Populate(output);
        }
Exemple #18
0
        public async Task <DepositOutput> Execute(Guid accountId, Amount amount)
        {
            Account account = await _accountReadOnlyRepository.Get(accountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {accountId} does not exists or is already closed.");
            }

            account.Deposit(amount);
            Credit credit = (Credit)account.GetLastTransaction();

            await _accountWriteOnlyRepository.Update(account, credit);

            DepositOutput output = new DepositOutput(
                credit,
                account.GetCurrentBalance());

            return(output);
        }
Exemple #19
0
        public async Task <DepositResult> Process(DepositCommand command)
        {
            Account account = await accountReadOnlyRepository.Get(command.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {command.AccountId} does not exists or is already closed.");
            }

            Credit credit = new Credit(new Amount(command.Amount));

            account.Deposit(credit);

            await accountWriteOnlyRepository.Update(account);

            TransactionResult transactionResult = resultConverter.Map <TransactionResult>(credit);
            DepositResult     result            = new DepositResult(transactionResult, account.GetCurrentBalance().Value);

            return(result);
        }
Exemple #20
0
        public async Task <DepositResult> Execute(DepositCommand command)
        {
            Account account = await _accountReadOnlyRepository.Get(command.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {command.AccountId} does not exist or it is already closed");
            }
            account.Deposit(command.Amount);
            Credit credit = (Credit)account.GetLastTransaction();
            await _accountWriteOnlyRepository.Update(
                account,
                credit);

            DepositResult result = new DepositResult(
                credit,
                account.GetCurrentBalance());

            return(result);
        }
        public async void Deposit_Valid_Amount(string accountId, double amount)
        {
            var account  = new Account(Guid.NewGuid());
            var customer = new Customer("08724050601", "Jorge Perales Diaz");

            accountReadOnlyRepository
            .Get(Guid.Parse(accountId))
            .Returns(account);

            var depositUseCase = new DepositUseCase(
                accountReadOnlyRepository,
                accountWriteOnlyRepository
                );

            DepositResult result = await depositUseCase.Execute(
                Guid.Parse(accountId),
                amount);

            Assert.Equal(amount, result.Transaction.Amount);
        }
Exemple #22
0
        public async Task Process(RegisterInput message)
        {
            Customer customer = new Customer(message.PIN, message.Name);

            Account account = new Account();

            account.Open(customer.Id, new Credit(account.Id, message.InitialAmount));
            customer.Register(account.Id);

            var customerEvents = customer.GetEvents();
            var accountEvents  = account.GetEvents();

            await bus.Publish(customerEvents);

            await bus.Publish(accountEvents);

            //
            // To ensure the Customer and Account are created in the database
            // we wait for the records be available in the following queries
            // with retry
            //

            bool consumerReady = await RetryGet(async() => await customerReadOnlyRepository.Get(customer.Id)) &&
                                 await RetryGet(async() => await accountReadOnlyRepository.Get(account.Id));

            if (!consumerReady)
            {
                customer = null;
                account  = null;

                //
                // TODO: Throw exception, monitor the inconsistencies and fail fast.
                //
            }

            CustomerOutput customerOutput = responseConverter.Map <CustomerOutput>(customer);
            AccountOutput  accountOutput  = responseConverter.Map <AccountOutput>(account);
            RegisterOutput output         = new RegisterOutput(customerOutput, accountOutput);

            outputBoundary.Populate(output);
        }
Exemple #23
0
        public async Task <RemoveFinanceStatementResult> Execute <T>(Guid accountId, Guid financeStatementId) where T : class, IFinanceStatement
        {
            Account account = await _accountReadOnlyRepository.Get(accountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {accountId} does not exists");
            }

            FinanceStatementCollection collection = account.GetCollecion <T>();

            T financeStatement = (T)collection.Get(financeStatementId);

            collection.Remove(financeStatement);

            await _accountWriteOnlyRepository.Remove(account, financeStatement);

            decimal totalIncomes     = account.Incomes.Total();
            decimal totalExpenses    = account.Expenses.Total();
            decimal totalInvestments = account.Investments.Total();

            RemoveFinanceStatementResult result = new RemoveFinanceStatementResult
            {
                Income = new Results.FinanceStatementResult
                {
                    Total = totalIncomes
                },
                Expense = new Results.FinanceStatementResult
                {
                    Total      = totalExpenses,
                    Percentage = account.Expenses.Percentage(totalIncomes)
                },
                Investment = new Results.FinanceStatementResult
                {
                    Total      = totalInvestments,
                    Percentage = account.Investments.Percentage(totalIncomes)
                },
            };

            return(result);
        }
        public async Task Process(WithdrawInput input)
        {
            Account account = await accountReadOnlyRepository.Get(input.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {input.AccountId} does not exists or is already closed.");
            }

            Debit debit = new Debit(account.Id, input.Amount);

            account.Withdraw(debit);

            var domainEvents = account.GetEvents();
            await bus.Publish(domainEvents);

            TransactionOutput transactionOutput = responseConverter.Map <TransactionOutput>(debit);
            WithdrawOutput    output            = new WithdrawOutput(transactionOutput, account.GetCurrentBalance().Value);

            outputBoundary.Populate(output);
        }
Exemple #25
0
        public async Task <WithdrawResult> Execute(Guid accountId, Amount amount)
        {
            Account account = await accountReadOnlyRepository.Get(accountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {accountId} does not exists or is already closed.");
            }

            account.Withdraw(amount);
            Debit debit = (Debit)account.GetLastTransaction();

            await accountWriteOnlyRepository.Update(account, debit);

            WithdrawResult result = new WithdrawResult(
                debit,
                account.GetCurrentBalance()
                );

            return(result);
        }
Exemple #26
0
        public async Task Process(GetCustomerDetailsInput input)
        {
            //
            // TODO: The following queries could be simplified
            //

            Customer customer = await customerReadOnlyRepository.Get(input.CustomerId);

            if (customer == null)
            {
                throw new CustomerNotFoundException($"The customer {input.CustomerId} does not exists or is not processed yet.");
            }

            List <AccountOutput> accounts = new List <AccountOutput>();

            foreach (var accountId in customer.Accounts)
            {
                Account account = await accountReadOnlyRepository.Get(accountId);

                //
                // TODO: The "Accout closed state" is not propagating to the Customer Aggregate
                //

                if (account != null)
                {
                    AccountOutput accountOutput = outputConverter.Map <AccountOutput>(account);
                    accounts.Add(accountOutput);
                }
            }

            CustomerOutput output = outputConverter.Map <CustomerOutput>(customer);

            output = new CustomerOutput(
                customer.Id,
                customer.PIN.Text,
                customer.Name.Text,
                accounts);

            outputBoundary.Populate(output);
        }
Exemple #27
0
        public async Task Execute <T>(Guid accountId, Guid financeStatementId, Title title) where T :  class, IFinanceStatement
        {
            Account account = await _accountReadOnlyRepository.Get(accountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {accountId} does not exists");
            }

            FinanceStatementCollection collection = account.GetCollecion <T>();

            if (collection.Any(x => x.Title == title && x.Id != financeStatementId))
            {
                throw new FinanceStatementAlreadyExistsException($"Title {title} already exists!");
            }


            FinanceStatement financeStatement = (FinanceStatement)collection.Get(financeStatementId);

            financeStatement.Update(title);

            await _accountWriteOnlyRepository.Update(account, financeStatement);
        }
Exemple #28
0
        public async Task Process(WithdrawInput input)
        {
            Account account = await accountReadOnlyRepository.Get(input.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {input.AccountId} does not exists or is already closed.");
            }

            Debit debit = new Debit(new Amount(input.Amount));

            account.Withdraw(debit);

            await accountWriteOnlyRepository.Update(account);

            TransactionOutput transactionOutput = outputConverter.Map <TransactionOutput>(debit);
            WithdrawOutput    output            = new WithdrawOutput(
                transactionOutput,
                account.GetCurrentBalance().Value
                );

            outputBoundary.Populate(output);
        }
        public async Task <WithdrawResult> Process(WithdrawCommand command)
        {
            Account account = await accountReadOnlyRepository.Get(command.AccountId);

            if (account == null)
            {
                throw new AccountNotFoundException($"The account {command.AccountId} does not exists or is already closed.");
            }

            Debit debit = new Debit(account.Id, command.Amount);

            account.Withdraw(debit);

            await accountWriteOnlyRepository.Update(account, debit);

            TransactionResult transactionResult = resultConverter.Map <TransactionResult>(debit);
            WithdrawResult    result            = new WithdrawResult(
                transactionResult,
                account.GetCurrentBalance().Value
                );

            return(result);
        }
        public async void Deposit_Valid_Amount(string accountId, double amount)
        {
            var account  = new Account(Guid.NewGuid());
            var customer = new Customer("08724050601", "Ivan Paulovich");

            accountReadOnlyRepository
            .Get(Guid.Parse(accountId))
            .Returns(account);

            var depositUseCase = new DepositService(
                accountReadOnlyRepository,
                accountWriteOnlyRepository
                );

            var request = new DepositCommand(
                Guid.Parse(accountId),
                amount
                );

            DepositResult result = await depositUseCase.Process(request);

            Assert.Equal(request.Amount, result.Transaction.Amount);
        }