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_BookDebit(DebitTransactionEntity newDebitTransaction)
        {
            try
            {
                var dateTimeNow        = DateTimeOffset.UtcNow;
                var foundAccountResult = await GetEntity(newDebitTransaction.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> _:
                    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.Subtract(newDebitTransaction.TransactionAmount);
                closingBookedBalance.LastChangeDateTime       = dateTimeNow;
                closingBookedBalance.LastCommittedTransaction = newDebitTransaction.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> > NewDebitTransaction(Guid accountId,
                                                                                           DebitNewTransactionInDto newTransactionInDto)
        {
            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 != newTransactionInDto.TransactionAmount.Currency)
                {
                    return(new BadRequestLockableResult <TransactionDetailsOutDto>(BadRequestOutDto.WrongCurrencyType));
                }

                var newDebitTransaction = new DebitTransactionEntity
                {
                    TransactionId       = Guid.NewGuid(),
                    AssociatedAccountId = accountId,
                    TransactionType     = TransactionTypeEnum.DEBIT,
                    CheckId             = newTransactionInDto.CheckId,
                    TransactionAmount   = newTransactionInDto.TransactionAmount.ToEntity(),
                    EntryDate           = DateTimeOffset.UtcNow,
                    BookingDate         = null,
                    BookingStatus       = BookingStatusEnum.PENDING,
                    DebtorName          = newTransactionInDto.DebtorName,
                    DebtorAccount       = new AccountReferenceEntity()
                    {
                        Msisdn         = newTransactionInDto.DebtorAccount.Msisdn,
                        Pan            = newTransactionInDto.DebtorAccount.Pan,
                        Currency       = newTransactionInDto.DebtorAccount.Currency,
                        RoutingNumbers = new AccountReferenceEntity.RoutingNumbersEntity()
                        {
                            Wire = newTransactionInDto.DebtorAccount.RoutingNumbers.Wire,
                            Ach  = newTransactionInDto.DebtorAccount.RoutingNumbers.Ach
                        }
                    }
                };

                await TransactionCollection.InsertOneAsync(newDebitTransaction);

                var updateAccountBalance = await AccountService.UpdateBalance_NewDebit(newDebitTransaction);

                if (updateAccountBalance is SuccessResult)
                {
                    return(new SuccessfulLockableResult <TransactionDetailsOutDto>(
                               TransactionDetailsOutDto.EntityToOutDto(newDebitTransaction)));
                }
                else
                {
                    var failedResult = updateAccountBalance as FailedResult;
                    TransactionCollection.FindOneAndDelete(t => t.TransactionId == newDebitTransaction.TransactionId);
                    return(new FailedLockableResult <TransactionDetailsOutDto>(
                               failedResult?.Exception ?? new Exception("Failed to update balances.")));
                }
            }
            catch (Exception e)
            {
                return(new FailedLockableResult <TransactionDetailsOutDto>(e));
            }
        }
Example #4
0
        public async Task <Result> UpdateBalance_NewDebit(DebitTransactionEntity newDebitTransaction)
        {
            try
            {
                var dateTimeNow        = DateTimeOffset.UtcNow;
                var foundAccountResult = await GetEntity(newDebitTransaction.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);
                var expectedBalance      = balances.FirstOrDefault(b => b.BalanceType == BalanceTypeEnum.expected);
                if (expectedBalance == null)
                {
                    expectedBalance = new BalanceEntity()
                    {
                        BalanceType         = BalanceTypeEnum.expected,
                        BalanceAmount       = closingBookedBalance.BalanceAmount.RealCopy(),
                        CreditLimitIncluded = false,
                        LastChangeDateTime  = dateTimeNow
                    };
                    balances.Add(expectedBalance);
                }

                expectedBalance.BalanceAmount            = expectedBalance.BalanceAmount.Subtract(newDebitTransaction.TransactionAmount);
                expectedBalance.LastChangeDateTime       = dateTimeNow;
                expectedBalance.LastCommittedTransaction = newDebitTransaction.TransactionId;

                if (foundAccount.AuthorizedLimit != null)
                {
                    var authorizedBalance = balances.FirstOrDefault(b => b.BalanceType == BalanceTypeEnum.authorised);
                    if (authorizedBalance == null)
                    {
                        authorizedBalance = new BalanceEntity()
                        {
                            BalanceType         = BalanceTypeEnum.authorised,
                            BalanceAmount       = expectedBalance.BalanceAmount.RealCopy(),
                            CreditLimitIncluded = true,
                            LastChangeDateTime  = dateTimeNow
                        };
                        balances.Add(authorizedBalance);
                    }

                    authorizedBalance.BalanceAmount            = expectedBalance.BalanceAmount.Add(foundAccount.AuthorizedLimit);
                    authorizedBalance.LastChangeDateTime       = dateTimeNow;
                    authorizedBalance.LastCommittedTransaction = newDebitTransaction.TransactionId;
                }

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

                _accounts.FindOneAndReplace(a => a.ResourceId == foundAccount.ResourceId, foundAccount);
                return(new SuccessResult());
            }
            catch (Exception e)
            {
                return(new FailedResult(e));
            }
        }