public static List <string> ValidateImpl(string explanation, List <int> expectedYears,
                                                 List <IFundingSourceExpenditure> projectFundingSourceExpenditures)
        {
            var errors = new List <string>();
            // Need to get FundingSources by IDs because we may have unsaved projectFundingSourceExpenditures that won't have a reference to the entity
            var fundingSourcesIDs = projectFundingSourceExpenditures.Select(x => x.FundingSourceID).Distinct().ToList();
            var fundingSources    =
                HttpRequestStorage.DatabaseEntities.FundingSources.Where(x => fundingSourcesIDs.Contains(x.FundingSourceID));

            var missingFundingSourceYears = new Dictionary <ProjectFirmaModels.Models.FundingSource, IEnumerable <int> >();

            foreach (var fundingSource in fundingSources)
            {
                var currentFundingSource = fundingSource;
                var missingYears         =
                    expectedYears
                    .GetMissingYears(projectFundingSourceExpenditures
                                     .Where(x => x.FundingSourceID == currentFundingSource.FundingSourceID)
                                     .Select(x => x.CalendarYear)).ToList();

                if (missingYears.Any())
                {
                    missingFundingSourceYears.Add(currentFundingSource, missingYears);
                }
            }

            foreach (var fundingSource in missingFundingSourceYears)
            {
                var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(fundingSource.Value));
                errors.Add($"Missing Expenditures for {FieldDefinitionEnum.FundingSource.ToType().GetFieldDefinitionLabel()} '{fundingSource.Key.GetDisplayName()}' for the following years: {string.Join(", ", yearsForErrorDisplay)}. If there are no expenditures to report, save the form with zeros.");
            }

            return(errors);
        }
        public static List <string> ValidateImpl(List <ProjectExemptReportingYearSimple> projectExemptReportingYearSimples,
                                                 string explanation,
                                                 List <int> expectedYears,
                                                 List <IGrantAllocationExpenditure> projectGrantAllocationExpenditures)
        {
            var errors = new List <string>();

            var grantAllocationsIDs = projectGrantAllocationExpenditures.Select(x => x.GrantAllocationID).Distinct().ToList();
            var grantAllocations    = HttpRequestStorage.DatabaseEntities.GrantAllocations.Where(x => grantAllocationsIDs.Contains(x.GrantAllocationID));

            // validation 1: ensure that we have expenditure values from ProjectUpdate start year to min(endyear, currentyear)
            if (projectExemptReportingYearSimples.Any(x => x.IsExempt) && string.IsNullOrWhiteSpace(explanation))
            {
                errors.Add(FirmaValidationMessages.ExplanationNecessaryForProjectExemptYears);
            }

            if (!projectExemptReportingYearSimples.Any(x => x.IsExempt) && !string.IsNullOrWhiteSpace(explanation))
            {
                errors.Add(FirmaValidationMessages.ExplanationNotNecessaryForProjectExemptYears);
            }

            var exemptReportingYears = projectExemptReportingYearSimples.Where(y => y.IsExempt).Select(y => y.CalendarYear).ToList();

            var everyYearIsExempt = exemptReportingYears.Count == expectedYears.Count;

            if (!everyYearIsExempt)
            {
                if (grantAllocations.Any())
                {
                    var missingGrantAllocationYears = new Dictionary <Models.GrantAllocation, IEnumerable <int> >();
                    foreach (var currentGrantAllocation in grantAllocations)
                    {
                        //Added check for 0 to prevent a user from submitting a 0 value with no comment
                        var yearsWithValues = projectGrantAllocationExpenditures
                                              .Where(x => x.GrantAllocationID == currentGrantAllocation.GrantAllocationID &&
                                                     x.ExpenditureAmount > 0)
                                              .Select(x => x.CalendarYear);
                        var missingYears =
                            expectedYears
                            .GetMissingYears(yearsWithValues).ToList()
                            .Where(year =>
                                   !exemptReportingYears.Contains(year)).ToList();

                        if (missingYears.Any())
                        {
                            missingGrantAllocationYears.Add(currentGrantAllocation, missingYears);
                        }
                    }

                    foreach (var grantAllocation in missingGrantAllocationYears)
                    {
                        var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(grantAllocation.Value));
                        errors.Add($"Missing Expenditures for {Models.FieldDefinition.GrantAllocation.GetFieldDefinitionLabel()} '{grantAllocation.Key.DisplayName}' for the following years: {string.Join(", ", yearsForErrorDisplay)}");
                    }
                }
            }


            // reported expenditures in exempt years - Added check for 0 to prevent a user from submitting a 0 value with no comment
            var yearsWithExpenditures = projectGrantAllocationExpenditures.Where(x => x.ExpenditureAmount > 0).GroupBy(x => x.GrantAllocationID);

            foreach (var grantAllocation in yearsWithExpenditures)
            {
                var exemptYearsWithReportedValues = grantAllocation
                                                    .Where(x => exemptReportingYears.Contains(x.CalendarYear)).Select(x => x.CalendarYear)
                                                    .ToList();
                if (exemptYearsWithReportedValues.Any())
                {
                    var grantAllocationName  = grantAllocations.SingleOrDefault(x => x.GrantAllocationID == grantAllocation.Key)?.GrantAllocationName;
                    var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(exemptYearsWithReportedValues));
                    errors.Add($"Grant Allocation {grantAllocationName} has reported values for the exempt years: {yearsForErrorDisplay}");
                }
            }

            return(errors);
        }
Example #3
0
        public static List <string> ValidateExpendituresByCostType(this ProjectUpdateBatch projectUpdateBatch)
        {
            if (!projectUpdateBatch.AreProjectBasicsValid())
            {
                return(new List <string> {
                    FirmaValidationMessages.UpdateSectionIsDependentUponBasicsSection
                });
            }

            if (projectUpdateBatch.ProjectUpdate.ProjectStage.RequiresReportedExpenditures() || projectUpdateBatch.ProjectUpdate.ProjectStage == ProjectStage.Completed)
            {
                // validation 1: ensure that we have expenditure values from ProjectUpdate start year to min(endyear, currentyear)
                var yearsExpected = projectUpdateBatch.ProjectUpdate.GetProjectUpdatePlanningDesignStartToCompletionYearRange();
                List <IFundingSourceExpenditure> projectFundingSourceExpenditures = new List <IFundingSourceExpenditure>(projectUpdateBatch.ProjectFundingSourceExpenditureUpdates);
                var errors = new List <string>();
                // Need to get FundingSources by IDs because we may have unsaved projectFundingSourceExpenditures that won't have a reference to the entity
                var fundingSourcesIDs = projectFundingSourceExpenditures.Select(x => x.FundingSourceID).Distinct().ToList();
                var fundingSources    =
                    HttpRequestStorage.DatabaseEntities.FundingSources.Where(x => fundingSourcesIDs.Contains(x.FundingSourceID));

                if (!projectFundingSourceExpenditures.Any())
                {
                    if (string.IsNullOrWhiteSpace(projectUpdateBatch.ExpendituresNote))
                    {
                        errors.Add(FirmaValidationMessages.ExplanationNecessaryForProjectExemptYears);
                    }
                }
                else
                {
                    if (!fundingSources.Any())
                    {
                        var yearsForErrorDisplay = string.Join(", ", FirmaHelpers.CalculateYearRanges(yearsExpected));
                        errors.Add($"Missing Expenditures for {string.Join(", ", yearsForErrorDisplay)}");
                    }
                    else
                    {
                        var missingFundingSourceYears =
                            new Dictionary <ProjectFirmaModels.Models.FundingSource, IEnumerable <int> >();
                        foreach (var fundingSource in fundingSources)
                        {
                            var currentFundingSource = fundingSource;
                            var missingYears         =
                                yearsExpected
                                .GetMissingYears(projectFundingSourceExpenditures
                                                 .Where(x => x.FundingSourceID == currentFundingSource.FundingSourceID)
                                                 .Select(x => x.CalendarYear)).ToList();

                            if (missingYears.Any())
                            {
                                missingFundingSourceYears.Add(currentFundingSource, missingYears);
                            }
                        }

                        foreach (var fundingSource in missingFundingSourceYears)
                        {
                            var yearsForErrorDisplay =
                                string.Join(", ", FirmaHelpers.CalculateYearRanges(fundingSource.Value));
                            errors.Add(
                                $"Missing Expenditures for {FieldDefinitionEnum.FundingSource.ToType().GetFieldDefinitionLabel()} '{fundingSource.Key.GetDisplayName()}' for the following years: {string.Join(", ", yearsForErrorDisplay)}");
                        }
                    }
                }

                return(errors);
            }
            return(new List <string>());
        }