/// <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}); }
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; }