public async Task Deposit(string jmbg, string pass, decimal amount) { if (string.IsNullOrEmpty(jmbg)) { throw new ArgumentNullException($"{nameof(jmbg)}"); } if (string.IsNullOrEmpty(pass)) { throw new ArgumentNullException($"{nameof(pass)}"); } if (amount < 0) { throw new InvalidOperationException("Amount must be greater than 0"); } Wallet wallet = await CoreUnitOfWork.WalletRepository.GetFirstOrDefaultWithIncludes( w => w.JMBG == jmbg, w => w.Transactions ); if (wallet == null) { throw new InvalidOperationException($"{nameof(Wallet)} with JMBG = {jmbg} doesn't exist"); } if (!wallet.IsPassValid(pass)) { throw new InvalidOperationException($"Invalid password."); } if (wallet.IsBlocked) { throw new InvalidOperationException($"{nameof(Deposit)} forbidden for blocked wallet"); } await CoreUnitOfWork.BeginTransactionAsync(); try { wallet.PayIn(amount, TransactionType.Deposit, MaxDeposit); await CoreUnitOfWork.WalletRepository.Update(wallet); await CoreUnitOfWork.SaveChangesAsync(); var withdrawResponse = await BankRoutingService.Withdraw(jmbg, wallet.BankPIN, amount, wallet.Bank); if (!withdrawResponse.IsSuccess) { throw new InvalidOperationException(withdrawResponse.ErrorMessage); } await CoreUnitOfWork.CommitTransactionAsync(); } catch (InvalidOperationException ex) { await CoreUnitOfWork.RollbackTransactionAsync(); throw ex; } }
/// <summary> /// Withdraw from bank, deposit to wallet /// </summary> /// <returns></returns> public async Task <WalletDTO> Deposit(string jmbg, string pass, decimal amount) { try { await UnitOfWork.BeginTransactionAsync(); var wallet = await UnitOfWork.WalletRepository.GetFirstOrDefaultWithIncludes(w => w.JMBG == jmbg); ValidateWallet(wallet, jmbg, pass); if (wallet.IsBlocked) { throw new WalletServiceException("Wallet je blokiran!", "Deposit: Wallet is blocked!"); } decimal thisMonthDepositSum = await UnitOfWork.TransactionRepository .GetTransactionSumByTransactionsTypeThisMonth(wallet.Id, TransactionType.Deposit); if (thisMonthDepositSum + amount > MaxDeposit) { throw new WalletServiceException("Vi ste terorista!", "Deposit: Max amount of deposit exceeded this month"); } Transaction transaction = new Transaction(wallet.Id, amount, TransactionType.Deposit); wallet.Deposit(transaction.Amount); await BankService.Withdraw(wallet.JMBG, wallet.PIN, amount); await UnitOfWork.WalletRepository.Update(wallet); await UnitOfWork.TransactionRepository.Insert(transaction); await UnitOfWork.SaveChangesAsync(); await UnitOfWork.CommitTransactionAsync(); return(new WalletDTO(wallet)); } catch (Exception e) { await UnitOfWork.RollbackTransactionAsync(); throw e; } }
public async Task Transfer(string sourceJmbg, string sourcePassword, string desitnationJmbg, decimal amount) { if (sourceJmbg == desitnationJmbg) { throw new ArgumentException("Source and destination Jmbg must be different."); } if (amount <= 0) { throw new ArgumentException("Amount must be higher than 0 RSD."); } Wallet walletSource = await CoreUnitOfWork.WalletRepository.GetFirstOrDefaultWithIncludes( wallet => wallet.Jmbg == sourceJmbg, wallet => wallet.Transactions ); if (walletSource == null || !walletSource.CheckPassword(sourcePassword)) { throw new ArgumentException($"No wallet for entered jmbg '{sourceJmbg}' and password pair."); } if (walletSource.IsBlocked) { throw new InvalidOperationException($"Wallet '{sourceJmbg}' is blocked"); } Wallet walletDestination = await CoreUnitOfWork.WalletRepository.GetFirstOrDefaultWithIncludes( wallet => wallet.Jmbg == desitnationJmbg, wallet => wallet.Transactions ); if (walletDestination == null) { throw new ArgumentException($"No wallet for jmbg '{desitnationJmbg}'."); } if (walletDestination.IsBlocked) { throw new InvalidOperationException($"Wallet '{desitnationJmbg}' is blocked"); } decimal maximalDeposit; decimal maximalWithdraw; bool success = decimal.TryParse(Configuration["MaximalDeposit"], NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out maximalDeposit); if (!success) { throw new ArgumentException($"Couldn't cast {Configuration["MaximalDeposit"]} (MaximalDeposit) to decimal"); } success = decimal.TryParse(Configuration["MaximalWithdraw"], NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out maximalWithdraw); if (!success) { throw new ArgumentException($"Couldn't cast {Configuration["MaximalWithdraw"]} (MaximalWithdraw) to decimal"); } decimal fee = CalculateFee(walletSource, amount); await CoreUnitOfWork.BeginTransactionAsync(); try { walletSource.PayOut(amount, TransactionType.TransferPayOut, desitnationJmbg, maximalWithdraw); await CoreUnitOfWork.WalletRepository.Update(walletSource); await CoreUnitOfWork.SaveChangesAsync(); if (fee > 0) { walletSource.PayOut(fee, TransactionType.FeePayOut, "System", maximalWithdraw); await CoreUnitOfWork.WalletRepository.Update(walletSource); await CoreUnitOfWork.SaveChangesAsync(); } walletDestination.PayIn(amount, TransactionType.TransferPayIn, sourceJmbg, maximalDeposit); await CoreUnitOfWork.WalletRepository.Update(walletDestination); await CoreUnitOfWork.SaveChangesAsync(); await CoreUnitOfWork.CommitTransactionAsync(); } catch (InvalidOperationException ex) { await CoreUnitOfWork.RollbackTransactionAsync(); throw ex; } }