public void YearSumsCorrectly() { var org1 = TestFramework.TestOrganization.Create(); var projectGrantAllocationExpenditures = BuildExpenditures(org1, "grant allocation 1", new Dictionary <int, decimal> { { 2010, 100.0m }, { 2011, 200.0m }, { 2012, 300.0m }, { 2013, 400.0m } }); var org2 = TestFramework.TestOrganization.Create(); projectGrantAllocationExpenditures.AddAll(BuildExpenditures(org2, "grant allocation 2", new Dictionary <int, decimal> { { 2010, 100.0m }, { 2011, 200.0m }, { 2012, 300.0m }, { 2013, 400.0m } })); var beginCalendarYear = projectGrantAllocationExpenditures.Min(x => x.CalendarYear); var endCalendarYear = projectGrantAllocationExpenditures.Max(x => x.CalendarYear); var rangeOfYears = FirmaDateUtilities.GetRangeOfYears(beginCalendarYear, endCalendarYear); var fullOrganizationTypeAndYearDictionary = projectGrantAllocationExpenditures.GetFullCategoryYearDictionary(x => x.GrantAllocation.BottommostOrganization.DisplayName, new List <string> { org1.DisplayName, org2.DisplayName }, x => x.GrantAllocation.BottommostOrganization.DisplayName, rangeOfYears); Assert.That(fullOrganizationTypeAndYearDictionary.Sum(x => x.Value[2012]), Is.EqualTo(600.0m)); }
public void ProjectUpdateSubmittedTest() { // Find all project update batches for given reporting year that are approved // If none approved, then look for submitted var project = TestFramework.TestProject.Create(); var reportingYear = FirmaDateUtilities.CalculateCurrentYearToUseForRequiredReporting(); // brand new project, should not have any updates AssertThatProjectHasNoSubmittedProjectUpdates(project, new List <int>(), $"Brand new {Models.FieldDefinition.Project.GetFieldDefinitionLabel()}, should not have any project updates submitted"); var projectUpdateBatch = TestFramework.TestProjectUpdateBatch.Create(project); projectUpdateBatch.LastUpdateDate = DateTime.Now; // brand new project update batch, should still not have any updates AssertThatProjectHasNoSubmittedProjectUpdates(project, new List <int>(), $"Brand new {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} update batch, should not have any project updates submitted"); var person = TestFramework.TestPerson.Create(); // create a "submitted" transition TestFramework.TestProjectUpdateHistory.Create(projectUpdateBatch, ProjectUpdateState.Submitted, person); Assert.That(project.IsUpdateMandatory, Is.True, "In submitted state, no previous approvals for this reporting year, so we should be true"); // add an "approved" transition TestFramework.TestProjectUpdateHistory.Create(projectUpdateBatch, ProjectUpdateState.Approved, person); Assert.That(project.IsUpdateMandatory, Is.True, "In approved state, no previous approvals for this reporting year, so we should be true"); // user decides to do another update in the same reporting year var projectUpdateBatch2 = TestFramework.TestProjectUpdateBatch.Create(project); projectUpdateBatch2.LastUpdateDate = DateTime.Now; AssertThatProjectHasNoSubmittedProjectUpdates(project, new List <int> { reportingYear }, $"Should not have any {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} updates submitted except for the reporting year"); }
public EditProjectViewData(EditProjectType editProjectType, string taxonomyLeafDisplayName, IEnumerable <ProjectStage> projectStages, IEnumerable <ProjectFirmaModels.Models.Organization> organizations, IEnumerable <Person> primaryContactPeople, Person defaultPrimaryContactPerson, decimal?totalExpenditures, List <ProjectFirmaModels.Models.TaxonomyLeaf> taxonomyLeafs, IEnumerable <ProjectFirmaModels.Models.ProjectCustomAttributeType> projectCustomAttributeTypes, TenantAttribute tenantAttribute) { EditProjectType = editProjectType; TaxonomyLeafDisplayName = taxonomyLeafDisplayName; TotalExpenditures = totalExpenditures; ProjectStages = projectStages.OrderBy(x => x.SortOrder).ToSelectListWithEmptyFirstRow(x => x.ProjectStageID.ToString(CultureInfo.InvariantCulture), y => y.ProjectStageDisplayName); ProjectStages = projectStages.OrderBy(x => x.SortOrder).ToSelectListWithEmptyFirstRow(x => x.ProjectStageID.ToString(CultureInfo.InvariantCulture), y => y.ProjectStageDisplayName); Organizations = organizations.ToSelectListWithEmptyFirstRow(x => x.OrganizationID.ToString(CultureInfo.InvariantCulture), y => y.GetDisplayName()); PrimaryContactPeople = primaryContactPeople.ToSelectListWithEmptyFirstRow( x => x.PersonID.ToString(CultureInfo.InvariantCulture), y => y.GetFullNameFirstLastAndOrgShortName(), $"<Set Based on {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}'s Associated {FieldDefinitionEnum.Organization.ToType().GetFieldDefinitionLabelPluralized()}>"); DefaultPrimaryContactPerson = defaultPrimaryContactPerson; TaxonomyLeafs = taxonomyLeafs.ToGroupedSelectList(); PlanningDesignStartYearRange = FirmaDateUtilities.YearsForUserInput().ToSelectListWithEmptyFirstRow(x => x.CalendarYear.ToString(CultureInfo.InvariantCulture), x => x.CalendarYearDisplay).ToList(); ImplementationStartYearRange = FirmaDateUtilities.YearsForUserInput().ToSelectListWithEmptyFirstRow(x => x.CalendarYear.ToString(CultureInfo.InvariantCulture), x => x.CalendarYearDisplay).ToList(); CompletionYearRange = FirmaDateUtilities.YearsForUserInput().ToSelectListWithEmptyFirstRow(x => x.CalendarYear.ToString(CultureInfo.InvariantCulture), x => x.CalendarYearDisplay).ToList(); HasThreeTierTaxonomy = MultiTenantHelpers.IsTaxonomyLevelTrunk(); DefaultPrimaryContactPersonName = DefaultPrimaryContactPerson != null?DefaultPrimaryContactPerson.GetFullNameFirstLastAndOrgShortName() : "nobody"; ProjectCustomAttributeTypes = projectCustomAttributeTypes; TenantAttribute = tenantAttribute; TenantUsesFiscalYears = MultiTenantHelpers.UseFiscalYears(); }
private void AssignParameters(IEnumerable <ProjectFirmaModels.Models.TaxonomyLeaf> taxonomyLeafs, IEnumerable <FundingType> fundingTypes, TenantAttribute tenantAttribute) { TaxonomyLeafs = taxonomyLeafs.ToList().OrderTaxonomyLeaves().ToList().ToGroupedSelectList(); FundingTypes = fundingTypes.ToSelectList(x => x.FundingTypeID.ToString(CultureInfo.InvariantCulture), y => y.FundingTypeDisplayName); PlanningDesignStartYearRange = FirmaDateUtilities.YearsForUserInput().ToSelectListWithEmptyFirstRow(x => x.CalendarYear.ToString(CultureInfo.InvariantCulture), x => x.CalendarYearDisplay).ToList(); ImplementationStartYearRange = FirmaDateUtilities.YearsForUserInput().ToSelectListWithEmptyFirstRow(x => x.CalendarYear.ToString(CultureInfo.InvariantCulture), x => x.CalendarYearDisplay).ToList(); CompletionYearRange = FirmaDateUtilities.YearsForUserInput().ToSelectListWithEmptyFirstRow(x => x.CalendarYear.ToString(CultureInfo.InvariantCulture), x => x.CalendarYearDisplay).ToList(); HasCanStewardProjectsOrganizationRelationship = MultiTenantHelpers.HasCanStewardProjectsOrganizationRelationship(); HasThreeTierTaxonomy = MultiTenantHelpers.IsTaxonomyLevelTrunk(); var pagetitle = ShowProjectStageDropDown ? $"Add {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}" : $"Propose {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()}"; PageTitle = $"{pagetitle}"; if (ProjectDisplayName != null) { PageTitle += $": {ProjectDisplayName}"; } TenantAttribute = tenantAttribute; TenantUsesFiscalYears = MultiTenantHelpers.UseFiscalYears(); }
private static List <int> GetYearRangesImpl(IProject projectUpdate, DateTime?startDate) { var currentYearToUse = FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting(); if (projectUpdate != null) { if (startDate.HasValue && startDate.Value.Year < MultiTenantHelpers.GetMinimumYear() && (projectUpdate.GetCompletionYear().HasValue&& projectUpdate.GetCompletionYear().Value < MultiTenantHelpers.GetMinimumYear())) { // both start and completion year are before the minimum year, so no year range required return(new List <int>()); } if (startDate.HasValue && startDate.Value.Year > currentYearToUse && (projectUpdate.GetCompletionYear().HasValue&& projectUpdate.GetCompletionYear().Value > currentYearToUse)) { return(new List <int>()); } if (startDate.HasValue && projectUpdate.GetCompletionYear().HasValue&& startDate.Value.Year > projectUpdate.GetCompletionYear().Value) { return(new List <int>()); } } return(FirmaDateUtilities.CalculateCalendarYearRangeAccountingForExistingYears(new List <int>(), startDate, projectUpdate.GetCompletionYear(), currentYearToUse, MultiTenantHelpers.GetMinimumYear(), currentYearToUse)); }
public EditProjectViewData(EditProjectType editProjectType, string projectTypeDisplayName, IEnumerable <ProjectStage> projectStages, IEnumerable <Models.Organization> organizations, IEnumerable <Person> primaryContactPeople, Person defaultPrimaryContactPerson, decimal?totalExpenditures, List <Models.ProjectType> projectTypes, IEnumerable <Models.FocusArea> focusAreas, bool projectTypeHasBeenSet, List <ProgramSimple> allPrograms, int projectID) { EditProjectTypeIntroductoryText = editProjectType.IntroductoryText; ProjectTypeDisplayName = projectTypeDisplayName; TotalExpenditures = totalExpenditures; ProjectStages = projectStages.OrderBy(x => x.SortOrder).ToSelectListWithEmptyFirstRow(x => x.ProjectStageID.ToString(CultureInfo.InvariantCulture), y => y.ProjectStageDisplayName); Organizations = organizations.ToSelectListWithEmptyFirstRow(x => x.OrganizationID.ToString(CultureInfo.InvariantCulture), y => y.DisplayName); PrimaryContactPeople = primaryContactPeople.ToSelectListWithEmptyFirstRow( x => x.PersonID.ToString(CultureInfo.InvariantCulture), y => y.FullNameFirstLastAndOrgShortName, $"<Set Based on {Models.FieldDefinition.Project.GetFieldDefinitionLabel()}'s Associated {Models.FieldDefinition.Organization.GetFieldDefinitionLabelPluralized()}>"); ProjectTypes = projectTypes.ToGroupedSelectList(); StartYearRange = FirmaDateUtilities.YearsForUserInput().ToSelectListWithEmptyFirstRow(x => x.CalendarYear.ToString(CultureInfo.InvariantCulture), x => x.CalendarYearDisplay); CompletionDateRange = FirmaDateUtilities.YearsForUserInput().ToSelectListWithEmptyFirstRow(x => x.CalendarYear.ToString(CultureInfo.InvariantCulture), x => x.CalendarYearDisplay); HasThreeTierTaxonomy = MultiTenantHelpers.IsTaxonomyLevelTrunk(); DefaultPrimaryContactPersonName = defaultPrimaryContactPerson?.FullNameFirstLastAndOrgShortName ?? "nobody"; FocusAreas = focusAreas.OrderBy(x => x.FocusAreaName).ToSelectListWithEmptyFirstRow(x => x.FocusAreaID.ToString(CultureInfo.InvariantCulture), y => y.FocusAreaName); ProjectTypeHasBeenSet = projectTypeHasBeenSet; AllPrograms = allPrograms; ProjectID = projectID; }
public ManageViewData(Person currentPerson, Models.FirmaPage firmaPage, string customNotificationUrl, ProjectUpdateStatusGridSpec projectsRequiringUpdateGridSpec, string projectsRequiringUpdateGridDataUrl, PeopleReceivingReminderGridSpec peopleReceivingReminderGridSpec, string peopleReceivingReminderGridDataUrl, int projectsWithNoContactCount, ProjectUpdateConfiguration projectUpdateConfiguration) : base(currentPerson, firmaPage) { var reportingYear = FirmaDateUtilities.CalculateCurrentYearToUseForRequiredReporting(); PageTitle = $"Manage {Models.FieldDefinition.Project.GetFieldDefinitionLabel()} Updates"; ReportingYear = reportingYear; ProjectsRequiringUpdateGridDataUrl = projectsRequiringUpdateGridDataUrl; ProjectsRequiringUpdateGridSpec = projectsRequiringUpdateGridSpec; ProjectsRequiringUpdateGridName = "projectsRequiringAnUpdateGrid"; PeopleReceivingReminderGridDataUrl = peopleReceivingReminderGridDataUrl; ProjectsWithNoContactCount = projectsWithNoContactCount; ProjectUpdateConfiguration = projectUpdateConfiguration ?? ProjectUpdateConfiguration.CreateNewBlank(); PeopleReceivingReminderGridSpec = peopleReceivingReminderGridSpec; PeopleReceivingReminderGridName = "peopleReceivingAnReminderGrid"; KickOffIntroPreviewUrl = SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.KickOffIntroPreview()); ReminderIntroPreviewUrl = SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.ReminderIntroPreview()); CloseOutIntroPreviewUrl = SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.CloseOutIntroPreview()); var getPersonIDFunctionString = $"function() {{ return Sitka.{PeopleReceivingReminderGridName}.getValuesFromCheckedGridRows({0}, \'PersonID\', \'PersonIDList\'); }}"; var modalDialogFormLink = ModalDialogFormHelper.ModalDialogFormLink( "<span class=\"glyphicon glyphicon-envelope\" style=\"margin-right:5px\"></span>Send Notification to Selected People", customNotificationUrl, "Send Notification to Selected People", 700, "Send", "Cancel", new List <string>(), null, getPersonIDFunctionString); PeopleReceivingReminderGridSpec.ArbitraryHtml = new List <string> { modalDialogFormLink.ToString() }; EditProjectUpdateConfigurationUrl = SitkaRoute <ProjectUpdateController> .BuildUrlFromExpression(x => x.EditProjectUpdateConfiguration()); }
private PartialViewResult ViewEditTechnicalAssistanceRequests(Project project, EditTechnicalAssistanceRequestsViewModel viewModel) { var firmaPage = FirmaPageTypeEnum.TechnicalAssistanceInstructions.GetFirmaPage(); var technicalAssistanceTypes = TechnicalAssistanceType.All; var fiscalYearStrings = FirmaDateUtilities.GetRangeOfYears(MultiTenantHelpers.GetMinimumYear(), FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting() + 2).OrderByDescending(x => x).Select(x => new CalendarYearString(x)).ToList(); var personDictionary = HttpRequestStorage.DatabaseEntities.People.Where(x => x.RoleID == Role.Admin.RoleID || x.RoleID == Role.ProjectSteward.RoleID).OrderBy(x => x.LastName).ThenBy(x => x.FirstName).ToList().Select(x => new PersonSimple(x)).ToList(); var viewData = new EditTechnicalAssistanceRequestsViewData(CurrentFirmaSession, firmaPage, project, technicalAssistanceTypes, fiscalYearStrings, personDictionary); return(RazorPartialView <EditTechnicalAssistanceRequests, EditTechnicalAssistanceRequestsViewData, EditTechnicalAssistanceRequestsViewModel>(viewData, viewModel)); }
public static IEnumerable <CalendarYearReportedValue> ToCalendarYearReportedValues(IEnumerable <ProjectGrantAllocationExpenditure> projectGrantAllocationExpenditures) { var yearRange = FirmaDateUtilities.GetRangeOfYearsForReporting(); return(yearRange.OrderBy(cy => cy).Select(cy => { var pmavForThisCalendarYear = projectGrantAllocationExpenditures.Where(x => x.CalendarYear == cy).ToList(); return new CalendarYearReportedValue(cy, pmavForThisCalendarYear.Any() ? (double?)pmavForThisCalendarYear.Sum(y => y.ExpenditureAmount) : null); })); }
private static bool TodayIsReminderDayForProjectUpdateConfiguration( ProjectUpdateSetting projectUpdateSetting) { var projectUpdateKickOffDate = FirmaDateUtilities.LastReportingPeriodStartDateForBackgroundJob(projectUpdateSetting.ProjectUpdateKickOffDate.GetValueOrDefault()); var projectUpdateCloseOutDate = FirmaDateUtilities.LastReportingPeriodEndDateForBackgroundJob(projectUpdateSetting.ProjectUpdateKickOffDate.GetValueOrDefault(), projectUpdateSetting.ProjectUpdateCloseOutDate.GetValueOrDefault()); var isReminderDay = DateTime.Today != projectUpdateKickOffDate && (DateTime.Today - projectUpdateKickOffDate).Days % projectUpdateSetting.ProjectUpdateReminderInterval == 0; var isAfterCloseOut = DateTime.Today.IsDateAfter(projectUpdateCloseOutDate); return(isReminderDay && !isAfterCloseOut); }
public static List <int> CalculateCalendarYearRangeForExpenditures(this IEnumerable <ProjectFundingSourceExpenditure> projectFundingSourceExpenditures, FundingSource fundingSource) { var existingYears = projectFundingSourceExpenditures.Select(x => x.CalendarYear).ToList(); return(FirmaDateUtilities.CalculateCalendarYearRangeAccountingForExistingYears(existingYears, fundingSource.GetProjectsWhereYouAreTheFundingSourceMinCalendarYear(), fundingSource.GetProjectsWhereYouAreTheFundingSourceMaxCalendarYear(), DateTime.Today.Year, MultiTenantHelpers.GetMinimumYear(), null)); }
protected virtual void ProcessRemindersImpl() { Logger.Info($"Processing '{JobName}' notifications."); // we're "tenant-agnostic" right now var projectUpdateSettings = DbContext.AllProjectUpdateSettings.ToList(); foreach (var projectUpdateSetting in projectUpdateSettings) { var notifications = new List <Notification>(); var tenantID = projectUpdateSetting.TenantID; var databaseEntities = new DatabaseEntities(tenantID); var projects = databaseEntities.Projects.ToList(); var tenantAttribute = databaseEntities.TenantAttributes.Single(); var reminderSubject = $"Time to update your {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabelPluralizedForBackgroundJob(tenantAttribute.TenantID)}"; if (projectUpdateSetting.EnableProjectUpdateReminders) { var projectUpdateKickOffDate = FirmaDateUtilities.LastReportingPeriodStartDateForBackgroundJob(projectUpdateSetting.ProjectUpdateKickOffDate.GetValueOrDefault()); if (DateTime.Today == projectUpdateKickOffDate) { notifications.AddRange(RunNotifications(projects, reminderSubject, projectUpdateSetting.ProjectUpdateKickOffIntroContent, tenantAttribute)); } } if (projectUpdateSetting.SendPeriodicReminders) { if (TodayIsReminderDayForProjectUpdateConfiguration(projectUpdateSetting)) { notifications.AddRange(RunNotifications(projects, reminderSubject, projectUpdateSetting.ProjectUpdateReminderIntroContent, tenantAttribute)); // notifyOnAll is false b/c we only send periodic reminders for projects whose updates haven't been submitted yet. } } if (projectUpdateSetting.SendCloseOutNotification) { var closeOutReminderDate = FirmaDateUtilities.LastReportingPeriodEndDateForBackgroundJob(projectUpdateSetting.ProjectUpdateKickOffDate.GetValueOrDefault(), projectUpdateSetting.ProjectUpdateCloseOutDate.GetValueOrDefault()); if (projectUpdateSetting.DaysBeforeCloseOutDateForReminder.HasValue) { closeOutReminderDate = closeOutReminderDate.AddDays(-projectUpdateSetting.DaysBeforeCloseOutDateForReminder.Value); } if (DateTime.Today == closeOutReminderDate) { notifications.AddRange(RunNotifications(projects, reminderSubject, projectUpdateSetting.ProjectUpdateCloseOutIntroContent, tenantAttribute)); } } databaseEntities.AllNotifications.AddRange(notifications); databaseEntities.SaveChangesWithNoAuditing(tenantID); } }
public ViewDataForAngularClass(ProjectFirmaModels.Models.Project project, List <FundingSourceSimple> allFundingSources, List <int> requiredCalendarYearRange) { RequiredCalendarYearRange = requiredCalendarYearRange; AllFundingSources = allFundingSources; ProjectID = project.ProjectID; MaxYear = FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting(); UseFiscalYears = MultiTenantHelpers.UseFiscalYears(); }
public ViewDataForAngularClass(Models.Project project, List <GrantAllocationSimple> allGrantAllocations, List <int> calendarYearRange, bool showNoExpendituresExplanation) { CalendarYearRange = calendarYearRange; ShowNoExpendituresExplanation = showNoExpendituresExplanation; AllGrantAllocations = allGrantAllocations; ProjectID = project.ProjectID; MaxYear = FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting(); UseFiscalYears = MultiTenantHelpers.UseFiscalYears(); }
private static List <int> GetRangeOfYears(List <ProjectFundingSourceExpenditure> projectFundingSourceExpenditures) { if (!projectFundingSourceExpenditures.Any()) { return(new List <int>()); } var beginCalendarYear = projectFundingSourceExpenditures.Min(x => x.CalendarYear); var endCalendarYear = projectFundingSourceExpenditures.Max(x => x.CalendarYear); var rangeOfYears = FirmaDateUtilities.GetRangeOfYears(beginCalendarYear, endCalendarYear); return(rangeOfYears); }
public static List <int> CalculateCalendarYearRangeForExpendituresWithoutAccountingForExistingYears(this ProjectUpdate projectUpdate) { if (projectUpdate.CompletionYear < projectUpdate.ImplementationStartYear) { return(new List <int>()); } if (projectUpdate.CompletionYear < projectUpdate.PlanningDesignStartYear) { return(new List <int>()); } return(FirmaDateUtilities.CalculateCalendarYearRangeForExpendituresAccountingForExistingYears(new List <int>(), projectUpdate, FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting())); }
private EditPerformanceMeasureActualsViewData(List <ProjectSimple> allProjects, List <Models.PerformanceMeasure> allPerformanceMeasures, Models.Project project, bool showExemptYears) { ShowExemptYears = showExemptYears; ProjectID = project.ProjectID; AllPerformanceMeasures = allPerformanceMeasures.SortByOrderThenName().Select(x => new PerformanceMeasureSimple(x)).ToList(); var performanceMeasureSubcategories = allPerformanceMeasures.SelectMany(x => x.PerformanceMeasureSubcategories).Distinct(new HavePrimaryKeyComparer <PerformanceMeasureSubcategory>()).ToList(); AllPerformanceMeasureSubcategories = performanceMeasureSubcategories.Select(x => new PerformanceMeasureSubcategorySimple(x)).ToList(); AllPerformanceMeasureSubcategoryOptions = performanceMeasureSubcategories.SelectMany(y => y.PerformanceMeasureSubcategoryOptions.Select(z => new PerformanceMeasureSubcategoryOptionSimple(z))).ToList(); AllProjects = allProjects; CalendarYearStrings = FirmaDateUtilities.ReportingYearsForUserInput().OrderByDescending(x => x.CalendarYear).ToList(); }
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)); }
public BasicsValidationResult(ProjectFirmaModels.Models.ProjectUpdate projectUpdate) { _warningMessages = new List <string>(); if (projectUpdate.PlanningDesignStartYear == null) { _warningMessages.Add(PlanningDesignStartYearIsRequired); } if (projectUpdate.ImplementationStartYear == null && projectUpdate.ProjectStage != ProjectStage.Terminated && projectUpdate.ProjectStage != ProjectStage.Deferred) { _warningMessages.Add(ImplementationStartYearIsRequired); } if ((projectUpdate.ProjectStage == ProjectStage.Completed || projectUpdate.ProjectStage == ProjectStage.PostImplementation) && projectUpdate.CompletionYear == null) { _warningMessages.Add(CompletionYearIsRequired); } if (GeneralUtility.IsNullOrEmptyOrOnlyWhitespace(projectUpdate.ProjectDescription)) { _warningMessages.Add(ProjectDescriptionIsRequired); } var currentYear = FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting(); if ((projectUpdate.ProjectStage == ProjectStage.Completed || projectUpdate.ProjectStage == ProjectStage.PostImplementation) && projectUpdate.CompletionYear > currentYear) { _warningMessages.Add(CompletionYearShouldBeLessThanCurrentYear); } if (projectUpdate.ProjectStage == ProjectStage.PlanningDesign && projectUpdate.PlanningDesignStartYear > currentYear) { _warningMessages.Add(PlanningDesignStartYearShouldBeLessThanCurrentYear); } if (projectUpdate.ProjectStage == ProjectStage.Implementation && projectUpdate.ImplementationStartYear > currentYear) { _warningMessages.Add(ImplementationStartYearShouldBeLessThanCurrentYear); } if (projectUpdate.ImplementationStartYear < projectUpdate.PlanningDesignStartYear) { _warningMessages.Add(FirmaValidationMessages.ImplementationStartYearGreaterThanPlanningDesignStartYear); } if (projectUpdate.CompletionYear < projectUpdate.ImplementationStartYear) { _warningMessages.Add(FirmaValidationMessages.CompletionYearGreaterThanEqualToImplementationStartYear); } if (projectUpdate.CompletionYear < projectUpdate.PlanningDesignStartYear) { _warningMessages.Add(FirmaValidationMessages.CompletionYearGreaterThanEqualToPlanningDesignStartYear); } }
public ViewDataForAngularClass(ProjectUpdateBatch projectUpdateBatch, List <FundingSourceSimple> allFundingSources, List <CostTypeSimple> allCostTypes, List <int> requiredCalendarYearRange, IEnumerable <SelectListItem> fundingTypes) { RequiredCalendarYearRange = requiredCalendarYearRange; AllFundingSources = allFundingSources; AllCostTypes = allCostTypes; ProjectID = projectUpdateBatch.ProjectID; ProjectUpdateBatchID = projectUpdateBatch.ProjectUpdateBatchID; FundingTypes = fundingTypes; MaxYear = FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting(); }
public void ProjectUpdateYearRangesTest() { var projectUpdate = TestFramework.TestProjectUpdate.Create(); projectUpdate.ProjectStageID = ProjectStage.Completed.ProjectStageID; var warningMessages = new BasicsValidationResult(projectUpdate).GetWarningMessages(); Assert.That(warningMessages.Contains(BasicsValidationResult.PlanningDesignStartYearIsRequired)); Assert.That(warningMessages.Contains(BasicsValidationResult.ImplementationStartYearIsRequired)); Assert.That(warningMessages.Contains(BasicsValidationResult.CompletionYearIsRequired)); projectUpdate.CompletionYear = 2007; warningMessages = new BasicsValidationResult(projectUpdate).GetWarningMessages(); Assert.That(warningMessages.Contains(BasicsValidationResult.PlanningDesignStartYearIsRequired)); Assert.That(warningMessages.Contains(BasicsValidationResult.ImplementationStartYearIsRequired)); Assert.That(!warningMessages.Contains(BasicsValidationResult.CompletionYearIsRequired)); projectUpdate.ImplementationStartYear = 2010; warningMessages = new BasicsValidationResult(projectUpdate).GetWarningMessages(); Assert.That(warningMessages.Contains(BasicsValidationResult.PlanningDesignStartYearIsRequired)); Assert.That(!warningMessages.Contains(BasicsValidationResult.ImplementationStartYearIsRequired)); Assert.That(!warningMessages.Contains(BasicsValidationResult.CompletionYearIsRequired)); Assert.That(warningMessages.Contains(FirmaValidationMessages.CompletionYearGreaterThanEqualToImplementationStartYear)); projectUpdate.ImplementationStartYear = 2006; warningMessages = new BasicsValidationResult(projectUpdate).GetWarningMessages(); Assert.That(!warningMessages.Contains(FirmaValidationMessages.CompletionYearGreaterThanEqualToImplementationStartYear)); // This should always be the next calendar year, I believe -- SLG 1/2/2020 (writing after this test started crashing) int nextCalendarYear = FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting() + 1; projectUpdate.ProjectStageID = ProjectStage.PlanningDesign.ProjectStageID; projectUpdate.PlanningDesignStartYear = nextCalendarYear; warningMessages = new BasicsValidationResult(projectUpdate).GetWarningMessages(); Assert.That(!warningMessages.Contains(BasicsValidationResult.PlanningDesignStartYearIsRequired)); Assert.That(warningMessages.Contains(BasicsValidationResult.PlanningDesignStartYearShouldBeLessThanCurrentYear)); Assert.That(warningMessages.Contains(FirmaValidationMessages.ImplementationStartYearGreaterThanPlanningDesignStartYear)); projectUpdate.ProjectStageID = ProjectStage.Implementation.ProjectStageID; projectUpdate.ImplementationStartYear = nextCalendarYear; warningMessages = new BasicsValidationResult(projectUpdate).GetWarningMessages(); Assert.That(warningMessages.Contains(BasicsValidationResult.ImplementationStartYearShouldBeLessThanCurrentYear)); }
public static List <int> CalculateCalendarYearRangeForExpenditures(this IList <ProjectGrantAllocationExpenditureUpdate> projectGrantAllocationExpenditureUpdates, ProjectUpdate projectUpdate) { if (projectUpdate.GetCompletionYear() < projectUpdate.GetImplementationStartYear()) { return(new List <int>()); } if (projectUpdate.GetCompletionYear() < projectUpdate.PlannedDate.GetValueOrDefault().Year) { return(new List <int>()); } var existingYears = projectGrantAllocationExpenditureUpdates.Select(x => x.CalendarYear).ToList(); return(FirmaDateUtilities.CalculateCalendarYearRangeForExpendituresAccountingForExistingYears(existingYears, projectUpdate, FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting())); }
public static List <int> CalculateCalendarYearRangeForExpenditures(this IList <ProjectFundingSourceExpenditureUpdate> projectFundingSourceExpenditureUpdates, ProjectUpdate projectUpdate) { if (projectUpdate.CompletionYear < projectUpdate.ImplementationStartYear) { return(new List <int>()); } if (projectUpdate.CompletionYear < projectUpdate.PlanningDesignStartYear) { return(new List <int>()); } var existingYears = projectFundingSourceExpenditureUpdates.Select(x => x.CalendarYear).ToList(); return(FirmaDateUtilities.CalculateCalendarYearRangeForExpendituresAccountingForExistingYears(existingYears, projectUpdate, FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting())); }
public List <PerformanceMeasureSubcategoriesTotalReportedValue> SubcategoriesTotalReportedValues(Person currentPerson) { var groupByProjectAndSubcategory = GetReportedPerformanceMeasureValues(currentPerson) .Where(x => FirmaDateUtilities.DateIsInReportingRange(x.CalendarYear)) .GroupBy(x => new { x.Project, x.PerformanceMeasureSubcategoriesAsString }) .ToList(); return (groupByProjectAndSubcategory.Select( reportedValuesGroup => new PerformanceMeasureSubcategoriesTotalReportedValue(reportedValuesGroup.Key.Project, reportedValuesGroup.First().PerformanceMeasureSubcategoryOptions, this, reportedValuesGroup.Sum(x => x.ReportedValue))).ToList()); }
public decimal?CalculateWeightedTotalExpenditure() { var reportedValuesForAllSubcategories = PerformanceMeasure.GetReportedPerformanceMeasureValues(Project) .Where(x => FirmaDateUtilities.DateIsInReportingRange(x.CalendarYear)) .Sum(x => x.ReportedValue ?? 0); if (Math.Abs(reportedValuesForAllSubcategories) < double.Epsilon) { return(null); } var projectGrantAllocationExpenditures = Project.ProjectGrantAllocationExpenditures.Where(x => FirmaDateUtilities.DateIsInReportingRange(x.CalendarYear)).ToList(); var weight = TotalReportedValue / reportedValuesForAllSubcategories; return(projectGrantAllocationExpenditures.Sum(x => x.ExpenditureAmount) * Convert.ToDecimal(weight)); }
public static List <PerformanceMeasureSubcategoriesTotalReportedValue> SubcategoriesTotalReportedValues(FirmaSession currentFirmaSession, PerformanceMeasure performanceMeasure) { var groupByProjectAndSubcategory = performanceMeasure.GetReportedPerformanceMeasureValues(currentFirmaSession) .Where(x => FirmaDateUtilities.DateIsInReportingRange(x.CalendarYear)) .GroupBy(x => new { x.Project, PerformanceMeasureSubcategoriesAsString = x.GetPerformanceMeasureSubcategoriesAsString() }) .ToList(); return (groupByProjectAndSubcategory.Select( reportedValuesGroup => new PerformanceMeasureSubcategoriesTotalReportedValue(reportedValuesGroup.Key.Project, reportedValuesGroup.First().GetPerformanceMeasureSubcategoryOptions(), performanceMeasure, reportedValuesGroup.Sum(x => x.GetReportedValue()))).ToList()); }
public ProjectTimelineUpdateEvent(ProjectUpdateBatch projectUpdateBatch) { var approvedProjectUpdateHistory = projectUpdateBatch.ProjectUpdateHistories.First(x => x.ProjectUpdateState == ProjectUpdateState.Approved); Date = approvedProjectUpdateHistory.TransitionDate; DateDisplay = Date.ToString("MMM dd, yyyy"); FiscalYear = FirmaDateUtilities.CalculateFiscalYearForTenant(Date); Quarter = (Quarter)FirmaDateUtilities.CalculateQuarterForTenant(Date); ProjectTimelineEventType = ProjectTimelineEventType.Update; TimelineEventTypeDisplayName = "Update"; TimelineEventPersonDisplayName = approvedProjectUpdateHistory.UpdatePerson.GetPersonDisplayNameWithContactTypesListForProject(projectUpdateBatch.Project); ProjectTimelineSide = ProjectTimelineSide.Left; EditButton = new HtmlString(string.Empty); DeleteButton = new HtmlString(string.Empty); ShowDetailsLinkHtmlString = ProjectTimeline.MakeProjectUpdateDetailsLinkButton(projectUpdateBatch); }
public EditProjectFundingSourceBudgetByCostTypeViewDataForAngular(ProjectFirmaModels.Models.ProjectUpdateBatch projectUpdateBatch, List <FundingSourceSimple> allFundingSources, List <CostTypeSimple> allCostTypes, List <int> requiredCalendarYearRange, IEnumerable <SelectListItem> fundingTypes) { RequiredCalendarYearRange = requiredCalendarYearRange; AllFundingSources = allFundingSources; AllCostTypes = allCostTypes; ProjectID = projectUpdateBatch.ProjectID; FundingTypes = fundingTypes; MaxYear = FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting(); UseFiscalYears = MultiTenantHelpers.UseFiscalYears(); ObligationItemBudgetRollUps = projectUpdateBatch.Project.GetObligationItemBudgetRollUpByYearAndCostTypeAndFundingSourceSimples(); ObligationItemInvoiceRollUps = projectUpdateBatch.Project.GetObligationItemInvoiceRollUpByYearAndCostTypeAndFundingSourceSimples(); }
public IEnumerable <ValidationResult> Validate(ValidationContext validationContext) { if (ImplementationStartYear < PlanningDesignStartYear) { yield return(new SitkaValidationResult <BasicsViewModel, int?>( FirmaValidationMessages.ImplementationStartYearGreaterThanPlanningDesignStartYear, m => m.ImplementationStartYear)); } if (CompletionYear < ImplementationStartYear) { yield return(new SitkaValidationResult <BasicsViewModel, int?>( FirmaValidationMessages.CompletionYearGreaterThanEqualToImplementationStartYear, m => m.CompletionYear)); } if (ProjectStageID == ProjectStage.Completed.ProjectStageID && !CompletionYear.HasValue) { yield return(new SitkaValidationResult <BasicsViewModel, int?>($"Since the {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} is in the Completed stage, the Completion year is required", m => m.CompletionYear)); } if (ProjectStageID == ProjectStage.PostImplementation.ProjectStageID && !CompletionYear.HasValue) { yield return(new SitkaValidationResult <BasicsViewModel, int?>($"Since the {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} is in the Post-Implementation stage, the Completion year is required", m => m.CompletionYear)); } var isCompletedOrPostImplementation = ProjectStageID == ProjectStage.Completed.ProjectStageID || ProjectStageID == ProjectStage.PostImplementation.ProjectStageID; var currentYear = FirmaDateUtilities.CalculateCurrentYearToUseForUpToAllowableInputInReporting(); if (isCompletedOrPostImplementation && CompletionYear > currentYear) { yield return(new SitkaValidationResult <BasicsViewModel, int?>( $"The {FieldDefinitionEnum.Project.ToType().GetFieldDefinitionLabel()} is in Completed or Post-Implementation stage; the Completion Year must be less than or equal to the current year", m => m.CompletionYear)); } if (!string.IsNullOrEmpty(BpaProjectNumber)) { var regexMatch = Regex.Match(BpaProjectNumber, "^" + ProjectModelExtensions.BpaProjectNumberRegexString); if (!regexMatch.Success) { yield return(new SitkaValidationResult <BasicsViewModel, string>( $"You must enter a valid {FieldDefinitionEnum.BpaProjectNumber.ToType().GetFieldDefinitionLabel()} (e.g. XXXX-XXX-XX).", m => m.BpaProjectNumber)); } } }
public ProjectTimelineProjectStatusChangeEvent(ProjectProjectStatus projectProjectStatus, bool canEditProjectProjectStatus, bool canEditFinalStatusReport) { Date = projectProjectStatus.ProjectProjectStatusUpdateDate; DateDisplay = Date.ToString("MMM dd, yyyy"); FiscalYear = FirmaDateUtilities.CalculateFiscalYearForTenant(Date); Quarter = (Quarter)FirmaDateUtilities.CalculateQuarterForTenant(Date); ProjectTimelineEventType = ProjectTimelineEventType.ProjectStatusChange; TimelineEventTypeDisplayName = projectProjectStatus.IsFinalStatusUpdate ? "Final Status Update" : "Status Updated"; TimelineEventPersonDisplayName = projectProjectStatus.ProjectProjectStatusCreatePerson.GetPersonDisplayNameWithContactTypesListForProject(projectProjectStatus.Project); ProjectTimelineSide = ProjectTimelineSide.Right; EditButton = ProjectTimeline.MakeProjectStatusEditLinkButton(projectProjectStatus, canEditProjectProjectStatus, canEditFinalStatusReport); DeleteButton = ProjectTimeline.MakeProjectStatusDeleteLinkButton(projectProjectStatus, canEditProjectProjectStatus, canEditFinalStatusReport); Color = projectProjectStatus.ProjectStatus.ProjectStatusColor; ShowDetailsLinkHtmlString = ProjectTimeline.MakeProjectStatusDetailsLinkButton(projectProjectStatus); ProjectProjectStatus = projectProjectStatus; }