Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCD-4516 - Build "developer attestations" report in PowerBI #1750

Merged
merged 17 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import gov.healthit.chpl.report.surveillance.CapCounts;
import gov.healthit.chpl.report.surveillance.NonconformityCounts;
import gov.healthit.chpl.report.surveillance.SurveillanceActivityCounts;
import gov.healthit.chpl.scheduler.job.report.attestation.AttestationReport;
import gov.healthit.chpl.scheduler.job.summarystatistics.data.CertificationBodyStatistic;
import gov.healthit.chpl.search.domain.ListingSearchResult;
import gov.healthit.chpl.util.SwaggerSecurityRequirement;
Expand Down Expand Up @@ -451,4 +452,14 @@ public ReportDataController(ReportDataManager reportDataManager, DeveloperSearch
return reportDataManager.getDirectReviewCounts();
}

@Operation(summary = "Retrieves the data used to generate the Attestations report.",
description = "Retrieves the data used to generate the Attestations report.",
security = {
@SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY)
})
@RequestMapping(value = "/attestations", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
public @ResponseBody List<AttestationReport> getAttestationReports() {
return reportDataManager.getAttestationReports();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -475,4 +475,11 @@
<KeyValuePair key="dd.span_id" value="%X{dd.span_id}" />
</JsonLayout>
</Console>
<Console name="attestationReportCreatorJobJson" target="SYSTEM_OUT">
<JsonLayout compact="true" eventEol="true" properties="true" stacktraceAsString="true">
<KeyValuePair key="service" value="attestationReportCreatorJob" />
<KeyValuePair key="dd.trace_id" value="%X{dd.trace_id}" />
<KeyValuePair key="dd.span_id" value="%X{dd.span_id}" />
</JsonLayout>
</Console>
</Appenders>
Original file line number Diff line number Diff line change
Expand Up @@ -808,4 +808,16 @@
interval="1" modulate="true" />
</Policies>
</RollingFile>
<RollingFile name="attestationReportCreatorJob"
fileName="${logDir}/scheduler/attestationReportCreatorJob.log"
filePattern="${logDir}/scheduler/history/attestationReportCreatorJob-%d{yyyy-MM-dd}.log"
filePermissions="rw-rw-r--">
<PatternLayout>
<Pattern>%d{ISO8601} %-5p (%t) [%C{1}(%M:%L)] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy
interval="1" modulate="true" />
</Policies>
</RollingFile>
</Appenders>
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,7 @@
<Logger name="updatedSedFriendlyIdsJobLogger" level="INFO" additivity="false">
<AppenderRef ref="updatedSedFriendlyIdsJob" />
</Logger>
<Logger name="attestationReportCreatorJobLogger" level="INFO" additivity="false">
<AppenderRef ref="attestationReportCreatorJob" />
</Logger>
</Loggers>
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,8 @@
<AppenderRef ref="updatedSedFriendlyIdsJob" />
<AppenderRef ref="updatedSedFriendlyIdsJobJson" />
</Logger>
<Logger name="attestationReportCreatorJobLogger" level="INFO" additivity="false">
<AppenderRef ref="attestationReportCreatorJob" />
<AppenderRef ref="attestationReportCreatorJobJson" />
</Logger>
</Loggers>
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ apiCriteriaKeys=criterion.170_315_g_7,\

###### Attestations ######
attestationExceptionWindowInDays=5
attestationApprovalWindowInDays=30
####################################

###### Redis Connection Properties ######
Expand Down
9 changes: 9 additions & 0 deletions chpl/chpl-resources/src/main/resources/jobs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -921,5 +921,14 @@
<durability>true</durability>
<recover>false</recover>
</job>

Check warning on line 924 in chpl/chpl-resources/src/main/resources/jobs.xml

View workflow job for this annotation

GitHub Actions / Checkstyle job

[reviewdog] reported by reviewdog 🐶 Line has trailing spaces. Raw Output: /github/workspace/./chpl/chpl-resources/src/main/resources/jobs.xml:924:0: warning: Line has trailing spaces. (com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineCheck)
<job>
<name>attestationReportCreatorJob</name>
<group>systemJobs</group>
<description>Generate data for the Attestation Report (Power BI)</description>
<job-class>gov.healthit.chpl.scheduler.job.report.attestation.AttestationReportCreatorJob</job-class>
<durability>true</durability>
<recover>false</recover>
</job>
</schedule>
</job-scheduling-data>
10 changes: 10 additions & 0 deletions chpl/chpl-resources/src/main/resources/system-triggers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -245,5 +245,15 @@
<cron-expression>0 30 6 * * ?</cron-expression> <!-- At 0630 UTC every day -->
</cron>
</trigger>
<trigger>
<cron>
<name>attestationReportCreator</name>
<group>AttestationReportCreatorJobTrigger</group>
<job-name>attestationReportCreatorJob</job-name>
<job-group>systemJobs</job-group>
<misfire-instruction>MISFIRE_INSTRUCTION_DO_NOTHING</misfire-instruction>
<cron-expression>0 30 10 * * ?</cron-expression> <!-- At 1030 UTC every day -->
</cron>
</trigger>
</schedule>
</job-scheduling-data>
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package gov.healthit.chpl.changerequest.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Repository;
Expand Down Expand Up @@ -47,4 +50,26 @@ public List<Developer> getDevelopersForCertificationBody(Long certificationBodyI
.map(item -> item.getDeveloper().toDomain())
.collect(Collectors.<Developer>toList());
}

public Map<Long, List<CertificationBody>> getCertificationBodiesForAllDeveloper() {
String hql = "SELECT main "
+ "FROM DeveloperCertificationBodyMapEntity main "
+ "JOIN FETCH main.developer dev "
+ "JOIN FETCH main.certificationBody cb "
+ "LEFT JOIN FETCH cb.address ";

List<DeveloperCertificationBodyMapEntity> entities = entityManager
.createQuery(hql, DeveloperCertificationBodyMapEntity.class)
.getResultList();

Map<Long, List<CertificationBody>> map = new HashMap<Long, List<CertificationBody>>();

entities.forEach(e -> {
if (!map.containsKey(e.getDeveloperId())) {
map.put(e.getDeveloperId(), new ArrayList<CertificationBody>());
}
map.get(e.getDeveloperId()).add(e.getCertificationBody().toDomain());
});
return map;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -188,9 +187,10 @@ public ChangeRequest createChangeRequest(ChangeRequest changeRequest)
return saveChangeRequest(changeRequest);
}

@Transactional(readOnly = true)
@PostAuthorize("@permissions.hasAccess(T(gov.healthit.chpl.permissions.Permissions).CHANGE_REQUEST, "
+ "T(gov.healthit.chpl.permissions.domains.ChangeRequestDomainPermissions).GET_BY_ID, returnObject)")
// THIS MUST BE PUT BACK WHEN OCD-4737 GET TO STG
andlar marked this conversation as resolved.
Show resolved Hide resolved
//@Transactional(readOnly = true)
//@PostAuthorize("@permissions.hasAccess(T(gov.healthit.chpl.permissions.Permissions).CHANGE_REQUEST, "
// + "T(gov.healthit.chpl.permissions.domains.ChangeRequestDomainPermissions).GET_BY_ID, returnObject)")
public ChangeRequest getChangeRequest(Long changeRequestId) throws EntityRetrievalException {
return changeRequestDAO.get(changeRequestId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.stereotype.Component;

import gov.healthit.chpl.developer.search.DeveloperSearchResult;
import gov.healthit.chpl.report.attestation.AttestationReportService;
import gov.healthit.chpl.report.criteriaattribute.StandardListingReport;
import gov.healthit.chpl.report.criteriaattribute.StandardReport;
import gov.healthit.chpl.report.criteriaattribute.StandardReportService;
Expand All @@ -28,6 +29,7 @@
import gov.healthit.chpl.report.surveillance.NonconformityCounts;
import gov.healthit.chpl.report.surveillance.SurveillanceActivityCounts;
import gov.healthit.chpl.report.surveillance.SurveillanceReportsService;
import gov.healthit.chpl.scheduler.job.report.attestation.AttestationReport;
import gov.healthit.chpl.scheduler.job.summarystatistics.data.CertificationBodyStatistic;
import gov.healthit.chpl.search.domain.ListingSearchResult;
import lombok.Synchronized;
Expand All @@ -46,13 +48,14 @@ public class ReportDataManager {
private TestToolReportService testToolReportService;
private StandardReportService standardReportService;
private DirectReviewReportsService directReviewReportsService;
private AttestationReportService attestationReportService;
private ReportMetadataDAO reportMetadataDAO;

@Autowired
public ReportDataManager(CriteriaMigrationReportService criteriaMigrationReportService, DeveloperReportsService developerReportsService,
SurveillanceReportsService surveillanceReportsService, ProductReportsService productReportsService, ListingReportsService listingReportsService,
TestToolReportService testToolReportService, DirectReviewReportsService directReviewReportsService, ReportMetadataDAO reportMetadataDAO,
StandardReportService standardReportService) {
TestToolReportService testToolReportService, DirectReviewReportsService directReviewReportsService, AttestationReportService attestationReportService,
StandardReportService standardReportService, ReportMetadataDAO reportMetadataDAO) {
this.criteriaMigrationReportService = criteriaMigrationReportService;
this.developerReportsService = developerReportsService;
this.surveillanceReportsService = surveillanceReportsService;
Expand All @@ -61,6 +64,7 @@ public ReportDataManager(CriteriaMigrationReportService criteriaMigrationReportS
this.testToolReportService = testToolReportService;
this.standardReportService = standardReportService;
this.directReviewReportsService = directReviewReportsService;
this.attestationReportService = attestationReportService;
this.reportMetadataDAO = reportMetadataDAO;
}

Expand Down Expand Up @@ -258,4 +262,10 @@ public List<StandardListingReport> getStandardListingReports() {
public DirectReviewCounts getDirectReviewCounts() {
return directReviewReportsService.getDirectReviewCounts();
}

@Synchronized("lock")
public List<AttestationReport> getAttestationReports() {
return attestationReportService.getAttestationReports();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package gov.healthit.chpl.report.attestation;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import gov.healthit.chpl.attestation.manager.AttestationPeriodService;
import gov.healthit.chpl.scheduler.job.report.attestation.AttestationReport;
import gov.healthit.chpl.scheduler.job.report.attestation.AttestationReportDAO;

@Component
public class AttestationReportService {

private AttestationReportDAO attestationReportDAO;
private AttestationPeriodService attestationPeriodService;

@Autowired
public AttestationReportService(AttestationReportDAO attestationReportDAO, AttestationPeriodService attestationPeriodService) {
this.attestationReportDAO = attestationReportDAO;
this.attestationPeriodService = attestationPeriodService;
}

@Transactional
public List<AttestationReport> getAttestationReports() {
return attestationReportDAO.getAttestationReportByAttestationPeriod(
attestationPeriodService.getMostRecentPastAttestationPeriod());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package gov.healthit.chpl.scheduler.job.report.attestation;

import java.time.LocalDate;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import gov.healthit.chpl.attestation.domain.AttestationPeriod;
import gov.healthit.chpl.domain.CertificationBody;
import gov.healthit.chpl.util.LocalDateDeserializer;
import gov.healthit.chpl.util.LocalDateSerializer;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class AttestationReport {
private Long id;

@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate reportDate;

private CertificationBody certificationBody;
private AttestationPeriod attestationPeriod;

@Builder.Default
private Long developerCount = 0L;

@Builder.Default
private Long approvedCount = 0L;

@Builder.Default
private Long pendingAcbActionCount = 0L;

@Builder.Default
private Long pendingDeveloperActionCount = 0L;

@Builder.Default
private Long noSubmissionCount = 0L;
}
Loading
Loading