/// <summary>
		///    Verschickt Erinnerungen für Aufgaben, die bald fällig werden, oder überfällig sind.
		/// </summary>
		/// <param name="db">Ein Datenbankkontext</param>
		/// <returns>Anzahl der Aufgaben, die betrachtet wurden.</returns>
		public static string SendReminders(DataContext db)
		{
			/* Gespeichert wird in der Datenbank ja nur der Datumsanteil. Eine Aufgabe, die am Donnerstag fällig wird, enthält hier also Do, 0:00 als Zeitangabe.
			 * Tatsächlich fällig wird sie allerdings erst am Donnerstag um 24:00. Damit erklärt sich der eine Tag Unterschied in den cutoff-Daten. */

			var mailsSent = 0;
			var statusMsg = new StringBuilder();
			var mailer = new UserMailer();
			var cutoff = DateTime.Now.AddDays(6);
			var due =
				db.Assignments.Where(a => !a.IsDone && !a.ReminderSent && a.IsActive && a.DueDate < cutoff && a.Owner.IsActive)
					.ToList();
			foreach (var a in due)
			{
				// Erinnerung für Umsetzungsaufgaben nur, wenn ein Beschluss gefallen ist 
				if (a.Type == AssignmentType.ToDo || a.Topic.HasDecision(DecisionType.Resolution))
				{
					mailer.SendAssignmentReminder(a);
					a.ReminderSent = true;
					mailsSent++;
				}
			}
			db.SaveChanges();

			statusMsg.AppendFormat("Zur Erinnerung: {0} Aufgaben, {1} Erinnerungsmails versendet.\n", due.Count, mailsSent);
			mailsSent = 0;

			cutoff = DateTime.Now.AddDays(-1);
			var overdue = db.Assignments.Where(a => !a.IsDone && a.IsActive && a.DueDate < cutoff && a.Owner.IsActive).ToList();
			foreach (var a in overdue.Where(a => a.Type == AssignmentType.ToDo || a.Topic.HasDecision(DecisionType.Resolution)))
			{
				mailer.SendAssignmentOverdue(a);
				mailsSent++;
			}

			statusMsg.AppendFormat("Möglicherweise überfällig: {0}, {1} E-Mails versendet.\n", due.Count, mailsSent);

			return statusMsg.ToString();
		}
		public async Task<ActionResult> Create([Bind] AssignmentEdit input)
		{
			if (IsTopicLocked(input.TopicID))
				throw new TopicLockedException();
			else if (!ModelState.IsValid)
			{
				input.OwnerSelectList = CreateOwnerSelectListitems();
				return View(input);
			}
			else
			{
				var topic = db.Topics.Find(input.TopicID);

				// Ungelesen-Markierung und Aktion aktualisieren
				MarkAsUnread(topic);
				if (input.Type == AssignmentType.ToDo && topic.Lock != null)
					topic.Lock.Action = TopicAction.None; // Falls ein ToDo hinzugefügt wird, Wiedervorlage auswählen.

				var userlist = input.OwnerID >= 0
					? input.OwnerID.ToEnumerable()
					: db.SessionTypes.Find(-input.OwnerID).Attendees.Select(a => a.ID).ToList();

				var mailer = new UserMailer();
				var list = new List<Assignment>();
				foreach (var userid in userlist)
				{
					var a = Assignment.FromViewModel(input);
					a.Owner = db.Users.Find(userid);
					list.Add(a);
				}

				db.Assignments.AddRange(list);
				db.SaveChanges();

				await Task.WhenAll(list
					.Where(assignment => assignment.Type == AssignmentType.ToDo && input.IsActive)
					.Select(a => mailer.SendNewAssignment(a)));

				return RedirectToAction("Details", "Topics", new {id = input.TopicID});
			}
		}
		public ActionResult Edit([Bind] AssignmentEdit input)
		{
			if (!ModelState.IsValid)
			{
				ViewBag.UserList = CreateUserSelectList();
				return View(input);
			}

			var assignment = db.Assignments.Find(input.ID);
			if (IsTopicLocked(assignment.TopicID))
				throw new TopicLockedException();
			if (assignment.IsActive && assignment.Type == AssignmentType.ToDo)
				input.IsActive = true; // Verhindert, dass das Aktiv-Flag bei ToDos zurück auf false geändert wird.

			if (assignment.Type == AssignmentType.ToDo && !assignment.IsActive && input.IsActive)
				// Das Aktiv-Flag hat sich auf true geändert
			{
				var mailer = new UserMailer();
				mailer.SendNewAssignment(assignment);
			}

			assignment.IncorporateUpdates(input);
			db.Entry(assignment).State = EntityState.Modified;
			db.SaveChanges();

			return RedirectToAction("Details", "Topics", new {id = input.TopicID});
		}
예제 #4
0
		private async Task<ActionResult> ProcessTopics(ActiveSession session, SessionReport report)
		{
			List<Topic> topics = db.Topics
				.Include(t => t.SessionType)
				.Include(t => t.Lock)
				.Include(t => t.Assignments)
				.Where(t => t.Lock.Session.ID == session.ID)
				.ToList();

			var mailer = new UserMailer();

			try
			{
				mailer.SendSessionReport(topics, report);
			}
			catch (Exception ex)
			{
				// return HTTPStatus(HttpStatusCode.InternalServerError, "Fehler beim Versenden der E-Mails: " + ex.Message);
			}

			foreach (var t in topics)
			{
				switch (t.Lock.Action)
				{
					case TopicAction.None:
						t.IsReadOnly = false;
						break;
					case TopicAction.Decide:
						t.Decision = new Decision
						{
							OriginTopic = t,
							Report = report,
							Text = t.Proposal,
							Type = DecisionType.Resolution
						};
						// Inaktive Aufgaben löschen
						db.Assignments.RemoveRange(db.Assignments.Where(a => a.TopicID == t.ID && !a.IsActive));

						// Für aktive Umsetzungaufgaben E-Mails verschicken
						var tasks = new List<Task>();
						foreach (var duty in t.Assignments.Where(a => a.Type == AssignmentType.Duty && a.IsActive))
							tasks.Add(mailer.SendNewAssignment(duty));
						await Task.WhenAll(tasks);

						break;
					case TopicAction.Close:
						t.Decision = new Decision
						{
							OriginTopic = t,
							Report = report,
							Text = t.Proposal,
							Type = DecisionType.Closed
						};
						break;
					case TopicAction.Delete:
						db.DeleteTopic(t.ID);
						break;
					default:
						throw new ArgumentOutOfRangeException();
				}
				if (t.Lock != null) // Wenn gelöscht wird, ist t.Lock hier bereits null
					db.TopicLocks.Remove(t.Lock);
			}

			return null;
		}