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); } }
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)); } }
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)); } }
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)); } }