// GET: Portfolios/Edit/5 public async Task <IActionResult> Edit(int?id) { if (id == null) { return(NotFound()); } // Get the portfolio and include navigation properties var portfolio = await _context.Portfolios .Include(p => p.PortfolioSecurities) .ThenInclude(p => p.Security) .Include(p => p.PortfolioSecurities) .ThenInclude(p => p.AssetClass) .FirstOrDefaultAsync(p => p.Id == id); var viewModel = new PortfolioEditViewModel() { Portfolio = portfolio, AssetClasses = _context.AssetClasses.ToList(), PortfolioSecurities = new List <PortfolioSecurityInput>() }; // Assign the current PortfolioSecurities to the viewModel's list of PortfolioSecurities foreach (PortfolioSecurity ps in viewModel.Portfolio.PortfolioSecurities) { PortfolioSecurityInput currentPS = new PortfolioSecurityInput() { Id = ps.Id, PortfolioId = ps.PortfolioId, SecurityId = ps.SecurityId, Security = new SecurityInput() { Ticker = ps.Security.Ticker }, Weight = ps.Weight, AssetClassId = ps.AssetClassId }; viewModel.PortfolioSecurities.Add(currentPS); } // Add 10 more PortfolioSecurity objects to the viewModel's list for (int i = 0; i < 10; i++) { viewModel.PortfolioSecurities.Add(new PortfolioSecurityInput()); } if (portfolio == null) { return(NotFound()); } ViewData["UserId"] = new SelectList(_context.ApplicationUsers, "Id", "Id", portfolio.UserId); return(View(viewModel)); }
public async Task <IActionResult> Edit(int id, [Bind("Portfolio", "PortfolioSecurities")] PortfolioEditViewModel viewModel) { // Make sure all weights add up to 100 if (viewModel.PortfolioSecurities.Select(ps => ps.Weight).Sum() != 100) { viewModel.AssetClasses = _context.AssetClasses.ToList(); ViewData["WeightError"] = "The sum of all weights must equal 100"; return(View(viewModel)); } var user = await GetCurrentUserAsync(); string token = GetToken(); var client = _clientFactory.CreateClient(); // Remove all of the current PortfolioSecurities for the portfolio var portfolioSecuritiesToDelete = await _context.PortfolioSecurities .Where(ps => ps.PortfolioId == viewModel.Portfolio.Id).ToListAsync(); foreach (PortfolioSecurity ps in portfolioSecuritiesToDelete) { _context.Remove(ps); } // Get all the securities from the database var securities = _context.Securities; // Iterate over the list of PortfolioSecurities entered by the user foreach (PortfolioSecurityInput ps in viewModel.PortfolioSecurities) { if (ps.Security.Ticker != null) // Only check for security if the row was not blank { string ticker = ps.Security.Ticker; if (!securities.Any(s => s.Ticker == ticker)) { // Security is not in the DB and needs to be retrieved from IEX Cloud and saved to the DB var request = new HttpRequestMessage(HttpMethod.Get, $"https://cloud.iexapis.com/stable/stock/{ticker}/company?token={token}"); var response = await client.SendAsync(request); if (response.IsSuccessStatusCode) { // Convert the response to an object and save the new security to the database var json = await response.Content.ReadAsStreamAsync(); var stockResponse = await System.Text.Json.JsonSerializer.DeserializeAsync <IEXSecurity>(json); //SaveSecurity(stockResponse); Security newSecurity = new Security { Name = stockResponse.CompanyName, Ticker = stockResponse.Ticker, Description = stockResponse.Description }; _context.Securities.Add(newSecurity); await _context.SaveChangesAsync(); } } } } // Now all the securities should be in the DB. Get a new reference to them and iterate over the list of portfolio securities again var updatedSecurities = _context.Securities; if (id != viewModel.Portfolio.Id) { return(NotFound()); } // Save the new portfolio to the database and get a reference to its Id viewModel.Portfolio.UserId = user.Id; _context.Update(viewModel.Portfolio); await _context.SaveChangesAsync(); int portfolioId = viewModel.Portfolio.Id; // iterate over PortfolioSecurities again and enter them into the database with their properties foreach (PortfolioSecurityInput ps in viewModel.PortfolioSecurities) { if (ps.Security.Ticker != null) // only create new PS if the row was not blank { Security matchingSecurity = updatedSecurities.First(s => s.Ticker == ps.Security.Ticker); PortfolioSecurity newPS = new PortfolioSecurity { PortfolioId = portfolioId, SecurityId = matchingSecurity.Id, Weight = (int)ps.Weight, AssetClassId = (int)ps.AssetClassId }; _context.Add(newPS); } } await _context.SaveChangesAsync(); return(RedirectToAction(nameof(Index))); }