Skip to content

Commit 595bff7

Browse files
committed
feat: add compliance report module
1 parent 96e1f7e commit 595bff7

File tree

7 files changed

+157
-62
lines changed

7 files changed

+157
-62
lines changed

backend/src/main/java/com/park/utmstack/domain/compliance/UtmComplianceReportConfig.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.park.utmstack.domain.chart_builder.UtmDashboard;
88
import com.park.utmstack.domain.chart_builder.UtmDashboardVisualization;
99
import com.park.utmstack.domain.chart_builder.types.query.FilterType;
10+
import com.park.utmstack.domain.compliance.enums.ComplianceStatus;
1011
import com.park.utmstack.domain.compliance.enums.ComplianceType;
1112
import com.park.utmstack.domain.compliance.types.RequestParamFilter;
1213
import com.park.utmstack.domain.shared_types.DataColumn;
@@ -92,6 +93,10 @@ public class UtmComplianceReportConfig implements Serializable {
9293
@Column(name = "config_report_name", length = 50)
9394
private String configReportName;
9495

96+
@Enumerated(EnumType.STRING)
97+
@Column(name = "config_report_status", length = 25)
98+
private ComplianceStatus configReportStatus;
99+
95100
@Transient
96101
@JsonSerialize
97102
@JsonDeserialize
@@ -105,6 +110,8 @@ public class UtmComplianceReportConfig implements Serializable {
105110
@JoinColumn(name = "dashboard_id", referencedColumnName = "id", insertable = false, updatable = false)
106111
private UtmDashboard associatedDashboard;
107112

113+
114+
108115
@Transient
109116
@JsonSerialize
110117
@JsonDeserialize
@@ -336,4 +343,12 @@ public String getConfigRemediation() {
336343
public void setConfigRemediation(String configRemediation) {
337344
this.configRemediation = configRemediation;
338345
}
346+
347+
public ComplianceStatus getConfigReportStatus() {
348+
return configReportStatus;
349+
}
350+
351+
public void setConfigReportStatus(ComplianceStatus complianceStatus) {
352+
this.configReportStatus = complianceStatus;
353+
}
339354
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.park.utmstack.domain.compliance.enums;
2+
public enum ComplianceStatus {
3+
COMPLAINT,
4+
NON_COMPLAINT
5+
}

backend/src/main/java/com/park/utmstack/repository/compliance/UtmComplianceReportConfigRepository.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.park.utmstack.repository.compliance;
22

33
import com.park.utmstack.domain.compliance.UtmComplianceReportConfig;
4+
import org.springframework.data.domain.Page;
5+
import org.springframework.data.domain.Pageable;
46
import org.springframework.data.jpa.repository.JpaRepository;
57
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
68
import org.springframework.data.jpa.repository.Modifying;
@@ -16,7 +18,6 @@
1618
/**
1719
* Spring Data repository for the ComplianceTemplate entity.
1820
*/
19-
@SuppressWarnings("unused")
2021
@Repository
2122
public interface UtmComplianceReportConfigRepository extends JpaRepository<UtmComplianceReportConfig, Long>, JpaSpecificationExecutor<UtmComplianceReportConfig> {
2223

@@ -28,4 +29,19 @@ public interface UtmComplianceReportConfigRepository extends JpaRepository<UtmCo
2829
@Transactional
2930
@Query("delete from UtmComplianceReportConfig r where r.standardSectionId in (select s.id from UtmComplianceStandardSection s where s.standardId = :standardId) and r.id not in :reportIds")
3031
void deleteReportsByStandardIdAndIdNotIn(@Param("standardId") Long standardId, @Param("reportIds") List<Long> reportIds);
32+
33+
@Query(value = "SELECT cfg FROM UtmComplianceReportConfig cfg " +
34+
"JOIN cfg.section sec " +
35+
"LEFT JOIN cfg.associatedDashboard d " +
36+
"WHERE (:standardId IS NULL OR sec.standardId = :standardId) " +
37+
"AND (:solution IS NULL OR lower(cfg.configSolution) LIKE %:solution%) " +
38+
"AND (:sectionId IS NULL OR sec.id = :sectionId) " +
39+
"AND (:search IS NULL OR lower(cfg.configReportName) LIKE %:search% OR d.name LIKE %:search%)")
40+
Page<UtmComplianceReportConfig> getReportsByFilters(
41+
@Param("standardId") Long standardId,
42+
@Param("solution") String solution,
43+
@Param("sectionId") Long sectionId,
44+
@Param("search") String search,
45+
Pageable pageable);
46+
3147
}

backend/src/main/java/com/park/utmstack/service/compliance/config/UtmComplianceReportConfigService.java

Lines changed: 49 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
package com.park.utmstack.service.compliance.config;
22

3+
import com.fasterxml.jackson.databind.node.ObjectNode;
4+
import com.park.utmstack.domain.chart_builder.UtmDashboard;
5+
import com.park.utmstack.domain.chart_builder.UtmDashboardVisualization;
6+
import com.park.utmstack.domain.chart_builder.UtmVisualization;
7+
import com.park.utmstack.domain.chart_builder.types.ChartType;
38
import com.park.utmstack.domain.compliance.UtmComplianceReportConfig;
49
import com.park.utmstack.domain.compliance.UtmComplianceStandard;
510
import com.park.utmstack.domain.compliance.UtmComplianceStandardSection;
11+
import com.park.utmstack.domain.compliance.enums.ComplianceStatus;
612
import com.park.utmstack.repository.compliance.UtmComplianceReportConfigRepository;
713
import com.park.utmstack.service.chart_builder.UtmDashboardService;
14+
import com.park.utmstack.service.chart_builder.UtmDashboardVisualizationService;
15+
import com.park.utmstack.service.elasticsearch.ElasticsearchService;
816
import com.park.utmstack.util.UtilPagination;
9-
import com.park.utmstack.util.exceptions.UtmPageNumberNotSupported;
17+
import com.park.utmstack.util.chart_builder.elasticsearch_dsl.requests.RequestDsl;
18+
import com.park.utmstack.util.exceptions.UtmElasticsearchException;
19+
import org.opensearch.client.opensearch.core.SearchResponse;
1020
import org.springframework.dao.DataIntegrityViolationException;
1121
import org.springframework.data.domain.Page;
1222
import org.springframework.data.domain.PageImpl;
@@ -17,6 +27,7 @@
1727
import org.springframework.util.StringUtils;
1828

1929
import javax.persistence.EntityManager;
30+
import java.util.Collections;
2031
import java.util.List;
2132
import java.util.Objects;
2233
import java.util.Optional;
@@ -29,17 +40,24 @@ public class UtmComplianceReportConfigService {
2940
private final UtmDashboardService dashboardService;
3041
private final UtmComplianceStandardService standardService;
3142
private final UtmComplianceStandardSectionService standardSectionService;
43+
44+
private final UtmDashboardVisualizationService dashboardVisualizationService;
45+
46+
private final ElasticsearchService elasticsearchService;
3247
private final EntityManager em;
3348

3449
public UtmComplianceReportConfigService(UtmComplianceReportConfigRepository complianceReportConfigRepository,
3550
UtmDashboardService dashboardService,
3651
UtmComplianceStandardService standardService,
3752
UtmComplianceStandardSectionService standardSectionService,
53+
UtmDashboardVisualizationService dashboardVisualizationService, ElasticsearchService elasticsearchService,
3854
EntityManager em) {
3955
this.complianceReportConfigRepository = complianceReportConfigRepository;
4056
this.dashboardService = dashboardService;
4157
this.standardService = standardService;
4258
this.standardSectionService = standardSectionService;
59+
this.dashboardVisualizationService = dashboardVisualizationService;
60+
this.elasticsearchService = elasticsearchService;
4361
this.em = em;
4462
}
4563

@@ -81,72 +99,31 @@ public void deleteReportsByStandardIdAndIdNotIn(Long standardId, List<Long> repo
8199
}
82100

83101
public Page<UtmComplianceReportConfig> getReportsByFilters(Long standardId, String solution, Long sectionId,
84-
String search, Pageable pageable) {
85-
StringBuilder script = new StringBuilder(
86-
"SELECT cfg.* FROM utm_compliance_report_config cfg " +
87-
"INNER JOIN utm_compliance_standard_section sec ON cfg.standard_section_id = sec.id " +
88-
"INNER JOIN utm_compliance_standard st ON sec.standard_id = st.id " +
89-
"LEFT JOIN utm_dashboard d ON cfg.dashboard_id = d.id");
90-
91-
StringBuilder countScript = new StringBuilder(
92-
"SELECT COUNT(cfg.id) FROM utm_compliance_report_config cfg " +
93-
"INNER JOIN utm_compliance_standard_section sec ON cfg.standard_section_id = sec.id " +
94-
"INNER JOIN utm_compliance_standard st ON sec.standard_id = st.id " +
95-
"LEFT JOIN utm_dashboard d ON cfg.dashboard_id = d.id");
96-
97-
boolean hasWhere = false;
98-
99-
if (standardId != null) {
100-
hasWhere = true;
101-
script.append(" WHERE st.id = ").append(standardId);
102-
countScript.append(" WHERE st.id = ").append(standardId);
103-
}
102+
String search, Boolean expandDashboard, Boolean setStatus, Pageable pageable) throws UtmElasticsearchException {
104103

105-
if (StringUtils.hasText(solution)) {
106-
String condition = "cfg.config_solution ILIKE '%" + solution + "%'";
107-
script.append(hasWhere ? " AND " : " WHERE ").append(condition);
108-
countScript.append(hasWhere ? " AND " : " WHERE ").append(condition);
109-
hasWhere = true;
110-
}
104+
Page<UtmComplianceReportConfig> page = complianceReportConfigRepository.getReportsByFilters(standardId, solution, sectionId, search, pageable);
111105

112-
if (sectionId != null) {
113-
String condition = "sec.id = " + sectionId;
114-
script.append(hasWhere ? " AND " : " WHERE ").append(condition);
115-
countScript.append(hasWhere ? " AND " : " WHERE ").append(condition);
116-
}
117-
118-
if (StringUtils.hasText(search)) {
119-
String condition = "(cfg.config_report_name ILIKE '%" + search + "%' OR d.name ILIKE '%" + search + "%')";
120-
script.append(hasWhere ? " AND " : " WHERE ").append(condition);
121-
countScript.append(hasWhere ? " AND " : " WHERE ").append(condition);
106+
if (expandDashboard != null && expandDashboard) {
107+
for (UtmComplianceReportConfig report : page) {
108+
dashboardVisualizationService.findAllByIdDashboard(report.getDashboardId()).ifPresent(report::setDashboard);
109+
}
122110
}
123111

124-
if (StringUtils.hasText(solution)) {
125-
pageable.getSort();
126-
String sortField = pageable.getSort().iterator().next().getProperty();
127-
String sortDirection = pageable.getSort().iterator().next().getDirection().name();
128-
script.append(" ORDER BY ").append(sortField).append(" ").append(sortDirection);
112+
if (setStatus) {
113+
for (UtmComplianceReportConfig report : page) {
114+
report.setConfigReportStatus(this.getStatus(report.getAssociatedDashboard()));
115+
}
129116
}
130117

131-
List<UtmComplianceReportConfig> results = em.createNativeQuery(script.toString(), UtmComplianceReportConfig.class)
132-
.setFirstResult(UtilPagination.getFirstForNativeSql(pageable.getPageSize(), pageable.getPageNumber()))
133-
.setMaxResults(pageable.getPageSize())
134-
.getResultList();
135-
136-
long total = ((Number) em.createNativeQuery(countScript.toString()).getSingleResult()).longValue();
118+
return page;
137119

138-
return new PageImpl<>(results, pageable, total);
139120
}
140121

141122

142123
public void deleteAllByConfigSolutionAndSectionIdAndDashboardId(String configSolution, Long sectionId, Long dashboardId) {
143124
complianceReportConfigRepository.deleteAllByConfigSolutionAndStandardSectionIdAndDashboardId(configSolution, sectionId, dashboardId);
144125
}
145126

146-
/**
147-
* @param reports
148-
* @param override
149-
*/
150127
public void importReports(List<UtmComplianceReportConfig> reports, boolean override) throws Exception {
151128
final String ctx = CLASSNAME + ".importReports";
152129
try {
@@ -200,4 +177,23 @@ public void importReports(List<UtmComplianceReportConfig> reports, boolean overr
200177
throw new Exception(msg);
201178
}
202179
}
180+
181+
private ComplianceStatus getStatus(UtmDashboard dashboard) throws UtmElasticsearchException {
182+
List<UtmDashboardVisualization> dashboardVisualizations = dashboardVisualizationService.findAllByIdDashboard(dashboard.getId())
183+
.orElse(Collections.emptyList());
184+
185+
UtmVisualization visualization = dashboardVisualizations.stream().filter(d -> d.getVisualization().getChartType().equals(ChartType.LIST_CHART)
186+
|| d.getVisualization().getChartType().equals(ChartType.TABLE_CHART))
187+
.map(UtmDashboardVisualization::getVisualization)
188+
.findFirst()
189+
.orElse(null);
190+
191+
if(Objects.nonNull(visualization)){
192+
RequestDsl requestQuery = new RequestDsl(visualization);
193+
SearchResponse<ObjectNode> result = elasticsearchService.search(requestQuery.getSearchSourceBuilderForCount().build(), ObjectNode.class);
194+
return result.hits().total().value() > 0 ? ComplianceStatus.COMPLAINT : ComplianceStatus.NON_COMPLAINT;
195+
} else {
196+
return ComplianceStatus.NON_COMPLAINT;
197+
}
198+
}
203199
}

backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/requests/RequestDsl.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,27 @@ public SearchRequest.Builder getSearchSourceBuilder() throws UtmElasticsearchExc
5757
}
5858
}
5959

60+
public SearchRequest.Builder getSearchSourceBuilderForCount() throws UtmElasticsearchException {
61+
final String ctx = CLASSNAME + ".getSearchSourceBuilderForCount";
62+
try {
63+
List<FilterType> filters = visualization.getFilterType();
64+
65+
if (CollectionUtils.isEmpty(filters))
66+
filters = new ArrayList<>();
67+
68+
searchRequestBuilder.query(SearchUtil.toQuery(filters));
69+
70+
searchRequestBuilder.size(0); // Esto asegura que no se devuelvan los documentos
71+
searchRequestBuilder.trackTotalHits(TrackHits.of(t -> t.enabled(true)));
72+
73+
return searchRequestBuilder;
74+
} catch (Exception e) {
75+
throw new UtmElasticsearchException(ctx + ": " + e.getMessage());
76+
}
77+
}
78+
79+
80+
6081
/**
6182
* Build an aggregation section for an elasticsearch dsl request
6283
*

backend/src/main/java/com/park/utmstack/web/rest/compliance/config/UtmComplianceReportConfigResource.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -173,17 +173,14 @@ public ResponseEntity<List<UtmComplianceReportConfig>> getReportsByFilters(@Requ
173173
@RequestParam(required = false) String solution,
174174
@RequestParam(required = false) Long sectionId,
175175
@RequestParam(required = false) String search,
176-
@RequestParam(required = false) Boolean expandDashboard,
176+
@RequestParam(required = false, defaultValue = "false") Boolean setStatus,
177+
@RequestParam(required = false, defaultValue = "false") Boolean expandDashboard,
177178
Pageable pageable) {
178179
final String ctx = CLASS_NAME + ".getReportsByFilters";
179180
try {
180-
Page<UtmComplianceReportConfig> page = complianceReportConfigService.getReportsByFilters(standardId, solution, sectionId, search, pageable);
181+
Page<UtmComplianceReportConfig> page = complianceReportConfigService.getReportsByFilters(standardId, solution, sectionId, search, expandDashboard, setStatus, pageable);
181182

182-
if (!Objects.isNull(expandDashboard) && expandDashboard) {
183-
for (UtmComplianceReportConfig report : page)
184-
dashboardVisualizationService.findAllByIdDashboard(report.getDashboardId()).ifPresent(report::setDashboard);
185-
}
186-
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/utm-asset-groups/searchGroupsByFilter");
183+
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/report-config/get-by-filters");
187184
return ResponseEntity.ok().headers(headers).body(page.getContent());
188185
} catch (Exception e) {
189186
String msg = ctx + ": " + e.getMessage();

0 commit comments

Comments
 (0)