Example #1
0
        public static TransactionDetailsOutDto EntityToOutDto(TransactionEntity transactionEntity)
        {
            TransactionDetailsOutDto createdTransactionDetails = transactionEntity switch
            {
                CreditTransactionEntity creditTransactionEntity => new CreditTransactionDetailsOutDto()
                {
                    CreditorName    = creditTransactionEntity.CreditorName,
                    CreditorAccount =
                        AccountReferenceOutDto.EntityToOutDto <AccountReferenceOutDto>(creditTransactionEntity
                                                                                       .CreditorAccount),
                    ValueDate       = creditTransactionEntity.ValueDate,
                    TransactionType = TransactionTypeEnum.CREDIT
                },
                DebitTransactionEntity debitTransactionEntity => new DebitTransactionDetailsOutDto()
                {
                    DebtorName    = debitTransactionEntity.DebtorName,
                    DebtorAccount =
                        AccountReferenceOutDto.EntityToOutDto <AccountReferenceOutDto>(debitTransactionEntity
                                                                                       .DebtorAccount),
                    TransactionType = TransactionTypeEnum.DEBIT
                },
                _ => throw new ArgumentOutOfRangeException(nameof(transactionEntity))
            };

            createdTransactionDetails.TransactionId     = transactionEntity.TransactionId;
            createdTransactionDetails.CheckId           = transactionEntity.CheckId;
            createdTransactionDetails.BookingDate       = transactionEntity.BookingDate;
            createdTransactionDetails.TransactionAmount = AmountOutDto.EntityToOutDto(transactionEntity.TransactionAmount);
            createdTransactionDetails.BookingStatus     = transactionEntity.BookingStatus;
            createdTransactionDetails.EntryDate         = transactionEntity.EntryDate;

            return(createdTransactionDetails);
        }
    }
Example #2
0
        public async Task <Result> UpdateBalance_BookCredit(CreditTransactionEntity newCreditTransaction)
        {
            try
            {
                var dateTimeNow        = DateTimeOffset.UtcNow;
                var foundAccountResult = await GetEntity(newCreditTransaction.AssociatedAccountId);

                AccountDetailEntity foundAccount;
                switch (foundAccountResult)
                {
                case BadRequestTypedResult <AccountDetailEntity> badRequestTypedResult:
                    return(new FailedResult(new Exception(badRequestTypedResult.Problem.Message)));

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

                case NotFoundTypedResult <AccountDetailEntity> notFoundTypedResult:
                    return(new FailedResult(new Exception("Account Not Found")));

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

                default:
                    return(new FailedResult(new ArgumentOutOfRangeException(nameof(foundAccountResult))));
                }

                var balances             = foundAccount.Balances.ToList();
                var closingBookedBalance = balances.First(b => b.BalanceType == BalanceTypeEnum.closingBooked);

                closingBookedBalance.BalanceAmount            = closingBookedBalance.BalanceAmount.Add(newCreditTransaction.TransactionAmount);
                closingBookedBalance.LastChangeDateTime       = dateTimeNow;
                closingBookedBalance.LastCommittedTransaction = newCreditTransaction.TransactionId;

                var expectedBalance = balances.FirstOrDefault(b => b.BalanceType == BalanceTypeEnum.expected);
                if (expectedBalance != null)
                {
                    if (expectedBalance.BalanceAmount.AreEqual(closingBookedBalance.BalanceAmount))
                    {
                        balances.Remove(expectedBalance);
                    }
                }

                foundAccount.Balances         = balances;
                foundAccount.LastModifiedDate = dateTimeNow;

                _accounts.FindOneAndReplace(a => a.ResourceId == foundAccount.ResourceId, foundAccount);
                return(new SuccessResult());
            }
            catch (Exception e)
            {
                return(new FailedResult(e));
            }
        }
Example #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));
            }
        }