public async Task <bool> BuyShareAsync(Guid requestId, BuyShareViewModel viewModel) { var request = await GetRequestByIdAsync(requestId); if (request == null) { throw new ArgumentException("request doesn't exist"); } if (request.Status == "closed") { throw new ArgumentException("request is closed"); } //TODO: Handle rollbacks try { // Get share from source var value = (await _sharesService.GetShareValue(request.ShareId)).SingleShareValue * request.Amount; // Check if user has enough funds var balance = (await _accountService.GetBalance(viewModel.AccountId)).Balance; if (balance < value) { throw new ArgumentException("User doesn't have enough funds"); } // Process transaction if (!await _paymentsService.CreateTransaction(request.OwnerAccountId, viewModel.AccountId, value)) { throw new ArgumentException("Couldn't create transaction"); } // Calculate taxes var taxes = value * 0.01m; // TAX RATE = 1% // Process taxes if (!await _accountService.PostTaxes(viewModel.AccountId, taxes)) { throw new ArgumentException("Couldn't post taxes"); } // Move shares if (!await _shareControlService.ChangeOwnershipOfShare(request.ShareId, request.PortfolioId, viewModel.PortfolioId, request.Amount)) { throw new ArgumentException("Couldn't post taxes"); } } catch (Exception e) { throw new ArgumentException("Something went wrong, try again"); } request.Status = "closed"; request.DateClosed = DateTime.UtcNow; // Success, update database _unitOfWork.RequestsRepository.Update(request); await _unitOfWork.CommitAsync(); return(true); }