public ActionResult AddSell(AddSellTransactionVm addSellTransactionVm) { if (ModelState.IsValid) { var brokerageAccount = BrokerageAccountService.GetBrokerageAccount(addSellTransactionVm.BrokerageAccountId); // Did we find the requested account and does it belong to the active user? if (brokerageAccount == null || brokerageAccount.UserId != ActiveUserService.GetUserId()) { this.FlashError("Please ensure the requested brokerage account is setup under the active user and try again.", "Index", "BrokerageAccounts"); return RedirectToAction("Index", "BrokerageAccounts", new { area = "" }); } int sellTransactionId = SellTransactionService.CreateSellTransaction(addSellTransactionVm); if (sellTransactionId > 0) { this.FlashSuccess("Successfully created the sell transaction.", "SellDetails", "StockTransactions"); return RedirectToAction("SellDetails", "StockTransactions", new { area = "", id = sellTransactionId }); } this.FlashError("Could not create the sell transaction. Please try again.", "AddSell", "StockTransactions"); } foreach (var transactionMatch in addSellTransactionVm.MatchingPurchaseTransactions) { transactionMatch.PurchaseTransaction = PurchaseTransactionService.GetPurchaseTransaction(transactionMatch.PurchaseTransactionId); } var brokerageAccountList = BrokerageAccountService.GetBrokerageAccountListForActiveUser(); // Does the active user have any brokerage accounts setup? if (!brokerageAccountList.Any()) { this.FlashError("Please ensure a brokerage account is setup and try again.", "Index", "BrokerageAccounts"); return RedirectToAction("Index", "BrokerageAccounts", new { area = "" }); } ViewBag.BrokerageAccountId = new SelectList(brokerageAccountList, "Id", "Title"); var stockList = PurchaseTransactionService.GetStocksWithOpenPositionsForBrokerageAccount(addSellTransactionVm.BrokerageAccountId); ViewBag.SecurityId = new SelectList(stockList, "Id", "Title", addSellTransactionVm.SecurityId); return View(addSellTransactionVm); }
public int CreateSellTransaction(AddSellTransactionVm addSellTransactionVm) { var shareQuantitySold = addSellTransactionVm.ShareQuantity; var sellUnitPrice = addSellTransactionVm.UnitPrice; var sellCommission = addSellTransactionVm.Commission; var sellDate = addSellTransactionVm.TransactionDate; decimal totalNetProfit = 0; decimal longTermPositionsClosed = 0; decimal longTermPositionsNetProfit = 0; decimal shortTermPositionsClosed = 0; decimal shortTermPositionsNetProfit = 0; var closingTransactionMatches = new List<ClosingTransactionMatch>(); foreach (var purchaseTransaction in addSellTransactionVm.MatchingPurchaseTransactions) { if (purchaseTransaction.ShareQuantity > 0) { var purchaseTransactionDetails = PurchaseTransactionRepository.GetPurchaseTransaction(purchaseTransaction.PurchaseTransactionId); // Requesting to close out more shares than the position has remaining open? if (purchaseTransaction.ShareQuantity > purchaseTransactionDetails.RemainingShares) { return -1; } var capitalGain = (purchaseTransaction.ShareQuantity*sellUnitPrice) // Individual Match Sell Value - (purchaseTransaction.ShareQuantity/shareQuantitySold)*sellCommission // Individual Match Sell Commission - (purchaseTransaction.ShareQuantity*purchaseTransactionDetails.UnitPrice) // Individual Match Purchase Value - (purchaseTransaction.ShareQuantity/purchaseTransactionDetails.ShareQuantity)* purchaseTransactionDetails.Commission; // Individual Match Purchase Commission totalNetProfit += capitalGain; if ((sellDate - purchaseTransactionDetails.TransactionDate).TotalDays > 365) { // Long Term Capital Gain - Greater than 1 year longTermPositionsClosed += purchaseTransaction.ShareQuantity; longTermPositionsNetProfit += capitalGain; } else { // Short Term Capital Gain - Less than 1 year shortTermPositionsClosed += purchaseTransaction.ShareQuantity; shortTermPositionsNetProfit += capitalGain; } purchaseTransactionDetails.ClosedShares += purchaseTransaction.ShareQuantity; purchaseTransactionDetails.RemainingShares -= purchaseTransaction.ShareQuantity; if (purchaseTransactionDetails.RemainingShares == 0) { purchaseTransactionDetails.PositionClosedStatus = true; } PurchaseTransactionRepository.UpdatePurchaseTransaction(purchaseTransactionDetails); var closingTransactionMatch = new ClosingTransactionMatch { MatchingShareCount = purchaseTransaction.ShareQuantity, PurchaseTransactionId = purchaseTransactionDetails.Id, TotalNetProfit = capitalGain }; closingTransactionMatches.Add(closingTransactionMatch); } } var sellTransaction = new SellTransaction { BrokerageAccountId = addSellTransactionVm.BrokerageAccountId, UnitPrice = sellUnitPrice, ShareQuantity = shareQuantitySold, SecurityId = addSellTransactionVm.SecurityId, Commission = sellCommission, TransactionDate = sellDate, TotalNetProfit = totalNetProfit, Profitable = (totalNetProfit >= 0), LongTermPositionsClosed = longTermPositionsClosed, LongTermPositionsNetProfit = longTermPositionsNetProfit, ShortTermPositionsClosed = shortTermPositionsClosed, ShortTermPositionsNetProfit = shortTermPositionsNetProfit, ClosingTransactionMatches = closingTransactionMatches }; DbOperationStatus opStatus = SellTransactionRepository.InsertSellTransaction(sellTransaction); if (opStatus.OperationSuccessStatus) { return opStatus.AffectedIndices.First(); } return -1; }