public async Task ImportProjectsAsync(string viewKey, MultipartFormDataStreamProvider files)
        {
            var context = ServiceContext.PortfolioContext;

            // Get the config and options
            var config = await portfolioService.GetConfigAsync(viewKey);

            ServiceContext.AssertAdmin(config.Portfolio);
            var options = await portfolioService.GetNewProjectOptionsAsync(config);

            // Import the projects
            var importer = new PropertyImporter();
            var projects = await importer.ImportProjectsAsync(files, config, options);

            // Update/create the projects
            foreach (var project in projects)
            {
                if (string.IsNullOrWhiteSpace(project.project_id))
                {
                    // Create a reservation
                    var reservation = await portfolioService.GetProjectReservationAsync(config);

                    project.project_id = reservation.ProjectId;
                    await projectService.UpdateProject(project, reservation);
                }
                else
                {
                    await projectService.UpdateProject(project);
                }
            }
        }
        public async Task <Project> DeleteProjectAsync(string projectId)
        {
            var logMessage = new StringBuilder();

            logMessage.AppendLine($"Beginning delete of {projectId}:");
            try
            {
                var context = ServiceContext.PortfolioContext;
                var project = await(from p in context.Projects.IncludeProjectForDelete()
                                    where p.Reservation.ProjectId == projectId
                                    select p).SingleOrDefaultAsync();
                if (project != null)
                {
                    ServiceContext.AssertAdmin(project.Reservation.Portfolio);

                    logMessage.AppendLine("    - Deleting collections");
                    project.DeleteCollections(context);
                    await context.SaveChangesAsync();

                    logMessage.AppendLine("    - Deleting project");
                    project.Reservation.Portfolio.Projects.Remove(project);
                    context.ProjectReservations.Remove(project.Reservation);
                    context.Projects.Remove(project);
                    await context.SaveChangesAsync();
                }
                return(project);
            }
            finally {
                AppLog.TraceWarning(logMessage.ToString());
            }
        }
        public async Task SeedAccessGroups()
        {
            var context = ServiceContext.PortfolioContext;

            // If it is not a fresh platform, make sure we are admin
            if (context.Users.Count() > 0)
            {
                ServiceContext.AssertAdmin();
            }
            context.AccessGroups.AddOrUpdate(ag => ag.ViewKey,
                                             new AccessGroup()
            {
                ViewKey = AccessGroupConstants.FSAViewKey, Description = AccessGroupConstants.FSAViewKey
            },
                                             new AccessGroup()
            {
                ViewKey = AccessGroupConstants.EditorViewKey, Description = AccessGroupConstants.EditorViewKey
            },
                                             new AccessGroup()
            {
                ViewKey = AccessGroupConstants.AdminViewKey, Description = AccessGroupConstants.AdminViewKey
            },
                                             new AccessGroup()
            {
                ViewKey = AccessGroupConstants.SupplierViewKey, Description = AccessGroupConstants.SupplierViewKey
            },
                                             new AccessGroup()
            {
                ViewKey = AccessGroupConstants.SuperuserViewKey, Description = AccessGroupConstants.SuperuserViewKey
            }
                                             );
            await context.SaveChangesAsync();
        }
        public async Task ResetADReferencesAsync()
        {
            ServiceContext.AssertAdmin();
            var context = ServiceContext.PortfolioContext;

            foreach (var person in context.People.Where(p => p.ActiveDirectoryPrincipalName == null))
            {
                if (person.Surname == null && person.Firstname == null && person.Email != null && !person.Email.Contains("@"))
                {
                    await EnsurePersonForPrincipalName(person.Email);
                }
            }
            await context.SaveChangesAsync();
        }
        public async Task <PortfolioConfigModel> GetConfigurationAsync(string portfolio)
        {
            var context = ServiceContext.PortfolioContext;
            var pfolio  = await context.Portfolios.IncludeConfig()
                          .SingleAsync(p => p.ViewKey == portfolio);

            ServiceContext.AssertAdmin(pfolio);

            var model = PortfolioMapper.ConfigMapper.Map <PortfolioConfigModel>(pfolio.Configuration);

            model.Labels = model.Labels.OrderBy(l => l.FieldGroup).ThenBy(l => l.FieldOrder).ToList();

            return(model);
        }
        public async Task RemoveDuplicatesAsync()
        {
            ServiceContext.AssertAdmin();
            var context = ServiceContext.PortfolioContext;

            var dupes = await(from p in context.People
                              where p.ActiveDirectoryId != null
                              group p by p.ActiveDirectoryId into adPeople
                              where adPeople.Count() > 1
                              select adPeople).ToListAsync();

            foreach (var dupe in dupes)
            {
                Person latest = null;
                foreach (var person in dupe.OrderByDescending(p => p.Timestamp))
                {
                    if (latest == null)
                    {
                        latest = person;
                    }
                    else
                    {
                        var projects = await context.Projects
                                       .Include(p => p.KeyContact1)
                                       .Include(p => p.KeyContact2)
                                       .Include(p => p.KeyContact3)
                                       .Include(p => p.People)
                                       .Where(p =>
                                              p.Lead_Id == person.Id ||
                                              p.KeyContact1.Id == person.Id ||
                                              p.KeyContact2.Id == person.Id ||
                                              p.KeyContact3.Id == person.Id ||
                                              p.People.Any(pp => pp.Id == person.Id) ||
                                              p.Updates.Any(u => u.Person.Id == person.Id)
                                              ).ToListAsync();

                        foreach (var project in projects)
                        {
                            if (project.Lead_Id == person.Id)
                            {
                                project.Lead = latest;
                            }
                            if (project.KeyContact1?.Id == person.Id)
                            {
                                project.KeyContact1 = latest;
                            }
                            if (project.KeyContact2?.Id == person.Id)
                            {
                                project.KeyContact2 = latest;
                            }
                            if (project.KeyContact3?.Id == person.Id)
                            {
                                project.KeyContact3 = latest;
                            }
                            if (project.People.Contains(person))
                            {
                                project.People.Remove(person);
                                if (!project.People.Contains(latest))
                                {
                                    project.People.Add(latest);
                                }
                            }
                        }
                        context.People.Remove(person);
                    }
                }
            }

            await context.SaveChangesAsync();
        }
        public async Task UpdateConfigAsync(string viewKey, PortfolioConfigUpdateRequest update)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(viewKey))
                {
                    viewKey = update.ViewKey;
                }

                var context = ServiceContext.PortfolioContext;

                // Map the updates to labels
                var labelUpdates = PortfolioMapper.ConfigMapper.Map <IEnumerable <PortfolioLabelConfig> >(update.Labels);

                // Get the config with labels
                var config = await context.PortfolioConfigurations
                             .IncludeFullConfiguration()
                             .Where(p => p.Portfolio.ViewKey == viewKey)
                             .SingleAsync();

                ServiceContext.AssertAdmin(config.Portfolio);

                // Update the labels
                foreach (var labelUpdate in labelUpdates)
                {
                    var label = config.Labels.Single(l => l.FieldName == labelUpdate.FieldName);
                    PortfolioMapper.UpdateMapper.Map(labelUpdate, label);
                }

                // Record changes
                AuditProvider.LogChanges(
                    context,
                    (ts, txt) => auditLogFactory(config, nameof(PortfolioLabelConfig), ts, txt),
                    context.PortfolioConfigAuditLogs,
                    DateTime.Now);

                // Map the collections here: don't do this in mapping because can't use async in resolvers
                await UpdateCollections(config);
            }
            catch (PortfolioConfigurationException pce)
            {
                var resp = new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    ReasonPhrase = pce.Message
                };
                throw new HttpResponseException(resp);
            }
            catch (DbEntityValidationException e)
            {
                var stringBuilder = new StringBuilder();
                foreach (var eve in e.EntityValidationErrors)
                {
                    var label = eve.Entry.Entity as PortfolioLabelConfig;
                    if (label != null)
                    {
                        stringBuilder.Append($"Problem with configuration for field {label.FieldTitle}: ");
                        stringBuilder.Append(string.Join("; ", eve.ValidationErrors.Select(ve => ve.ErrorMessage)));
                    }
                    else
                    {
                        stringBuilder.Append($"Contact administrator: unrecognised issue with configuration update.");
                    }
                }
                var resp = new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    ReasonPhrase = stringBuilder.ToString()
                };
                throw new HttpResponseException(resp);
            }
            catch (Exception e)
            {
                AppLog.Trace(e);
                var resp = new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    ReasonPhrase = e.Message
                };
                throw new HttpResponseException(resp);
            }
        }