Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 @@ -21,6 +21,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.report.surveillance.SurveillanceByDeveloper;
import gov.healthit.chpl.scheduler.job.summarystatistics.data.CertificationBodyStatistic;
import gov.healthit.chpl.search.domain.ListingSearchResult;
import gov.healthit.chpl.util.LogMethodUsage;
Expand Down Expand Up @@ -59,6 +60,17 @@ public ReportDataController(ReportDataManager reportDataManager,
return reportDataManager.getHti1CriteriaMigrationReport();
}

@Operation(summary = "Retrieves the data about each surveillance including the related developer.",
description = "Retrieves the data about each surveillance including the related developer.",
security = {
@SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY)
})
@LogMethodUsage
@RequestMapping(value = "/surveillance-by-developer", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
public @ResponseBody List<SurveillanceByDeveloper> getSurveillanceOpenDuringTheLastYearForActiveDevelopers() {
return reportDataManager.getSurveillanceOpenDuringTheLastYearForActiveDevelopers();
}

@Operation(summary = "Retrieves the data used to generate the Surveillance Activity Counts report.",
description = "Retrieves the data used to generate the Surveillance Activity Counts report.",
security = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;

Expand All @@ -27,8 +29,11 @@
import gov.healthit.chpl.domain.surveillance.SurveillanceRequirement;
import gov.healthit.chpl.domain.surveillance.SurveillanceResultType;
import gov.healthit.chpl.domain.surveillance.SurveillanceType;
import gov.healthit.chpl.entity.developer.DeveloperSearchResultEntity;
import gov.healthit.chpl.exception.EntityRetrievalException;
import gov.healthit.chpl.exception.UserPermissionRetrievalException;
import gov.healthit.chpl.report.surveillance.SurveillanceByDeveloper;
import gov.healthit.chpl.search.entity.ListingSearchEntity;
import gov.healthit.chpl.util.NullSafeEvaluator;
import jakarta.persistence.Query;
import lombok.extern.log4j.Log4j2;
Expand All @@ -47,6 +52,17 @@ public class SurveillanceDAO extends BaseDAOImpl {
+ "LEFT OUTER JOIN FETCH ncs.type nct "
+ "WHERE surv.deleted <> true ";

private String unformattedListingDetailsUrl;
private String unformattedDeveloperDetailsUrl;

@Autowired
public SurveillanceDAO(@Value("${chplUrlBegin}") String chplUrlBegin,
@Value("${developerUrlPart}") String developerUrlPart,
@Value("${listingDetailsUrlPart}") String listingDetailsUrlPart) {
this.unformattedDeveloperDetailsUrl = chplUrlBegin + developerUrlPart;
this.unformattedListingDetailsUrl = chplUrlBegin + listingDetailsUrlPart;
}

public Long insertSurveillance(Long certifiedProductId, Surveillance surv) throws UserPermissionRetrievalException {
SurveillanceEntity toInsert = new SurveillanceEntity();
populateSurveillanceEntity(certifiedProductId, toInsert, surv);
Expand Down Expand Up @@ -268,7 +284,6 @@ public Long updateSurveillance(Long certifiedProductId, Surveillance updatedSurv
return updatedSurveillance.getId();
}


public SurveillanceEntity getSurveillanceByCertifiedProductAndFriendlyId(Long certifiedProductId,
String survFriendlyId) {
Query query = entityManager.createQuery(
Expand All @@ -287,7 +302,6 @@ public SurveillanceEntity getSurveillanceByCertifiedProductAndFriendlyId(Long ce
return null;
}


public SurveillanceEntity getSurveillanceById(Long id) throws EntityRetrievalException {
SurveillanceEntity result = fetchSurveillanceById(id);
return result;
Expand All @@ -310,23 +324,6 @@ public SurveillanceEntity getSurveillanceByNonconformityId(Long nonconformityId)
}
}

public SurveillanceEntity getSurveillanceByDocumentId(Long documentId)
throws EntityRetrievalException {
entityManager.clear();
Query query = entityManager.createQuery(SURVEILLANCE_FULL_HQL
+ "AND docs.id = :entityid",
SurveillanceEntity.class);
query.setParameter("entityid", documentId);

List<SurveillanceEntity> results = query.getResultList();
if (results == null || results.size() == 0) {
String msg = msgUtil.getMessage("surveillance.notFound");
throw new EntityRetrievalException(msg);
} else {
return results.get(0);
}
}

public List<SurveillanceEntity> getSurveillanceByCertifiedProductId(Long id) {
entityManager.clear();
Query query = entityManager.createQuery(SURVEILLANCE_FULL_HQL
Expand All @@ -338,6 +335,39 @@ public List<SurveillanceEntity> getSurveillanceByCertifiedProductId(Long id) {
return results;
}

public List<SurveillanceByDeveloper> getSurveillanceOpenDuringTheLastYearForActiveDevelopers() {
Query query = entityManager.createQuery("SELECT DISTINCT surv, listing, developer "
+ "FROM SurveillanceEntity surv, ListingSearchEntity listing, DeveloperSearchResultEntity developer "
+ "WHERE (surv.endDate IS NULL OR surv.endDate >= :oneYearAgo) "
+ "AND surv.certifiedProductId = listing.id "
+ "AND listing.developerId = developer.id "
+ "AND developer.currentActiveListingCount > 0 "
+ "AND surv.deleted <> true ");

List<SurveillanceByDeveloper> results = new ArrayList<SurveillanceByDeveloper>();
List<Object[]> entities = query
.setParameter("oneYearAgo", LocalDate.now().minusYears(1))
.getResultList();
for (Object[] entity : entities) {
SurveillanceEntity surveillance = (SurveillanceEntity) entity[0];
ListingSearchEntity listing = (ListingSearchEntity) entity[1];
DeveloperSearchResultEntity developer = (DeveloperSearchResultEntity) entity[2];
results.add(SurveillanceByDeveloper.builder()
.developerId(developer.getId())
.developerName(developer.getDeveloperName())
.developerDetailsUrl(String.format(unformattedDeveloperDetailsUrl, developer.getId() + ""))
.developerHasActiveListings(developer.getCurrentActiveListingCount() > 0)
.listingId(listing.getId())
.chplProductNumber(listing.getChplProductNumber())
.listingDetailsUrl(String.format(unformattedListingDetailsUrl, listing.getId() + ""))
.surveillanceId(surveillance.getId())
.surveillanceStartDate(surveillance.getStartDate())
.surveillanceEndDate(surveillance.getEndDate())
.build());
}
return results;

}

public void deleteSurveillance(Surveillance surv) throws EntityRetrievalException {
LOGGER.debug("Looking for surveillance with id " + surv.getId() + " to delete.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,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.report.surveillance.SurveillanceByDeveloper;
import gov.healthit.chpl.report.surveillance.SurveillanceReportsService;
import gov.healthit.chpl.report.svap.SvapReportService;
import gov.healthit.chpl.scheduler.job.summarystatistics.data.CertificationBodyStatistic;
Expand Down Expand Up @@ -112,6 +113,11 @@ public List<CriteriaMigrationReportDenormalized> getHti1CriteriaMigrationReport(
return criteriaMigrationReportService.getHtiReportData(CriteriaMigrationReportService.HTI1_REPORT_ID);
}

@Synchronized("lock")
public List<SurveillanceByDeveloper> getSurveillanceOpenDuringTheLastYearForActiveDevelopers() {
return surveillanceReportsService.getSurveillanceOpenDuringTheLastYearForActiveDevelopers();
}

@Synchronized("lock")
public SurveillanceActivityCounts getSurveillanceActivityCounts() {
return surveillanceReportsService.getSurveiilanceActivityCounts();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package gov.healthit.chpl.report.surveillance;

import java.time.LocalDate;

import gov.healthit.chpl.util.LocalDateDeserializer;
import gov.healthit.chpl.util.LocalDateSerializer;
import lombok.Builder;
import lombok.Data;
import tools.jackson.databind.annotation.JsonDeserialize;
import tools.jackson.databind.annotation.JsonSerialize;

@Data
@Builder
public class SurveillanceByDeveloper {
private Long developerId;
private String developerName;
private String developerDetailsUrl;
private boolean developerHasActiveListings;
private Long listingId;
private String chplProductNumber;
private String listingDetailsUrl;

private Long surveillanceId;

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

@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate surveillanceEndDate;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import gov.healthit.chpl.compliance.surveillance.SurveillanceDAO;
import gov.healthit.chpl.dao.statistics.SummaryStatisticsDAO;
import gov.healthit.chpl.entity.CertificationStatusType;
import gov.healthit.chpl.exception.ValidationException;
Expand All @@ -19,18 +20,29 @@
import gov.healthit.chpl.search.domain.ListingSearchResult;
import gov.healthit.chpl.search.domain.NonConformitySearchOptions;
import gov.healthit.chpl.search.domain.SearchRequest;
import jakarta.transaction.Transactional;
import lombok.extern.log4j.Log4j2;

@Log4j2
@Component
public class SurveillanceReportsService extends SummaryStatisticsReportBaseService {

private ListingSearchService listingSearchService;
private SurveillanceDAO surveillanceDao;

@Autowired
public SurveillanceReportsService(SummaryStatisticsDAO summaryStatisticsDAO, ListingSearchService listingSearchService, CertificationBodyManager certificationBodyManager) {
public SurveillanceReportsService(SummaryStatisticsDAO summaryStatisticsDAO,
ListingSearchService listingSearchService,
CertificationBodyManager certificationBodyManager,
SurveillanceDAO surveillanceDao) {
super(summaryStatisticsDAO, certificationBodyManager);
this.listingSearchService = listingSearchService;
this.surveillanceDao = surveillanceDao;
}

@Transactional
public List<SurveillanceByDeveloper> getSurveillanceOpenDuringTheLastYearForActiveDevelopers() {
return surveillanceDao.getSurveillanceOpenDuringTheLastYearForActiveDevelopers();
}

public SurveillanceActivityCounts getSurveiilanceActivityCounts() {
Expand Down
Loading