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;
            }
        }
예제 #2
0
        /// <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;
            }
        }
예제 #3
0
        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;
            }
        }