Skip to content

Commit

Permalink
feat: add endpoints to support the SVAP Power BI report
Browse files Browse the repository at this point in the history
OCD-4717
  • Loading branch information
tmy1313 committed Jan 29, 2025
1 parent 6703fdb commit 44464e4
Show file tree
Hide file tree
Showing 9 changed files with 375 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package gov.healthit.chpl.web.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import gov.healthit.chpl.report.ReportDataManager;
import gov.healthit.chpl.report.common.CertificationCriterionWithOrder;
import gov.healthit.chpl.report.criteriaattribute.SvapListingReport;
import gov.healthit.chpl.report.svap.CriteriaWithAnySvap;
import gov.healthit.chpl.report.svap.CriteriaWithSvap;
import gov.healthit.chpl.util.SwaggerSecurityRequirement;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.log4j.Log4j2;

@Log4j2
@Tag(name = "report-data/svaps", description = "Allows retrieval of data used by SVAP report.")
@RestController
@RequestMapping("/report-data/svaps")
public class SvapReportController {

private ReportDataManager reportDataManager;

@Autowired
public SvapReportController(ReportDataManager reportDataManager) {
this.reportDataManager = reportDataManager;
}

@Operation(summary = "",
description = "",
security = {
@SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY)
})
@RequestMapping(value = "/criteria-with-any-svap-counts", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
public @ResponseBody List<CriteriaWithAnySvap> getCriteriaWithAnySvap() {
return reportDataManager.getSvapReportService().getCriteriaWithAnySvap();
}

@Operation(summary = "",
description = "",
security = {
@SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY)
})
@RequestMapping(value = "/criteria-with-svap-counts", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
public @ResponseBody List<CriteriaWithSvap> getTestToolReports() {
return reportDataManager.getSvapReportService().getCriteriaWithSvap();
}

@Operation(summary = "",
description = "",
security = {
@SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY)
})
@RequestMapping(value = "/listings", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
public @ResponseBody List<SvapListingReport> getSvapListingReports() {
return reportDataManager.getSvapReportService().getSvapListingReports();
}

@Operation(summary = "",
description = "",
security = {
@SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY)
})
@RequestMapping(value = "/criteria", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
public @ResponseBody List<CertificationCriterionWithOrder> getCertificationCriteria() {
return reportDataManager.getSvapReportService().getCertificationCriteria();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,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.report.svap.SvapReportService;
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;
Expand All @@ -47,6 +48,7 @@ public class ReportDataManager {
private ReportMetadataDAO reportMetadataDAO;
private CriteriaAttributeReportService criteriaAttributeReportService;
private ServiceBaseUrlListReportService serviceBaseUrlListReportService;
private SvapReportService svapReportService;


@Autowired
Expand All @@ -59,7 +61,8 @@ public ReportDataManager(CriteriaMigrationReportService criteriaMigrationReportS
AttestationReportService attestationReportService,
ReportMetadataDAO reportMetadataDAO,
CriteriaAttributeReportService criteriaAttributeReportService,
ServiceBaseUrlListReportService serviceBaseUrlListReportService) {
ServiceBaseUrlListReportService serviceBaseUrlListReportService,
SvapReportService svapReportService) {
this.criteriaMigrationReportService = criteriaMigrationReportService;
this.developerReportsService = developerReportsService;
this.surveillanceReportsService = surveillanceReportsService;
Expand All @@ -71,6 +74,7 @@ public ReportDataManager(CriteriaMigrationReportService criteriaMigrationReportS
this.reportMetadataDAO = reportMetadataDAO;
this.criteriaAttributeReportService = criteriaAttributeReportService;
this.serviceBaseUrlListReportService = serviceBaseUrlListReportService;
this.svapReportService = svapReportService;
}

public List<ReportMetadata> getReportMetadataByReportGroup(String reportGroup) {
Expand Down Expand Up @@ -263,4 +267,10 @@ public List<AttestationReport> getAttestationReports() {
return attestationReportService.getAttestationReports();
}

@Synchronized("lock")
public SvapReportService getSvapReportService() {
return svapReportService;
}


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

import gov.healthit.chpl.certificationCriteria.CertificationCriterion;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.SuperBuilder;

@SuperBuilder
@Data
@EqualsAndHashCode(callSuper = false)
public class CertificationCriterionWithOrder extends CertificationCriterion {
private static final long serialVersionUID = -859127653800126456L;

private Long order;

public CertificationCriterionWithOrder(CertificationCriterion cc) {
this.setId(cc.getId());
this.setNumber(cc.getNumber());
this.setTitle(cc.getTitle());
this.setDescription(cc.getDescription());
this.setCertificationEdition(cc.getCertificationEdition());
this.setCertificationEditionId(cc.getCertificationEditionId());
this.setStartDay(cc.getStartDay());
this.setEndDay(cc.getEndDay());
this.setRule(cc.getRule());
this.setCompanionGuideLink(cc.getCompanionGuideLink());
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
package gov.healthit.chpl.report.criteriaattribute;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import gov.healthit.chpl.certificationCriteria.CertificationCriterion;
import gov.healthit.chpl.certificationCriteria.CertificationCriterionEntity;
import gov.healthit.chpl.dao.impl.BaseDAOImpl;
import gov.healthit.chpl.report.svap.CriteriaWithAnySvap;
import gov.healthit.chpl.report.svap.CriteriaWithSvap;
import gov.healthit.chpl.report.svap.CriterionCount;
import gov.healthit.chpl.service.CertificationCriterionService;
import gov.healthit.chpl.svap.entity.SvapEntity;
import jakarta.persistence.Query;
import lombok.extern.log4j.Log4j2;

@Log4j2
@Repository
public class SvapReportDao extends BaseDAOImpl {
private CertificationCriterionService certificationCriterionService;

@Autowired
public SvapReportDao(CertificationCriterionService certificationCriterionService) {
this.certificationCriterionService = certificationCriterionService;
}

public List<SvapReport> getSvapReports() {
String hql = "SELECT cc, s, count(*) as svapCount "
Expand Down Expand Up @@ -74,4 +89,120 @@ public List<SvapListingReport> getSvapListingReports() {
.toList();
}

public List<CriteriaWithAnySvap> getCriteriaWithAnySvap() {
String criteriaCountsWithSvapHql = "SELECT cc, count(*) as criteriaCount "
+ "FROM CertificationCriterionEntity cc, "
+ "CertificationResultEntity cr, "
+ "CertifiedProductDetailsEntity cpd, "
+ "CertificationResultSvapEntity crs, "
+ "CertificationCriterionAttributeEntity cca "
+ "WHERE cc.id = cr.certificationCriterionId "
+ "AND cr.certifiedProductId = cpd.id "
+ "AND cr.id = crs.certificationResultId "
+ "AND cc.id = cca.criterion.id "
+ "AND cpd.certificationStatusId IN (1,6,7) "
+ "AND (cc.endDay is null OR cc.endDay > CURRENT_DATE()) "
+ "AND cca.svap = true "
+ "AND cc.deleted = false "
+ "AND cr.deleted = false "
+ "AND crs.deleted = false "
+ "AND cpd.deleted = false "
+ "GROUP BY cc.id";

Query criteriaWithAnySvapCountsQuery = entityManager.createQuery(criteriaCountsWithSvapHql);
List<Object[]> criteriaWithAnySvapCountsResults = criteriaWithAnySvapCountsQuery.getResultList();

List<CriterionCount> criteriaWithAnySvapCounts = criteriaWithAnySvapCountsResults.stream()
.map(result -> CriterionCount.builder()
.criterion(((CertificationCriterionEntity) result[0]).toDomain())
.count((Long) result[1])
.build())
.toList();


String criteriaCountsHql = "SELECT cc, count(*) as criteriaCount "
+ "FROM CertificationCriterionEntity cc, "
+ "CertificationResultEntity cr, "
+ "CertifiedProductDetailsEntity cpd, "
+ "CertificationCriterionAttributeEntity cca "
+ "WHERE cc.id = cr.certificationCriterionId "
+ "AND cr.certifiedProductId = cpd.id "
+ "AND cc.id = cca.criterion.id "
+ "AND cpd.certificationStatusId IN (1,6,7) "
+ "AND (cc.endDay is null OR cc.endDay > CURRENT_DATE()) "
+ "AND cca.svap = true "
+ "AND cc.deleted = false "
+ "AND cr.deleted = false "
+ "AND cpd.deleted = false "
+ "GROUP BY cc.id";

Query criteriaCountsQuery = entityManager.createQuery(criteriaCountsHql);
List<Object[]> criteriaCountsResults = criteriaCountsQuery.getResultList();

List<CriterionCount> criteriaCounts = criteriaCountsResults.stream()
.map(result -> CriterionCount.builder()
.criterion(((CertificationCriterionEntity) result[0]).toDomain())
.count((Long) result[1])
.build())
.toList();


return criteriaCounts.stream()
.map(cc -> CriteriaWithAnySvap.builder()
.certificationCriterion(cc.getCriterion())
.activeListingCountAttestingToCriteria(cc.getCount())
.activeListingCountAttestingToCriteriaAndAnySvap(lookupCountByCriteria(criteriaWithAnySvapCounts, cc.getCriterion()))
.sortOrder(certificationCriterionService.getCertificationResultSortIndex(cc.getCriterion().getId()))
.build())
.peek(x -> LOGGER.info(x.toString()))
.toList();
}

public List<CriteriaWithSvap> getCriteriaWithSvap() {
String criteriaCountsWithSvapHql = "SELECT cc, s, count(*) as criteriaCount "
+ "FROM CertificationCriterionEntity cc, "
+ "CertificationResultEntity cr, "
+ "CertifiedProductDetailsEntity cpd, "
+ "CertificationResultSvapEntity crs, "
+ "SvapEntity s, "
+ "CertificationCriterionAttributeEntity cca "
+ "WHERE cc.id = cr.certificationCriterionId "
+ "AND cr.certifiedProductId = cpd.id "
+ "AND cr.id = crs.certificationResultId "
+ "AND cc.id = cca.criterion.id "
+ "AND crs.svapId = s.id "
+ "AND cpd.certificationStatusId IN (1,6,7) "
+ "AND (cc.endDay is null OR cc.endDay > CURRENT_DATE()) "
+ "AND cca.svap = true "
+ "AND cc.deleted = false "
+ "AND cr.deleted = false "
+ "AND crs.deleted = false "
+ "AND cpd.deleted = false "
+ "GROUP BY cc.id, s.id";

Query criteriaWithSvapCountsQuery = entityManager.createQuery(criteriaCountsWithSvapHql);
List<Object[]> criteriaWithSvapCountsResults = criteriaWithSvapCountsQuery.getResultList();

return criteriaWithSvapCountsResults.stream()
.map(result -> CriteriaWithSvap.builder()
.certificationCriterion(((CertificationCriterionEntity) result[0]).toDomain())
.svap(((SvapEntity) result[1]).toDomain())
.activeListingCountAttestingToSvap((Long) result[2])
.build())
.toList();
}


private Long lookupCountByCriteria(List<CriterionCount> criteriaCounts, CertificationCriterion criterion) {
Optional<CriterionCount> criterionCount = criteriaCounts.stream()
.filter(cc -> cc.getCriterion().getId().equals(criterion.getId()))
.findAny();

if (criterionCount.isPresent()) {
return criterionCount.get().getCount();
} else {
return 0L;
}
}

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

import gov.healthit.chpl.certificationCriteria.CertificationCriterion;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class CriteriaWithAnySvap {
private CertificationCriterion certificationCriterion;
private Long activeListingCountAttestingToCriteria;
private Long activeListingCountAttestingToCriteriaAndAnySvap;
private Integer sortOrder;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package gov.healthit.chpl.report.svap;

import gov.healthit.chpl.certificationCriteria.CertificationCriterion;
import gov.healthit.chpl.svap.domain.Svap;
import lombok.Builder;
import lombok.Data;

@Builder
@Data
public class CriteriaWithSvap {
private CertificationCriterion certificationCriterion;
private Svap svap;
private Long activeListingCountAttestingToSvap;
private Integer sortOrder;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package gov.healthit.chpl.report.svap;

import gov.healthit.chpl.certificationCriteria.CertificationCriterion;
import lombok.Builder;
import lombok.Data;

@Builder
@Data
public class CriterionCount {
private CertificationCriterion criterion;
private Long count;
}
Loading

0 comments on commit 44464e4

Please sign in to comment.