From ac7d503c8a79c53737041adeb4126a07a81e482d Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Tue, 18 Jul 2023 14:42:54 +0530 Subject: [PATCH 01/11] Added changes for HLM-3092 : proximity based search for household --- .../repository/HouseholdRepository.java | 27 +++++++++++++++++++ .../household/service/HouseholdService.java | 13 +++++++++ .../household/web/models/HouseholdSearch.java | 20 ++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java index 6b98b89cb5b..01d0a3c1d83 100644 --- a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java +++ b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java @@ -88,4 +88,31 @@ public List find(HouseholdSearch searchObject, Integer limit, Integer paramsMap.put("offset", offset); return this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); } + + public List findByRadius(HouseholdSearch searchObject, Integer limit, Integer offset, String tenantId, Boolean includeDeleted) throws QueryBuilderException { + String query = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))\n" + + "SELECT * FROM (SELECT h.*, a.*, ( 6371.4 * acos (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )\n" + + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ) ) ) AS distance \n" + + "FROM public.household h LEFT JOIN public.address a ON h.addressid = a.id AND h.tenantid = a.tenantid, cte_search_criteria_waypoint cte_scw "; + Map paramsMap = new HashMap<>(); + List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, QueryFieldChecker.isNotNull, paramsMap); + query = GenericQueryBuilder.generateQuery(query, whereFields).toString(); + query = query.replace("id IN (:id)", "h.id IN (:id)"); + query = query.replace("clientReferenceId IN (:clientReferenceId)", "h.clientReferenceId IN (:clientReferenceId)"); + query = query + " and h.tenantId=:tenantId "; + if (Boolean.FALSE.equals(includeDeleted)) { + query = query + "and isDeleted=:isDeleted "; + } + query = query + " ) AS rt "; + query = query + " WHERE distance < :distance "; + query = query + " ORDER BY distance ASC LIMIT :limit OFFSET :offset "; + paramsMap.put("s_latitude", searchObject.getLatitude()); + paramsMap.put("s_longitude", searchObject.getLongitude()); + paramsMap.put("tenantId", tenantId); + paramsMap.put("isDeleted", includeDeleted); + paramsMap.put("distance", searchObject.getSearchRadius()); + paramsMap.put("limit", limit); + paramsMap.put("offset", offset); + return this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); + } } diff --git a/health-services/household/src/main/java/org/egov/household/service/HouseholdService.java b/health-services/household/src/main/java/org/egov/household/service/HouseholdService.java index feada174cd4..ec03d4b07fb 100644 --- a/health-services/household/src/main/java/org/egov/household/service/HouseholdService.java +++ b/health-services/household/src/main/java/org/egov/household/service/HouseholdService.java @@ -125,6 +125,16 @@ public List search(HouseholdSearch householdSearch, Integer limit, In log.info("households found for search by id, size: {}", households.size()); return households; } + if(isProximityBasedSearch(householdSearch)) { + try { + List households = householdRepository.findByRadius(householdSearch, limit, offset, tenantId, includeDeleted); + log.info("households found for search, size: {}", households.size()); + return households; + } catch (QueryBuilderException e) { + log.error("error occurred while searching households", e); + throw new CustomException("ERROR_IN_QUERY", e.getMessage()); + } + } try { List households = householdRepository.find(householdSearch, limit, offset, tenantId, lastChangedSince, includeDeleted); @@ -231,4 +241,7 @@ private Tuple, Map> validate(List(validHouseholds, errorDetailsMap); } + private Boolean isProximityBasedSearch(HouseholdSearch householdSearch) { + return householdSearch.getLatitude() != null && householdSearch.getLongitude() != null && householdSearch.getSearchRadius() != null; + } } diff --git a/health-services/household/src/main/java/org/egov/household/web/models/HouseholdSearch.java b/health-services/household/src/main/java/org/egov/household/web/models/HouseholdSearch.java index 839a161a859..b946b1a8d5c 100644 --- a/health-services/household/src/main/java/org/egov/household/web/models/HouseholdSearch.java +++ b/health-services/household/src/main/java/org/egov/household/web/models/HouseholdSearch.java @@ -7,9 +7,12 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.egov.common.data.query.annotations.Exclude; import org.egov.common.data.query.annotations.Table; import org.springframework.validation.annotation.Validated; +import javax.validation.constraints.DecimalMax; +import javax.validation.constraints.DecimalMin; import java.util.List; /** @@ -38,5 +41,22 @@ public class HouseholdSearch { @JsonProperty("boundaryCode") private String localityCode = null; + + @Exclude + @JsonProperty("latitude") + @DecimalMin("-90") + @DecimalMax("90") + private Double latitude = null; + + @Exclude + @JsonProperty("longitude") + @DecimalMin("-180") + @DecimalMax("180") + private Double longitude = null; + + @Exclude + @JsonProperty("searchRadius") + @DecimalMin("0") + private Double searchRadius = null; } From 5aea581a0fb633f77d2e7ce3da62704960b57689 Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Wed, 19 Jul 2023 15:51:07 +0530 Subject: [PATCH 02/11] Added changes for HLM-3092 : proximity based search for individual --- .../repository/IndividualRepository.java | 56 +++++++++++++++++++ .../web/models/IndividualSearch.java | 13 +++++ 2 files changed, 69 insertions(+) diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java index 48d8f01dedf..4d2bf294186 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java @@ -79,6 +79,10 @@ public List find(IndividualSearch searchObject, Integer limit, Integ Map paramsMap = new HashMap<>(); String query = getQueryForIndividual(searchObject, limit, offset, tenantId, lastChangedSince, includeDeleted, paramsMap); + if (isProximityBasedSearch(searchObject)) { + List individuals = findByRadius(query, searchObject, includeDeleted, paramsMap); + return individuals; + } if (searchObject.getIdentifier() == null) { List individuals = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); if (!individuals.isEmpty()) { @@ -113,6 +117,58 @@ public List find(IndividualSearch searchObject, Integer limit, Integ } } + public List findByRadius(String query, IndividualSearch searchObject, Boolean includeDeleted, Map paramsMap) { + String cte_query = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))"; + paramsMap.put("s_latitude", searchObject.getLatitude()); + paramsMap.put("s_longitude", searchObject.getLongitude()); + if (searchObject.getIdentifier() != null) { + Map identifierParamMap = new HashMap<>(); + String identifierQuery = getIdentifierQuery(searchObject.getIdentifier(), identifierParamMap); + identifierParamMap.put("isDeleted", includeDeleted); + List identifiers = this.namedParameterJdbcTemplate + .query(identifierQuery, identifierParamMap, new IdentifierRowMapper()); + if (!identifiers.isEmpty()) { + query = query.replace(" tenantId=:tenantId ", " tenantId=:tenantId AND id=:individualId "); + paramsMap.put("individualId", identifiers.stream().findAny().get().getIndividualId()); + List individuals = this.namedParameterJdbcTemplate.query(query, + paramsMap, this.rowMapper); + if (!individuals.isEmpty()) { + individuals.forEach(individual -> { + individual.setIdentifiers(identifiers); + List
addresses = getAddressForIndividual(individual.getId(), includeDeleted); + individual.setAddress(addresses); + Map indServerGenIdParamMap = new HashMap<>(); + indServerGenIdParamMap.put("individualId", individual.getId()); + indServerGenIdParamMap.put("isDeleted", includeDeleted); + enrichSkills(includeDeleted, individual, indServerGenIdParamMap); + }); + } + return individuals; + } + } else { + query = cte_query + ", cte_individual AS (" + query + ")"; + query = query + "SELECT * FROM (SELECT cte_i.*, ( 6371.4 * acos (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )"; + query = query + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ) ) ) AS distance FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; + if(searchObject.getSearchRadius() != null) { + query = query + " WHERE rt.distance < :distance "; + } + query = query + " ORDER BY distance ASC "; + paramsMap.put("distance", searchObject.getSearchRadius()); + List individuals = this.namedParameterJdbcTemplate.query(query, + paramsMap, this.rowMapper); + if (!individuals.isEmpty()) { + enrichIndividuals(individuals, includeDeleted); + } + return individuals; + } + return Collections.emptyList(); + } + + + private Boolean isProximityBasedSearch(IndividualSearch searchObject) { + return searchObject.getLatitude() != null && searchObject.getLongitude() != null && searchObject.getSearchRadius() != null; + } + private void enrichSkills(Boolean includeDeleted, Individual individual, Map indServerGenIdParamMap) { String individualSkillQuery = getQuery("SELECT * FROM individual_skill WHERE individualId =:individualId", includeDeleted); diff --git a/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java b/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java index f846d1187f4..c58a72997f9 100644 --- a/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java +++ b/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java @@ -96,5 +96,18 @@ public class IndividualSearch { @Exclude @JsonProperty("userId") private Long userId; + + @Exclude + @JsonProperty("latitude") + private Double latitude; + + @Exclude + @JsonProperty("longitude") + private Double longitude; + + @Exclude + @JsonProperty("searchRadius") + private Double searchRadius; + } From ccc34fd35291a624d219b019361a6b66a80ee7ce Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Thu, 27 Jul 2023 15:06:24 +0530 Subject: [PATCH 03/11] Added changes for HLM-3092 : edge cases for acos function used in query --- .../household/repository/HouseholdRepository.java | 4 ++-- .../individual/repository/IndividualRepository.java | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java index 01d0a3c1d83..023b473c74c 100644 --- a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java +++ b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java @@ -91,8 +91,8 @@ public List find(HouseholdSearch searchObject, Integer limit, Integer public List findByRadius(HouseholdSearch searchObject, Integer limit, Integer offset, String tenantId, Boolean includeDeleted) throws QueryBuilderException { String query = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))\n" + - "SELECT * FROM (SELECT h.*, a.*, ( 6371.4 * acos (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )\n" + - "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ) ) ) AS distance \n" + + "SELECT * FROM (SELECT h.*, a.*, ( 6371.4 * acos (GREATEST (least (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )\n" + + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), 1), -1) ) ) AS distance \n" + "FROM public.household h LEFT JOIN public.address a ON h.addressid = a.id AND h.tenantid = a.tenantid, cte_search_criteria_waypoint cte_scw "; Map paramsMap = new HashMap<>(); List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, QueryFieldChecker.isNotNull, paramsMap); diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java index 4d2bf294186..1f1a2746416 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java @@ -130,6 +130,14 @@ public List findByRadius(String query, IndividualSearch searchObject if (!identifiers.isEmpty()) { query = query.replace(" tenantId=:tenantId ", " tenantId=:tenantId AND id=:individualId "); paramsMap.put("individualId", identifiers.stream().findAny().get().getIndividualId()); + query = cte_query + ", cte_individual AS (" + query + ")"; + query = query + "SELECT * FROM (SELECT cte_i.*, ( 6371.4 * acos ( GREATEST ( LEAST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )"; + query = query + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), 1), -1) ) ) AS distance FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; + if(searchObject.getSearchRadius() != null) { + query = query + " WHERE rt.distance < :distance "; + } + query = query + " ORDER BY distance ASC "; + paramsMap.put("distance", searchObject.getSearchRadius()); List individuals = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); if (!individuals.isEmpty()) { @@ -147,8 +155,8 @@ public List findByRadius(String query, IndividualSearch searchObject } } else { query = cte_query + ", cte_individual AS (" + query + ")"; - query = query + "SELECT * FROM (SELECT cte_i.*, ( 6371.4 * acos (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )"; - query = query + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ) ) ) AS distance FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; + query = query + "SELECT * FROM (SELECT cte_i.*, ( 6371.4 * acos ( GREATEST ( LEAST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )"; + query = query + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), 1), -1) ) ) AS distance FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; if(searchObject.getSearchRadius() != null) { query = query + " WHERE rt.distance < :distance "; } From d3b53f0b0f83ac81cdd54595fe7b81a3ecd7a2ed Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Tue, 1 Aug 2023 17:20:48 +0530 Subject: [PATCH 04/11] fixed null point issue : HLM-3092 --- .../egov/household/repository/HouseholdRepository.java | 4 ++-- .../egov/individual/repository/IndividualRepository.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java index 023b473c74c..48dd9413cc6 100644 --- a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java +++ b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java @@ -91,8 +91,8 @@ public List find(HouseholdSearch searchObject, Integer limit, Integer public List findByRadius(HouseholdSearch searchObject, Integer limit, Integer offset, String tenantId, Boolean includeDeleted) throws QueryBuilderException { String query = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))\n" + - "SELECT * FROM (SELECT h.*, a.*, ( 6371.4 * acos (GREATEST (least (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )\n" + - "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), 1), -1) ) ) AS distance \n" + + "SELECT * FROM (SELECT h.*, a.*, ( 6371.4 * acos (LEAST (GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )\n" + + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance \n" + "FROM public.household h LEFT JOIN public.address a ON h.addressid = a.id AND h.tenantid = a.tenantid, cte_search_criteria_waypoint cte_scw "; Map paramsMap = new HashMap<>(); List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, QueryFieldChecker.isNotNull, paramsMap); diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java index 1f1a2746416..c4a23bf4334 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java @@ -131,8 +131,8 @@ public List findByRadius(String query, IndividualSearch searchObject query = query.replace(" tenantId=:tenantId ", " tenantId=:tenantId AND id=:individualId "); paramsMap.put("individualId", identifiers.stream().findAny().get().getIndividualId()); query = cte_query + ", cte_individual AS (" + query + ")"; - query = query + "SELECT * FROM (SELECT cte_i.*, ( 6371.4 * acos ( GREATEST ( LEAST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )"; - query = query + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), 1), -1) ) ) AS distance FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; + query = query + "SELECT * FROM (SELECT cte_i.*, ( 6371.4 * acos ( LEAST ( GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )"; + query = query + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; if(searchObject.getSearchRadius() != null) { query = query + " WHERE rt.distance < :distance "; } @@ -155,8 +155,8 @@ public List findByRadius(String query, IndividualSearch searchObject } } else { query = cte_query + ", cte_individual AS (" + query + ")"; - query = query + "SELECT * FROM (SELECT cte_i.*, ( 6371.4 * acos ( GREATEST ( LEAST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )"; - query = query + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), 1), -1) ) ) AS distance FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; + query = query + "SELECT * FROM (SELECT cte_i.*, ( 6371.4 * acos ( LEAST ( GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )"; + query = query + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; if(searchObject.getSearchRadius() != null) { query = query + " WHERE rt.distance < :distance "; } From bd25b79554f33ca9091bd308110046cb50f3e95e Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Thu, 3 Aug 2023 11:17:52 +0530 Subject: [PATCH 05/11] HLM-3092 : fixed address null issue due to client audit detail changes --- .../household/repository/rowmapper/HouseholdRowMapper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdRowMapper.java b/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdRowMapper.java index 6846f9bb3bd..bcf6eebca9e 100644 --- a/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdRowMapper.java +++ b/health-services/household/src/main/java/org/egov/household/repository/rowmapper/HouseholdRowMapper.java @@ -37,9 +37,9 @@ public Household mapRow(ResultSet resultSet, int i) throws SQLException { .additionalFields(resultSet.getString("additionalDetails") == null ? null : objectMapper.readValue(resultSet .getString("additionalDetails"), AdditionalFields.class)) .address(Address.builder() - .id(resultSet.getString(13)) - .clientReferenceId(resultSet.getString(28)) - .tenantId(resultSet.getString(14)) + .id(resultSet.getString(15)) + .clientReferenceId(resultSet.getString(30)) + .tenantId(resultSet.getString(16)) .doorNo(resultSet.getString("doorNo")) .latitude(resultSet.getDouble("latitude")) .longitude(resultSet.getDouble("longitude")) From 3166bd12c4c944a08b75eafa1ee06faf7f0ccbd9 Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Fri, 4 Aug 2023 18:48:02 +0530 Subject: [PATCH 06/11] HLM-3092: fixed bug, incorrect placement of limit in query --- .../org/egov/individual/repository/IndividualRepository.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java index c4a23bf4334..ac752e3c66f 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java @@ -118,6 +118,7 @@ public List find(IndividualSearch searchObject, Integer limit, Integ } public List findByRadius(String query, IndividualSearch searchObject, Boolean includeDeleted, Map paramsMap) { + query = query.replace("LIMIT :limit OFFSET :offset", ""); String cte_query = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))"; paramsMap.put("s_latitude", searchObject.getLatitude()); paramsMap.put("s_longitude", searchObject.getLongitude()); @@ -137,6 +138,7 @@ public List findByRadius(String query, IndividualSearch searchObject query = query + " WHERE rt.distance < :distance "; } query = query + " ORDER BY distance ASC "; + query = query + "LIMIT :limit OFFSET :offset"; paramsMap.put("distance", searchObject.getSearchRadius()); List individuals = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); @@ -161,6 +163,7 @@ public List findByRadius(String query, IndividualSearch searchObject query = query + " WHERE rt.distance < :distance "; } query = query + " ORDER BY distance ASC "; + query = query + "LIMIT :limit OFFSET :offset"; paramsMap.put("distance", searchObject.getSearchRadius()); List individuals = this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); From 710b2751a4d4162df72546ed42379ea2c9d49834 Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Mon, 9 Oct 2023 13:44:50 +0530 Subject: [PATCH 07/11] HLM-3092 : changes as per code review comments --- .../repository/HouseholdRepository.java | 18 ++++++++++--- .../household/web/models/HouseholdSearch.java | 3 +++ .../repository/IndividualRepository.java | 25 +++++++++++++------ .../web/models/IndividualSearch.java | 10 ++++++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java index ae45bcb00f8..b023481a1f4 100644 --- a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java +++ b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java @@ -29,6 +29,8 @@ @Slf4j public class HouseholdRepository extends GenericRepository { + private final String searchCriteriaWaypointQuery = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))\n"; + private final String calculateDistanceQuery = "( 6371.4 * acos (LEAST (GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) ) + sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance "; @Autowired protected HouseholdRepository(Producer producer, NamedParameterJdbcTemplate namedParameterJdbcTemplate, @@ -89,10 +91,20 @@ public List find(HouseholdSearch searchObject, Integer limit, Integer return this.namedParameterJdbcTemplate.query(query, paramsMap, this.rowMapper); } + /** + * @param searchObject + * @param limit + * @param offset + * @param tenantId + * @param includeDeleted + * @return + * @throws QueryBuilderException + * + * Fetch all the household which falls under the radius provided using longitude and latitude provided. + */ public List findByRadius(HouseholdSearch searchObject, Integer limit, Integer offset, String tenantId, Boolean includeDeleted) throws QueryBuilderException { - String query = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))\n" + - "SELECT * FROM (SELECT h.*, a.*, ( 6371.4 * acos (LEAST (GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )\n" + - "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance \n" + + String query = searchCriteriaWaypointQuery + + "SELECT * FROM (SELECT h.*, a.*, " + calculateDistanceQuery + " \n" + "FROM public.household h LEFT JOIN public.address a ON h.addressid = a.id AND h.tenantid = a.tenantid, cte_search_criteria_waypoint cte_scw "; Map paramsMap = new HashMap<>(); List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, QueryFieldChecker.isNotNull, paramsMap); diff --git a/health-services/household/src/main/java/org/egov/household/web/models/HouseholdSearch.java b/health-services/household/src/main/java/org/egov/household/web/models/HouseholdSearch.java index b946b1a8d5c..96b8e529b4a 100644 --- a/health-services/household/src/main/java/org/egov/household/web/models/HouseholdSearch.java +++ b/health-services/household/src/main/java/org/egov/household/web/models/HouseholdSearch.java @@ -54,6 +54,9 @@ public class HouseholdSearch { @DecimalMax("180") private Double longitude = null; + /* + * @value unit of measurement in Kilometer + * */ @Exclude @JsonProperty("searchRadius") @DecimalMin("0") diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java index ac752e3c66f..f99b093da37 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java @@ -38,6 +38,9 @@ @Slf4j public class IndividualRepository extends GenericRepository { + private final String cteQuery = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))"; + private final String calculateDistanceQuery = "( 6371.4 * acos ( LEAST ( GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance "; + protected IndividualRepository(@Qualifier("individualProducer") Producer producer, NamedParameterJdbcTemplate namedParameterJdbcTemplate, RedisTemplate redisTemplate, @@ -117,9 +120,17 @@ public List find(IndividualSearch searchObject, Integer limit, Integ } } + /** + * @param query + * @param searchObject + * @param includeDeleted + * @param paramsMap + * @return + * + * Fetch all the household which falls under the radius provided using longitude and latitude provided. + */ public List findByRadius(String query, IndividualSearch searchObject, Boolean includeDeleted, Map paramsMap) { query = query.replace("LIMIT :limit OFFSET :offset", ""); - String cte_query = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))"; paramsMap.put("s_latitude", searchObject.getLatitude()); paramsMap.put("s_longitude", searchObject.getLongitude()); if (searchObject.getIdentifier() != null) { @@ -131,9 +142,9 @@ public List findByRadius(String query, IndividualSearch searchObject if (!identifiers.isEmpty()) { query = query.replace(" tenantId=:tenantId ", " tenantId=:tenantId AND id=:individualId "); paramsMap.put("individualId", identifiers.stream().findAny().get().getIndividualId()); - query = cte_query + ", cte_individual AS (" + query + ")"; - query = query + "SELECT * FROM (SELECT cte_i.*, ( 6371.4 * acos ( LEAST ( GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )"; - query = query + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; + query = cteQuery + ", cte_individual AS (" + query + ")"; + query = query + "SELECT * FROM (SELECT cte_i.*, " + calculateDistanceQuery + +" FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; if(searchObject.getSearchRadius() != null) { query = query + " WHERE rt.distance < :distance "; } @@ -156,9 +167,9 @@ public List findByRadius(String query, IndividualSearch searchObject return individuals; } } else { - query = cte_query + ", cte_individual AS (" + query + ")"; - query = query + "SELECT * FROM (SELECT cte_i.*, ( 6371.4 * acos ( LEAST ( GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )"; - query = query + "+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; + query = cteQuery + ", cte_individual AS (" + query + ")"; + query = query + "SELECT * FROM (SELECT cte_i.*, "+ calculateDistanceQuery + +" FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; if(searchObject.getSearchRadius() != null) { query = query + " WHERE rt.distance < :distance "; } diff --git a/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java b/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java index c58a72997f9..397b60304ce 100644 --- a/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java +++ b/health-services/individual/src/main/java/org/egov/individual/web/models/IndividualSearch.java @@ -15,6 +15,8 @@ import org.springframework.validation.annotation.Validated; import javax.validation.Valid; +import javax.validation.constraints.DecimalMax; +import javax.validation.constraints.DecimalMin; import java.math.BigDecimal; import java.util.Date; import java.util.List; @@ -99,14 +101,22 @@ public class IndividualSearch { @Exclude @JsonProperty("latitude") + @DecimalMin("-90") + @DecimalMax("90") private Double latitude; @Exclude @JsonProperty("longitude") + @DecimalMin("-180") + @DecimalMax("180") private Double longitude; + /* + * @value unit of measurement in Kilometer + * */ @Exclude @JsonProperty("searchRadius") + @DecimalMin("0") private Double searchRadius; } From 3567fde0d855d6416f0444205a879cb0eb06c7c7 Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Mon, 9 Oct 2023 17:25:16 +0530 Subject: [PATCH 08/11] HLM-3092: added collectionutils isempty check --- .../org/egov/individual/repository/IndividualRepository.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java index f99b093da37..13f64853a9c 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java @@ -20,6 +20,7 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Repository; +import org.springframework.util.CollectionUtils; import org.springframework.util.ReflectionUtils; import java.lang.reflect.Method; @@ -139,7 +140,7 @@ public List findByRadius(String query, IndividualSearch searchObject identifierParamMap.put("isDeleted", includeDeleted); List identifiers = this.namedParameterJdbcTemplate .query(identifierQuery, identifierParamMap, new IdentifierRowMapper()); - if (!identifiers.isEmpty()) { + if (CollectionUtils.isEmpty(identifiers)) { query = query.replace(" tenantId=:tenantId ", " tenantId=:tenantId AND id=:individualId "); paramsMap.put("individualId", identifiers.stream().findAny().get().getIndividualId()); query = cteQuery + ", cte_individual AS (" + query + ")"; From d24231cb57c05ec0257ee7e73b29683d46343794 Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Mon, 9 Oct 2023 17:33:11 +0530 Subject: [PATCH 09/11] HLM-3092: updated HouseholdRepository.java and IndividualRepository.java as per review comments --- .../org/egov/household/repository/HouseholdRepository.java | 4 ++-- .../egov/individual/repository/IndividualRepository.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java index b023481a1f4..b23a6df9c18 100644 --- a/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java +++ b/health-services/household/src/main/java/org/egov/household/repository/HouseholdRepository.java @@ -30,7 +30,7 @@ public class HouseholdRepository extends GenericRepository { private final String searchCriteriaWaypointQuery = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))\n"; - private final String calculateDistanceQuery = "( 6371.4 * acos (LEAST (GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) ) + sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance "; + private final String calculateDistanceFromTwoWaypointsFormulaQuery = "( 6371.4 * acos (LEAST (GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) ) + sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance "; @Autowired protected HouseholdRepository(Producer producer, NamedParameterJdbcTemplate namedParameterJdbcTemplate, @@ -104,7 +104,7 @@ public List find(HouseholdSearch searchObject, Integer limit, Integer */ public List findByRadius(HouseholdSearch searchObject, Integer limit, Integer offset, String tenantId, Boolean includeDeleted) throws QueryBuilderException { String query = searchCriteriaWaypointQuery + - "SELECT * FROM (SELECT h.*, a.*, " + calculateDistanceQuery + " \n" + + "SELECT * FROM (SELECT h.*, a.*, " + calculateDistanceFromTwoWaypointsFormulaQuery + " \n" + "FROM public.household h LEFT JOIN public.address a ON h.addressid = a.id AND h.tenantid = a.tenantid, cte_search_criteria_waypoint cte_scw "; Map paramsMap = new HashMap<>(); List whereFields = GenericQueryBuilder.getFieldsWithCondition(searchObject, QueryFieldChecker.isNotNull, paramsMap); diff --git a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java index 13f64853a9c..4362e1f1811 100644 --- a/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java +++ b/health-services/individual/src/main/java/org/egov/individual/repository/IndividualRepository.java @@ -40,7 +40,7 @@ public class IndividualRepository extends GenericRepository { private final String cteQuery = "WITH cte_search_criteria_waypoint(s_latitude, s_longitude) AS (VALUES(:s_latitude, :s_longitude))"; - private final String calculateDistanceQuery = "( 6371.4 * acos ( LEAST ( GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance "; + private final String calculateDistanceFromTwoWaypointsFormulaQuery = "( 6371.4 * acos ( LEAST ( GREATEST (cos ( radians(cte_scw.s_latitude) ) * cos( radians(a.latitude) ) * cos( radians(a.longitude) - radians(cte_scw.s_longitude) )+ sin ( radians(cte_scw.s_latitude) ) * sin( radians(a.latitude) ), -1), 1) ) ) AS distance "; protected IndividualRepository(@Qualifier("individualProducer") Producer producer, NamedParameterJdbcTemplate namedParameterJdbcTemplate, @@ -144,7 +144,7 @@ public List findByRadius(String query, IndividualSearch searchObject query = query.replace(" tenantId=:tenantId ", " tenantId=:tenantId AND id=:individualId "); paramsMap.put("individualId", identifiers.stream().findAny().get().getIndividualId()); query = cteQuery + ", cte_individual AS (" + query + ")"; - query = query + "SELECT * FROM (SELECT cte_i.*, " + calculateDistanceQuery + query = query + "SELECT * FROM (SELECT cte_i.*, " + calculateDistanceFromTwoWaypointsFormulaQuery +" FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; if(searchObject.getSearchRadius() != null) { query = query + " WHERE rt.distance < :distance "; @@ -169,7 +169,7 @@ public List findByRadius(String query, IndividualSearch searchObject } } else { query = cteQuery + ", cte_individual AS (" + query + ")"; - query = query + "SELECT * FROM (SELECT cte_i.*, "+ calculateDistanceQuery + query = query + "SELECT * FROM (SELECT cte_i.*, "+ calculateDistanceFromTwoWaypointsFormulaQuery +" FROM cte_individual cte_i LEFT JOIN public.individual_address ia ON ia.individualid = cte_i.id LEFT JOIN public.address a ON ia.addressid = a.id , cte_search_criteria_waypoint cte_scw) rt "; if(searchObject.getSearchRadius() != null) { query = query + " WHERE rt.distance < :distance "; From 336dce56db8e8708b66e8a9382b2932f94cb21fd Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Wed, 18 Oct 2023 11:20:19 +0530 Subject: [PATCH 10/11] household version increased from 1.1.0 to 1.1.1-beta and individual version increased from 1.1.1 to 1.1.2-beta and added changelog --- health-services/household/CHANGELOG.md | 8 +++++++- health-services/household/pom.xml | 2 +- health-services/individual/CHANGELOG.md | 8 +++++++- health-services/individual/pom.xml | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/health-services/household/CHANGELOG.md b/health-services/household/CHANGELOG.md index 645e12b40e1..9fb0bc133a6 100644 --- a/health-services/household/CHANGELOG.md +++ b/health-services/household/CHANGELOG.md @@ -1,7 +1,13 @@ All notable changes to this module will be documented in this file. +## 1.1.1-beta + +- Added proximity based search support + +## 1.1.0 + + ## 1.0.0 - Base version -## 1.1.0 \ No newline at end of file diff --git a/health-services/household/pom.xml b/health-services/household/pom.xml index ee09d2ed4e3..0d726bd8cce 100644 --- a/health-services/household/pom.xml +++ b/health-services/household/pom.xml @@ -5,7 +5,7 @@ household jar household - 1.1.0 + 1.1.1-beta 1.8 ${java.version} diff --git a/health-services/individual/CHANGELOG.md b/health-services/individual/CHANGELOG.md index 645e12b40e1..94e615fa82f 100644 --- a/health-services/individual/CHANGELOG.md +++ b/health-services/individual/CHANGELOG.md @@ -1,7 +1,13 @@ All notable changes to this module will be documented in this file. +## 1.1.2-beta + +- Added proximity based search support + +## 1.1.0 + + ## 1.0.0 - Base version -## 1.1.0 \ No newline at end of file diff --git a/health-services/individual/pom.xml b/health-services/individual/pom.xml index 40a071672a4..6eca870f705 100644 --- a/health-services/individual/pom.xml +++ b/health-services/individual/pom.xml @@ -5,7 +5,7 @@ individual jar individual - 1.1.1 + 1.1.2-beta 1.8 ${java.version} From 069d842955c2167fc38ceca9cf7d81cdb864e9e7 Mon Sep 17 00:00:00 2001 From: kanishq-egov Date: Wed, 18 Oct 2023 15:07:28 +0530 Subject: [PATCH 11/11] updated health-campaign-models dependency in individual, household --- health-services/household/pom.xml | 2 +- health-services/individual/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/health-services/household/pom.xml b/health-services/household/pom.xml index 0d726bd8cce..dd4e667a832 100644 --- a/health-services/household/pom.xml +++ b/health-services/household/pom.xml @@ -49,7 +49,7 @@ org.egov.common health-services-models - 1.0.7-SNAPSHOT + 1.0.9-SNAPSHOT compile diff --git a/health-services/individual/pom.xml b/health-services/individual/pom.xml index 6eca870f705..61e349b8cc2 100644 --- a/health-services/individual/pom.xml +++ b/health-services/individual/pom.xml @@ -49,7 +49,7 @@ org.egov.common health-services-models - 1.0.7-SNAPSHOT + 1.0.9-SNAPSHOT compile