public List <DropDownItemModel> Resolve(PortfolioConfiguration source, ProjectEditOptionsModel destination, List <DropDownItemModel> destMember, ResolutionContext context)
 {
     return(source.PriorityGroups.Select(pg => new DropDownItemModel()
     {
         Display = pg.Name, Value = pg.ViewKey, Order = pg.Order
     }).ToList());
 }
        public async Task <ProjectEditOptionsModel> GetNewProjectOptionsAsync(PortfolioConfiguration config, ProjectEditViewModel projectModel = null)
        {
            var options = PortfolioMapper.ProjectMapper.Map <ProjectEditOptionsModel>(config);
            await ProjectEditOptionsManualMaps.MapAsync(ServiceContext.PortfolioContext, config, options, projectModel);

            return(options);
        }
        private async Task UpdateRAGStatusOptions(PortfolioConfiguration config)
        {
            var context     = ServiceContext.PortfolioContext;
            var labelConfig = config.Labels.Single(l => l.FieldName == ProjectPropertyConstants.rag);
            int options     = int.Parse(labelConfig.FieldOptions);

            if (config.RAGStatuses.Count != options)
            {
                ProjectRAGStatus redAmber, amberGreen;
                switch (options)
                {
                case 6:
                    // Add Red/Amber and Amber/Green and set the order
                    var redAmberMap   = SyncMaps.ragMap[RagConstants.RedAmberViewKey];
                    var amberGreenMap = SyncMaps.ragMap[RagConstants.AmberGreenViewKey];
                    redAmber = new ProjectRAGStatus()
                    {
                        ViewKey = RagConstants.RedAmberViewKey, Name = redAmberMap.Item1, Order = redAmberMap.Item2
                    };
                    amberGreen = new ProjectRAGStatus()
                    {
                        ViewKey = RagConstants.AmberGreenViewKey, Name = amberGreenMap.Item1, Order = amberGreenMap.Item2
                    };
                    config.RAGStatuses.Add(redAmber);
                    config.RAGStatuses.Add(amberGreen);
                    break;

                case 4:
                    // Remove Red/Amber and Amber/Green, map any projects with those RAGs
                    var red   = config.RAGStatuses.Single(rag => rag.ViewKey == RagConstants.RedViewKey);
                    var amber = config.RAGStatuses.Single(rag => rag.ViewKey == RagConstants.AmberViewKey);
                    redAmber   = config.RAGStatuses.Single(rag => rag.ViewKey == RagConstants.RedAmberViewKey);
                    amberGreen = config.RAGStatuses.Single(rag => rag.ViewKey == RagConstants.AmberGreenViewKey);

                    var redAmberUpdates = await context.ProjectUpdates.Where(u => u.RAGStatus.Id == redAmber.Id).ToListAsync();

                    foreach (var update in redAmberUpdates)
                    {
                        update.RAGStatus = red;
                    }

                    var amberGreenUpdates = await context.ProjectUpdates.Where(u => u.RAGStatus.Id == amberGreen.Id).ToListAsync();

                    foreach (var update in amberGreenUpdates)
                    {
                        update.RAGStatus = amber;
                    }

                    context.ProjectRAGStatuses.Remove(redAmber);
                    context.ProjectRAGStatuses.Remove(amberGreen);

                    break;

                default:
                    throw new ArgumentOutOfRangeException($"The label configuration for fieldname=[{ProjectPropertyConstants.rag}] has an unrecognised value. Should be 3 or 5.");
                }
            }
        }
 private PortfolioConfigAuditLog auditLogFactory(PortfolioConfiguration con, string type, DateTime timestamp, string text)
 {
     return(new PortfolioConfigAuditLog()
     {
         Timestamp = timestamp,
         PortfolioConfiguration_Id = con.Portfolio_Id,
         AuditType = type,
         Text = text
     });
 }
        public List <DropDownItemModel> Resolve(PortfolioConfiguration source, ProjectEditOptionsModel destination, IEnumerable <TOption> sourceMember, List <DropDownItemModel> destMember, ResolutionContext context)
        {
            List <DropDownItemModel> items = null;

            if (sourceMember != null)
            {
                items = context.Mapper.Map <List <DropDownItemModel> >(sourceMember);
                if (emptyOption)
                {
                    items.Insert(0, new DropDownItemModel()
                    {
                        Display = "None", Value = null
                    });
                }
            }
            return(items);
        }
Beispiel #6
0
        public static IEnumerable <PhaseProjectsModel> GetQuery(PortfolioConfiguration config, Func <Project, bool> projectPredicate, ResolutionContext context)
        {
            var q = from ph in config.Phases.Where(p => p.Id != config.CompletedPhase.Id) // Non-completed phases...
                    join pr in config.Portfolio.Projects
                    .Where(p => p.LatestUpdate?.Phase != null)
                    .Where(projectPredicate)
                    on ph.Id equals pr.LatestUpdate.Phase.Id into projects // ... get projects joined to each phase ...
                    from pr in projects.DefaultIfEmpty()                   // ... need to get all phases ...
                    group pr by ph into phaseGroup                         // ... group projects by phase ...
                    select new PhaseProjectsModel()
            {
                ViewKey  = phaseGroup.Key.ViewKey,
                Order    = phaseGroup.Key.Order,
                Projects = context.Mapper.Map <IEnumerable <ProjectIndexModel> >(phaseGroup.Where(p => p != null).OrderByDescending(p => p.Priority))
            };

            return(q.OrderBy(p => p.Order));
        }
        public IEnumerable <ProjectLabelModel> Resolve(PortfolioConfiguration source, ProjectLabelConfigModel destination,
                                                       ICollection <PortfolioLabelConfig> sourceMember,
                                                       IEnumerable <ProjectLabelModel> destMember,
                                                       ResolutionContext context)
        {
            IEnumerable <PortfolioLabelConfig> labels = sourceMember;

            // Get the settings from the context.
            var flagsKey        = nameof(PortfolioFieldFlags);
            var includedOnlyKey = nameof(PortfolioLabelConfig.Included);
            var customLabelKey  = nameof(PortfolioLabelConfig);

            // Filter
            if (context.Items.ContainsKey(flagsKey))
            {
                var flags = (PortfolioFieldFlags)context.Items[flagsKey];
                labels = labels.Where(s => (s.Flags & flags) != 0);
            }

            if (context.Items.ContainsKey(includedOnlyKey))
            {
                var includedOnly = (bool)context.Items[includedOnlyKey];
                if (includedOnly)
                {
                    labels = labels.Where(s => s.Included);
                }
            }

            // Add custom labels
            if (context.Items.ContainsKey(customLabelKey))
            {
                IEnumerable <PortfolioLabelConfig> customLabels = (IEnumerable <PortfolioLabelConfig>)context.Items[customLabelKey];
                labels = labels.Union(customLabels);
            }

            // Map to the models
            var models = context.Mapper.Map <ICollection <ProjectLabelModel> >(labels)
                         .OrderBy(l => l.GroupOrder)
                         .ThenBy(l => l.FieldOrder)
                         .ToList();

            return(models);
        }
Beispiel #8
0
        internal static async Task MapAsync(PortfolioContext context, PortfolioConfiguration config, ProjectEditOptionsModel options, ProjectEditViewModel project = null)
        {
            var directorates = await context.Directorates.OrderBy(d => d.Order).ToListAsync();

            var directorateItems = PortfolioMapper.ProjectMapper.Map <List <DropDownItemModel> >(directorates);

            directorateItems.Insert(0, new DropDownItemModel()
            {
                Display = "None", Value = "", Order = 0
            });
            options.Directorates = directorateItems;

            var teams = PortfolioMapper.ProjectMapper.Map <List <DropDownItemModel> >(config.Portfolio.Teams.OrderBy(d => d.Order));

            options.G6Team = teams;

            // Get the OptionList labels...
            var optionListLabels = config.Labels
                                   .Where(l => l.FieldType == PortfolioFieldType.OptionList || l.FieldType == PortfolioFieldType.MultiOptionList || l.FieldType == PortfolioFieldType.PredefinedMultiList)
                                   .ToList();

            // Get the edit option properties that have a json property name in the OptionList labels...
            var editOptionProperties =
                typeof(ProjectEditOptionsModel)
                .GetProperties()
                .Select(p => new _jsonProperty()
            {
                property = p, json = p.GetCustomAttribute <JsonPropertyAttribute>()
            })
                .Where(p => p.json != null)
                .ToList();

            if (project != null)
            {
                RemoveUnusedEditOptions(options, project, optionListLabels, editOptionProperties);
            }
            else
            {
                RemoveUnusedNewOptions(options, optionListLabels, editOptionProperties);
            }
        }
        public List <DropDownItemModel> Resolve(PortfolioConfiguration source, ProjectEditOptionsModel destination, List <DropDownItemModel> destMember, ResolutionContext context)
        {
            List <DropDownItemModel> items = null;
            var label = source.Labels.SingleOrDefault(l => l.FieldName == fieldName);

            if (!string.IsNullOrEmpty(label?.FieldOptions))
            {
                items = label.FieldOptions.Split(',').Select((l, i) =>
                {
                    var value   = l.Trim();
                    var display = value;
                    return(NewDropDownItem(i + 1, value, display));
                })
                        .ToList();
                if (emptyOption)
                {
                    items.Insert(0, NewDropDownItem(1, null, "None"));
                }
            }
            return(items);
        }
        public async Task <ProjectReservation> GetProjectReservationAsync(PortfolioConfiguration config)
        {
            var timestamp = DateTime.Now;
            int year      = timestamp.Year;
            int month     = timestamp.Month;

            var maxIndexQuery = ServiceContext.PortfolioContext.ProjectReservations
                                .Where(r => r.Portfolio_Id == config.Portfolio_Id && r.Year == year && r.Month == month)
                                .Select(r => (int?)r.Index);
            int maxIndex = (await maxIndexQuery.MaxAsync()) ?? 0;

            var reservation = new ProjectReservation()
            {
                Year         = year,
                Month        = month,
                Index        = maxIndex + 1,
                ReservedAt   = timestamp,
                Portfolio_Id = config.Portfolio_Id
            };

            ServiceContext.PortfolioContext.ProjectReservations.Add(reservation);
            return(reservation);
        }
Beispiel #11
0
 public static ProjectLabelConfigModel GetProjectLabelConfigModel(
     PortfolioConfiguration config,
     PortfolioFieldFlags flags = PortfolioFieldFlags.Read,
     bool includedOnly         = false,
     IEnumerable <PortfolioLabelConfig> customLabels = null,
     bool fsaOnly = false)
 {
     return(ProjectMapper.Map <ProjectLabelConfigModel>(config, opts => {
         opts.Items[nameof(PortfolioFieldFlags)] = flags;
         if (includedOnly)
         {
             opts.Items[nameof(PortfolioLabelConfig.Included)] = includedOnly;
         }
         if (customLabels != null)
         {
             opts.Items[nameof(PortfolioLabelConfig)] = customLabels;
         }
         if (fsaOnly)
         {
             opts.Items[nameof(PortfolioFieldFlags.FSAOnly)] = fsaOnly;
         }
     }));
 }
        public void NoLeadSummaryTest()
        {
            // Configure test data
            var l1 = new Person()
            {
                Id = 1, ActiveDirectoryDisplayName = "Person1"
            };
            var ph1 = new ProjectPhase()
            {
                Id = 1, Name = "Phase1", ViewKey = "phase1", Order = 0
            };
            var ph2 = new ProjectPhase()
            {
                Id = 2, Name = "Phase2", ViewKey = "phase2", Order = 1
            };
            var ph5 = new ProjectPhase()
            {
                Id = 5, Name = "Phase5", ViewKey = "phase5", Order = 2
            };

            PortfolioConfiguration config = new PortfolioConfiguration()
            {
                Phases = new List <ProjectPhase>()
                {
                    ph1, ph2, ph5
                },
                Labels = new List <PortfolioLabelConfig>()
            };

            ph1.Configuration = config;
            ph2.Configuration = config;
            ph5.Configuration = config;

            var up1 = new ProjectUpdateItem()
            {
                Phase = ph1
            };
            var up2 = new ProjectUpdateItem()
            {
                Phase = ph1
            };
            Portfolio portfolio = new Portfolio()
            {
                Configuration = config,
                Projects      = new List <Project>()
                {
                    new Project()
                    {
                        ProjectReservation_Id = 1,
                        Name    = "Project1",
                        Updates = new List <ProjectUpdateItem>()
                        {
                            up1
                        },
                        LatestUpdate = up1
                    },
                    new Project()
                    {
                        ProjectReservation_Id = 2,
                        Name    = "Project2",
                        Updates = new List <ProjectUpdateItem>()
                        {
                            up2
                        },
                        LatestUpdate = up2,
                        Lead         = l1,
                        Lead_Id      = l1.Id
                    }
                }
            };

            portfolio.Configuration.Portfolio      = portfolio;
            portfolio.Configuration.CompletedPhase = ph5;
            var summaryType = PortfolioSummaryModel.ByLead;

            // Initialise mapping configuration
            PortfolioMapper.Configure();

            // Map the test data
            var result = PortfolioMapper.ConfigMapper.Map <PortfolioSummaryModel>(
                portfolio,
                opt =>
            {
                opt.Items[nameof(PortfolioConfiguration)]          = portfolio.Configuration;
                opt.Items[PortfolioSummaryResolver.SummaryTypeKey] = summaryType;
            });

            // Check result
            // result
            // -- Phases
            //  -- Phases[0]
            //      -- ViewKey: phase1
            //      -- Count: 2
            //  -- Phases[1]
            //      -- ViewKey: phase2
            //      -- Count: 0
            // -- Summaries
            //  -- Summaries[0]
            //      -- Name: "None set"
            //      -- PhaseProjects
            //          -- Count: 2
            //          -- PhaseProjects[0]
            //              -- ViewKey: "phase1"
            //              -- Projects
            //                  -- Count: 1
            //                  -- Projects[0]
            //                      -- Name: "Project1"
            //          -- PhaseProjects[1]
            //              -- ViewKey: "phase2"
            //              -- Projects
            //                  -- Count: 0
            //  -- Summaries[1]
            //      -- Name: "Person1"
            //      -- PhaseProjects
            //          -- PhaseProjects[0]
            //              -- ViewKey: "phase1"
            //              -- Projects
            //                  -- Count: 1
            //                  -- Projects[0]
            //                      -- Name: "Project2"
            //          -- PhaseProjects[1]
            //              -- ViewKey: "phase2"
            //              -- Projects
            //                  -- Count: 0
            var phases = result.Phases.ToList();

            Assert.AreEqual(2, phases.Count());
            Assert.AreEqual("phase1", phases[0].ViewKey);
            Assert.AreEqual("phase2", phases[1].ViewKey);
            Assert.AreEqual(2, phases[0].Count); // Projects in phase 1
            Assert.AreEqual(0, phases[1].Count); // This is phase 2 (completed phase is hidden)

            var summaries = result.Summaries.ToList();

            // ... counts
            Assert.AreEqual(2, summaries.Count());

            // ... Summary 0 ("None set") should have 1 project in phase1
            Assert.AreEqual(ProjectTeamConstants.NotSetName, summaries[0].Name);
            Assert.AreEqual(2, summaries[0].PhaseProjects.ToList().Count());
            Assert.AreEqual("phase1", summaries[0].PhaseProjects.ToList()[0].ViewKey);
            Assert.AreEqual(1, summaries[0].PhaseProjects.ToList()[0].Projects.Count());
            Assert.AreEqual("Project1", summaries[0].PhaseProjects.ToList()[0].Projects.First().Name);

            Assert.AreEqual("phase2", summaries[0].PhaseProjects.ToList()[1].ViewKey);
            Assert.AreEqual(0, summaries[0].PhaseProjects.ToList()[1].Projects.Count());

            // ... Summary 1 ("Person1") should have 1 project in phase1
            Assert.AreEqual("Person1", summaries[1].Name);
            Assert.AreEqual(2, summaries[1].PhaseProjects.ToList().Count());
            Assert.AreEqual("phase1", summaries[1].PhaseProjects.ToList()[0].ViewKey);
            Assert.AreEqual(1, summaries[1].PhaseProjects.ToList()[0].Projects.Count());
            Assert.AreEqual("Project2", summaries[1].PhaseProjects.ToList()[0].Projects.First().Name);

            Assert.AreEqual("phase2", summaries[1].PhaseProjects.ToList()[1].ViewKey);
            Assert.AreEqual(0, summaries[1].PhaseProjects.ToList()[1].Projects.Count());
        }
        private void UpdateProjectOptions <T>(
            PortfolioConfiguration config,
            string fieldName,
            IQueryable <T> existingQuery,
            ICollection <T> optionCollection,
            DbSet <T> dbSet,
            string collectionDescription,
            string optionDescription,
            string viewKeyPrefix,
            int?maxOptionCount = null,
            bool hideHistoric  = true)
            where T : class, IProjectOption, new()
        {
            var labelConfig = config.Labels.Single(l => l.FieldName == fieldName);

            var optionNames = labelConfig.FieldOptions
                              .Split(',')
                              .Where(n => !string.IsNullOrWhiteSpace(n))
                              .Select((n, i) => (index: i, value: n.Trim(), lowervalue: n.Trim().ToLower()))
                              .ToArray();

            if (maxOptionCount.HasValue && optionNames.Length > maxOptionCount.Value)
            {
                throw new PortfolioConfigurationException($"Can't update {collectionDescription}: you entered {optionNames.Length} {collectionDescription}; the {optionDescription} limit is {maxOptionCount.Value}.");
            }

            var matchedNamesQuery =
                from name in optionNames
                join option in optionCollection on name.lowervalue equals option.Name.ToLower() into options
                from option in options.DefaultIfEmpty()
                orderby name.index
                select(name, option);

            var matchedNames = matchedNamesQuery.ToList();

            // If the option has no matching name, check the options has no existing assignments and then delete it
            var unmatchedOptionsQuery =
                // Get options that don't have a match in the new list
                from existingOption in optionCollection
                join name in optionNames on existingOption.Name.ToLower() equals name.lowervalue into names
                from name in names.DefaultIfEmpty()
                    where name == default
                select existingOption;

            existingQuery = existingQuery.Where(e => e != null);

            var unableToDeleteQuery =
                // Join this to all uses of the option
                from option in unmatchedOptionsQuery
                join existingOption in existingQuery
                on option.Id equals existingOption.Id into usedOptions
                from usedOption in usedOptions
                group usedOption by option into options
                select new { option = options.Key, projectCount = options.Count() };

            var unableToDelete = unableToDeleteQuery.ToList();

            if (unableToDelete.Count > 0)
            {
                if (hideHistoric)
                {
                    // Use Order = -1 to hide options
                    foreach (var noDeleteOption in unableToDelete)
                    {
                        noDeleteOption.option.Order = ProjectOptionConstants.HideOrderValue;

                        // Because we are hiding this option, need to add it back into the matched names so it gets added to the collection further down
                        matchedNames.Add(((noDeleteOption.option.Order, noDeleteOption.option.Name, noDeleteOption.option.Name.ToLower()), noDeleteOption.option));
                    }
                }
                else
                {
                    // Can't do this update while the options are assigned to projects
                    Func <string, int, string> categoryError = (n, c) =>
                    {
                        return(c == 1 ?
                               $"[{n}] is used as a {optionDescription} ({c} occurrence)" :
                               $"[{n}] is used as a {optionDescription} ({c} occurrences)");
                    };
                    throw new PortfolioConfigurationException($"Can't update {collectionDescription}: {string.Join("; ", unableToDelete.Select(c => categoryError(c.option.Name, c.projectCount)))}");
                }
            }

            var unmatchedOptions = unmatchedOptionsQuery.ToList();

            foreach (var option in unmatchedOptions)
            {
                if (!unableToDelete.Any(o => o.option.ViewKey == option.ViewKey))
                {
                    optionCollection.Remove(option);
                    dbSet.Remove(option);
                }
            }

            // If name has no matching option, add a option
            int viewKeyIndex = 0;

            optionCollection.Clear();
            for (int i = 0; i < matchedNames.Count(); i++)
            {
                var match  = matchedNames.ElementAt(i);
                T   option = match.option ?? new T();
                option.Name = match.name.value;

                // Assign next viewkey
                if (option.ViewKey == null)
                {
                    do
                    {
                        option.ViewKey = $"{viewKeyPrefix}{viewKeyIndex++}";
                    }while (matchedNames.Any(m => m.option != null && m.option != option && m.option.ViewKey == option.ViewKey));
                }

                // Assign order and add to collection
                option.Order = match.name.index;
                optionCollection.Add(option);
            }
        }
        private void UpdatePhaseOptions(PortfolioConfiguration config)
        {
            var context     = ServiceContext.PortfolioContext;
            var labelConfig = config.Labels.Single(l => l.FieldName == ProjectPropertyConstants.phase);
            var optionNames = labelConfig.FieldOptions
                              .Split(',')
                              .Where(n => !string.IsNullOrWhiteSpace(n))
                              .Select((n, i) => new { index = i, value = n.Trim(), lowervalue = n.Trim().ToLower() })
                              .ToArray();

            if (optionNames.Length > PhaseConstants.MaxCount)
            {
                throw new PortfolioConfigurationException($"Can't update phases: you entered {optionNames.Length} phases; the maximum number of phases is {PhaseConstants.MaxCount}.");
            }
            else if (optionNames.Length < 2)
            {
                throw new PortfolioConfigurationException($"Can't update phases: you entered {optionNames.Length} phases; the minimum number of phases is 2.");
            }

            var optionCollection = config.Phases;
            var dbSet            = context.ProjectPhases;
            var viewKeyPrefix    = ViewKeyPrefix.Phase;

            // If name has no matching option, add a option
            var matchedNamesQuery =
                from name in optionNames
                join option in optionCollection on name.lowervalue equals option.Name.ToLower() into options
                from option in options.DefaultIfEmpty()
                orderby name.index
                select new { name, option };
            var matchedNames = matchedNamesQuery.ToList();

            int phaseIndex                     = 0;
            int matchIndex                     = 0;
            int lastButOnePhaseIndex           = PhaseConstants.MaxCount - 2;
            int lastButOneMatchIndex           = matchedNames.Count() - 2;
            int lastMatchIndex                 = matchedNames.Count() - 1;
            List <ProjectPhase> phasesToRemove = new List <ProjectPhase>();

            // Write over the existing elements - add any new ones
            while (phaseIndex < PhaseConstants.MaxCount)
            {
                var match        = matchedNames.ElementAt(matchIndex);
                var phaseViewKey = $"{viewKeyPrefix}{phaseIndex}";
                if (matchIndex == lastButOneMatchIndex)
                {
                    // Removed unrequired phases
                    while (phaseIndex < lastButOnePhaseIndex)
                    {
                        var phase = optionCollection.SingleOrDefault(p => p.ViewKey == phaseViewKey);
                        if (phase != null)
                        {
                            phasesToRemove.Add(phase);
                        }
                        phaseViewKey = $"{viewKeyPrefix}{++phaseIndex}";
                    }
                }

                ProjectPhase option = optionCollection.SingleOrDefault(p => p.ViewKey == phaseViewKey);
                if (option == null)
                {
                    option = new ProjectPhase()
                    {
                        ViewKey = phaseViewKey, Order = phaseIndex
                    };
                    optionCollection.Add(option);
                }
                option.Name = match.name.value;

                // Set the archive and completed phases
                if (matchIndex == lastButOneMatchIndex)
                {
                    config.ArchivePhase = option;
                }
                if (matchIndex == lastMatchIndex)
                {
                    config.CompletedPhase = option;
                }

                phaseIndex++;
                matchIndex++;
            }

            foreach (var phase in phasesToRemove)
            {
                optionCollection.Remove(phase);
                dbSet.Remove(phase);
            }
        }
        private async Task UpdateCollections(PortfolioConfiguration config)
        {
            var context = ServiceContext.PortfolioContext;

            await UpdateRAGStatusOptions(config);

            UpdatePhaseOptions(config);

            UpdateProjectOptions(
                config,
                ProjectPropertyConstants.category,
                context.Projects.Select(p => p.Category).Union(context.Projects.SelectMany(p => p.Subcategories)),
                config.Categories,
                context.ProjectCategories,
                "categories",
                "project category or subcategory",
                ViewKeyPrefix.Category,
                CategoryConstants.MaxCount
                );

            UpdateProjectOptions(
                config,
                ProjectPropertyConstants.onhold,
                context.ProjectUpdates.Select(p => p.OnHoldStatus),
                config.OnHoldStatuses,
                context.ProjectOnHoldStatuses,
                "statuses",
                "project status",
                ViewKeyPrefix.Status,
                OnHoldConstants.MaxCount
                );

            UpdateProjectOptions(
                config,
                ProjectPropertyConstants.project_size,
                context.Projects.Select(p => p.Size),
                config.ProjectSizes,
                context.ProjectSizes,
                "sizes",
                "project size",
                ViewKeyPrefix.ProjectSize,
                ProjectSizeConstants.MaxCount
                );

            UpdateProjectOptions(
                config,
                ProjectPropertyConstants.budgettype,
                context.Projects.Select(p => p.BudgetType),
                config.BudgetTypes,
                context.BudgetTypes,
                "budget types",
                "project budget type",
                ViewKeyPrefix.BudgetType,
                BudgetTypeConstants.MaxCount
                );

            try
            {
                // Allow phases to be reordered with same names:
                using (var transaction = context.Database.BeginTransaction())
                {
                    // - give the phase names a temporary prefix and save
                    foreach (var phase in config.Phases)
                    {
                        phase.Name = $"__{phase.Name}";
                    }
                    await context.SaveChangesAsync();

                    // - remove the prefix
                    foreach (var phase in config.Phases)
                    {
                        phase.Name = Regex.Match(phase.Name, "^__(.*)").Groups[1].Value;
                    }
                    await context.SaveChangesAsync();

                    transaction.Commit();
                }
            }
            catch (DbUpdateException e)
            {
                var builder = new StringBuilder();
                foreach (var entry in e.Entries)
                {
                    if (entry.Entity is ProjectPhase && entry.State == EntityState.Deleted)
                    {
                        var phase = entry.Entity as ProjectPhase;
                        builder.Append($"Phase [{phase.Name}] can't be removed because it has projects assigned to it. This is likely occurring because you are trying to reduce the number of phases but there are projects assigned to the phase to be removed.");
                    }
                    else
                    {
                        builder.Append($"Please send this message to system support: Error updating project collections Entity type = {entry.Entity.GetType().Name}, Entity State = {entry.State}");
                    }
                }
                throw new PortfolioConfigurationException(builder.ToString(), e);
            }
        }
        public PortfolioLabelConfig[] GetCustomFilterLabels(PortfolioConfiguration config)
        {
            var customLabels = new PortfolioLabelConfig[] {
                new PortfolioLabelConfig()
                {
                    Included  = true,
                    Group     = config.LabelGroups.SingleOrDefault(g => g.Name == FieldGroupConstants.FieldGroupName_ProjectTeam),
                    Label     = FilterFieldConstants.TeamMemberNameName,
                    FieldName = FilterFieldConstants.TeamMemberNameFilter,
                    FieldType = PortfolioFieldType.FreeText
                },
                new PortfolioLabelConfig()
                {
                    Included  = true,
                    Group     = config.LabelGroups.SingleOrDefault(g => g.Name == FieldGroupConstants.FieldGroupName_ProjectTeam),
                    Label     = FilterFieldConstants.LeadTeamName,
                    FieldName = FilterFieldConstants.LeadTeamFilter,
                    FieldType = PortfolioFieldType.OptionList
                },
                new PortfolioLabelConfig()
                {
                    Included  = true,
                    Group     = config.LabelGroups.SingleOrDefault(g => g.Name == FieldGroupConstants.FieldGroupName_Updates),
                    Label     = FilterFieldConstants.LastUpdateName,
                    FieldName = FilterFieldConstants.LastUpdateFilter,
                    FieldType = PortfolioFieldType.Date
                },
                new PortfolioLabelConfig()
                {
                    Included  = true,
                    Group     = config.LabelGroups.SingleOrDefault(g => g.Name == FieldGroupConstants.FieldGroupName_Updates),
                    Label     = FilterFieldConstants.NoUpdatesName,
                    FieldName = FilterFieldConstants.NoUpdatesFilter,
                    FieldType = PortfolioFieldType.NullableBoolean
                },
                new PortfolioLabelConfig()
                {
                    Included  = true,
                    Group     = config.LabelGroups.SingleOrDefault(g => g.Name == FieldGroupConstants.FieldGroupName_ProjectPlan),
                    Label     = FilterFieldConstants.PastIntendedStartDateName,
                    FieldName = FilterFieldConstants.PastIntendedStartDateFilter,
                    FieldType = PortfolioFieldType.NullableBoolean
                },
                new PortfolioLabelConfig()
                {
                    Included  = true,
                    Group     = config.LabelGroups.SingleOrDefault(g => g.Name == FieldGroupConstants.FieldGroupName_ProjectPlan),
                    Label     = FilterFieldConstants.MissedEndDateName,
                    FieldName = FilterFieldConstants.MissedEndDateFilter,
                    FieldType = PortfolioFieldType.NullableBoolean
                },
                new PortfolioLabelConfig()
                {
                    Included  = true,
                    Group     = config.LabelGroups.SingleOrDefault(g => g.Name == FieldGroupConstants.FieldGroupName_Prioritisation),
                    Label     = FilterFieldConstants.PriorityGroupName,
                    FieldName = FilterFieldConstants.PriorityGroupFilter,
                    FieldType = PortfolioFieldType.OptionList
                }
            };

            return(customLabels);
        }
 public ProjectSearchFilters(ProjectQueryModel searchTerms, IQueryable <Project> filteredQuery, PortfolioConfiguration config)
 {
     this.searchTerms = searchTerms;
     this.Query       = filteredQuery;
     this.config      = config;
 }
 public DefaultFieldLabels(PortfolioConfiguration config)
 {
     this.config = config;
 }
Beispiel #19
0
 internal _projectPropertyMap(PropertyInfo property, PortfolioConfiguration config) : base(property)
 {
     this.property = property;
     this.json     = property.GetCustomAttribute <JsonPropertyAttribute>();
     this.label    = config.Labels.SingleOrDefault(l => l.FieldName == (json?.PropertyName ?? property.Name));
 }
Beispiel #20
0
        public async Task <List <ProjectUpdateModel> > ImportProjectsAsync(MultipartFormDataStreamProvider files, PortfolioConfiguration config, ProjectEditOptionsModel options)
        {
            var projects          = new List <ProjectUpdateModel>();
            var optionsProperties = typeof(ProjectEditOptionsModel).GetProperties().Select(p => new _optionsPropertyMap(p, options)).ToList();;
            var projectProperties = typeof(ProjectUpdateModel).GetProperties().Select(p => new _projectPropertyMap(p, config)).ToList();

            foreach (var file in files.FileData)
            {
                using (var reader = new StreamReader(file.LocalFileName))
                    using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
                    {
                        if (await csv.ReadAsync())
                        {
                            if (csv.ReadHeader())
                            {
                                // Go through the header and get the properties used in the import
                                List <_projectPropertyMap> headerProperties = new List <_projectPropertyMap>();
                                foreach (var h in csv.HeaderRecord)
                                {
                                    var property = projectProperties.SingleOrDefault(p => h == p.Name);
                                    if (property != null)
                                    {
                                        property.optionsProperty = optionsProperties.SingleOrDefault(op => op.JsonPropertyName == property.JsonPropertyName);
                                        headerProperties.Add(property);
                                    }
                                }

                                // Read in the project records
                                while (await csv.ReadAsync())
                                {
                                    var project = new ProjectUpdateModel();
                                    foreach (var property in headerProperties)
                                    {
                                        MapProperty(csv, project, property);
                                    }
                                    projects.Add(project);
                                }
                            }
                        }
                    }
            }
            return(projects);
        }