public static Report CreateCdcReport( HedwigContext context, ReportingPeriod reportingPeriod = null, Organization organization = null, string submittedAt = null ) { reportingPeriod = reportingPeriod ?? ReportingPeriodHelper.CreateReportingPeriod(context, type: FundingSource.CDC); organization = organization ?? OrganizationHelper.CreateOrganization(context); var report = new CdcReport { ReportingPeriodId = reportingPeriod.Id, OrganizationId = organization.Id }; if (submittedAt != null) { report.SubmittedAt = DateTime.Parse(submittedAt); } context.Reports.Add(report); context.SaveChanges(); return(report); }
public List <Enrollment> GetEnrollmentsForReport(CdcReport report) { var sites = report.Organization != null && report.Organization.Sites != null ? report.Organization.Sites.ToList() : _context.Sites.Where(s => s.OrganizationId == report.OrganizationId).ToList(); var siteIds = sites.Select(site => site.Id); // Potential optimization to fetch only the enrollments that are funded during the reporting period var enrollments = (report.SubmittedAt.HasValue ? _context.Enrollments.AsOf(report.SubmittedAt.Value) : _context.Enrollments) .Where(enrollment => siteIds.Contains(enrollment.SiteId)) .ToList(); var enrollmentIds = enrollments.Select(enrollment => enrollment.Id); var fundings = (report.SubmittedAt.HasValue ? _context.Fundings.AsOf(report.SubmittedAt.Value) : _context.Fundings) .Include(funding => funding.FirstReportingPeriod) .Include(funding => funding.LastReportingPeriod) .Include(funding => funding.FundingSpace) .ThenInclude(fundingSpace => fundingSpace.TimeSplit) .Where(funding => enrollmentIds.Contains(funding.EnrollmentId)) .Where(funding => funding.FirstReportingPeriod.PeriodStart <= report.ReportingPeriod.PeriodStart) .Where(funding => funding.LastReportingPeriod == null || funding.LastReportingPeriod.PeriodEnd >= report.ReportingPeriod.PeriodEnd) .ToList(); // Add fundings to enrollments enrollments.ForEach(enrollment => { enrollment.Fundings = fundings.Where(funding => funding.EnrollmentId == enrollment.Id).ToList(); }); // Filter for funded enrollments (only funded enrollments are included in report) return(enrollments.Where(enrollment => enrollment.Fundings.Any(funding => funding.Source == report.Type)).ToList()); }
public void Execute_WithReportParentEntity_ReturnsError_IfEnrollmentFunded_AndDeterminationDateNotValid( bool enrollmentIsFunded, bool dateIsValid, bool doesError ) { // if var enrollment = new Enrollment { Fundings = new List <Funding>() }; if (enrollmentIsFunded) { enrollment.Fundings.Add(new Funding { Source = FundingSource.CDC }); } var periodEnd = DateTime.Now.Date.AddDays(-10); var report = new CdcReport(); var reportingPeriod = new ReportingPeriod { PeriodEnd = periodEnd }; report.GetType().GetProperty(nameof(report.ReportingPeriod)).SetValue(report, reportingPeriod, null); var determination = new FamilyDetermination { // a valid date is < 1 year older than report reporting period end DeterminationDate = dateIsValid ? periodEnd.AddMonths(-8) : periodEnd.AddMonths(-18) }; // when var fundings = new Mock <IFundingRepository>(); var reportingPeriods = new Mock <IReportingPeriodRepository>(); var rule = new IfEnrollmentFunded_DeterminationDateValid(fundings.Object, reportingPeriods.Object); var context = new NonBlockingValidationContext(); context.AddParentEntity(enrollment); context.AddParentEntity(report); var result = rule.Execute(determination, context); // then Assert.Equal(doesError, result != null); }
public async Task <ActionResult <CdcReport> > Put( int id, int orgId, CdcReport report ) { if (report.Id != id) { return(BadRequest()); } if (report.OrganizationId != orgId) { return(BadRequest()); } if (report.ValidationErrors.Count > 0) { return(BadRequest("Report cannot be submitted with validation errors")); } try { // TODO what are the update rules for this field? // and should we put this somewhere besides the controller? if (report.SubmittedAt == null) { report.SubmittedAt = DateTime.UtcNow; } var reportDTO = _mapper.Map <CdcReport, CdcReportDTO>(report); _reports.UpdateReport(report, reportDTO); await _reports.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { return(NotFound()); } return(Ok(report)); }
public void Execute_ReturnsError_IfAnyEnrollmentIsNotValid( bool enrollmentsNotValid, bool doesError ) { // if var e1 = new Enrollment(); var e2 = new Enrollment(); var enrollments = new List <Enrollment> { e1, e2 }; var report = new CdcReport { Enrollments = enrollments }; var enrollmentRule = new Mock <IValidationRule <Enrollment> >(); var enrollmentResult = enrollmentsNotValid ? null : new ValidationError("message", field: "field"); enrollmentRule.Setup(er => er.Execute(e1, It.IsAny <NonBlockingValidationContext>())) .Returns(enrollmentResult); var _serviceProvider = new Mock <IServiceProvider>(); _serviceProvider.Setup(sp => sp.GetService(typeof(IEnumerable <IValidationRule <Enrollment> >))) .Returns(new List <IValidationRule <Enrollment> > { enrollmentRule.Object }); var _validator = new NonBlockingValidator(_serviceProvider.Object); var _reports = new Mock <IReportRepository>(); // when var rule = new EnrollmentsAreValid(_validator, _reports.Object); var result = rule.Execute(report, new NonBlockingValidationContext()); // Then Assert.Equal(doesError, result != null); }
public async Task Put_UpdatesReport_IfValid_AndExists( int pathId, int id, bool shouldNotFind, bool shouldUpdateReport, Type resultType ) { var _reports = new Mock <IReportRepository>(); if (shouldNotFind) { _reports.Setup(r => r.SaveChangesAsync()) .Throws(new DbUpdateConcurrencyException()); } var _mapper = new Mock <IMapper>(); _mapper.Setup(m => m.Map <CdcReport, CdcReportDTO>(It.IsAny <CdcReport>())) .Returns(It.IsAny <CdcReportDTO>()); var controller = new ReportsController(_reports.Object, _mapper.Object); var orgId = 1; var report = new CdcReport { Id = id, OrganizationId = orgId, ValidationErrors = new List <ValidationError>() }; var result = await controller.Put(pathId, orgId, report); var times = shouldUpdateReport ? Times.Once() : Times.Never(); _reports.Verify(r => r.UpdateReport(report, It.IsAny <CdcReportDTO>()), times); Assert.IsType(resultType, result.Result); }
private Report CreateCdcReport( int organizationId, int reportingPeriodId, string submittedAt = null, bool accredited = true, bool usedSplitTime = false, FundingSpace splitTimeFundingSpace = null ) { var report = new CdcReport { OrganizationId = organizationId, ReportingPeriodId = reportingPeriodId, Accredited = accredited }; if (usedSplitTime && splitTimeFundingSpace != null) { report.TimeSplitUtilizations = new List <FundingTimeSplitUtilization> { new FundingTimeSplitUtilization { FundingSpaceId = splitTimeFundingSpace.Id, ReportingPeriodId = reportingPeriodId, FullTimeWeeksUsed = 2, PartTimeWeeksUsed = 2, } }; } if (submittedAt != null) { report.SubmittedAt = DateTime.Parse(submittedAt); } _context.Reports.Add(report); _context.SaveChanges(); return(report); }
public async Task TryGenerateReports() { _logger.LogInformation("Starting CDC report generation task"); try { var lastReportingPeriod = _periods.GetLastReportingPeriodBeforeDate(FundingSource.CDC, _dateTime.UtcNow.Date); var createdReportsCount = 0; var organizations = _organizations.GetOrganizationsWithFundingSpaces(FundingSource.CDC); foreach (var organization in organizations) { // If report has not been created for last reporting period, create it if (!_reports.HasCdcReportForOrganizationAndReportingPeriod(organization.Id, lastReportingPeriod)) { var previousReport = _reports.GetMostRecentSubmittedCdcReportForOrganization(organization.Id); var report = new CdcReport { OrganizationId = organization.Id, ReportingPeriodId = lastReportingPeriod.Id, Accredited = previousReport != null && previousReport.Accredited, }; _reports.AddReport(report); createdReportsCount += 1; } } await _reports.SaveChangesAsync(); _logger.LogInformation($"Successfully created {createdReportsCount} reports for reporting period {lastReportingPeriod.Period.Date}"); } catch (Exception e) { // TODO: figure out how to alert on this when alerting exists _logger.LogError($"Unable to create reports", e); } }
public void IsValid_ReturnsValidationResult_IfWeeksUsedExceedsTotalAvailableWeeks_AndMultipleFundingSpaces( int fullTimeWeeksUsed, bool returnsValidationResult ) { // if var fundingSpaces = new List <FundingSpace> { new FundingSpace { Id = 1, OrganizationId = 1, AgeGroup = Age.InfantToddler, TimeSplit = new FundingTimeSplit { FullTimeWeeks = 10, PartTimeWeeks = 42 }, }, new FundingSpace { Id = 2, OrganizationId = 1, AgeGroup = Age.SchoolAge, TimeSplit = new FundingTimeSplit { FullTimeWeeks = 5, PartTimeWeeks = 47 }, }, new FundingSpace { Id = 3, OrganizationId = 1, AgeGroup = Age.Preschool, } }; var organization = new Organization { Id = 1, FundingSpaces = fundingSpaces, }; var timeSplitUtilizations = new List <FundingTimeSplitUtilization> { new FundingTimeSplitUtilization { FundingSpaceId = 1, FullTimeWeeksUsed = fullTimeWeeksUsed, PartTimeWeeksUsed = 0, }, new FundingTimeSplitUtilization { FundingSpaceId = 2, FullTimeWeeksUsed = fullTimeWeeksUsed, PartTimeWeeksUsed = 0, }, }; var report = new CdcReport { OrganizationId = organization.Id, TimeSplitUtilizations = timeSplitUtilizations, }; typeof(Report).GetProperty(nameof(Report.ReportingPeriod)).SetValue(report, new ReportingPeriod { Period = new DateTime(2010, 1, 1) }); var reports = new Mock <IReportRepository>(); reports.Setup(r => r.GetReportsForOrganizationByFiscalYear(It.IsAny <int>(), It.IsAny <DateTime>())) .Returns(new List <CdcReport> { report }); var organizations = new Mock <IOrganizationRepository>(); organizations.Setup(o => o.GetOrganizationWithFundingSpaces(It.IsAny <int>())) .Returns(organization); var serviceProvider = new Mock <IServiceProvider>(); serviceProvider.Setup(v => v.GetService(typeof(IReportRepository))) .Returns(reports.Object); serviceProvider.Setup(v => v.GetService(typeof(IOrganizationRepository))) .Returns(organizations.Object); var validationContext = new ValidationContext(report, serviceProvider.Object, new Dictionary <object, object>()); var attribute = new FundingTimeUtilizationsWeeksUsedDoNotExceedTotalAvailableWeeks(); // when var value = timeSplitUtilizations; var result = attribute.GetValidationResult(value, validationContext); // then Assert.Equal(returnsValidationResult, result != null); }
public void UpdateReport(CdcReport report, CdcReportDTO reportDTO) { UpdateHedwigIdEntityWithNavigationProperties <CdcReport, CdcReportDTO, int>(report, reportDTO); }
public void IsValid_ReturnsValidationResult_IfWeeksUsedExceedsWeeksInReportingPeriod( int fullTimeWeeksUsed, bool returnsValidationResult ) { // if var fundingSpaces = new List <FundingSpace> { new FundingSpace { Id = 1, OrganizationId = 1, AgeGroup = Age.InfantToddler, TimeSplit = new FundingTimeSplit { FullTimeWeeks = 10, PartTimeWeeks = 42 }, } }; var organization = new Organization { Id = 1, FundingSpaces = fundingSpaces, }; var timeSplitUtilizations = new List <FundingTimeSplitUtilization> { new FundingTimeSplitUtilization { FundingSpaceId = 1, FullTimeWeeksUsed = fullTimeWeeksUsed, PartTimeWeeksUsed = 0, }, }; var report = new CdcReport { OrganizationId = organization.Id, TimeSplitUtilizations = timeSplitUtilizations, }; typeof(Report).GetProperty(nameof(Report.ReportingPeriod)).SetValue(report, new ReportingPeriod { Period = new DateTime(2010, 1, 1), PeriodStart = new DateTime(2010, 1, 1), PeriodEnd = new DateTime(2010, 1, 31) }); var organizations = new Mock <IOrganizationRepository>(); organizations.Setup(o => o.GetOrganizationWithFundingSpaces(It.IsAny <int>())) .Returns(organization); var serviceProvider = new Mock <IServiceProvider>(); serviceProvider.Setup(v => v.GetService(typeof(IOrganizationRepository))) .Returns(organizations.Object); var validationContext = new ValidationContext(report, serviceProvider.Object, new Dictionary <object, object>()); var attribute = new FundingTimeUtilizationsWeeksUsedAreLessThanReportingPeriodWeeks(); // when var value = timeSplitUtilizations; var result = attribute.GetValidationResult(value, validationContext); // then Assert.Equal(returnsValidationResult, result != null); }
public async Task ReportControllerOrganizationsReportPut_IsSuccessfull_OrReturnsValidationError( int partTimeWeeksUsed, bool shouldSucceed ) { User user; Organization organization; FundingSpace fundingSpace; Site site; CdcReport report; using (var context = new TestHedwigContextProvider().Context) { organization = OrganizationHelper.CreateOrganization(context); var reportingPeriod = ReportingPeriodHelper.CreateReportingPeriod(context, period: "2010-01-01", periodStart: "2010-01-01", periodEnd: "2010-01-31"); fundingSpace = FundingSpaceHelper.CreateFundingSpace(context, organization.Id, time: FundingTime.Split); site = SiteHelper.CreateSite(context, organization: organization); report = ReportHelper.CreateCdcReport(context, organization: organization, reportingPeriod: reportingPeriod) as CdcReport; EnrollmentHelper.CreateEnrollment(context, site: site); user = UserHelper.CreateUser(context); PermissionHelper.CreateSitePermission(context, user, site); PermissionHelper.CreateOrganizationPermission(context, user, organization); } var timeSplitUtilization = new FundingTimeSplitUtilization { ReportId = report.Id, ReportingPeriodId = report.ReportingPeriodId, FundingSpaceId = fundingSpace.Id, PartTimeWeeksUsed = partTimeWeeksUsed, FullTimeWeeksUsed = 0, }; typeof(FundingTimeSplitUtilization).GetProperty(nameof(FundingTimeSplitUtilization.ReportingPeriod)).SetValue(timeSplitUtilization, report.ReportingPeriod); var reportForPut = new CdcReport { Id = report.Id, Accredited = report.Accredited, Comment = report.Comment, Enrollments = report.Enrollments, C4KRevenue = 0, FamilyFeesRevenue = 0, OrganizationId = report.OrganizationId, ReportingPeriodId = report.ReportingPeriodId, TimeSplitUtilizations = new List <FundingTimeSplitUtilization> { timeSplitUtilization }, }; typeof(Report).GetProperty(nameof(Report.ReportingPeriod)).SetValue(reportForPut, report.ReportingPeriod); var request = HedwigAPIRequests.OrganizationReportPut( user, organization, reportForPut ); var client = _factory.CreateClient(); var response = await client.SendAsync(request); if (shouldSucceed) { response.EnsureSuccessStatusCode(); } else { Assert.False(response.IsSuccessStatusCode); } }
public void UpdateReport(CdcReport report, CdcReportDTO reportDTO) { // Should this be _context.Update(report) as in EnrollmentRepository ? // depends on if we include sub-objets on report that should _not_ be updated UpdateHedwigIdEntityWithNavigationProperties <CdcReport, CdcReportDTO, int>(report, reportDTO); }