public ViewResult Detail(ClassificationPrimaryKey classificationPrimaryKey)
        {
            var classification                = classificationPrimaryKey.EntityObject;
            var mapDivID                      = $"classification_{classification.ClassificationID}_Map";
            var associatedProjects            = classification.GetAssociatedProjects(CurrentFirmaSession);
            var currentPersonCanViewProposals = CurrentFirmaSession.CanViewProposals();

            var projectMapCustomization      = ProjectMapCustomization.CreateDefaultCustomization(associatedProjects, currentPersonCanViewProposals);
            var projectLocationsLayerGeoJson = new LayerGeoJson($"{FieldDefinitionEnum.ProjectLocation.ToType().GetFieldDefinitionLabelPluralized()}",
                                                                associatedProjects.MappedPointsToGeoJsonFeatureCollection(false, true, false), "red", 1, LayerInitialVisibility.LayerInitialVisibilityEnum.Show);
            var projectLocationsMapInitJson = new ProjectLocationsMapInitJson(projectLocationsLayerGeoJson,
                                                                              projectMapCustomization, mapDivID, false)
            {
                AllowFullScreen = true,
            };

            // Add Organization Type boundaries according to configuration
            projectLocationsMapInitJson.Layers.AddRange(HttpRequestStorage.DatabaseEntities.Organizations.GetConfiguredBoundaryLayersGeoJson().
                                                        Where(x => x.LayerInitialVisibility == LayerInitialVisibility.LayerInitialVisibilityEnum.Show));
            var filteredProjectList = associatedProjects.Where(x1 => x1.HasProjectLocationPointViewableByUser(CurrentFirmaSession)).
                                      Where(x => x.ProjectStage.ShouldShowOnMap()).ToList();

            // filteredProjectList only contains project location points the user has permission to see
            projectLocationsMapInitJson.BoundingBox =
                new BoundingBox(filteredProjectList.Select(x => x.GetProjectLocationPoint(true)).ToList());
            var projectLocationsMapViewData = new ProjectLocationsMapViewData(projectLocationsMapInitJson.MapDivID,
                                                                              ProjectColorByType.ProjectStage.GetDisplayNameFieldDefinition(), MultiTenantHelpers.GetTopLevelTaxonomyTiers(), currentPersonCanViewProposals);

            var projectFundingSourceExpenditures = associatedProjects.SelectMany(x => x.ProjectFundingSourceExpenditures);
            var organizationTypes = HttpRequestStorage.DatabaseEntities.OrganizationTypes.ToList();

            const string chartTitle       = "Reported Expenditures By Organization Type";
            var          chartContainerID = chartTitle.Replace(" ", "");
            var          googleChart      = projectFundingSourceExpenditures.ToGoogleChart(x => x.FundingSource.Organization.OrganizationType.OrganizationTypeName,
                                                                                           organizationTypes.Select(x => x.OrganizationTypeName).ToList(),
                                                                                           x => x.FundingSource.Organization.OrganizationType.OrganizationTypeName,
                                                                                           chartContainerID,
                                                                                           chartTitle,
                                                                                           organizationTypes.ToDictionary(x => x.OrganizationTypeName, x => x.LegendColor));

            var viewGoogleChartViewData = new ViewGoogleChartViewData(googleChart, chartTitle, 405, true);

            var performanceMeasures = associatedProjects
                                      .SelectMany(x => x.PerformanceMeasureActuals)
                                      .Select(x => x.PerformanceMeasure).Distinct(new HavePrimaryKeyComparer <PerformanceMeasure>())
                                      .OrderBy(x => x.PerformanceMeasureDisplayName)
                                      .ToList();

            var projectCustomDefaultGridConfigurations = HttpRequestStorage.DatabaseEntities.ProjectCustomGridConfigurations.Where(x => x.IsEnabled && x.ProjectCustomGridTypeID == ProjectCustomGridType.Default.ProjectCustomGridTypeID).OrderBy(x => x.SortOrder).ToList();
            var viewData = new DetailViewData(CurrentFirmaSession, classification, projectLocationsMapViewData, projectLocationsMapInitJson, viewGoogleChartViewData, performanceMeasures, projectCustomDefaultGridConfigurations);

            return(RazorView <Detail, DetailViewData>(viewData));
        }
Beispiel #2
0
        public ViewResult ProjectMap()
        {
            List <int> filterValues;
            ProjectLocationFilterType projectLocationFilterType;
            ProjectColorByType        colorByValue;

            var currentPersonCanViewProposals = CurrentFirmaSession.CanViewProposals();

            if (!String.IsNullOrEmpty(Request.QueryString[ProjectMapCustomization.FilterByQueryStringParameter]))
            {
                projectLocationFilterType = ProjectLocationFilterType.ToType(Request
                                                                             .QueryString[ProjectMapCustomization.FilterByQueryStringParameter]
                                                                             .ParseAsEnum <ProjectLocationFilterTypeEnum>());
            }
            else
            {
                projectLocationFilterType = ProjectMapCustomization.DefaultLocationFilterType;
            }

            if (!String.IsNullOrEmpty(Request.QueryString[ProjectMapCustomization.FilterValuesQueryStringParameter]))
            {
                var filterValuesAsString = Request.QueryString[ProjectMapCustomization.FilterValuesQueryStringParameter]
                                           .Split(',');
                filterValues = filterValuesAsString.Select(Int32.Parse).ToList();
            }
            else
            {
                filterValues = GetDefaultFilterValuesForFilterType(projectLocationFilterType.ToEnum, currentPersonCanViewProposals);
            }

            if (!String.IsNullOrEmpty(Request.QueryString[ProjectMapCustomization.ColorByQueryStringParameter]))
            {
                colorByValue = ProjectColorByType.ToType(Request
                                                         .QueryString[ProjectMapCustomization.ColorByQueryStringParameter]
                                                         .ParseAsEnum <ProjectColorByTypeEnum>());
            }
            else
            {
                colorByValue = ProjectMapCustomization.DefaultColorByType;
            }

            var firmaPage = FirmaPageTypeEnum.ProjectMap.GetFirmaPage();

            var projectsToShow = ProjectMapCustomization.ProjectsForMap(currentPersonCanViewProposals, CurrentFirmaSession);

            var initialCustomization =
                new ProjectMapCustomization(projectLocationFilterType, filterValues, colorByValue);
            var projectLocationsLayerGeoJson =
                new LayerGeoJson($"{FieldDefinitionEnum.ProjectLocation.ToType().GetFieldDefinitionLabel()}",
                                 projectsToShow.MappedPointsToGeoJsonFeatureCollection(false, true, true), "red", 1,
                                 LayerInitialVisibility.LayerInitialVisibilityEnum.Show);
            var projectLocationsMapInitJson = new ProjectLocationsMapInitJson(projectLocationsLayerGeoJson,
                                                                              initialCustomization, "ProjectLocationsMap", true);

            // Add Organization Type boundaries according to configuration
            projectLocationsMapInitJson.Layers.AddRange(HttpRequestStorage.DatabaseEntities.Organizations.GetConfiguredBoundaryLayersGeoJson());

            var projectLocationsMapViewData = new ProjectLocationsMapViewData(projectLocationsMapInitJson.MapDivID, null, MultiTenantHelpers.GetTopLevelTaxonomyTiers(), currentPersonCanViewProposals, true);


            var projectLocationFilterTypesAndValues = CreateProjectLocationFilterTypesAndValuesDictionary(currentPersonCanViewProposals);
            var projectLocationsUrl = SitkaRoute <ResultsController> .BuildAbsoluteUrlHttpsFromExpression(x => x.ProjectMap());

            var filteredProjectsWithLocationAreasUrl =
                SitkaRoute <ResultsController> .BuildUrlFromExpression(x => x.FilteredProjectsWithLocationAreas(null));

            var projectColorByTypes = new List <ProjectColorByType> {
                ProjectColorByType.ProjectStage
            };

            if (MultiTenantHelpers.IsTaxonomyLevelTrunk())
            {
                projectColorByTypes.Add(ProjectColorByType.TaxonomyTrunk);
            }
            else if (MultiTenantHelpers.IsTaxonomyLevelBranch())
            {
                projectColorByTypes.Add(ProjectColorByType.TaxonomyBranch);
            }
            var viewData = new ProjectMapViewData(CurrentFirmaSession,
                                                  firmaPage,
                                                  projectLocationsMapInitJson,
                                                  projectLocationsMapViewData,
                                                  projectLocationFilterTypesAndValues,
                                                  projectLocationsUrl, filteredProjectsWithLocationAreasUrl, projectColorByTypes, ProjectColorByType.ProjectStage.GetDisplayNameFieldDefinition());

            return(RazorView <ProjectMap, ProjectMapViewData>(viewData));
        }
Beispiel #3
0
        public ViewResult Detail(TaxonomyLeafPrimaryKey taxonomyLeafPrimaryKey)
        {
            var taxonomyLeaf = taxonomyLeafPrimaryKey.EntityObject;
            var currentPersonCanViewProposals = CurrentFirmaSession.CanViewProposals();

            var primaryTaxonomyLeafProjects = taxonomyLeaf.GetProjects().ToList()
                                              .GetActiveProjectsAndProposals(currentPersonCanViewProposals)
                                              .Where(x => x.ProjectStage.ShouldShowOnMap())
                                              .ToList();
            var secondaryTaxonomyLeafProjects = primaryTaxonomyLeafProjects.Union(
                taxonomyLeaf.SecondaryProjectTaxonomyLeafs.Select(x => x.Project)
                .ToList()
                .GetActiveProjectsAndProposals(currentPersonCanViewProposals)
                .Where(x => x.ProjectStage.ShouldShowOnMap()))
                                                .ToList();

            // This page supports two maps for cases where secondary taxonomy leafs are supported
            var primaryProjectMapCustomization = new ProjectMapCustomization(ProjectLocationFilterType.TaxonomyLeaf,
                                                                             new List <int> {
                taxonomyLeaf.TaxonomyLeafID
            }, ProjectColorByType.ProjectStage);
            var secondaryProjectMapCustomization = new ProjectMapCustomization(ProjectLocationFilterType.TaxonomyLeaf,
                                                                               secondaryTaxonomyLeafProjects.Select(x => x.GetTaxonomyLeaf().TaxonomyLeafID).Union(new List <int> {
                taxonomyLeaf.TaxonomyLeafID
            }).ToList(),
                                                                               ProjectColorByType.ProjectStage);
            var primaryProjectLocationsLayerGeoJson =
                new LayerGeoJson($"{FieldDefinitionEnum.ProjectLocation.ToType().GetFieldDefinitionLabel()}",
                                 primaryTaxonomyLeafProjects.MappedPointsToGeoJsonFeatureCollection(false, true, false), "red", 1,
                                 LayerInitialVisibility.LayerInitialVisibilityEnum.Show);
            var secondaryProjectLocationsLayerGeoJson =
                new LayerGeoJson($"{FieldDefinitionEnum.ProjectLocation.ToType().GetFieldDefinitionLabel()}",
                                 secondaryTaxonomyLeafProjects.MappedPointsToGeoJsonFeatureCollection(false, true, false), "red", 1,
                                 LayerInitialVisibility.LayerInitialVisibilityEnum.Show);
            // Add Organization Type boundaries according to configuration
            var configuredOrganizationBoundariesMapInitJson = HttpRequestStorage.DatabaseEntities.Organizations.GetConfiguredBoundaryLayersGeoJson();

            var primaryProjectLocationsMapInitJson = new ProjectLocationsMapInitJson(primaryProjectLocationsLayerGeoJson,
                                                                                     primaryProjectMapCustomization, "TaxonomyLeafProjectMap", false);

            primaryProjectLocationsMapInitJson.Layers.AddRange(configuredOrganizationBoundariesMapInitJson);

            var secondaryProjectLocationsMapInitJson = new ProjectLocationsMapInitJson(secondaryProjectLocationsLayerGeoJson,
                                                                                       secondaryProjectMapCustomization, "SecondaryTaxonomyLeafProjectMap", false);

            secondaryProjectLocationsMapInitJson.Layers.AddRange(configuredOrganizationBoundariesMapInitJson);

            var primaryProjectLocationsMapViewData = new ProjectLocationsMapViewData(primaryProjectLocationsMapInitJson.MapDivID,
                                                                                     ProjectColorByType.ProjectStage.GetDisplayNameFieldDefinition(), MultiTenantHelpers.GetTopLevelTaxonomyTiers(),
                                                                                     CurrentFirmaSession.CanViewProposals());
            var secondaryProjectLocationsMapViewData = new ProjectLocationsMapViewData(secondaryProjectLocationsMapInitJson.MapDivID,
                                                                                       ProjectColorByType.ProjectStage.GetDisplayNameFieldDefinition(), MultiTenantHelpers.GetTopLevelTaxonomyTiers(),
                                                                                       CurrentFirmaSession.CanViewProposals());

            var associatePerformanceMeasureTaxonomyLevel =
                MultiTenantHelpers.GetAssociatePerformanceMeasureTaxonomyLevel();
            var canHaveAssociatedPerformanceMeasures = associatePerformanceMeasureTaxonomyLevel == TaxonomyLevel.Leaf;
            var taxonomyTierPerformanceMeasures      = taxonomyLeaf.GetTaxonomyTierPerformanceMeasures();
            var relatedPerformanceMeasuresViewData   = new RelatedPerformanceMeasuresViewData(
                associatePerformanceMeasureTaxonomyLevel, true, taxonomyTierPerformanceMeasures,
                canHaveAssociatedPerformanceMeasures);

            var taxonomyLevel   = MultiTenantHelpers.GetTaxonomyLevel();
            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();

            var performanceMeasures = taxonomyLeaf.TaxonomyLeafPerformanceMeasures.Select(x => x.PerformanceMeasure)
                                      .ToList();
            var primaryPerformanceMeasureChartViewDataByPerformanceMeasure = performanceMeasures.ToDictionary(
                x => x.PerformanceMeasureID,
                x => new PerformanceMeasureChartViewData(x, CurrentFirmaSession, false, primaryTaxonomyLeafProjects, $"primary{x.GetJavascriptSafeChartUniqueName()}"));
            var secondaryPerformanceMeasureChartViewDataByPerformanceMeasure = performanceMeasures.ToDictionary(
                x => x.PerformanceMeasureID,
                x => new PerformanceMeasureChartViewData(x, CurrentFirmaSession, false, secondaryTaxonomyLeafProjects, $"secondary{x.GetJavascriptSafeChartUniqueName()}"));

            var projectCustomDefaultGridConfigurations = HttpRequestStorage.DatabaseEntities.ProjectCustomGridConfigurations.Where(x => x.IsEnabled && x.ProjectCustomGridTypeID == ProjectCustomGridType.Default.ProjectCustomGridTypeID).OrderBy(x => x.SortOrder).ToList();

            var viewData = new DetailViewData(CurrentFirmaSession, taxonomyLeaf, primaryProjectLocationsMapInitJson,
                                              secondaryProjectLocationsMapInitJson, primaryProjectLocationsMapViewData,
                                              secondaryProjectLocationsMapViewData, canHaveAssociatedPerformanceMeasures,
                                              relatedPerformanceMeasuresViewData, taxonomyLevel, tenantAttribute, performanceMeasures,
                                              primaryPerformanceMeasureChartViewDataByPerformanceMeasure,
                                              secondaryPerformanceMeasureChartViewDataByPerformanceMeasure,
                                              projectCustomDefaultGridConfigurations);

            return(RazorView <Summary, DetailViewData>(viewData));
        }
Beispiel #4
0
        private static LtInfoMenuItem BuildProgramInfoMenu(FirmaSession currentFirmaSession)
        {
            var programInfoMenu = new LtInfoMenuItem(FirmaMenuItem.ProgramInfo.GetFirmaMenuItemDisplayName());

            programInfoMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProgramInfoController>(c => c.Taxonomy()), currentFirmaSession, MultiTenantHelpers.GetTaxonomySystemName(), "Group1"));

            MultiTenantHelpers.GetClassificationSystems().ForEach(x =>
            {
                programInfoMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProgramInfoController>(c => c.ClassificationSystem(x.ClassificationSystemID)), currentFirmaSession, ClassificationSystemModelExtensions.GetClassificationSystemNamePluralized(x), "Group1"));
            });
            programInfoMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <PerformanceMeasureController>(c => c.Index()), currentFirmaSession, MultiTenantHelpers.GetPerformanceMeasureNamePluralized(), "Group1"));

            foreach (var geospatialAreaType in HttpRequestStorage.DatabaseEntities.GeospatialAreaTypes.ToList())
            {
                programInfoMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <GeospatialAreaController>(c => c.Index(geospatialAreaType)), currentFirmaSession, $"{geospatialAreaType.GeospatialAreaTypeNamePluralized}", "Group2"));
            }

            if (MultiTenantHelpers.HasCanStewardProjectsOrganizationRelationship())
            {
                programInfoMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectStewardOrganizationController>(c => c.Index()), currentFirmaSession, $"{FieldDefinitionEnum.ProjectStewardOrganizationDisplayName.ToType().GetFieldDefinitionLabelPluralized()}", "Group3"));
            }
            programInfoMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <OrganizationController>(c => c.Index()), currentFirmaSession, $"{FieldDefinitionEnum.Organization.ToType().GetFieldDefinitionLabelPluralized()}", "Group3"));
            programInfoMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <FundingSourceController>(c => c.Index()), currentFirmaSession, $"{FieldDefinitionEnum.FundingSource.ToType().GetFieldDefinitionLabelPluralized()}", "Group3"));

            programInfoMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <WebServicesController>(c => c.Index()), currentFirmaSession, $"Web Services", "Group4"));

            AddCustomPagesToMenu(currentFirmaSession, FirmaMenuItem.ProgramInfo, programInfoMenu, "Group5");

            return(programInfoMenu);
        }
Beispiel #5
0
 public string GetCalendarYear()
 {
     return(MultiTenantHelpers.FormatReportingYear(CalendarYear));
 }
        public IEnumerable <ValidationResult> Validate(ValidationContext validationContext)
        {
            var errors = new List <ValidationResult>();

            if (ProjectExemptReportingYears != null && ProjectExemptReportingYears.Any(x => x.IsExempt) && string.IsNullOrWhiteSpace(Explanation))
            {
                errors.Add(new ValidationResult(FirmaValidationMessages.ExplanationNecessaryForProjectExemptYears));
            }

            var exemptYears = ProjectExemptReportingYears?.Where(x => x.IsExempt).Select(x => x.CalendarYear).ToList();

            var performanceMeasureActualsWithDuplicatesDisplayNames = PerformanceMeasureActuals
                                                                      ?.GroupBy(x => new { x.PerformanceMeasureID, x.CalendarYear })
                                                                      .Select(x => x.ToList())
                                                                      .ToList()
                                                                      .Select(x => x)
                                                                      .Where(x => x.Select(m => m.PerformanceMeasureActualSubcategoryOptions).ToList()
                                                                             .Select(z => String.Join("_", z.Select(s => s.PerformanceMeasureSubcategoryOptionID).ToList()))
                                                                             .ToList().HasDuplicates()).SelectMany(x => x.Select(y => y.PerformanceMeasureActualName).Distinct())
                                                                      .ToList();

            var performanceMeasureActualsWithMissingDataDisplayNames = PerformanceMeasureActuals?.Where(x =>
                                                                                                        x.ActualValue == null ||
                                                                                                        x.PerformanceMeasureActualSubcategoryOptions.Any(y =>
                                                                                                                                                         y.PerformanceMeasureSubcategoryOptionID == null))
                                                                       .Select(x => x.PerformanceMeasureActualName).Distinct().ToList();

            var performanceMeasureActualsWithValuesInExemptYearsDisplayNames = PerformanceMeasureActuals
                                                                               ?.Where(x => exemptYears.Contains(x.CalendarYear))
                                                                               .Select(x => x.PerformanceMeasureActualName).Distinct().ToList();

            performanceMeasureActualsWithMissingDataDisplayNames?.ForEach(x => errors.Add(new ValidationResult($"{x} has rows with missing data. All values are required.")));

            performanceMeasureActualsWithDuplicatesDisplayNames?.ForEach(x => errors.Add(new ValidationResult($"{x} has duplicate rows. The {FieldDefinitionEnum.PerformanceMeasureSubcategory.ToType().GetFieldDefinitionLabelPluralized()} must be unique for each {MultiTenantHelpers.GetPerformanceMeasureName()}. Collapse the duplicate rows into one entry row then save the page.")));

            performanceMeasureActualsWithValuesInExemptYearsDisplayNames?.ForEach(x =>
                                                                                  errors.Add(new ValidationResult(
                                                                                                 $"{x} has reported values for exempt years. For years which it is indicated that there are no accomplishments to report, you cannot enter {MultiTenantHelpers.GetPerformanceMeasureNamePluralized()}. You must either correct the years for which you have no accomplishments to report, or the reported {MultiTenantHelpers.GetPerformanceMeasureNamePluralized()}.")));


            return(errors);
        }
 public static MailAddress DoNotReplyMailAddress()
 {
     return(new MailAddress(FirmaWebConfiguration.DoNotReplyEmail, MultiTenantHelpers.GetToolDisplayName()));
 }
Beispiel #8
0
        public IEnumerable <ValidationResult> GetValidationResults()
        {
            var projects = HttpRequestStorage.DatabaseEntities.Projects.ToList();

            if (ProjectTypeID == -1)
            {
                yield return(new SitkaValidationResult <BasicsViewModel, int?>($"{MultiTenantHelpers.GetProjectTypeDisplayNameForProject()} is required.", m => m.ProjectTypeID));
            }

            if (!Models.Project.IsProjectNameUnique(projects, ProjectName, ProjectID))
            {
                yield return(new SitkaValidationResult <BasicsViewModel, string>(FirmaValidationMessages.ProjectNameUnique, m => m.ProjectName));
            }

            if (CompletionDate < PlannedDate)
            {
                yield return(new SitkaValidationResult <BasicsViewModel, DateTime?>(FirmaValidationMessages.CompletionDateGreaterThanEqualToImplementationStartYear, m => m.CompletionDate));
            }

            if (CompletionDate < PlannedDate)
            {
                yield return(new SitkaValidationResult <BasicsViewModel, DateTime?>(FirmaValidationMessages.CompletionDateGreaterThanEqualToPlannedDate, m => m.CompletionDate));
            }

            var currentYear = FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting();

            if (ProjectStageID == ProjectStage.Implementation.ProjectStageID)
            {
                if (PlannedDate?.Year > currentYear)
                {
                    yield return(new SitkaValidationResult <BasicsViewModel, DateTime?>(
                                     FirmaValidationMessages.ImplementationYearMustBePastOrPresentForImplementationProjects,
                                     m => m.PlannedDate));
                }
            }

            if (PlannedDate == null && ProjectStageID != ProjectStage.Cancelled.ProjectStageID)
            {
                yield return(new SitkaValidationResult <BasicsViewModel, DateTime?>(
                                 $"Implementation year is required when the {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} stage is not Deferred or Terminated",
                                 m => m.PlannedDate));
            }

            if (ProjectStageID == ProjectStage.Completed.ProjectStageID && !CompletionDate.HasValue)
            {
                yield return(new SitkaValidationResult <BasicsViewModel, DateTime?>($"Since the {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} is in the Completed stage, the Completion year is required", m => m.CompletionDate));
            }
            if (ProjectStageID == ProjectStage.Completed.ProjectStageID)
            {
                var landownerCostShareLineItemsOnProject = HttpRequestStorage.DatabaseEntities.GrantAllocationAwardLandownerCostShareLineItems.Where(x => x.ProjectID == ProjectID).ToList();
                if (landownerCostShareLineItemsOnProject.Any(x => x.LandownerCostShareLineItemStatus == LandownerCostShareLineItemStatus.Planned))
                {
                    yield return(new SitkaValidationResult <BasicsViewModel, int?>($"Before marking the {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} completed, all {Models.FieldDefinition.GrantAllocationAwardLandownerCostShareLineItem} Treatments must be Completed or Cancelled.", m => m.ProjectStageID));
                }
            }


            if ((ProjectStageID == ProjectStage.Completed.ProjectStageID) && CompletionDate?.Year > currentYear)
            {
                yield return(new SitkaValidationResult <BasicsViewModel, DateTime?>(FirmaValidationMessages.CompletionDateMustBePastOrPresentForCompletedProjects, m => m.CompletionDate));
            }

            if (ProjectStageID == ProjectStage.Planned.ProjectStageID && PlannedDate?.Year > currentYear)
            {
                yield return(new SitkaValidationResult <BasicsViewModel, DateTime?>(
                                 $"Since the {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} is in the Planning / Design stage, the Planning / Design start year must be less than or equal to the current year",
                                 m => m.PlannedDate));
            }
        }
Beispiel #9
0
        public static string MapServiceUrl(this GeospatialAreaType geospatialAreaType)
        {
            var geoServerNamespace = MultiTenantHelpers.GetTenantAttributeFromCache().GeoServerNamespace;

            return($"{FirmaWebConfiguration.GeoServerUrl}{geoServerNamespace}/wms");
        }
        public static void SendApprovalMessage(Project project)
        {
            Check.Require(project.ProjectApprovalStatus == ProjectApprovalStatus.Approved, "Need to be in Approved state to send the Approved email!");
            var submitterPerson             = project.ProposingPerson;
            var fieldDefinitionLabelProject = FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel();
            var subject   = $"Your {fieldDefinitionLabelProject} \"{project.GetDisplayName().ToEllipsifiedString(80)}\" was approved!";
            var detailUrl = SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Detail(project.ProjectID));

            var projectListUrl = SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Index());

            var message     = $@"
<p>Dear {submitterPerson.GetFullNameFirstLast()},</p>
<p>The {MultiTenantHelpers.GetToolDisplayName()} {fieldDefinitionLabelProject} submitted on {project.SubmissionDate.ToStringDate()} was approved by {project.ReviewedByPerson.GetFullNameFirstLastAndOrg()}.</p>
<p>This {fieldDefinitionLabelProject} is now on the <a href=""{projectListUrl}"">{MultiTenantHelpers.GetToolDisplayName()} {fieldDefinitionLabelProject} List</a> and is visible to the public via the {fieldDefinitionLabelProject} detail page.</p>
<p><a href=""{detailUrl}"">View this {fieldDefinitionLabelProject}</a></p>
<p>Thank you for using the {MultiTenantHelpers.GetToolDisplayName()}!</p>
<p>{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}<br/><br/><img src=""cid:tool-logo"" width=""160"" /></p>
";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            var emailsToSendTo = new List <string> {
                submitterPerson.Email
            };
            var emailsToReplyTo = new List <string> {
                project.ReviewedByPerson.Email
            };
            var primaryContactPerson = project.GetPrimaryContact();

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                emailsToSendTo.Add(primaryContactPerson.Email);
            }
            var contactsWhoCanManageProject = project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    emailsToSendTo.Add(contact.Email);
                }
            }

            SendMessageAndLogNotification(project,
                                          mailMessage,
                                          emailsToSendTo,
                                          emailsToReplyTo, project.GetProjectStewardPeople().Select(x => x.Email).ToList(),
                                          NotificationType.ProjectUpdateApproved);
        }
        private static List <Notification> SendMessageAndLogNotification(Project project,
                                                                         MailMessage mailMessage,
                                                                         List <string> emailsToSendTo,
                                                                         List <string> emailsToReplyTo,
                                                                         List <string> emailsToCc,
                                                                         NotificationType notificationType)
        {
            var submitterPerson      = project.ProposingPerson;
            var primaryContactPerson = project.PrimaryContactPerson;

            var notificationPeople = new List <Person> {
                submitterPerson
            };

            if (primaryContactPerson != null && submitterPerson.PersonID != primaryContactPerson.PersonID)
            {
                notificationPeople.Add(primaryContactPerson);
            }

            var contactsWhoCanManageProject = project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (contact.PersonID != submitterPerson.PersonID && (primaryContactPerson == null || primaryContactPerson.PersonID != contact.PersonID))
                {
                    notificationPeople.Add(contact);
                }
            }

            NotificationModelExtensions.SendMessage(mailMessage, emailsToSendTo, emailsToReplyTo, emailsToCc, MultiTenantHelpers.GetToolDisplayName());
            var notifications = new List <Notification>();

            foreach (var notificationPerson in notificationPeople)
            {
                var notification = new Notification(notificationType, notificationPerson, DateTime.Now);
                notification.NotificationProjects = new List <Project> {
                    project
                }.Select(p => new NotificationProject(notification, p)).ToList();
                notifications.Add(notification);
            }
            return(notifications);
        }
        public static void SendReturnedMessage(List <Person> peopleToCc, ProjectUpdateBatch projectUpdateBatch)
        {
            Check.Require(projectUpdateBatch.ProjectUpdateState == ProjectUpdateState.Returned, "Need to be in Returned state to send the Returned email!");
            var latestProjectUpdateHistorySubmitted = projectUpdateBatch.GetLatestProjectUpdateHistorySubmitted();
            var submitterPerson = latestProjectUpdateHistorySubmitted.UpdatePerson;
            var emailsToSendTo  = new List <string> {
                submitterPerson.Email
            };

            var personNames          = submitterPerson.GetFullNameFirstLast();
            var primaryContactPerson = projectUpdateBatch.Project.GetPrimaryContact();

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                emailsToSendTo.Add(primaryContactPerson.Email);
                personNames += $" and {primaryContactPerson.GetFullNameFirstLast()}";
            }
            var contactsWhoCanManageProject = projectUpdateBatch.Project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    emailsToSendTo.Add(contact.Email);
                    personNames += $" and {contact.GetFullNameFirstLast()}";
                }
            }

            var returnerPerson  = projectUpdateBatch.GetLatestProjectUpdateHistoryReturned().UpdatePerson;
            var instructionsUrl = SitkaRoute <ProjectUpdateController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Instructions(projectUpdateBatch.Project));

            var message = $@"
Dear {personNames},
<p>
    The update submitted for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {
                    projectUpdateBatch.Project.GetDisplayName()
                } on {latestProjectUpdateHistorySubmitted.TransitionDate.ToStringDate()} has been returned by {
                    returnerPerson.GetFullNameFirstLastAndOrg()
                }.
</p>
<p>
    <a href=""{instructionsUrl}"">View this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} update</a>
</p>
<p>
    Please review this update and address the comments that {
                    returnerPerson.FirstName
                } left for you. If you have questions, please email: {returnerPerson.Email}
</p>
Thank you,<br />
{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}<br/><br/><img src=""cid:tool-logo"" width=""160"" />
";

            var subject =
                $"The update for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {projectUpdateBatch.Project.GetDisplayName()} has been returned - please review and re-submit";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            SendMessageAndLogNotificationForProjectUpdateTransition(projectUpdateBatch,
                                                                    mailMessage,
                                                                    emailsToSendTo,
                                                                    new List <string> {
                returnerPerson.Email
            },
                                                                    peopleToCc.Select(x => x.Email).ToList(),
                                                                    NotificationType.ProjectUpdateReturned);
        }
        public static void SendApprovalMessage(List <Person> peopleToCc, ProjectUpdateBatch projectUpdateBatch)
        {
            Check.Require(projectUpdateBatch.ProjectUpdateState == ProjectUpdateState.Approved, "Need to be in Approved state to send the Approved email!");
            var latestProjectUpdateHistorySubmitted = projectUpdateBatch.GetLatestProjectUpdateHistorySubmitted();
            var submitterPerson = latestProjectUpdateHistorySubmitted.UpdatePerson;
            var emailsToSendTo  = new List <string> {
                submitterPerson.Email
            };

            var personNames          = submitterPerson.GetFullNameFirstLast();
            var primaryContactPerson = projectUpdateBatch.Project.GetPrimaryContact();

            if (primaryContactPerson != null && !String.Equals(primaryContactPerson.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase))
            {
                emailsToSendTo.Add(primaryContactPerson.Email);
                personNames += $" and {primaryContactPerson.GetFullNameFirstLast()}";
            }
            var contactsWhoCanManageProject = projectUpdateBatch.Project.GetContactsWhoCanManageProject();

            foreach (var contact in contactsWhoCanManageProject)
            {
                if (!string.Equals(contact.Email, submitterPerson.Email, StringComparison.InvariantCultureIgnoreCase) && (primaryContactPerson == null || !string.Equals(contact.Email, primaryContactPerson.Email, StringComparison.InvariantCultureIgnoreCase)))
                {
                    emailsToSendTo.Add(contact.Email);
                    personNames += $" and {contact.GetFullNameFirstLast()}";
                }
            }

            var approverPerson = projectUpdateBatch.LastUpdatePerson;
            var detailUrl      = SitkaRoute <ProjectController> .BuildAbsoluteUrlHttpsFromExpression(x => x.Detail(projectUpdateBatch.Project));

            var message = $@"
Dear {personNames},
<p>
    The update submitted for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {projectUpdateBatch.Project.GetDisplayName()} on {
                    latestProjectUpdateHistorySubmitted.TransitionDate.ToStringDate()
                } was approved by {approverPerson.GetFullNameFirstLastAndOrg()}.
</p>
<p>
    There is no action for you to take - this is simply a notification email. The updates for this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} are now visible to the general public on this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}'s detail page:
</p>
<p>
    <a href=""{detailUrl}"">View this {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}</a>
</p>
Thank you for keeping your {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} information and accomplishments up to date!<br />
{$"- {MultiTenantHelpers.GetToolDisplayName()} team"}<br/><br/><img src=""cid:tool-logo"" width=""160"" />
";

            var subject     = $"The update for {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} {projectUpdateBatch.Project.GetDisplayName()} was approved";
            var mailMessage = new MailMessage {
                Subject = subject, Body = message, IsBodyHtml = true
            };

            var tenantAttribute = MultiTenantHelpers.GetTenantAttributeFromCache();
            var toolLogo        = tenantAttribute.TenantSquareLogoFileResourceInfo ??
                                  tenantAttribute.TenantBannerLogoFileResourceInfo;
            var htmlView = AlternateView.CreateAlternateViewFromString(message, null, "text/html");

            htmlView.LinkedResources.Add(
                new LinkedResource(new MemoryStream(toolLogo.FileResourceData.Data), "img/jpeg")
            {
                ContentId = "tool-logo"
            });
            mailMessage.AlternateViews.Add(htmlView);

            SendMessageAndLogNotificationForProjectUpdateTransition(projectUpdateBatch,
                                                                    mailMessage,
                                                                    emailsToSendTo,
                                                                    new List <string> {
                approverPerson.Email
            },
                                                                    peopleToCc.Select(x => x.Email).ToList(),
                                                                    NotificationType.ProjectUpdateApproved);
        }
        public ViewResult Index()
        {
            var firmaPageTypeHomePage       = FirmaPageType.ToType(FirmaPageTypeEnum.HomePage);
            var firmaPageByPageTypeHomePage = FirmaPage.GetFirmaPageByPageType(firmaPageTypeHomePage);

            var firmaPageTypeHomePageAdditionalInfo       = FirmaPageType.ToType(FirmaPageTypeEnum.HomeAdditionalInfo);
            var firmaPageByPageTypeHomePageAdditionalInfo = FirmaPage.GetFirmaPageByPageType(firmaPageTypeHomePageAdditionalInfo);

            var firmaPageTypeHomePageMapInfo       = FirmaPageType.ToType(FirmaPageTypeEnum.HomeMapInfo);
            var firmaPageByPageTypeHomePageMapInfo = FirmaPage.GetFirmaPageByPageType(firmaPageTypeHomePageMapInfo);

            var firmaHomePageImages = HttpRequestStorage.DatabaseEntities.FirmaHomePageImages.ToList().OrderBy(x => x.SortOrder).ToList();

            var currentPersonCanViewProposals = CurrentPerson.CanViewProposals;
            var projectsToShow = ProjectMapCustomization.ProjectsForMap(CurrentPerson);

            var projectMapCustomization      = ProjectMapCustomization.CreateDefaultCustomization(projectsToShow, currentPersonCanViewProposals);
            var projectLocationsLayerGeoJson = new LayerGeoJson($"{FieldDefinition.ProjectLocation.GetFieldDefinitionLabelPluralized()}", Project.MappedPointsToGeoJsonFeatureCollection(projectsToShow, false, true), "red", 1, LayerInitialVisibility.Show);
            var projectLocationsMapInitJson  = new ProjectLocationsMapInitJson(projectLocationsLayerGeoJson,
                                                                               projectMapCustomization, "ProjectLocationsMap")
            {
                AllowFullScreen = false,
                Layers          = HttpRequestStorage.DatabaseEntities.Organizations.GetBoundaryLayerGeoJson().Where(x => x.LayerInitialVisibility == LayerInitialVisibility.Show).ToList()
            };
            var projectLocationsMapViewData = new ProjectLocationsMapViewData(projectLocationsMapInitJson.MapDivID, ProjectColorByType.ProjectStage.DisplayName, MultiTenantHelpers.GetTopLevelTaxonomyTiers(), currentPersonCanViewProposals);

            var featuredProjectsViewData = new FeaturedProjectsViewData(HttpRequestStorage.DatabaseEntities.Projects.Where(x => x.IsFeatured).ToList().GetActiveProjectsVisibleToUser(CurrentPerson));

            var viewData = new IndexViewData(CurrentPerson, firmaPageByPageTypeHomePage, firmaPageByPageTypeHomePageAdditionalInfo, firmaPageByPageTypeHomePageMapInfo, featuredProjectsViewData, projectLocationsMapViewData, projectLocationsMapInitJson, firmaHomePageImages);

            return(RazorView <Index, IndexViewData>(viewData));
        }
        private static LtInfoMenuItem BuildManageMenu(Person currentPerson)
        {
            var manageMenu = new LtInfoMenuItem("Manage");

            // Group 1 - Project Classifications Stuff (taxonomies, classification systems, PMs)
            if (MultiTenantHelpers.IsTaxonomyLevelTrunk())
            {
                manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <TaxonomyTrunkController>(c => c.Manage()), currentPerson, Models.FieldDefinition.TaxonomyTrunk.GetFieldDefinitionLabelPluralized(), "Group1"));
            }

            if (!MultiTenantHelpers.IsTaxonomyLevelLeaf())
            {
                manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <TaxonomyBranchController>(c => c.Manage()), currentPerson, Models.FieldDefinition.TaxonomyBranch.GetFieldDefinitionLabelPluralized(), "Group1"));
            }
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectTypeController>(c => c.Manage()), currentPerson, Models.FieldDefinition.ProjectType.GetFieldDefinitionLabelPluralized(), "Group1"));
            MultiTenantHelpers.GetClassificationSystems().ForEach(x =>
            {
                manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ClassificationController>(c => c.Index(x.ClassificationSystemID)), currentPerson, x.ClassificationSystemNamePluralized, "Group1"));
            });


            // Group 2 - System Config stuff
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <UserController>(c => c.Index()), currentPerson, "Users and Contacts", "Group2"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectController>(c => c.FeaturedList()), currentPerson, $"Featured {Models.FieldDefinition.Project.GetFieldDefinitionLabelPluralized()}", "Group2"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <TagController>(c => c.Index()), currentPerson, $"{Models.FieldDefinition.Project.GetFieldDefinitionLabel()} Tags", "Group2"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectUpdateController>(c => c.Manage()), currentPerson, $"{Models.FieldDefinition.Project.GetFieldDefinitionLabel()} Updates", "Group2"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <HomeController>(c => c.ManageHomePageImages()), currentPerson, "Homepage Configuration", "Group2"));

            // Group 3 - Content Editing stuff
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <FirmaPageController>(c => c.Index()), currentPerson, "Custom Page Content", "Group3"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <FieldDefinitionController>(c => c.Index()), currentPerson, "Custom Labels & Definitions", "Group3"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <CustomPageController>(c => c.Index()), currentPerson, "Custom Pages", "Group3"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectCustomAttributeTypeController>(c => c.Manage()), currentPerson, "Custom Attributes", "Group3"));

            // Group 4 - Other
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <HomeController>(c => c.InternalSetupNotes()), currentPerson, "Internal Setup Notes", "Group4"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <HomeController>(c => c.StyleGuide()), currentPerson, "Style Guide", "Group4"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ExcelUploadController>(c => c.ManageExcelUploadsAndEtl()), currentPerson, $"Upload Excel Files / ETL", "Group4"));

            // Group 5 - Organizations
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <OrganizationAndRelationshipTypeController>(c => c.Index()), currentPerson, Models.FieldDefinition.OrganizationType.GetFieldDefinitionLabelPluralized(), "Group5"));

            if (new ProgramViewFeature().HasPermissionByPerson(currentPerson))
            {
                manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProgramController>(c => c.Index()), currentPerson, $"{Models.FieldDefinition.Program.GetFieldDefinitionLabelPluralized()}", "Group5"));
            }

            // Group 6 - Jobs
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <JobController>(c => c.JobIndex()), currentPerson, Models.FieldDefinition.Job.GetFieldDefinitionLabelPluralized(), "Group6"));

            // Group 7 - JSON APIs
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <JsonApiManagementController>(c => c.JsonApiLandingPage()), currentPerson, "JSON APIs", "Group7"));

            // Group 8 - Hangfire menu
            if (currentPerson.IsAdministrator())
            {
                LtInfoMenuItem hangfireMenuItem = new LtInfoMenuItem("/hangfire", "Hangfire", true, false, "Group8");
                manageMenu.AddMenuItem(hangfireMenuItem);
            }

            return(manageMenu);
        }
Beispiel #16
0
        private void AddProjectCustomGridField(FirmaSession currentFirmaSession
                                               , ProjectCustomGridConfiguration projectCustomGridConfiguration
                                               , bool userHasEditProjectAsAdminPermissions
                                               , Dictionary <int, vProjectDetail> projectDetailsDictionary
                                               , Dictionary <int, ProjectFirmaModels.Models.TaxonomyLeaf> taxonomyLeafDictionary
                                               , string projectLabel
                                               , bool hasProjectApprovalPermissionBySession
                                               , string statusUpdateLabel
                                               , List <int> sitkaAdminPersonIDs)
        {
            switch (projectCustomGridConfiguration.ProjectCustomGridColumn.ToEnum)
            {
            // Non-optional fields
            // Project Name
            case ProjectCustomGridColumnEnum.ProjectName:
                Add(FieldDefinitionEnum.ProjectName.ToType().ToGridHeaderString(), x => UrlTemplate.MakeHrefString(x.GetDetailUrl(), x.ProjectName), 300, DhtmlxGridColumnFilterType.Html);
                break;

            case ProjectCustomGridColumnEnum.PrimaryContactOrganization:
                Add(FieldDefinitionEnum.IsPrimaryContactOrganization.ToType().ToGridHeaderString(),
                    x => OrganizationModelExtensions.GetShortNameAsUrl(projectDetailsDictionary[x.ProjectID].PrimaryContactOrganizationID, projectDetailsDictionary[x.ProjectID].PrimaryContactOrganizationDisplayName), 150, DhtmlxGridColumnFilterType.Html);
                break;

            case ProjectCustomGridColumnEnum.ProjectStage:
                Add(FieldDefinitionEnum.ProjectStage.ToType().ToGridHeaderString(), x => x.ProjectStage.ProjectStageDisplayName, 90, DhtmlxGridColumnFilterType.SelectFilterStrict);
                break;

            case ProjectCustomGridColumnEnum.NumberOfExpectedPerformanceMeasureRecords:
                Add($"# Of Expected {MultiTenantHelpers.GetPerformanceMeasureName()} Records", x => projectDetailsDictionary[x.ProjectID].PerformanceMeasureExpectedCount, 100);
                break;

            case ProjectCustomGridColumnEnum.NumberOfReportedPerformanceMeasures:
                Add($"# Of Reported {MultiTenantHelpers.GetPerformanceMeasureName()} Records", x => projectDetailsDictionary[x.ProjectID].PerformanceMeasureActualCount, 100);
                break;

            case ProjectCustomGridColumnEnum.ProjectsStewardOrganizationRelationshipToProject:
                if (MultiTenantHelpers.HasCanStewardProjectsOrganizationRelationship())
                {
                    Add(FieldDefinitionEnum.ProjectsStewardOrganizationRelationshipToProject.ToType().ToGridHeaderString(), x => OrganizationModelExtensions.GetShortNameAsUrl(projectDetailsDictionary[x.ProjectID].CanStewardProjectsOrganizationID, projectDetailsDictionary[x.ProjectID].CanStewardProjectsOrganizationDisplayName), 150, DhtmlxGridColumnFilterType.Html);
                }
                break;

            case ProjectCustomGridColumnEnum.ProjectPrimaryContact:
                Add(FieldDefinitionEnum.ProjectPrimaryContact.ToType().ToGridHeaderString(),
                    x => projectDetailsDictionary[x.ProjectID].PrimaryContactPersonID.HasValue ?
                    new UserViewFeature().HasPermissionForPersonID(currentFirmaSession, projectDetailsDictionary[x.ProjectID].PrimaryContactPersonID.Value, sitkaAdminPersonIDs).HasPermission ? UrlTemplate.MakeHrefString(PersonModelExtensions.DetailUrlTemplate.ParameterReplace(projectDetailsDictionary[x.ProjectID].PrimaryContactPersonID.Value), projectDetailsDictionary[x.ProjectID].PrimaryContactPersonFullNameFirstLast) : new HtmlString(projectDetailsDictionary[x.ProjectID].PrimaryContactPersonFullNameFirstLast) : new HtmlString(""),
                    150, DhtmlxGridColumnFilterType.Html);
                break;

            case ProjectCustomGridColumnEnum.ProjectPrimaryContactEmail:
                var userHasEmailViewingPermissions = new LoggedInAndNotUnassignedRoleUnclassifiedFeature().HasPermissionByFirmaSession(currentFirmaSession);
                if (userHasEmailViewingPermissions)
                {
                    Add(FieldDefinitionEnum.ProjectPrimaryContactEmail.ToType().ToGridHeaderString(),
                        x => projectDetailsDictionary[x.ProjectID].PrimaryContactPersonID.HasValue ? new HtmlString($"<a href='mailto:{projectDetailsDictionary[x.ProjectID].PrimaryContactPersonEmail}'> {projectDetailsDictionary[x.ProjectID].PrimaryContactPersonEmail}</a>") : new HtmlString(""),
                        200, DhtmlxGridColumnFilterType.SelectFilterHtmlStrict);
                }
                break;

            case ProjectCustomGridColumnEnum.PlanningDesignStartYear:
                Add(FieldDefinitionEnum.PlanningDesignStartYear.ToType().ToGridHeaderString(), x => ProjectModelExtensions.GetPlanningDesignStartYear(x), 90, DhtmlxGridColumnFilterType.SelectFilterStrict);
                break;

            case ProjectCustomGridColumnEnum.ImplementationStartYear:
                Add(FieldDefinitionEnum.ImplementationStartYear.ToType().ToGridHeaderString(), x => ProjectModelExtensions.GetImplementationStartYear(x), 115, DhtmlxGridColumnFilterType.SelectFilterStrict);
                break;

            case ProjectCustomGridColumnEnum.CompletionYear:
                Add(FieldDefinitionEnum.CompletionYear.ToType().ToGridHeaderString(), x => ProjectModelExtensions.GetCompletionYear(x), 90, DhtmlxGridColumnFilterType.SelectFilterStrict);
                break;

            case ProjectCustomGridColumnEnum.PrimaryTaxonomyLeaf:
                var gridHeaderString = MultiTenantHelpers.GetTenantAttributeFromCache().EnableSecondaryProjectTaxonomyLeaf
                        ? FieldDefinitionEnum.TaxonomyLeafDisplayNameForProject.ToType().ToGridHeaderString()
                        : FieldDefinitionEnum.TaxonomyLeaf.ToType().ToGridHeaderString();
                Add(gridHeaderString, x => UrlTemplate.MakeHrefString(TaxonomyLeafModelExtensions.DetailUrlTemplate.ParameterReplace(projectDetailsDictionary[x.ProjectID].TaxonomyLeafID), projectDetailsDictionary[x.ProjectID].TaxonomyLeafDisplayName), 240, DhtmlxGridColumnFilterType.Html);
                break;

            case ProjectCustomGridColumnEnum.SecondaryTaxonomyLeaf:
                if (MultiTenantHelpers.GetTenantAttributeFromCache().EnableSecondaryProjectTaxonomyLeaf)
                {
                    Add(FieldDefinitionEnum.SecondaryProjectTaxonomyLeaf.ToType().ToGridHeaderStringPlural()
                        , x => new HtmlString(string.Join(", ", x.SecondaryProjectTaxonomyLeafs.Select(y => taxonomyLeafDictionary[y.TaxonomyLeafID].GetDisplayNameAsUrl().ToString()))), 300, DhtmlxGridColumnFilterType.Html);
                }
                break;

            case ProjectCustomGridColumnEnum.NumberOfReportedExpenditures:
                Add($"# Of {FieldDefinitionEnum.ReportedExpenditure.ToType().GetFieldDefinitionLabel()} Records", x => projectDetailsDictionary[x.ProjectID].ProjectFundingSourceExpenditureCount, 100);
                break;

            case ProjectCustomGridColumnEnum.FundingType:
                Add(FieldDefinitionEnum.FundingType.ToType().ToGridHeaderString(), x => x.FundingType != null ? x.FundingType.FundingTypeDisplayName : "", 300, DhtmlxGridColumnFilterType.SelectFilterStrict);
                break;

            case ProjectCustomGridColumnEnum.EstimatedTotalCost:
                Add(FieldDefinitionEnum.EstimatedTotalCost.ToType().ToGridHeaderString(), x => x.GetEstimatedTotalRegardlessOfFundingType(), 110, DhtmlxGridColumnFormatType.Currency, DhtmlxGridColumnAggregationType.Total);
                break;

            case ProjectCustomGridColumnEnum.SecuredFunding:
                Add(FieldDefinitionEnum.SecuredFunding.ToType().ToGridHeaderString(), x => x.GetSecuredFunding(), 110, DhtmlxGridColumnFormatType.Currency, DhtmlxGridColumnAggregationType.Total);
                break;

            case ProjectCustomGridColumnEnum.TargetedFunding:
                Add(FieldDefinitionEnum.TargetedFunding.ToType().ToGridHeaderString(), x => x.GetTargetedFunding(), 100, DhtmlxGridColumnFormatType.Currency, DhtmlxGridColumnAggregationType.Total);
                break;

            case ProjectCustomGridColumnEnum.NoFundingSourceIdentified:
                Add(FieldDefinitionEnum.NoFundingSourceIdentified.ToType().ToGridHeaderString(), x => x.GetNoFundingSourceIdentifiedAmount(), 110, DhtmlxGridColumnFormatType.Currency, DhtmlxGridColumnAggregationType.Total);
                break;

            case ProjectCustomGridColumnEnum.ProjectDescription:
                Add(FieldDefinitionEnum.ProjectDescription.ToType().ToGridHeaderString(), x => x.ProjectDescription, 200);
                break;

            case ProjectCustomGridColumnEnum.NumberOfPhotos:
                Add("# of Photos", x => projectDetailsDictionary[x.ProjectID].ProjectImageCount, 60);
                break;

            case ProjectCustomGridColumnEnum.ProjectID:
                Add(FieldDefinitionEnum.ProjectID.ToType().ToGridHeaderString(), x => x.ProjectID.ToString(), 140);
                break;

            case ProjectCustomGridColumnEnum.ProjectLastUpdated:
                Add(FieldDefinitionEnum.ProjectLastUpdated.ToType().ToGridHeaderString(), x => x.LastUpdatedDate, 140);
                break;

            case ProjectCustomGridColumnEnum.ProjectStatus:
                if (MultiTenantHelpers.GetTenantAttributeFromCache().UseProjectTimeline&& userHasEditProjectAsAdminPermissions)
                {
                    Add(FieldDefinitionEnum.Status.ToType().ToGridHeaderString()
                        , x => MakeProjectStatusAddLinkAndText(x, currentFirmaSession, projectDetailsDictionary[x.ProjectID], projectLabel, hasProjectApprovalPermissionBySession, statusUpdateLabel)
                        , 100
                        , DhtmlxGridColumnFilterType.SelectFilterHtmlStrict
                        );
                }
                break;

            case ProjectCustomGridColumnEnum.FinalStatusUpdateStatus:
                if (MultiTenantHelpers.GetTenantAttributeFromCache().UseProjectTimeline&& userHasEditProjectAsAdminPermissions)
                {
                    Add(FieldDefinitionEnum.FinalStatusUpdateStatus.ToType().ToGridHeaderString()
                        , x => projectDetailsDictionary[x.ProjectID].FinalStatusReportStatusDescription
                        , 100
                        , DhtmlxGridColumnFilterType.SelectFilterStrict
                        );
                }
                break;

            case ProjectCustomGridColumnEnum.GeospatialAreaName:
                break;

            case ProjectCustomGridColumnEnum.CustomAttribute:
                break;

            case ProjectCustomGridColumnEnum.ProjectCategory:
                if (MultiTenantHelpers.GetTenantAttributeFromCache().EnableProjectCategories)
                {
                    Add(FieldDefinitionEnum.ProjectCategory.ToType().ToGridHeaderString(), x => x.ProjectCategory.ProjectCategoryDisplayName, 140, DhtmlxGridColumnFilterType.SelectFilterStrict);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        private static LtInfoMenuItem BuildProjectsMenu(Person currentPerson)
        {
            var projectsMenu = new LtInfoMenuItem($"{Models.FieldDefinition.Project.GetFieldDefinitionLabelPluralized()}");

            projectsMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ResultsController>(c => c.ProjectMap()), currentPerson, $"{Models.FieldDefinition.Project.GetFieldDefinitionLabel()} Map", "Group1"));
            projectsMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectController>(c => c.Index()), currentPerson, $"Full {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} List", "Group2"));
            projectsMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProgramInfoController>(c => c.Taxonomy()), currentPerson, MultiTenantHelpers.GetTaxonomySystemName(), "Group2"));
            MultiTenantHelpers.GetClassificationSystems().ForEach(x =>
            {
                projectsMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProgramInfoController>(c => c.ClassificationSystem(x.ClassificationSystemID)), currentPerson, x.ClassificationSystemDefinition, "Group2"));
            });
            projectsMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectController>(c => c.Proposed()), currentPerson, $"{Models.FieldDefinition.Application.GetFieldDefinitionLabelPluralized()}", "Group3"));
            projectsMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectController>(c => c.Pending()), currentPerson, $"Pending {Models.FieldDefinition.Project.GetFieldDefinitionLabelPluralized()}", "Group3"));

            if (new GrantAllocationAwardLandownerCostShareLineItemViewFeature().HasPermissionByPerson(currentPerson))
            {
                projectsMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <GrantAllocationAwardLandownerCostShareLineItemController>(tac => tac.Index()), currentPerson, "DNR Cost Share Treatments", "Group4"));
            }

            projectsMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <InteractionEventController>(iec => iec.Index()), currentPerson, $"Full {Models.FieldDefinition.InteractionEvent.GetFieldDefinitionLabelPluralized()} List", "Group5"));

            MultiTenantHelpers.GetCustomPagesByNavigationSection(CustomPageNavigationSectionEnum.Projects).ForEach(x =>
            {
                var isVisible = x.CustomPageDisplayType == CustomPageDisplayType.Public ||
                                (!currentPerson.IsAnonymousUser &&
                                 x.CustomPageDisplayType == CustomPageDisplayType.Protected);
                if (isVisible)
                {
                    projectsMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <CustomPageController>(c => c.About(x.CustomPageVanityUrl)), currentPerson, x.CustomPageDisplayName, "Group6"));
                }
            });


            return(projectsMenu);
        }
Beispiel #18
0
        public static List <int> CalculateCalendarYearRangeForExpenditures(this IEnumerable <ProjectGrantAllocationExpenditure> projectGrantAllocationExpenditures, GrantAllocation grantAllocation)
        {
            var existingYears = projectGrantAllocationExpenditures.Select(x => x.CalendarYear).ToList();
            var grantAllocationProjectsWhereYouAreTheGrantAllocationMinCalendarYear = grantAllocation.ProjectsWhereYouAreTheGrantAllocationMinCalendarYear;

            return(FirmaDateUtilities.CalculateCalendarYearRangeAccountingForExistingYears(existingYears,
                                                                                           grantAllocationProjectsWhereYouAreTheGrantAllocationMinCalendarYear.HasValue ?
                                                                                           (DateTime?)new DateTime(grantAllocationProjectsWhereYouAreTheGrantAllocationMinCalendarYear.Value, 1, 1) : null,
                                                                                           grantAllocation.ProjectsWhereYouAreTheGrantAllocationMaxCalendarYear,
                                                                                           DateTime.Today.Year,
                                                                                           MultiTenantHelpers.GetMinimumYear(),
                                                                                           null));
        }
Beispiel #19
0
 public ProjectsInProposalStageViewListFeature()
     : base(MultiTenantHelpers.ShowProposalsToThePublic() ? Role.All : FirmaBaseFeatureHelpers.AllRolesExceptUnassigned)
 {
 }
Beispiel #20
0
        public IndexGridSpec(Person currentPerson, Dictionary <int, FundingType> fundingTypes, List <GeospatialAreaType> geospatialAreaTypes, List <ProjectFirmaModels.Models.ProjectCustomAttributeType> projectCustomAttributeTypes)
        {
            var userHasTagManagePermissions    = new FirmaAdminFeature().HasPermissionByPerson(currentPerson);
            var userHasDeletePermissions       = new ProjectDeleteFeature().HasPermissionByPerson(currentPerson);
            var userHasEmailViewingPermissions = new LoggedInAndNotUnassignedRoleUnclassifiedFeature().HasPermissionByPerson(currentPerson);

            if (userHasTagManagePermissions)
            {
                BulkTagModalDialogForm = new BulkTagModalDialogForm(SitkaRoute <TagController> .BuildUrlFromExpression(x => x.BulkTagProjects(null)), $"Tag Checked {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabelPluralized()}", $"Tag {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabelPluralized()}");
                AddCheckBoxColumn();
                Add("ProjectID", x => x.ProjectID, 0);
            }

            if (userHasDeletePermissions)
            {
                Add(string.Empty, x => DhtmlxGridHtmlHelpers.MakeDeleteIconAndLinkBootstrap(x.GetDeleteUrl(), true), 30, DhtmlxGridColumnFilterType.None);
            }

            Add(string.Empty, x => UrlTemplate.MakeHrefString(x.GetFactSheetUrl(), FirmaDhtmlxGridHtmlHelpers.FactSheetIcon.ToString()), 30, DhtmlxGridColumnFilterType.None);

            Add(FieldDefinitionEnum.ProjectName.ToType().ToGridHeaderString(), x => UrlTemplate.MakeHrefString(x.GetDetailUrl(), x.ProjectName), 300, DhtmlxGridColumnFilterType.Html);
            if (MultiTenantHelpers.HasCanStewardProjectsOrganizationRelationship())
            {
                Add(FieldDefinitionEnum.ProjectsStewardOrganizationRelationshipToProject.ToType().ToGridHeaderString(), x => x.GetCanStewardProjectsOrganization()?.GetShortNameAsUrl() ?? new HtmlString(""), 150, DhtmlxGridColumnFilterType.Html);
            }
            Add(FieldDefinitionEnum.IsPrimaryContactOrganization.ToType().ToGridHeaderString(), x => x.GetPrimaryContactOrganization().GetShortNameAsUrl(), 150, DhtmlxGridColumnFilterType.Html);
            Add(FieldDefinitionEnum.ProjectPrimaryContact.ToType().ToGridHeaderString(),
                x => x.GetPrimaryContact() != null ? UrlTemplate.MakeHrefString(x.GetPrimaryContact().GetDetailUrl(), x.GetPrimaryContact().GetFullNameLastFirst()) : new HtmlString(""),
                150, DhtmlxGridColumnFilterType.Html);
            if (userHasEmailViewingPermissions)
            {
                Add(FieldDefinitionEnum.ProjectPrimaryContactEmail.ToType().ToGridHeaderString(),
                    x => x.GetPrimaryContact() != null ? new HtmlString($"<a href='mailto:{x.GetPrimaryContact().Email}'> {x.GetPrimaryContact().Email}</a>") : new HtmlString(""),
                    200, DhtmlxGridColumnFilterType.SelectFilterHtmlStrict);
            }
            Add(FieldDefinitionEnum.ProjectStage.ToType().ToGridHeaderString(), x => x.ProjectStage.ProjectStageDisplayName, 90, DhtmlxGridColumnFilterType.SelectFilterStrict);
            Add(FieldDefinitionEnum.PlanningDesignStartYear.ToType().ToGridHeaderString(), x => ProjectModelExtensions.GetPlanningDesignStartYear(x), 90, DhtmlxGridColumnFilterType.SelectFilterStrict);
            Add(FieldDefinitionEnum.ImplementationStartYear.ToType().ToGridHeaderString(), x => ProjectModelExtensions.GetImplementationStartYear(x), 115, DhtmlxGridColumnFilterType.SelectFilterStrict);
            Add(FieldDefinitionEnum.CompletionYear.ToType().ToGridHeaderString(), x => ProjectModelExtensions.GetCompletionYear(x), 90, DhtmlxGridColumnFilterType.SelectFilterStrict);

            Add($"Primary {FieldDefinitionEnum.TaxonomyLeaf.ToType().ToGridHeaderString()}", x => x.TaxonomyLeaf.GetDisplayNameAsUrl(), 200, DhtmlxGridColumnFilterType.Html);
            var enableSecondaryProjectTaxonomyLeaf = MultiTenantHelpers.GetTenantAttribute().EnableSecondaryProjectTaxonomyLeaf;

            if (enableSecondaryProjectTaxonomyLeaf)
            {
                Add(FieldDefinitionEnum.SecondaryProjectTaxonomyLeaf.ToType().ToGridHeaderStringPlural(), x => new HtmlString(string.Join(", ", x.SecondaryProjectTaxonomyLeafs.Select(y => y.TaxonomyLeaf.GetDisplayNameAsUrl().ToString()))), 300, DhtmlxGridColumnFilterType.Html);
            }

            // Agreements for this project
            Add(FieldDefinitionEnum.Agreement.ToType().ToGridHeaderStringPlural(), x => GetAgreementHrefsString(x), 100, DhtmlxGridColumnFilterType.Text);

            // TODO: add links to Cost Authorities
            Add(FieldDefinitionEnum.CostAuthorityWorkBreakdownStructure.ToType().ToGridHeaderStringPlural(), x => GetCostAuthorityHrefsString(x), 100, DhtmlxGridColumnFilterType.Text);

            Add($"Number Of Reported {MultiTenantHelpers.GetPerformanceMeasureName()} Records", x => x.PerformanceMeasureActuals.Count, 100);
            Add($"Number Of {FieldDefinitionEnum.ReportedExpenditure.ToType().GetFieldDefinitionLabel()} Records", x => x.ProjectFundingSourceExpenditures.Count, 100);
            Add(FieldDefinitionEnum.FundingType.ToType().ToGridHeaderString(), x => x.FundingTypeID.HasValue ? fundingTypes[x.FundingTypeID.Value].FundingTypeDisplayName : "", 300, DhtmlxGridColumnFilterType.SelectFilterStrict);
            Add(FieldDefinitionEnum.EstimatedTotalCost.ToType().ToGridHeaderString(), x => x.GetEstimatedTotalRegardlessOfFundingType(), 110, DhtmlxGridColumnFormatType.Currency, DhtmlxGridColumnAggregationType.Total);
            Add(FieldDefinitionEnum.SecuredFunding.ToType().ToGridHeaderString(), x => x.GetSecuredFunding(), 110, DhtmlxGridColumnFormatType.Currency, DhtmlxGridColumnAggregationType.Total);
            Add(FieldDefinitionEnum.TargetedFunding.ToType().ToGridHeaderString(), x => x.GetTargetedFunding(), 100, DhtmlxGridColumnFormatType.Currency, DhtmlxGridColumnAggregationType.Total);
            Add(FieldDefinitionEnum.NoFundingSourceIdentified.ToType().ToGridHeaderString(), x => x.GetNoFundingSourceIdentifiedAmount(), 110, DhtmlxGridColumnFormatType.Currency, DhtmlxGridColumnAggregationType.Total);
            foreach (var projectCustomAttributeType in projectCustomAttributeTypes.OrderBy(x => x.ProjectCustomAttributeTypeName))
            {
                if (projectCustomAttributeType.IncludeInProjectGrid && projectCustomAttributeType.HasViewPermission(currentPerson))
                {
                    Add($"{projectCustomAttributeType.ProjectCustomAttributeTypeName}", a => a.GetProjectCustomAttributesValue(projectCustomAttributeType), 150, DhtmlxGridColumnFilterType.Text);
                }
            }
            foreach (var geospatialAreaType in geospatialAreaTypes.OrderBy(x => x.GeospatialAreaTypeName))
            {
                Add($"{geospatialAreaType.GeospatialAreaTypeNamePluralized}", a => a.GetProjectGeospatialAreaNamesAsHyperlinks(geospatialAreaType), 350, DhtmlxGridColumnFilterType.Html);
            }

            Add(FieldDefinitionEnum.ProjectDescription.ToType().ToGridHeaderString(), x => x.ProjectDescription, 200);
            if (userHasTagManagePermissions)
            {
                Add("Tags", x => new HtmlString(!x.ProjectTags.Any() ? string.Empty : string.Join(", ", x.ProjectTags.Select(pt => pt.Tag.GetDisplayNameAsUrl()))), 100, DhtmlxGridColumnFilterType.Html);
            }

            Add("# of Photos", x => x.ProjectImages.Count, 60);
        }
        public static IEnumerable <SelectListItem> ToGroupedSelectList(this List <TaxonomyLeaf> taxonomyLeafs)
        {
            var selectListItems = new List <SelectListItem>();
            var groups          = new Dictionary <string, SelectListGroup>();

            if (MultiTenantHelpers.IsTaxonomyLevelTrunk())
            {
                BuildThreeTierSelectList(taxonomyLeafs, groups, selectListItems);
            }
            else if (MultiTenantHelpers.IsTaxonomyLevelBranch())
            {
                foreach (var taxonomyBranchGrouping in taxonomyLeafs.GroupBy(x => x.TaxonomyBranch)
                         .OrderBy(x => x.Key.TaxonomyBranchSortOrder).ThenBy(x => x.Key.GetDisplayName()))
                {
                    var taxonomyBranch  = taxonomyBranchGrouping.Key;
                    var selectListGroup = new SelectListGroup {
                        Name = taxonomyBranch.GetDisplayName()
                    };
                    groups.Add(taxonomyBranch.GetDisplayName(), selectListGroup);

                    foreach (var taxonomyLeaf in taxonomyBranchGrouping.OrderBy(x => x.TaxonomyLeafSortOrder).ThenBy(x => x.GetDisplayName()))
                    {
                        selectListItems.Add(new SelectListItem
                        {
                            Value = taxonomyLeaf.TaxonomyLeafID.ToString(),
                            Text  = taxonomyLeaf.GetDisplayName(),
                            Group = selectListGroup
                        });
                    }
                }
            }
            else
            {
                return(taxonomyLeafs.SortByOrderThenName().ToSelectListWithEmptyFirstRow(m => m.TaxonomyLeafID.ToString(), m => m.GetDisplayName(),
                                                                                         $"Select the {MultiTenantHelpers.GetTaxonomyLeafDisplayNameForProject()}"));
            }

            return(selectListItems);
        }
        public static string GetSectionUrl(this ProjectUpdateSection projectUpdateSection, Project project)
        {
            if (!ModelObjectHelpers.IsRealPrimaryKeyValue(
                    project.GetLatestNotApprovedUpdateBatch().ProjectUpdateBatchID))
            {
                return(null);
            }

            switch (projectUpdateSection.ToEnum)
            {
            case ProjectUpdateSectionEnum.Basics:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.Basics(project)));

            case ProjectUpdateSectionEnum.CustomAttributes:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.ProjectCustomAttributes(project)));

            case ProjectUpdateSectionEnum.LocationSimple:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.LocationSimple(project)));

            case ProjectUpdateSectionEnum.Organizations:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.Organizations(project)));

            case ProjectUpdateSectionEnum.Contacts:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.Contacts(project)));

            case ProjectUpdateSectionEnum.LocationDetailed:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.LocationDetailed(project)));

            case ProjectUpdateSectionEnum.ReportedAccomplishments:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.ReportedPerformanceMeasures(project)));

            case ProjectUpdateSectionEnum.Budget:
                return(MultiTenantHelpers.GetTenantAttributeFromCache().BudgetType == BudgetType.AnnualBudgetByCostType
                            ? SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.ExpectedFundingByCostType(project.ProjectID))
                            : UnsupportedBudgetMode.UnsupportedBudgetModeWarning);

            //case ProjectUpdateSectionEnum.Expenditures:
            //    return MultiTenantHelpers.GetTenantAttributeFromCache().BudgetType == BudgetType.AnnualBudgetByCostType ?
            //        SitkaRoute<ProjectUpdateController>.BuildUrlFromExpression(x => x.ExpendituresByCostType(project)) :
            //        SitkaRoute<ProjectUpdateController>.BuildUrlFromExpression(x => x.Expenditures(project));
            case ProjectUpdateSectionEnum.Photos:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.Photos(project)));

            case ProjectUpdateSectionEnum.ExternalLinks:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.ExternalLinks(project)));

            case ProjectUpdateSectionEnum.AttachmentsAndNotes:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.AttachmentsAndNotes(project)));

            case ProjectUpdateSectionEnum.ExpectedAccomplishments:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.ExpectedPerformanceMeasures(project)));

            case ProjectUpdateSectionEnum.TechnicalAssistanceRequests:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.TechnicalAssistanceRequests(project)));

            case ProjectUpdateSectionEnum.BulkSetSpatialInformation:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.BulkSetSpatialInformation(project)));

            case ProjectUpdateSectionEnum.PartnerFinder:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.PartnerFinder(project)));

            case ProjectUpdateSectionEnum.Classifications:
                return(SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.Classifications(project)));

            default:
                throw new ArgumentOutOfRangeException($"Unhandled Project Update Section Enum: {projectUpdateSection.ToEnum}");
            }
        }
Beispiel #23
0
        private static LtInfoMenuItem BuildManageMenu(FirmaSession currentFirmaSession)
        {
            var manageMenu = new LtInfoMenuItem("Manage");

            // Group 1 - Project Classifications Stuff (taxonomies, classification systems, PMs)
            if (MultiTenantHelpers.IsTaxonomyLevelTrunk())
            {
                manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <TaxonomyTrunkController>(c => c.Manage()), currentFirmaSession, FieldDefinitionEnum.TaxonomyTrunk.ToType().GetFieldDefinitionLabelPluralized(), "Group1"));
            }

            if (!MultiTenantHelpers.IsTaxonomyLevelLeaf())
            {
                manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <TaxonomyBranchController>(c => c.Manage()), currentFirmaSession, FieldDefinitionEnum.TaxonomyBranch.ToType().GetFieldDefinitionLabelPluralized(), "Group1"));
            }

            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <TaxonomyLeafController>(c => c.Manage()), currentFirmaSession, FieldDefinitionEnum.TaxonomyLeaf.ToType().GetFieldDefinitionLabelPluralized(), "Group1"));
            MultiTenantHelpers.GetClassificationSystems().ForEach(x =>
            {
                manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ClassificationController>(c => c.Index(x.ClassificationSystemID)), currentFirmaSession, ClassificationSystemModelExtensions.GetClassificationSystemNamePluralized(x), "Group1"));
            });
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <PerformanceMeasureController>(c => c.Manage()), currentFirmaSession, MultiTenantHelpers.GetPerformanceMeasureNamePluralized(), "Group1"));

            MultiTenantHelpers.AddTechnicalAssistanceParametersMenuItem(manageMenu, currentFirmaSession, "Group1");
            MultiTenantHelpers.AddEvaluationsMenuItem(manageMenu, currentFirmaSession, "Group1");

            // Group 2 - System Config stuff
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectController>(c => c.FeaturedList()), currentFirmaSession, $"Featured {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabelPluralized()}", "Group2"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <HomeController>(c => c.ManageHomePageImages()), currentFirmaSession, "Homepage Images", "Group2"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <CustomPageController>(c => c.Index()), currentFirmaSession, "Custom Pages", "Group2"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <FieldDefinitionController>(c => c.Index()), currentFirmaSession, "Labels & Definitions", "Group2"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <DocumentLibraryController>(c => c.Index()), currentFirmaSession, "Document Libraries", "Group2"));

            // Group 3
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectFactSheetController>(c => c.Manage()), currentFirmaSession, $"{FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} Fact Sheets", "Group3"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <TagController>(c => c.Index()), currentFirmaSession, $"{FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} Tags", "Group3"));
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <ProjectUpdateController>(c => c.Manage()), currentFirmaSession, $"{FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} Updates", "Group3"));

            // Group 4
            manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <UserController>(c => c.Index()), currentFirmaSession, "Users", "Group4"));
            // Group 4 - Other

            // Group 5 - Project Firma Configuration stuff
            if (HttpRequestStorage.Tenant == ProjectFirmaModels.Models.Tenant.SitkaTechnologyGroup)
            {
                manageMenu.AddMenuItem(LtInfoMenuItem.MakeItem(new SitkaRoute <HomeController>(c => c.DemoScript()), currentFirmaSession, "Demo Script", "Group6")); // TODO: poor man's hack until we do tenant specific menu and features
            }

            return(manageMenu);
        }
        public BackwardLookingFactSheetViewData(FirmaSession currentFirmaSession, ProjectFirmaModels.Models.Project project,
                                                ProjectLocationSummaryMapInitJson projectLocationSummaryMapInitJson,
                                                GoogleChartJson projectFactSheetGoogleChart,
                                                List <GooglePieChartSlice> expenditureGooglePieChartSlices, List <string> chartColorRange,
                                                ProjectFirmaModels.Models.FirmaPage firmaPageFactSheet,
                                                List <TechnicalAssistanceParameter> technicalAssistanceParameters,
                                                bool withCustomAttributes,
                                                ProjectController.FactSheetPdfEnum factSheetPdfEnum) : base(currentFirmaSession, project)
        {
            PageTitle       = project.GetDisplayName();
            BreadCrumbTitle = "Fact Sheet";

            EstimatedTotalCost        = Project.GetEstimatedTotalRegardlessOfFundingType().HasValue ? Project.GetEstimatedTotalRegardlessOfFundingType().ToStringCurrency() : "";
            NoFundingSourceIdentified = project.GetNoFundingSourceIdentifiedAmount() != null?Project.GetNoFundingSourceIdentifiedAmount().ToStringCurrency() : "";

            ProjectedFunding = Project.GetProjectedFunding().ToStringCurrency();

            PerformanceMeasureReportedValues =
                project.GetPerformanceMeasureReportedValues().GroupBy(x => x.PerformanceMeasure).OrderBy(x => x.Key.PerformanceMeasureSortOrder).ThenBy(x => x.Key.PerformanceMeasureDisplayName).ToList();
            PerformanceMeasureExpectedValues = project.PerformanceMeasureExpecteds.GroupBy(x => x.PerformanceMeasure, new HavePrimaryKeyComparer <ProjectFirmaModels.Models.PerformanceMeasure>())
                                               .OrderBy(x => x.Key.PerformanceMeasureSortOrder).ThenBy(x => x.Key.PerformanceMeasureDisplayName).ToList();

            ShowExpectedPerformanceMeasures =
                MultiTenantHelpers.GetTenantAttributeFromCache().ShowExpectedPerformanceMeasuresOnFactSheet&&
                (project.ProjectStage == ProjectStage.Implementation || project.ProjectStage == ProjectStage.PostImplementation) && !PerformanceMeasureReportedValues.Any();

            ChartID  = $"fundingChartForProject{project.ProjectID}";
            KeyPhoto = project.GetKeyPhoto();
            ProjectImagesExceptKeyPhotoGroupedByTiming =
                project.ProjectImages.Where(x => !x.IsKeyPhoto && x.ProjectImageTiming != ProjectImageTiming.Unknown && !x.ExcludeFromFactSheet)
                .GroupBy(x => x.ProjectImageTiming)
                .OrderBy(x => x.Key.SortOrder)
                .ToList();
            ProjectImagesPerTimingGroup = ProjectImagesExceptKeyPhotoGroupedByTiming.Count == 1 ? 6 : 2;
            Classifications             = project.ProjectClassifications.Select(x => x.Classification).ToList().SortByOrderThenName().ToList();

            ProjectLocationSummaryMapInitJson = projectLocationSummaryMapInitJson;
            GoogleChartJson = projectFactSheetGoogleChart;

            ExpenditureGooglePieChartSlices = expenditureGooglePieChartSlices;
            ChartColorRange = chartColorRange;
            //Dynamically resize chart based on how much space the legend requires
            CalculatedChartHeight = 350 - ExpenditureGooglePieChartSlices.Count * 19;
            FactSheetPdfUrl       = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.FactSheetPdf(project));

            FactSheetWithCustomAttributesPdfUrl = SitkaRoute <ProjectController> .BuildUrlFromExpression(c => c.FactSheetWithCustomAttributesPdf(project));

            if (project.GetTaxonomyLeaf() == null)
            {
                TaxonomyColor = "blue";
            }
            else
            {
                switch (MultiTenantHelpers.GetTaxonomyLevel().ToEnum)
                {
                case TaxonomyLevelEnum.Leaf:
                    TaxonomyColor = project.GetTaxonomyLeaf().ThemeColor;
                    break;

                case TaxonomyLevelEnum.Branch:
                    TaxonomyColor = project.GetTaxonomyLeaf().TaxonomyBranch.ThemeColor;
                    break;

                case TaxonomyLevelEnum.Trunk:
                    TaxonomyColor = project.GetTaxonomyLeaf().TaxonomyBranch.TaxonomyTrunk.ThemeColor;
                    break;
                }
            }
            TaxonomyLeafName                = project.GetTaxonomyLeaf() == null ? $"{FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} Taxonomy Not Set" : project.GetTaxonomyLeaf().GetDisplayName();
            TaxonomyBranchName              = project.GetTaxonomyLeaf() == null ? $"{FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} Taxonomy Not Set" : project.GetTaxonomyLeaf().TaxonomyBranch.GetDisplayName();
            TaxonomyLeafDisplayName         = FieldDefinitionEnum.TaxonomyLeaf.ToType().GetFieldDefinitionLabel();
            PrimaryContactPerson            = project.GetPrimaryContact();
            CustomFactSheetPageTextViewData = new ViewPageContentViewData(firmaPageFactSheet, false);
            TechnicalAssistanceParameters   = technicalAssistanceParameters;
            TechnicalAssistanceRequests     = project.TechnicalAssistanceRequests.ToList();

            ViewableProjectCustomAttributeTypes = HttpRequestStorage.DatabaseEntities.ProjectCustomAttributeTypes.ToList().Where(x => x.HasViewPermission(currentFirmaSession) && x.IsViewableOnFactSheet).ToList();
            ViewableProjectCustomAttributes     = project.ProjectCustomAttributes.Where(x => x.ProjectCustomAttributeType.HasViewPermission(currentFirmaSession) && ViewableProjectCustomAttributeTypes.Contains(x.ProjectCustomAttributeType)).ToList();

            WithCustomAttributes = withCustomAttributes;
            LastUpdated          = project.LastUpdatedDate;
            FactSheetPdfEnum     = factSheetPdfEnum;

            // No delay loading our fake image by default
            int fakeImageDelayInMilliseconds = 0;

            // When set the page is being rendered for PDF
            if (factSheetPdfEnum == ProjectController.FactSheetPdfEnum.Pdf)
            {
                // If we are printing for PDF, we have a fake 1x1 transparent image that we deliberately take time to load. This causes Headless Chrome
                // to delay printing the page until the map is ready to be viewed.
                //
                // We hope that 4 seconds is enough to allow the mapping components to load. Increase if they don't render properly.
                fakeImageDelayInMilliseconds = ForwardLookingFactSheetViewData.FactSheetPdfEmptyImageLoadDelayInMilliseconds;
            }

            FakeImageWithDelayUrl = new SitkaRoute <FakeImageController>(c => c.ReturnEmptyImageAfterDelayInMilliseconds(fakeImageDelayInMilliseconds)).BuildAbsoluteUrlHttpsFromExpression();

            ProjectLocationIsProvided = project.ProjectLocationPoint != null || project.ProjectLocations.Any();
        }
Beispiel #25
0
        public PartialViewResult OrganizationAccomplishments(int organizationID, int taxonomyTierID)
        {
            List <Project> projects;

            if (ModelObjectHelpers.IsRealPrimaryKeyValue(organizationID) &&
                MultiTenantHelpers.DisplayAccomplishmentDashboard())
            {
                var organization = HttpRequestStorage.DatabaseEntities.Organizations.GetOrganization(organizationID);
                projects = organization.GetAllActiveProjectsAndProposals(CurrentFirmaSession);
            }
            else
            {
                projects = HttpRequestStorage.DatabaseEntities.Projects.ToList().GetActiveProjectsAndProposals(MultiTenantHelpers.ShowProposalsToThePublic(), CurrentFirmaSession).ToList();
            }

            var          associatePerformanceMeasureTaxonomyLevel = MultiTenantHelpers.GetAssociatePerformanceMeasureTaxonomyLevel();
            TaxonomyTier taxonomyTier;

            if (associatePerformanceMeasureTaxonomyLevel == TaxonomyLevel.Trunk)
            {
                taxonomyTier = new TaxonomyTier(HttpRequestStorage.DatabaseEntities.TaxonomyTrunks.GetTaxonomyTrunk(taxonomyTierID));
            }
            else if (associatePerformanceMeasureTaxonomyLevel == TaxonomyLevel.Branch)
            {
                taxonomyTier = new TaxonomyTier(HttpRequestStorage.DatabaseEntities.TaxonomyBranches.GetTaxonomyBranch(taxonomyTierID));
            }
            else
            {
                taxonomyTier = new TaxonomyTier(HttpRequestStorage.DatabaseEntities.TaxonomyLeafs.GetTaxonomyLeaf(taxonomyTierID));
            }

            var projectIDs = projects.Select(x => x.ProjectID).Distinct().ToList();
            var primaryPerformanceMeasuresForTaxonomyTier = taxonomyTier.TaxonomyTierPerformanceMeasures.Select(x => x.Key).ToList();
            var performanceMeasures = primaryPerformanceMeasuresForTaxonomyTier.SelectMany(x => x.PerformanceMeasureActuals.Where(y => projectIDs.Contains(y.ProjectID))).Select(x => x.PerformanceMeasure).Distinct(new HavePrimaryKeyComparer <PerformanceMeasure>()).OrderBy(x => x.PerformanceMeasureDisplayName).ToList();
            var performanceMeasureChartViewDatas = performanceMeasures.Select(x => new PerformanceMeasureChartViewData(x, CurrentFirmaSession, false, projects)).ToList();

            var viewData = new OrganizationAccomplishmentsViewData(performanceMeasureChartViewDatas, taxonomyTier, associatePerformanceMeasureTaxonomyLevel);

            return(RazorPartialView <OrganizationAccomplishments, OrganizationAccomplishmentsViewData>(viewData));
        }
Beispiel #26
0
 public static List <HtmlString> GetProjectStewardshipAreaHtmlStringList(this Person person)
 {
     return(MultiTenantHelpers.GetProjectStewardshipAreaType()?.GetProjectStewardshipAreaHtmlStringList(person));
 }
Beispiel #27
0
        private static Dictionary <ProjectLocationFilterTypeSimple, IEnumerable <SelectListItem> > CreateProjectLocationFilterTypesAndValuesDictionary(bool showProposals)
        {
            var projectLocationFilterTypesAndValues =
                new Dictionary <ProjectLocationFilterTypeSimple, IEnumerable <SelectListItem> >();

            if (MultiTenantHelpers.IsTaxonomyLevelTrunk())
            {
                var taxonomyTrunksAsSelectListItems =
                    HttpRequestStorage.DatabaseEntities.TaxonomyTrunks.OrderBy(x => x.TaxonomyTrunkSortOrder).ThenBy(x => x.TaxonomyTrunkName).ToSelectList(
                        x => x.TaxonomyTrunkID.ToString(CultureInfo.InvariantCulture), x => x.GetDisplayName());
                projectLocationFilterTypesAndValues.Add(new ProjectLocationFilterTypeSimple(ProjectLocationFilterType.TaxonomyTrunk),
                                                        taxonomyTrunksAsSelectListItems);
            }

            if (!MultiTenantHelpers.IsTaxonomyLevelLeaf())
            {
                var taxonomyBranchesAsSelectListItems =
                    HttpRequestStorage.DatabaseEntities.TaxonomyBranches.OrderBy(x => x.TaxonomyTrunk.TaxonomyTrunkSortOrder).ThenBy(x => x.TaxonomyBranchSortOrder).ThenBy(x => x.TaxonomyBranchName).ToSelectList(
                        x => x.TaxonomyBranchID.ToString(CultureInfo.InvariantCulture), x => x.GetDisplayName());
                projectLocationFilterTypesAndValues.Add(new ProjectLocationFilterTypeSimple(ProjectLocationFilterType.TaxonomyBranch),
                                                        taxonomyBranchesAsSelectListItems);
            }


            var taxonomyLeafsAsSelectListItems =
                HttpRequestStorage.DatabaseEntities.TaxonomyLeafs.OrderBy(x => x.TaxonomyBranch.TaxonomyTrunk.TaxonomyTrunkSortOrder).ThenBy(x => x.TaxonomyBranch.TaxonomyBranchSortOrder).ThenBy(x => x.TaxonomyLeafSortOrder).ThenBy(x => x.TaxonomyLeafName).ToSelectList(
                    x => x.TaxonomyLeafID.ToString(CultureInfo.InvariantCulture), x => x.GetDisplayName());

            projectLocationFilterTypesAndValues.Add(new ProjectLocationFilterTypeSimple(ProjectLocationFilterType.TaxonomyLeaf),
                                                    taxonomyLeafsAsSelectListItems);

            var classificationsAsSelectList = MultiTenantHelpers.GetClassificationSystems().SelectMany(x => x.Classifications).ToSelectList(x => x.ClassificationID.ToString(CultureInfo.InvariantCulture), x => MultiTenantHelpers.GetClassificationSystems().Count > 1 ? $"{x.ClassificationSystem.ClassificationSystemName} - {x.GetDisplayName()}" : x.GetDisplayName());

            projectLocationFilterTypesAndValues.Add(new ProjectLocationFilterTypeSimple(ProjectLocationFilterType.Classification, string.Join(" & ", MultiTenantHelpers.GetClassificationSystems().Select(x => x.ClassificationSystemName).ToList())), classificationsAsSelectList);

            var projectStagesAsSelectListItems = ProjectMapCustomization.GetProjectStagesForMap(showProposals).ToSelectList(x => x.ProjectStageID.ToString(CultureInfo.InvariantCulture), x => x.ProjectStageDisplayName);

            projectLocationFilterTypesAndValues.Add(new ProjectLocationFilterTypeSimple(ProjectLocationFilterType.ProjectStage), projectStagesAsSelectListItems);

            return(projectLocationFilterTypesAndValues);
        }
Beispiel #28
0
 public static bool CanStewardProject(this Person person, Project project)
 {
     return(MultiTenantHelpers.GetProjectStewardshipAreaType()?.CanStewardProject(person, project) ?? true);
 }
Beispiel #29
0
        public IEnumerable <ValidationResult> GetValidationResults()
        {
            var validationResults = new List <ValidationResult>();

            if ((PerformanceMeasureExpecteds == null || !PerformanceMeasureExpecteds.Any()) && string.IsNullOrWhiteSpace(PerformanceMeasureNotes))
            {
                var errorMessage = string.Format("You must provide one or more expected {0}, or provide a brief note describing why the {0} are not yet known for this proposal.", MultiTenantHelpers.GetPerformanceMeasureNamePluralized());
                validationResults.Add(new SitkaValidationResult <ExpectedPerformanceMeasureValuesViewModel, string>(errorMessage, x => x.PerformanceMeasureNotes));
            }
            return(validationResults);
        }
        public DetailViewData(Person currentPerson,
                              Person personToView,
                              ProjectInfoForUserDetailGridSpec basicProjectInfoGridSpec,
                              string basicProjectInfoGridName,
                              string basicProjectInfoGridDataUrl,
                              UserNotificationGridSpec userNotificationGridSpec,
                              string userNotificationGridName,
                              string userNotificationGridDataUrl,
                              string activateInactivateUrl,
                              bool atLeastOneAgreementHasFile)
            : base(currentPerson)
        {
            Person = personToView;
            PersonIsMereContact = !personToView.IsFullUser();
            PageTitle           = personToView.FullNameFirstLast + (!personToView.IsActive ? " (inactive)" : string.Empty);
            EntityName          = "User";
            //TODO: This gets pulled up to root
            EditPersonOrganizationPrimaryContactUrl = SitkaRoute <PersonOrganizationController> .BuildUrlFromExpression(c => c.EditPersonOrganizationPrimaryContacts(personToView));

            Index = SitkaRoute <UserController> .BuildUrlFromExpression(x => x.Index());

            UserHasPersonViewPermissions     = new UserViewFeature().HasPermission(currentPerson, personToView).HasPermission;
            UserHasEditBasicsPermission      = new UserEditBasicsFeature().HasPermission(currentPerson, personToView).HasPermission;
            UserCanViewAndCreateNewContacts  = new ContactCreateAndViewFeature().HasPermissionByPerson(currentPerson);
            UserHasViewEverythingPermissions = new FirmaAdminFeature().HasPermissionByPerson(currentPerson);
            IsViewingSelf          = currentPerson != null && currentPerson.PersonID == personToView.PersonID;
            UserHasAdminPermission = new UserEditAsAdminFeature().HasPermissionByPerson(currentPerson);
            EditRolesLink          = UserHasAdminPermission
                ? ModalDialogFormHelper.MakeEditIconLink(SitkaRoute <UserController> .BuildUrlFromExpression(c => c.EditRoles(personToView)),
                                                         $"Edit Roles for User - {personToView.FullNameFirstLast}",
                                                         true)
                : new HtmlString(string.Empty);
            AuthenticatorsDisplayString = string.Join(", ", Person.PersonAllowedAuthenticators.OrderBy(x => x.Authenticator.AuthenticatorFullName).Select(x => $"{x.Authenticator.AuthenticatorFullName} ({x.Authenticator.AuthenticatorName})"));

            BasicProjectInfoGridSpec    = basicProjectInfoGridSpec;
            BasicProjectInfoGridName    = basicProjectInfoGridName;
            BasicProjectInfoGridDataUrl = basicProjectInfoGridDataUrl;

            UserNotificationGridSpec    = userNotificationGridSpec;
            UserNotificationGridName    = userNotificationGridName;
            UserNotificationGridDataUrl = userNotificationGridDataUrl;
            ActivateInactivateUrl       = activateInactivateUrl;

            TenantHasStewardshipAreas = MultiTenantHelpers.GetProjectStewardshipAreaType() != null;
            EditContactUrl            = SitkaRoute <UserController> .BuildUrlFromExpression(x => x.EditContact(personToView));

            ProjectsForWhichUserIsAContactGridTitle = personToView.IsFullUser()
                ? $"{Models.FieldDefinition.Project.GetFieldDefinitionLabelPluralized()} for which {Person.FullNameFirstLast} is an {Models.FieldDefinition.OrganizationPrimaryContact.GetFieldDefinitionLabel()}"
                : $"{Models.FieldDefinition.Project.GetFieldDefinitionLabelPluralized()} for which {Person.FullNameFirstLast} is a {Models.FieldDefinition.Contact.GetFieldDefinitionLabel()}";

            AgreementsForWhichUserIsAContactGridTitle = personToView.IsFullUser()
                ? $"{Models.FieldDefinition.Agreement.GetFieldDefinitionLabelPluralized()} for which {Person.FullNameFirstLast} is an {Models.FieldDefinition.OrganizationPrimaryContact.GetFieldDefinitionLabel()}"
                : $"{Models.FieldDefinition.Agreement.GetFieldDefinitionLabelPluralized()} for which {Person.FullNameFirstLast} is a {Models.FieldDefinition.Contact.GetFieldDefinitionLabel()}";

            UserAgreementsGridSpec = new AgreementGridSpec(CurrentPerson, atLeastOneAgreementHasFile, false, false)
            {
                CustomExcelDownloadUrl = SitkaRoute <UserController> .BuildUrlFromExpression(tc => tc.UserAgreementsExcelDownload(personToView.PrimaryKey))
            };
            UserAgreementsGridName    = "userAgreementsFromUserGrid";
            UserAgreementsGridDataUrl =
                SitkaRoute <UserController> .BuildUrlFromExpression(
                    tc => tc.UserAgreementsGridJsonData(personToView));

            InteractionEventsForWhichUserIsAContactGridTitle = $"{Models.FieldDefinition.InteractionEvent.GetFieldDefinitionLabelPluralized()} for which {Person.FullNameFirstLast} is a {Models.FieldDefinition.Contact.GetFieldDefinitionLabel()}";
            UserInteractionEventsGridSpec    = new InteractionEventGridSpec(CurrentPerson, personToView);
            UserInteractionEventsGridName    = "userInteractionEventsFromUserGrid";
            UserInteractionEventsGridDataUrl =
                SitkaRoute <UserController> .BuildUrlFromExpression(x => x.UserInteractionEventsGridJsonData(personToView));
        }