public static async Task UpdateDetentionsAsync(IList <BehaviourIncident> incidents, string key, TimeSpan detentionStart, TimeSpan detentionEnd, string recipientOverride) { foreach (var student in incidents.GroupBy(o => o.StudentEmail)) { await Task.Delay(250); StudentCalendar cal = null; try { cal = new StudentCalendar(student.Key, key, detentionStart, detentionEnd, recipientOverride); foreach (var incident in student) { if (incident.PreviousDetentionDate != null) { await cal.DeleteDetentionAsync(incident.PreviousDetentionDate.Value); } if (incident.Status == Status.Cancel) { await cal.DeleteDetentionAsync(incident.DetentionDate.Value); } else if (incident.EmailRequired) { await cal.AddDetentionAsync(incident); } } } catch { } finally { if (cal != null) { cal.Dispose(); } } } }
public static async Task <HttpResponseMessage> Run([HttpTrigger("POST")] HttpRequestMessage req, [Blob("emails")] CloudBlobContainer emailContainer, [Queue("emails")] IAsyncCollector <string> emailQueue, [Queue("emailtriggers")] IAsyncCollector <string> triggerQueue, TraceWriter log, ExecutionContext context) { var config = Config.Instance(context.FunctionDirectory); var spreadsheet = new BehaviourSpreadsheet(config.BehaviourSpreadsheetId, config.Key); await spreadsheet.GetTrackerDataAsync(); #if !DEBUG if (spreadsheet.Tracker.LastExported >= DateTime.Today) { log.Error("Export has already run today."); return(req.CreateResponse(HttpStatusCode.Conflict, new { error = "Export has already run today." })); } #endif // Append new expectations incidents var newIncidents = await ReadIncidentsAsync(req.Content); log.Info($"Request contains {newIncidents[true].Count()} expectation and {newIncidents[false].Count()} behaviour incidents."); await spreadsheet.AddIncidentsAsync(SheetNames.Expectations, newIncidents[true].ToList()); // Fetch and parse spreadsheet data var sheets = await spreadsheet.GetSheetsAsync($"{SheetNames.Expectations}!{spreadsheet.Tracker.StartRow}:{MAX_ROWS}", SheetNames.Contacts, SheetNames.DetentionDays, SheetNames.EmailTemplates); var(unresolved, newStartRow) = Readers.ReadUnresolved(sheets[0], spreadsheet.Tracker.ExpectationColumns, spreadsheet.Tracker.StartRow); var contacts = Readers.ReadContacts(sheets[1]); var detentionDays = Readers.ReadDetentionDays(sheets[2]); var emailTemplates = Readers.ReadTemplates(sheets[3]); // Append new behaviour incidents var escalated = Escalate(unresolved.Where(o => o.Status == Status.Escalate).ToList()); await spreadsheet.AddIncidentsAsync(SheetNames.Incidents, newIncidents[false].Union(escalated).ToList()); // Set detentions CalculateDetentions(unresolved, detentionDays); await spreadsheet.UpdateDetentionsAsync(unresolved.Where(o => o.IsChanged).ToList()); // Delete cancelled detentions await spreadsheet.DeleteIncidentsAsync(unresolved.Where(o => o.Status == Status.Cancel).ToList()); // Email students, parents and contacts var mailer = new Mailer(config.SenderEmail, emailQueue, emailContainer, emailTemplates, contacts, config.BehaviourSpreadsheetId, config.DebugRecipientEmail); await mailer.QueueEmailsAsync(unresolved.ToList()); await triggerQueue.AddAsync(string.Empty); // Sort expectations sheet await spreadsheet.SortExpectationsSheet(spreadsheet.Tracker.ExpectationColumns); // Write last edit date and new start row await spreadsheet.WriteTrackerDataAsync(newStartRow); // Update calendar events var calendarChanges = unresolved.Where(o => o.EmailRequired || o.Status == Status.Cancel || o.PreviousDetentionDate != null).ToList(); if (config.DebugRecipientEmail == null) { await StudentCalendar.UpdateDetentionsAsync(calendarChanges, config.Key, config.DetentionStartTimeSpan, config.DetentionEndTimeSpan, config.DebugRecipientEmail); } log.Info("Function completed successfully."); return(req.CreateResponse(HttpStatusCode.OK)); }