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