From 3f4a0a8e0ada716dbc20fc9dc1d2cc9d27b2a6eb Mon Sep 17 00:00:00 2001 From: Katy Ekey Date: Tue, 19 May 2026 11:08:10 -0400 Subject: [PATCH] feat!: Add endpoints & response fields for updated criteria status rept [#OCD-5294] [#OCD-5268] --- .../CriteriaUpToDateReportController.java | 2 +- .../web/controller/ReportDataController.java | 6 +---- .../CertificationCriteriaManager.java | 24 +++++++++++++------ .../CertificationCriterion.java | 4 ++-- .../CertificationCriterionWithAttributes.java | 1 + .../CriteriaUpToDateReportService.java | 8 ++++++- .../ListingNotUpToDateReport.java | 12 ++++++++++ 7 files changed, 41 insertions(+), 16 deletions(-) diff --git a/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/CriteriaUpToDateReportController.java b/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/CriteriaUpToDateReportController.java index 61aa4f6875..47c4183841 100644 --- a/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/CriteriaUpToDateReportController.java +++ b/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/CriteriaUpToDateReportController.java @@ -103,7 +103,7 @@ public CriteriaUpToDateReportController(CertificationBodyManager acbManager, }) @LogMethodUsage @RequestMapping(value = "/listings", method = RequestMethod.GET, produces = "application/json; charset=utf-8") - public @ResponseBody List getCriteriaUpToDateListings() { + public @ResponseBody List getCriteriaNotUpToDateByListing() { return reportDataManager.getCriteriaAttributeUpToDateService().getAllListingNotUpToDateReports(); } diff --git a/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ReportDataController.java b/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ReportDataController.java index d970488a1d..d7c5a6d723 100644 --- a/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ReportDataController.java +++ b/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/ReportDataController.java @@ -9,7 +9,6 @@ import org.springframework.web.bind.annotation.RestController; import gov.healthit.chpl.developer.search.DeveloperSearchResult; -import gov.healthit.chpl.developer.search.DeveloperSearchService; import gov.healthit.chpl.manager.StatisticsManager; import gov.healthit.chpl.report.ReportDataManager; import gov.healthit.chpl.report.criteriamigrationreport.CriteriaMigrationReportDenormalized; @@ -41,15 +40,12 @@ public class ReportDataController { private ReportDataManager reportDataManager; private StatisticsManager statisticsManager; - private DeveloperSearchService developerSearchService; @Autowired public ReportDataController(ReportDataManager reportDataManager, - StatisticsManager statisticsManager, - DeveloperSearchService developerSearchService) { + StatisticsManager statisticsManager) { this.reportDataManager = reportDataManager; this.statisticsManager = statisticsManager; - this.developerSearchService = developerSearchService; } @Operation(summary = "Retrieves the data used to generate the HTI-1 Criteria Migration Report.", diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriteriaManager.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriteriaManager.java index 6c7464db41..18e248faff 100644 --- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriteriaManager.java +++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriteriaManager.java @@ -45,18 +45,20 @@ public CertificationCriteriaManager(CertificationCriterionDAO certificationCrite public List getAllWithAttributes() { LOGGER.debug("Getting all criterion with attributes from the database (not cached)."); List allCriteria = getAll(); - return allCriteria.stream() + List allCriteriaWithAttributes = allCriteria.stream() .map(criterion -> buildCertificationCriterionWithAttributes(criterion)) - .sorted(criterionComparator) .collect(Collectors.toList()); + setSortOrder(allCriteriaWithAttributes); + return allCriteriaWithAttributes; } public List getActiveWithAttributes(String certificationEdition, LocalDate startDay, LocalDate endDay) { - return getActive(certificationEdition, startDay, endDay).stream() + List activeCriteriaWithAttributes = getActive(certificationEdition, startDay, endDay).stream() .map(criterion -> buildCertificationCriterionWithAttributes(criterion)) - .sorted(criterionComparator) .collect(Collectors.toList()); + setSortOrder(activeCriteriaWithAttributes); + return activeCriteriaWithAttributes; } public List getActive(String certificationEdition, LocalDate startDay, LocalDate endDay) { @@ -65,24 +67,23 @@ public List getActive(String certificationEdition, Local .filter(criterion -> StringUtils.isEmpty(certificationEdition) ? true : criterion.getCertificationEdition() == null || criterion.getCertificationEdition().equals(certificationEdition)) - .sorted(criterionComparator) .collect(Collectors.toList()); } public List getCriteriaAvailableToListingAndUser(CertifiedProductSearchDetails listing) { - List allCriteriaAvailableToListing = Stream.concat( + return Stream.concat( getAttestedCriteria(listing).stream(), getEditableCriteria(listing).stream()) .distinct() .sorted(criterionComparator) .collect(Collectors.toList()); - return allCriteriaAvailableToListing; } private List getAttestedCriteria(CertifiedProductSearchDetails listing) { return listing.getCertificationResults().stream() .filter(certResult -> certResult.getSuccess()) .map(certResult -> certResult.getCriterion()) + .sorted(criterionComparator) .collect(Collectors.toList()); } @@ -95,6 +96,7 @@ private List getEditableCriteria(CertifiedProductSearchD && !resourcePermissionsFactory.get().isUserRoleOnc()) { return allActiveCriteria.stream() .filter(criterion -> criterion.isEditable()) + .sorted(criterionComparator) .collect(Collectors.toList()); } return allActiveCriteria; @@ -113,6 +115,7 @@ public List getActiveBetween(LocalDate startDay, LocalDa .filter(criterion -> DateUtil.datesOverlap( Pair.of(criterion.getStartDay(), criterion.getEndDay()), Pair.of(startDay, endDay))) + .sorted(criterionComparator) .collect(Collectors.toList()); } @@ -123,6 +126,7 @@ public List getActiveToday() { .filter(criterion -> DateUtil.datesOverlap( Pair.of(criterion.getStartDay(), criterion.getEndDay()), Pair.of(today, today))) + .sorted(criterionComparator) .collect(Collectors.toList()); } @@ -164,4 +168,10 @@ private CertificationCriterionWithAttributes buildCertificationCriterionWithAttr .build()) .build(); } + + private void setSortOrder(List criteria) { + for (int i = 0; i < criteria.size(); i++) { + criteria.get(i).setSortOrder(i); + } + } } diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriterion.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriterion.java index 45043bb66f..e8b97a5c7a 100644 --- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriterion.java +++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriterion.java @@ -9,8 +9,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty.Access; -import tools.jackson.databind.annotation.JsonDeserialize; -import tools.jackson.databind.annotation.JsonSerialize; import gov.healthit.chpl.criteriaattribute.rule.Rule; import gov.healthit.chpl.domain.CertifiedProductSearchDetails; @@ -25,6 +23,8 @@ import lombok.Setter; import lombok.ToString; import lombok.experimental.SuperBuilder; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; @JsonIgnoreProperties(ignoreUnknown = true) @SuperBuilder diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriterionWithAttributes.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriterionWithAttributes.java index 95073a076b..a96e01b2b0 100644 --- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriterionWithAttributes.java +++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/certificationCriteria/CertificationCriterionWithAttributes.java @@ -19,6 +19,7 @@ public class CertificationCriterionWithAttributes extends CertificationCriterion private static final long serialVersionUID = 5732322243571111895L; private AllowedAttributes attributes; + private Integer sortOrder; @Override public int hashCode() { diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/criteriauptodate/CriteriaUpToDateReportService.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/criteriauptodate/CriteriaUpToDateReportService.java index ecce97c275..f37422d408 100644 --- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/criteriauptodate/CriteriaUpToDateReportService.java +++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/criteriauptodate/CriteriaUpToDateReportService.java @@ -37,6 +37,7 @@ public class CriteriaUpToDateReportService { private SummaryStatisticsDAO summaryStatisticsDao; private List allCertificationStatuses; private String unformattedListingDetailsUrl; + private String unformattedDeveloperDetailsUrl; @Autowired public CriteriaUpToDateReportService(CriteriaUpToDateStatusReportDateService reportDateService, @@ -45,13 +46,15 @@ public CriteriaUpToDateReportService(CriteriaUpToDateStatusReportDateService rep SummaryStatisticsDAO summaryStatisticsDao, CertificationStatusDAO certificationStatusDao, @Value("${chplUrlBegin}") String chplUrlBegin, - @Value("${listingDetailsUrlPart}") String listingDetailsUrlPart) { + @Value("${listingDetailsUrlPart}") String listingDetailsUrlPart, + @Value("${developerUrlPart}") String developerDetailsUrlPart) { this.reportDateService = reportDateService; this.criteriaManager = criteriaManager; this.updatedCriteriaStatusReportDao = updatedCriteriaStatusReportDao; this.summaryStatisticsDao = summaryStatisticsDao; this.allCertificationStatuses = certificationStatusDao.findAll(); this.unformattedListingDetailsUrl = chplUrlBegin + listingDetailsUrlPart; + this.unformattedDeveloperDetailsUrl = chplUrlBegin + developerDetailsUrlPart; } @@ -110,6 +113,9 @@ public List getAllListingNotUpToDateReports() { .chplProductNumber(report.getChplProductNumber()) .certifiedProductId(report.getCertifiedProductId()) .listingDetailsUrl(String.format(unformattedListingDetailsUrl, report.getCertifiedProductId())) + .developerName(report.getDeveloper()) + .developerDetailsUrl(String.format(unformattedDeveloperDetailsUrl, report.getDeveloperId())) + .requiredDay(report.getRequiredDay()) .build()) .collect(Collectors.toSet()); return results.stream().collect(Collectors.toList()); diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/criteriauptodate/ListingNotUpToDateReport.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/criteriauptodate/ListingNotUpToDateReport.java index ce547d48b3..152b7f0f49 100644 --- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/criteriauptodate/ListingNotUpToDateReport.java +++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/report/criteriauptodate/ListingNotUpToDateReport.java @@ -1,9 +1,15 @@ package gov.healthit.chpl.report.criteriauptodate; +import java.time.LocalDate; + import gov.healthit.chpl.certificationCriteria.CertificationCriterion; +import gov.healthit.chpl.util.LocalDateDeserializer; +import gov.healthit.chpl.util.LocalDateSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; @Data @Builder @@ -14,4 +20,10 @@ public class ListingNotUpToDateReport { private Long certifiedProductId; private String listingDetailsUrl; private String chplProductNumber; + private String developerName; + private String developerDetailsUrl; + + @JsonDeserialize(using = LocalDateDeserializer.class) + @JsonSerialize(using = LocalDateSerializer.class) + private LocalDate requiredDay; }