public async Task Execute(RefundInput input)
        {
            IAccount account = await _accountRepository.Get(input.AccountId);

            if (account == null)
            {
                _outputHandler.Error($"The account {input.AccountId} does not exist or is already closed.");
                return;
            }

            IDebit debit = account.Withdraw(_entityFactory, input.Amount);

            if (debit == null)
            {
                _outputHandler.Error($"The account {input.AccountId} does not have enough funds to withdraw {input.Amount}.");
                return;
            }

            await _accountRepository.Update(account, debit);

            // Publish the event to the enterprice service bus
            await _serviceBus.PublishEventAsync(new Shared.Events.WithdrawCompleted()
            {
                AccountId = input.AccountId, Amount = input.Amount.ToMoney().ToDecimal()
            });

            await _unitOfWork.Save();

            RefundOutput output = new RefundOutput(
                debit,
                account.GetCurrentBalance()
                );

            _outputHandler.Default(output);
        }
        public async Task Execute(Input input)
        {
            Guid AccountId;
            var  result = CommonAccess.GetAccessAccount(input.AccountId, _accountRepository, _loginUserService).Result.ToString();

            if (!Guid.TryParse(result, out AccountId))
            {
                _outputHandler.Error(result);
                return;
            }
            IAccount account = await _accountRepository.Get(AccountId);

            if (account == null)
            {
                _outputHandler.Error($"The account {input.AccountId} does not exists or is already closed.");
                return;
            }

            IDebit debit = account.Withdraw(input.Amount);

            if (debit == null)
            {
                _outputHandler.Error($"The account {input.AccountId} does not have enough funds to withdraw {input.Amount}.");
                return;
            }

            await _accountRepository.Update(account, debit);

            Output output = new Output(
                debit,
                account.GetCurrentBalance()
                );

            _outputHandler.Handle(output);
        }
        public async Task Execute(WithdrawInput input)
        {
            IAccount account = await _accountRepository.Get(input.AccountId);

            if (account == null)
            {
                _outputHandler.Error($"The account {input.AccountId} does not exist or is already closed.");
                return;
            }

            IDebit debit = account.Withdraw(_entityFactory, input.Amount);

            if (debit == null)
            {
                _outputHandler.Error($"The account {input.AccountId} does not have enough funds to withdraw {input.Amount}.");
                return;
            }

            await _accountRepository.Update(account, debit);

            await _unitOfWork.Save();

            WithdrawOutput output = new WithdrawOutput(
                debit,
                account.GetCurrentBalance()
                );

            _outputHandler.Default(output);
        }
Example #4
0
 public CardController([FromServices] ICredit credit,
                       [FromServices] IDebit debit,
                       [FromServices] IGetBonusCard getBonusCard)
 {
     _credit       = credit;
     _debit        = debit;
     _getBonusCard = getBonusCard;
 }
        private void BuildOutput(IDebit debit, IAccount account)
        {
            var output = new WithdrawOutput(
                debit,
                account.GetCurrentBalance());

            _outputPort.Standard(output);
        }
Example #6
0
        public async Task Update(IAccount account, IDebit debit)
        {
            Domain.Accounts.Account accountOld = this._context.Accounts
                                                 .Where(e => e.Id.Equals(account.Id))
                                                 .SingleOrDefault();

            accountOld = (Domain.Accounts.Account)account;
            await Task.CompletedTask;
        }
Example #7
0
        public async Task Update(IAccount account, IDebit debit)
        {
            Account accountOld = _context.Accounts
                                 .Where(e => e.Id == account.Id)
                                 .SingleOrDefault();

            accountOld = (Account)account;
            await Task.CompletedTask;
        }
Example #8
0
        public void BuildOutput(IDebit debit, IAccount originAccount, IAccount destinationAccount)
        {
            var output = new TransferOutput(
                debit,
                originAccount.GetCurrentBalance(),
                originAccount.Id,
                destinationAccount.Id);

            _outputPort.Standard(output);
        }
        public WithdrawOutput(IDebit debit, Money updatedBalance)
        {
            Debit debitEntity = (Debit)debit;

            Transaction = new Transaction(
                debitEntity.Description,
                debitEntity.Amount,
                debitEntity.TransactionDate);

            UpdatedBalance = updatedBalance;
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="TransferOutput" /> class.
 /// </summary>
 /// <param name="debit">Debit object.</param>
 /// <param name="updatedBalance">Updated balance.</param>
 /// <param name="originAccountId">Origin Account Id.</param>
 /// <param name="destinationAccountId">Destination Account Id.</param>
 public TransferOutput(
     IDebit debit,
     Money updatedBalance,
     AccountId originAccountId,
     AccountId destinationAccountId)
 {
     this.Transaction          = debit;
     this.OriginAccountId      = originAccountId;
     this.DestinationAccountId = destinationAccountId;
     this.UpdatedBalance       = updatedBalance;
 }
        public WithdrawOutput(IDebit debit, Amount updatedBalance)
        {
            Debit debitEntity = (Debit)debit;

            Transaction = new Transaction(
                debitEntity.Description,
                debitEntity.Amount
                .ToAmount()
                .ToDouble(),
                debitEntity.TransactionDate);

            UpdatedBalance = updatedBalance.ToDouble();
        }
Example #12
0
        public TransferOutput(IDebit debit, Money updatedBalance, Guid originAccountId, Guid destinationAccountId)
        {
            Debit debitEntity = (Debit)debit;

            Transaction = new Transaction(
                originAccountId,
                destinationAccountId,
                debitEntity.Description,
                debitEntity.Amount,
                debitEntity.TransactionDate);

            UpdatedBalance = updatedBalance;
        }
Example #13
0
        public RefundOutput(IDebit debit, Money updatedBalance)
        {
            Debit debitEntity = (Debit)debit;

            Transaction = new Transaction(
                debitEntity.Description,
                debitEntity.Amount
                .ToMoney()
                .ToDecimal(),
                debitEntity.TransactionDate);

            UpdatedBalance = updatedBalance.ToDecimal();
        }
Example #14
0
        public void Account_With_200_Balance_Should_Not_Allow_50000_Withdraw()
        {
            //
            // Arrange
            Account sut    = new Account(Guid.NewGuid());
            ICredit credit = sut.Deposit(new PositiveAmount(200));

            // Act
            IDebit actual = sut.Withdraw(new PositiveAmount(5000));

            //
            // Act and Assert
            Assert.Null(actual);
        }
Example #15
0
        /// <summary>
        ///     Withdrawls from Account.
        /// </summary>
        /// <param name="account">Account.</param>
        /// <param name="amount">Amount.</param>
        /// <returns>Debit Transaction.</returns>
        public async Task <IDebit> Withdraw(IAccount account, PositiveMoney amount)
        {
            if (account is null)
            {
                throw new ArgumentNullException(nameof(account));
            }

            IDebit debit = account.Withdraw(this._accountFactory, amount);

            await this._accountRepository.Update(account, debit)
            .ConfigureAwait(false);

            return(debit);
        }
Example #16
0
        public Output(IDebit debit, Amount updatedBalance, Guid originAccountId, Guid destinationAccountId)
        {
            Debit debitEntity = (Debit)debit;

            Transaction = new Transaction(
                originAccountId,
                destinationAccountId,
                debitEntity.Description,
                debitEntity.Amount
                .ToAmount()
                .ToDouble(),
                debitEntity.TransactionDate);

            UpdatedBalance = updatedBalance.ToDouble();
        }
Example #17
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="WithdrawOutput" /> class.
        /// </summary>
        /// <param name="debit">Debit object.</param>
        /// <param name="updatedBalance">Updated balance.</param>
        public WithdrawOutput(IDebit debit, Money updatedBalance)
        {
            if (debit is Debit debitEntity)
            {
                this.Transaction = new Transaction(
                    Debit.Description,
                    debitEntity.Amount,
                    debitEntity.TransactionDate);

                this.UpdatedBalance = updatedBalance;
            }
            else
            {
                throw new ArgumentNullException(nameof(debit));
            }
        }
Example #18
0
        /// <inheritdoc />
        public IDebit Withdraw(IAccountFactory entityFactory, PositiveMoney amountToWithdraw)
        {
            if (entityFactory is null)
            {
                throw new ArgumentNullException(nameof(entityFactory));
            }

            if (this.GetCurrentBalance().LessThan(amountToWithdraw))
            {
                throw new MoneyShouldBePositiveException(Messages.AccountHasNotEnoughFunds);
            }

            IDebit debit = entityFactory.NewDebit(this, amountToWithdraw, DateTime.UtcNow);

            this.Debits.Add(debit);
            return(debit);
        }
Example #19
0
        /// <summary>
        ///     Executes the Use Case.
        /// </summary>
        /// <param name="input">Input Message.</param>
        /// <returns>Task.</returns>
        public async Task Execute(TransferInput input)
        {
            if (input is null)
            {
                this._transferOutputPort.WriteError(Messages.InputIsNull);
                return;
            }

            IAccount originAccount = await this._accountRepository
                                     .GetAccount(input.OriginAccountId)
                                     .ConfigureAwait(false);

            if (originAccount == null)
            {
                this._transferOutputPort
                .NotFound(Messages.AccountDoesNotExist);
                return;
            }

            IAccount destinationAccount = await this._accountRepository
                                          .GetAccount(input.DestinationAccountId)
                                          .ConfigureAwait(false);

            if (destinationAccount == null)
            {
                this._transferOutputPort
                .NotFound(Messages.AccountDoesNotExist);
                return;
            }

            IDebit debit = await this._accountService
                           .Withdraw(originAccount, input.Amount)
                           .ConfigureAwait(false);

            await this._accountService
            .Deposit(destinationAccount, input.Amount)
            .ConfigureAwait(false);

            await this._unitOfWork
            .Save()
            .ConfigureAwait(false);

            this.BuildOutput(debit, originAccount, destinationAccount);
        }
        public async Task Execute(TransferInput input)
        {
            IAccount originAccount = await _accountRepository.Get(input.OriginAccountId);

            if (originAccount == null)
            {
                _outputHandler.Error($"The account {input.OriginAccountId} does not exist or is already closed.");
                return;
            }

            IAccount destinationAccount = await _accountRepository.Get(input.DestinationAccountId);

            if (destinationAccount == null)
            {
                _outputHandler.Error($"The account {input.DestinationAccountId} does not exist or is already closed.");
                return;
            }

            IDebit  debit  = originAccount.Withdraw(_entityFactory, input.Amount);
            ICredit credit = destinationAccount.Deposit(_entityFactory, input.Amount);

            await _accountRepository.Update(originAccount, debit);

            await _accountRepository.Update(destinationAccount, credit);

            // Publish the event to the enterprice service bus
            await _serviceBus.PublishEventAsync(new Shared.Events.TransferCompleted()
            {
                OriginalAccountId = originAccount.Id, DestinationAccountId = destinationAccount.Id, Amount = input.Amount.ToMoney().ToDecimal()
            });

            await _unitOfWork.Save();

            TransferOutput output = new TransferOutput(
                debit,
                originAccount.GetCurrentBalance(),
                input.OriginAccountId,
                input.DestinationAccountId);

            _outputHandler.Default(output);
        }
        public void Account_With_200_Balance_Should_Not_Allow_50000_Withdraw()
        {
            var entityFactory = new Manga.Infrastructure.InMemoryDataAccess.EntityFactory();

            //
            // Arrange
            ICustomer customer = entityFactory.NewCustomer(
                new SSN("198608179922"),
                new Name("Ivan Paulovich")
                );

            IAccount sut = entityFactory.NewAccount(customer);

            ICredit credit = sut.Deposit(entityFactory, new PositiveAmount(200));

            // Act
            IDebit actual = sut.Withdraw(entityFactory, new PositiveAmount(5000));

            //
            // Act and Assert
            Assert.Null(actual);
        }
Example #22
0
        public void Account_With_200_Balance_Should_Not_Allow_50000_Withdraw()
        {
            var entityFactory = new Infrastructure.PersistenceLayer.InMemory.EntityFactory();

            //
            // Arrange
            ICustomer customer = entityFactory.NewCustomer(
                new SSN("198608179922"),
                new Name("Nocco Giovanni Emanuele")
                );

            IAccount sut = entityFactory.NewAccount(customer);

            ICredit credit = sut.Deposit(entityFactory, new PositiveMoney(200));

            // Act
            IDebit actual = sut.Withdraw(entityFactory, new PositiveMoney(5000));

            //
            // Act and Assert
            Assert.Null(actual);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TransferOutput"/> class.
        /// </summary>
        /// <param name="debit">Debit object.</param>
        /// <param name="updatedBalance">Updated balance.</param>
        /// <param name="originAccountId">Origin Account Id.</param>
        /// <param name="destinationAccountId">Destination Account Id.</param>
        public TransferOutput(
            IDebit debit,
            Money updatedBalance,
            AccountId originAccountId,
            AccountId destinationAccountId)
        {
            if (debit is Debit debitEntity)
            {
                this.Transaction = new Transaction(
                    originAccountId,
                    destinationAccountId,
                    Debit.Description,
                    debitEntity.Amount,
                    debitEntity.TransactionDate);

                this.UpdatedBalance = updatedBalance;
            }
            else
            {
                throw new ArgumentNullException(nameof(debit));
            }
        }
        /// <summary>
        ///     Executes the Use Case.
        /// </summary>
        /// <param name="input">Input Message.</param>
        /// <returns>Task.</returns>
        public async Task Execute(WithdrawInput input)
        {
            if (input is null)
            {
                this._withdrawOutputPort
                .WriteError(Messages.InputIsNull);
                return;
            }

            IAccount account = await this._accountRepository
                               .GetAccount(input.AccountId)
                               .ConfigureAwait(false);

            if (account is null)
            {
                this._withdrawOutputPort
                .NotFound(Messages.AccountDoesNotExist);
                return;
            }

            try
            {
                IDebit debit = await this._accountService
                               .Withdraw(account, input.Amount)
                               .ConfigureAwait(false);

                await this._unitOfWork
                .Save()
                .ConfigureAwait(false);

                this.BuildOutput(debit, account);
            }
            catch (MoneyShouldBePositiveException outOfBalanceEx)
            {
                this._withdrawOutputPort
                .OutOfBalance(outOfBalanceEx.Message);
            }
        }
Example #25
0
 public async Task Update(IAccount account, IDebit debit)
 => await _DbSetDebit.FindOneAndReplaceAsync(f => f.Id == debit.Id, (MongoDb.Debit) debit);
Example #26
0
 public async Task Update(IAccount account, IDebit debit)
 {
     await _context.Debits.AddAsync((Debit)debit);
 }
Example #27
0
 public async Task Update(IAccount account, IDebit debit)
 {
     await _context.Debits.AddAsync((EntityFrameworkDataAccess.Debit) debit);
 }
 public void Add(IDebit debit) => _debits.Add(debit);
Example #29
0
 public void Add(IDebit debit)
 {
     _debits.Add(debit);
 }
 /// <summary>
 /// Adds a Debit.
 /// </summary>
 /// <param name="debit">Debit instance.</param>
 public void Add(IDebit debit) => this.debits.Add(debit);