public void SendSingleEmail(int emailDefinitionId, string recipientUserId)
        {
            EmailDefinition    definition = _db.EmailDefinitions.Find(emailDefinitionId);
            TimetableUserEntry user       = _timetableUserRepository.GetByUsername(recipientUserId);

            if (definition == null)
            {
                throw new ArgumentOutOfRangeException(nameof(emailDefinitionId), "No email definition with such id");
            }

            if (user == null)
            {
                throw new ArgumentOutOfRangeException(nameof(user), "No timetable user entry with such id");
            }

            MailMessage message = new MailMessage
            {
                Subject    = definition.Subject,
                Body       = definition.Body,
                IsBodyHtml = true,
                From       = EmailHelpers.DefaultSender,
                To         = { new MailAddress(user.InternalEmail, user.Fullname) },
            };

            _smtpClient.Send(message);
        }
        public ActionResult NewElectionEntry(NewElectionEntry model)
        {
            if (!ModelState.IsValid)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }

            // STEP 1: Fetch everything we got as IDs

            Election           election = _db.Elections.Find(model.ElectionId);
            TimetableUserEntry user     = _userRepository.GetByUsername(model.UserId);

            // STEP 2: Check that everything is correct

            List <string> errors        = new List <string>();
            bool          suggestReload = false;

            if (election == null)
            {
                errors.Add("Failed to find election");
                suggestReload = true;
            }

            if (user == null)
            {
                errors.Add("Invalid student ID");
            }

            if (user != null && !user.IsStudentActive)
            {
                errors.Add("Only active students can participate in elections");
            }

            if (errors.Count > 0)
            {
                ViewBag.SuggestReload = suggestReload;
                string errorHtml = PartialView("_ErrorsDisplay", errors).RenderToString();

                return(Json(new
                {
                    Success = false,
                    HumanErrorHtml = errorHtml
                }));
            }

            // STEP 3: Check that there isn't an entry already for this user

            // ReSharper disable PossibleNullReferenceException
            if (_db.ElectionEligibilityEntries.Find(user.UserId, election.Id) != null)
            {
                return(Json(new
                {
                    Success = false,
                    HumanError = "Error: there is already an entry for this user"
                }));
            }

            // STEP 4: Create a new entity and save it

            ElectionEligibilityEntry newEntry = new ElectionEligibilityEntry()
            {
                Username = model.UserId,
                Election = election
            };

            _db.ElectionEligibilityEntries.Add(newEntry);
            _db.SaveChanges();

            // STEP 5: Prepare the displayed table row

            ElectionTableRow tableRow = new ElectionTableRow {
                UserId = user.UserId
            };

            PopulateUserInfo(tableRow, user);

            // STEP 6: Reply that we are done

            return(Json(new
            {
                Success = true,
                Entry = tableRow
            }));
        }