private static async Task ProcessDriveItem(GraphService graphClient, Microsoft.Graph.DriveItem item) { if (item.File != null) { // Query the database var teams = await DatabaseHelper.GetFlightTeamsAsync(f => f.SharePointListItemId.Equals(item.Id)); var team = teams.FirstOrDefault(); if (item.Deleted != null && team != null) { // Remove the team await TeamProvisioning.ArchiveTeamAsync(team); // Remove the database item await DatabaseHelper.DeleteFlightTeamAsync(team.Id); return; } // Get the file's list data var listItem = await graphClient.GetDriveItemListItem(item.ParentReference.DriveId, item.Id); if (listItem == null) { return; } if (team == null) { team = FlightTeam.FromListItem(item.Id, listItem); if (team == null) { // Item was added to list but required metadata // isn't filled in yet. No-op. return; } // New item, provision team team.TeamId = await TeamProvisioning.ProvisionTeamAsync(team); await DatabaseHelper.CreateFlightTeamAsync(team); } else { var updatedTeam = FlightTeam.FromListItem(item.Id, listItem); updatedTeam.TeamId = team.TeamId; // Existing item, process changes await TeamProvisioning.UpdateTeamAsync(team, updatedTeam); updatedTeam.Id = team.Id; await DatabaseHelper.UpdateFlightTeamAsync(team.Id, updatedTeam); } } }
private static async Task AddFlightToCalendars(FlightTeam flightTeam, List <string> usersToAdd = null) { // Get all flight members var allCrewIds = await graphClient.GetUserIds(flightTeam.Pilots, flightTeam.FlightAttendants); // Initialize flight event var flightEvent = new Event { Subject = $"Flight {flightTeam.FlightNumber}", Location = new Location { DisplayName = flightTeam.Description }, Start = new DateTimeTimeZone { DateTime = flightTeam.DepartureTime.ToString("s"), TimeZone = "UTC" }, End = new DateTimeTimeZone { DateTime = flightTeam.DepartureTime.AddHours(4).ToString("s"), TimeZone = "UTC" }, Categories = new string[] { "Assigned Flight" }, Extensions = new EventExtensionsCollectionPage() }; var flightExtension = new OpenTypeExtension { ODataType = "microsoft.graph.openTypeExtension", ExtensionName = "com.contoso.flightData", AdditionalData = new Dictionary <string, object>() }; flightExtension.AdditionalData.Add("departureGate", flightTeam.DepartureGate); flightExtension.AdditionalData.Add("crewMembers", allCrewIds); flightEvent.Extensions.Add(flightExtension); if (usersToAdd == null) { usersToAdd = allCrewIds; } foreach (var userId in usersToAdd) { //var user = await graphClient.GetUserByUpn(userId); await graphClient.CreateEventInUserCalendar(userId, flightEvent); } }
public static async Task ArchiveTeamAsync(FlightTeam team) { var crew = await graphClient.GetUserIds(team.Pilots, team.FlightAttendants); // Remove event from crew calendars await TeamProvisioning.RemoveFlightFromCalendars(crew, team.FlightNumber); // Archive team try { await graphClient.ArchiveTeamAsync(team.TeamId); } catch (ServiceException ex) { logger.LogInformation($"Attempt to archive team failed: {ex.Message}"); } }
private static async Task <Group> CreateUnifiedGroupAsync(FlightTeam flightTeam) { // Initialize members list with pilots and flight attendants var members = await graphClient.GetUserIds(flightTeam.Pilots, flightTeam.FlightAttendants, true); // Add admin and me as members members.Add($"https://graph.microsoft.com/beta/users/{flightTeam.Admin}"); // Create owner list var owners = new List <string>() { $"https://graph.microsoft.com/beta/users/{flightTeam.Admin}" }; // Create the group var flightGroup = new Group { DisplayName = $"Flight {flightTeam.FlightNumber}", Description = flightTeam.Description, Visibility = "Private", MailEnabled = true, MailNickname = $"flight{flightTeam.FlightNumber}{GetTimestamp()}", GroupTypes = new string[] { "Unified" }, SecurityEnabled = false, AdditionalData = new Dictionary <string, object>() }; flightGroup.AdditionalData.Add("*****@*****.**", members); flightGroup.AdditionalData.Add("*****@*****.**", owners); var createdGroup = await graphClient.CreateGroupAsync(flightGroup); logger.LogInformation("Created group"); if (!string.IsNullOrEmpty(flightTeam.CateringLiaison)) { await AddGuestUser(createdGroup.Id, flightTeam.CateringLiaison); } return(createdGroup); }
public static async Task <string> ProvisionTeamAsync(FlightTeam flightTeam) { // Create the unified group var group = await CreateUnifiedGroupAsync(flightTeam); // Create the team in the group var teamChannel = await InitializeTeamInGroupAsync(group.Id, $"Welcome to Flight {flightTeam.FlightNumber}!"); // Create Planner plan and tasks // TODO: Disabled because you cannot create planner plans with app-only token // await CreatePreflightPlanAsync(group.Id, teamChannel.Id, flightTeam.DepartureTime); // Create SharePoint list await CreateChallengingPassengersListAsync(group.Id, teamChannel.Id); // Create SharePoint page await CreateSharePointPageAsync(group.Id, teamChannel.Id, flightTeam.FlightNumber); await AddFlightToCalendars(flightTeam); return(group.Id); }
public static async Task UpdateTeamAsync(FlightTeam originalTeam, FlightTeam updatedTeam) { // Look for changes that require an update via Graph // Did the admin change? var admin = await graphClient.GetUserByUpn(updatedTeam.Admin); updatedTeam.Admin = admin.Id; if (!admin.Id.Equals(originalTeam.Admin)) { // Add new owner await graphClient.AddMemberAsync(originalTeam.TeamId, admin.Id, true); // Remove old owner await graphClient.RemoveMemberAsync(originalTeam.TeamId, admin.Id, true); } bool isCrewChanged = false; // Add new pilots var newPilots = updatedTeam.Pilots.Except(originalTeam.Pilots); foreach (var pilot in newPilots) { isCrewChanged = true; var pilotUser = await graphClient.GetUserByUpn(pilot); await graphClient.AddMemberAsync(originalTeam.TeamId, pilotUser.Id); } if (newPilots.Count() > 0) { await TeamProvisioning.AddFlightToCalendars(updatedTeam, newPilots.ToList()); } // Remove any removed pilots var removedPilots = originalTeam.Pilots.Except(updatedTeam.Pilots); foreach (var pilot in removedPilots) { isCrewChanged = true; var pilotUser = await graphClient.GetUserByUpn(pilot); await graphClient.RemoveMemberAsync(originalTeam.TeamId, pilotUser.Id); } if (removedPilots.Count() > 0) { await TeamProvisioning.RemoveFlightFromCalendars(removedPilots.ToList(), updatedTeam.FlightNumber); } // Add new flight attendants var newFlightAttendants = updatedTeam.FlightAttendants.Except(originalTeam.FlightAttendants); foreach (var attendant in newFlightAttendants) { isCrewChanged = true; var attendantUser = await graphClient.GetUserByUpn(attendant); await graphClient.AddMemberAsync(originalTeam.TeamId, attendantUser.Id); } if (newFlightAttendants.Count() > 0) { await TeamProvisioning.AddFlightToCalendars(updatedTeam, newFlightAttendants.ToList()); } // Remove any removed flight attendants var removedFlightAttendants = originalTeam.FlightAttendants.Except(updatedTeam.FlightAttendants); foreach (var attendant in removedFlightAttendants) { isCrewChanged = true; var attendantUser = await graphClient.GetUserByUpn(attendant); await graphClient.RemoveMemberAsync(originalTeam.TeamId, attendantUser.Id); } if (removedFlightAttendants.Count() > 0) { await TeamProvisioning.RemoveFlightFromCalendars(removedFlightAttendants.ToList(), updatedTeam.FlightNumber); } // Swap out catering liaison if needed if (updatedTeam.CateringLiaison != null && !updatedTeam.CateringLiaison.Equals(originalTeam.CateringLiaison)) { var oldCateringLiaison = await graphClient.GetUserByEmail(originalTeam.CateringLiaison); await graphClient.RemoveMemberAsync(originalTeam.TeamId, oldCateringLiaison.Id); await AddGuestUser(originalTeam.TeamId, updatedTeam.CateringLiaison); } // Check for changes to gate, time bool isGateChanged = updatedTeam.DepartureGate != originalTeam.DepartureGate; bool isDepartureTimeChanged = updatedTeam.DepartureTime != originalTeam.DepartureTime; List <string> crew = null; string newGate = null; if (isCrewChanged || isGateChanged || isDepartureTimeChanged) { crew = await graphClient.GetUserIds(updatedTeam.Pilots, updatedTeam.FlightAttendants); newGate = isGateChanged ? updatedTeam.DepartureGate : null; logger.LogInformation("Updating flight in crew members' calendars"); if (isDepartureTimeChanged) { await TeamProvisioning.UpdateFlightInCalendars(crew, updatedTeam.FlightNumber, updatedTeam.DepartureGate, updatedTeam.DepartureTime); } else { await TeamProvisioning.UpdateFlightInCalendars(crew, updatedTeam.FlightNumber, updatedTeam.DepartureGate); } } if (isGateChanged || isDepartureTimeChanged) { var localTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); string newDepartureTime = isDepartureTimeChanged ? TimeZoneInfo.ConvertTime(updatedTeam.DepartureTime, localTimeZone).ToString("g") : null; logger.LogInformation("Sending notification to crew members' devices"); await TeamProvisioning.SendDeviceNotifications(crew, updatedTeam.FlightNumber, newGate, newDepartureTime); } }
public static async Task <FlightTeam> UpdateFlightTeamAsync(string id, FlightTeam flightTeam) { return(await UpdateItemAsync(id, flightTeam, flightCollection)); }
public static async Task <FlightTeam> CreateFlightTeamAsync(FlightTeam flightTeam) { return(await CreateItemAsync(flightTeam, flightCollection)); }