Exemplo n.º 1
0
        public async Task <TypedResult <TransactionDetailsOutDto> > GetTransaction(Guid accountId, Guid transactionId)
        {
            try
            {
                var foundTransaction =
                    (await TransactionCollection.FindAsync(t =>
                                                           t.TransactionId == transactionId && t.AssociatedAccountId == accountId)).FirstOrDefault();

                if (foundTransaction == null)
                {
                    return(new NotFoundTypedResult <TransactionDetailsOutDto>());
                }

                return(new SuccessfulTypedResult <TransactionDetailsOutDto>(
                           TransactionDetailsOutDto.EntityToOutDto(foundTransaction)));
            }
            catch (Exception e)
            {
                return(new FailedTypedResult <TransactionDetailsOutDto>(e));
            }
        }
Exemplo n.º 2
0
        public async Task <LockableResult <TransactionDetailsOutDto> > BookTransaction(Guid accountId, Guid creditTransactionId)
        {
            try
            {
                var foundAccountResult = await AccountService.GetEntity(accountId);

                switch (foundAccountResult)
                {
                case BadRequestTypedResult <AccountDetailEntity> badRequestTypedResult:
                    return(new BadRequestLockableResult <TransactionDetailsOutDto>(badRequestTypedResult.Problem));

                case FailedTypedResult <AccountDetailEntity> failedTypedResult:
                    return(new FailedLockableResult <TransactionDetailsOutDto>(failedTypedResult.Error));

                case NotFoundTypedResult <AccountDetailEntity> _:
                    return(new BadRequestLockableResult <TransactionDetailsOutDto>(BadRequestOutDto.AccountNotFound));

                case SuccessfulTypedResult <AccountDetailEntity> _:
                    break;

                default:
                    return(new FailedLockableResult <TransactionDetailsOutDto>(
                               new ArgumentOutOfRangeException(nameof(foundAccountResult))));
                }

                var updatedTransaction = TransactionCollection.FindOneAndUpdate <TransactionEntity>(
                    t => t.TransactionId == creditTransactionId && t.AssociatedAccountId == accountId && t.BookingStatus == BookingStatusEnum.PENDING,
                    Builders <TransactionEntity> .Update.Set(t => t.BookingStatus, BookingStatusEnum.BOOKED),
                    GetEntityAfterUpdateOption <TransactionEntity>());

                if (updatedTransaction == null)
                {
                    return(new BadRequestLockableResult <TransactionDetailsOutDto>(
                               "Failed to find matching transaction to book."));
                }

                Result accountBalanceUpdateResult;
                switch (updatedTransaction)
                {
                case CreditTransactionEntity creditTransactionEntity:
                    accountBalanceUpdateResult = await AccountService.UpdateBalance_BookCredit(creditTransactionEntity);

                    break;

                case DebitTransactionEntity debitTransactionEntity:
                    accountBalanceUpdateResult = await AccountService.UpdateBalance_BookDebit(debitTransactionEntity);

                    break;

                default:
                    accountBalanceUpdateResult = new FailedResult(new ArgumentOutOfRangeException(nameof(updatedTransaction)));
                    break;
                }

                if (accountBalanceUpdateResult is SuccessResult)
                {
                    return(new SuccessfulLockableResult <TransactionDetailsOutDto>(
                               TransactionDetailsOutDto.EntityToOutDto(updatedTransaction)));
                }
                else
                {
                    var failedResult = accountBalanceUpdateResult as FailedResult;
                    TransactionCollection.FindOneAndUpdate(t => t.TransactionId == updatedTransaction.TransactionId,
                                                           Builders <TransactionEntity> .Update.Set(t => t.BookingStatus, BookingStatusEnum.PENDING));
                    return(new FailedLockableResult <TransactionDetailsOutDto>(
                               failedResult?.Exception ?? new Exception("Failed to update balances.")));
                }
            }
            catch (Exception e)
            {
                return(new FailedLockableResult <TransactionDetailsOutDto>(e));
            }
        }
Exemplo n.º 3
0
        public async Task <LockableResult <TransactionDetailsOutDto> > NewCreditTransaction(Guid accountId,
                                                                                            CreditNewTransactionInDto newCreditTransactionInDto)
        {
            try
            {
                var foundAccountResult = await AccountService.GetEntity(accountId);

                AccountDetailEntity foundAccount;
                switch (foundAccountResult)
                {
                case BadRequestTypedResult <AccountDetailEntity> badRequestTypedResult:
                    return(new BadRequestLockableResult <TransactionDetailsOutDto>(badRequestTypedResult.Problem));

                case FailedTypedResult <AccountDetailEntity> failedTypedResult:
                    return(new FailedLockableResult <TransactionDetailsOutDto>(failedTypedResult.Error));

                case NotFoundTypedResult <AccountDetailEntity> _:
                    return(new BadRequestLockableResult <TransactionDetailsOutDto>(BadRequestOutDto.AccountNotFound));

                case SuccessfulTypedResult <AccountDetailEntity> successfulTypedResult:
                    foundAccount = successfulTypedResult.Value;
                    break;

                default:
                    return(new FailedLockableResult <TransactionDetailsOutDto>(
                               new ArgumentOutOfRangeException(nameof(foundAccountResult))));
                }

                if (foundAccount.Status != AccountStatusEnum.enabled)
                {
                    return(new BadRequestLockableResult <TransactionDetailsOutDto>(BadRequestOutDto.AccountNotEnabled));
                }

                if (foundAccount.Currency != newCreditTransactionInDto.TransactionAmount.Currency)
                {
                    return(new BadRequestLockableResult <TransactionDetailsOutDto>(BadRequestOutDto.WrongCurrencyType));
                }

                var newCreditTransaction = new CreditTransactionEntity()
                {
                    TransactionId       = Guid.NewGuid(),
                    AssociatedAccountId = accountId,
                    TransactionType     = TransactionTypeEnum.CREDIT,
                    CheckId             = newCreditTransactionInDto.CheckId,
                    TransactionAmount   = newCreditTransactionInDto.TransactionAmount.ToEntity(),
                    EntryDate           = DateTimeOffset.UtcNow,
                    BookingDate         = null,
                    BookingStatus       = BookingStatusEnum.PENDING,
                    CreditorName        = newCreditTransactionInDto.CreditorName,
                    CreditorAccount     = new AccountReferenceEntity()
                    {
                        Msisdn         = newCreditTransactionInDto.CreditorAccount.Msisdn,
                        Pan            = newCreditTransactionInDto.CreditorAccount.Pan,
                        Currency       = newCreditTransactionInDto.CreditorAccount.Currency,
                        RoutingNumbers = new AccountReferenceEntity.RoutingNumbersEntity()
                        {
                            Wire = newCreditTransactionInDto.CreditorAccount.RoutingNumbers.Wire,
                            Ach  = newCreditTransactionInDto.CreditorAccount.RoutingNumbers.Ach
                        }
                    },
                    ValueDate = newCreditTransactionInDto.ValueDate
                };

                await TransactionCollection.InsertOneAsync(newCreditTransaction);

                var updateAccountBalance = await AccountService.UpdateBalance_NewCredit(newCreditTransaction);

                if (updateAccountBalance is SuccessResult)
                {
                    return(new SuccessfulLockableResult <TransactionDetailsOutDto>(
                               TransactionDetailsOutDto.EntityToOutDto(newCreditTransaction)));
                }
                else
                {
                    var failedResult = updateAccountBalance as FailedResult;
                    TransactionCollection.FindOneAndDelete(t => t.TransactionId == newCreditTransaction.TransactionId);
                    return(new FailedLockableResult <TransactionDetailsOutDto>(
                               failedResult?.Exception ?? new Exception("Failed to update balances.")));
                }
            }
            catch (Exception e)
            {
                return(new FailedLockableResult <TransactionDetailsOutDto>(e));
            }
        }