Skip to content

Commit

Permalink
avniproject/avni-webapp#1360 | Resolve merge issues after cherry-pick…
Browse files Browse the repository at this point in the history
… of avni-webapp#1300 changes
  • Loading branch information
1t5j0y authored and himeshr committed Oct 18, 2024
1 parent c9a23e3 commit 8e3a36c
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.avni.server.dao;

import org.avni.server.application.projections.LocationProjection;
import org.avni.server.application.projections.CatchmentAddressProjection;
import org.avni.server.application.projections.LocationProjection;
import org.avni.server.domain.AddressLevel;
import org.avni.server.domain.AddressLevelType;
import org.avni.server.domain.Catchment;
Expand All @@ -18,20 +18,21 @@

import javax.persistence.QueryHint;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Repository
@RepositoryRestResource(collectionResourceRel = "locations", path = "locations")
public interface LocationRepository extends ReferenceDataRepository<AddressLevel>, FindByLastModifiedDateTime<AddressLevel>, OperatingIndividualScopeAwareRepository<AddressLevel> {

@Query(value = "select al.id, al.uuid, title, type_id as typeId, alt.name as typeString, al.parent_id as parentId, " +
"cast(lineage as text) as lineage, title_lineage as titleLineage, alt.level " +
String locationProjectionBaseQuery = "select al.id, al.uuid, al.title, al.type_id as typeId, alt.name as typeString, al.parent_id as parentId, " +
"cast(al.lineage as text) as lineage, null as titleLineage, alt.level " +
"from address_level al " +
"left join address_level_type alt on alt.id = al.type_id " +
"left join title_lineage_locations_view tll on tll.lowestpoint_id = al.id " +
"where al.id in (:ids)",
nativeQuery = true)
List<LocationProjection> findByIdIn(Long[] ids);
"where (:title is null or lower(al.title) like lower(concat('%', :title,'%'))) " +
"and al.is_voided = false ";

@Query(value = "select al1.*\n" +
"from catchment c\n" +
Expand All @@ -56,13 +57,13 @@ public interface LocationRepository extends ReferenceDataRepository<AddressLevel

AddressLevel findByTitleAndCatchmentsUuid(String title, String uuid);

String locationProjectionBaseQuery = "select al.id, al.uuid, al.title, al.type_id as typeId, alt.name as typeString, al.parent_id as parentId, " +
"cast(al.lineage as text) as lineage, tll.title_lineage as titleLineage, alt.level " +
@Query(value = "select al.id, al.uuid, title, type_id as typeId, alt.name as typeString, al.parent_id as parentId, " +
"cast(lineage as text) as lineage, null as titleLineage, alt.level " +
"from address_level al " +
"left join address_level_type alt on alt.id = al.type_id " +
"left join title_lineage_locations_view tll on tll.lowestpoint_id = al.id " +
"where (:title is null or lower(al.title) like lower(concat('%', :title,'%'))) " +
"and al.is_voided = false ";
"where al.id in (:ids)",
nativeQuery = true)
List<LocationProjection> findByIdIn(Long[] ids);

String orderByTitle = " order by al.title ";
String findLocationProjectionByTitleQuery = locationProjectionBaseQuery + orderByTitle;
Expand Down Expand Up @@ -214,40 +215,38 @@ default Optional<AddressLevel> findByTitleLineageIgnoreCase(String locationTitle
String getTitleLineageById(Long addressId);

@Query(value = "select al.id, al.uuid, title, type_id as typeId, alt.name as typeString, al.parent_id as parentId, " +
"cast(lineage as text) as lineage, title_lineage as titleLineage, alt.level " +
"cast(lineage as text) as lineage, " +
"null as titleLineage, " +
"alt.level " +
"from address_level al " +
"left join address_level_type alt on alt.id = al.type_id " +
"left join title_lineage_locations_view tll on tll.lowestpoint_id = al.id " +
"where al.is_voided = false",
nativeQuery = true)
Page<LocationProjection> findNonVoidedLocations(Pageable pageable);

@Query(value = "select al.id, al.uuid, title, type_id as typeId, alt.name as typeString, al.parent_id as parentId, " +
"cast(lineage as text) as lineage, title_lineage as titleLineage, alt.level " +
"cast(lineage as text) as lineage, null as titleLineage, alt.level " +
"from address_level al " +
"left join address_level_type alt on alt.id = al.type_id " +
"left join title_lineage_locations_view tll on tll.lowestpoint_id = al.id " +
"where al.is_voided = false " +
"and al.type_id = :typeId " +
"order by al.title ",
nativeQuery = true)
List<LocationProjection> findNonVoidedLocationsByTypeId(Long typeId);

@Query(value = "select al.id, al.uuid, title, type_id as typeId, alt.name as typeString, al.parent_id as parentId, " +
"cast(lineage as text) as lineage, title_lineage as titleLineage, alt.level " +
"cast(lineage as text) as lineage, null as titleLineage, alt.level " +
"from address_level al " +
"left join address_level_type alt on alt.id = al.type_id " +
"left join title_lineage_locations_view tll on tll.lowestpoint_id = al.id " +
"where al.is_voided = false " +
"and al.uuid = :uuid ",
nativeQuery = true)
LocationProjection findNonVoidedLocationsByUuid(String uuid);

@Query(value = "select al.id, al.uuid, title, type_id as typeId, alt.name as typeString, al.parent_id as parentId,\n" +
"cast(lineage as text) as lineage, title_lineage as titleLineage, alt.level " +
"cast(lineage as text) as lineage, null as titleLineage, alt.level " +
"from address_level al\n" +
"left join address_level_type alt on alt.id = al.type_id\n" +
"left join title_lineage_locations_view tll on tll.lowestpoint_id = al.id " +
"where lineage @>" +
" (select lineage" +
" from address_level" +
Expand All @@ -256,10 +255,9 @@ default Optional<AddressLevel> findByTitleLineageIgnoreCase(String locationTitle
List<LocationProjection> getParentsWithMaxLevelTypeId(String uuid, Long maxLevelTypeId);

@Query(value = "select al.id, al.uuid, title, type_id as typeId, alt.name as typeString, al.parent_id as parentId,\n" +
"cast(lineage as text) as lineage, title_lineage as titleLineage, alt.level " +
"cast(lineage as text) as lineage, null as titleLineage, alt.level " +
"from address_level al\n" +
"left join address_level_type alt on alt.id = al.type_id\n" +
"left join title_lineage_locations_view tll on tll.lowestpoint_id = al.id " +
"where lineage @>" +
" (select lineage" +
" from address_level" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import org.avni.server.application.KeyType;
import org.avni.server.application.projections.CatchmentAddressProjection;
import org.avni.server.application.projections.LocationProjection;
import org.avni.server.dao.AddressLevelTypeRepository;
import org.avni.server.dao.LocationRepository;
import org.avni.server.domain.*;
import org.avni.server.util.ObjectMapperSingleton;
import org.avni.server.web.request.AddressLevelContract;
import org.avni.server.web.request.AddressLevelContractWeb;
import org.avni.server.web.request.webapp.SubjectTypeSetting;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;

import java.util.*;
Expand Down Expand Up @@ -99,6 +103,20 @@ public String getTitleLineage(AddressLevel location) {
return locationRepository.getTitleLineageById(location.getId());
}

public List<AddressLevelContractWeb> addTitleLineageToLocation(List<LocationProjection> locationProjections) {
Map<Long, String> titleLineages = getTitleLineages(locationProjections.stream().map(LocationProjection::getId).collect(Collectors.toList()));
return locationProjections.stream().map(locationProjection -> {
AddressLevelContractWeb addressLevel = AddressLevelContractWeb.fromEntity(locationProjection);
addressLevel.setTitleLineage(titleLineages.get(locationProjection.getId()));
return addressLevel;
}).collect(Collectors.toList());
}

public Page<AddressLevelContractWeb> addTitleLineageToLocation(Page<LocationProjection> locationProjections) {
List<AddressLevelContractWeb> locationWebContracts = addTitleLineageToLocation(locationProjections.getContent());
return new PageImpl<>(locationWebContracts, locationProjections.getPageable(), locationProjections.getTotalElements());
}

// This method uses in memory approach instead of database, because for smaller number of addresses the query plan to achive this is expensive due to over estimation by postgres.
public Map<Long, String> getTitleLineages(List<Long> addressIds) {
List<AddressLevel> addresses = locationRepository.findAllByIdIn(addressIds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.avni.server.dao.sync.SyncEntityName;
import org.avni.server.domain.AddressLevel;
import org.avni.server.domain.accessControl.PrivilegeType;
import org.avni.server.service.AddressLevelService;
import org.avni.server.service.LocationService;
import org.avni.server.service.ScopeBasedSyncService;
import org.avni.server.service.UserService;
Expand All @@ -34,8 +35,8 @@

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@RepositoryRestController
public class LocationController implements RestControllerResourceProcessor<AddressLevel> {
Expand All @@ -47,15 +48,17 @@ public class LocationController implements RestControllerResourceProcessor<Addre
private final ScopeBasedSyncService<AddressLevel> scopeBasedSyncService;
private final AccessControlService accessControlService;
private final LocationSyncRepository locationSyncRepository;
private final AddressLevelService addressLevelService;

@Autowired
public LocationController(LocationRepository locationRepository, UserService userService, LocationService locationService, ScopeBasedSyncService<AddressLevel> scopeBasedSyncService, AccessControlService accessControlService, LocationSyncRepository locationSyncRepository) {
public LocationController(LocationRepository locationRepository, UserService userService, LocationService locationService, ScopeBasedSyncService<AddressLevel> scopeBasedSyncService, AccessControlService accessControlService, LocationSyncRepository locationSyncRepository, AddressLevelService addressLevelService) {
this.locationRepository = locationRepository;
this.userService = userService;
this.locationService = locationService;
this.scopeBasedSyncService = scopeBasedSyncService;
this.accessControlService = accessControlService;
this.locationSyncRepository = locationSyncRepository;
this.addressLevelService = addressLevelService;
this.logger = LoggerFactory.getLogger(this.getClass());
}

Expand All @@ -77,18 +80,18 @@ public ResponseEntity<?> save(@RequestBody List<LocationContract> locationContra

@GetMapping(value = "/locations")
@ResponseBody
public Page<LocationProjection> getAll(Pageable pageable) {
return locationRepository.findNonVoidedLocations(pageable);
public Page<AddressLevelContractWeb> getAll(Pageable pageable) {
return addressLevelService.addTitleLineageToLocation(locationRepository.findNonVoidedLocations(pageable));
}

@GetMapping(value = "locations/search/find")
@ResponseBody
public Page<LocationProjection> find(
public Page<AddressLevelContractWeb> find(
@RequestParam(value = "title", defaultValue = "") String title,
@RequestParam(value = "typeId", required = false) Integer typeId,
@RequestParam(value = "parentId", required = false) Integer parentId,
Pageable pageable) {
return locationService.find(new LocationSearchRequest(title, typeId, parentId, pageable));
return addressLevelService.addTitleLineageToLocation(locationService.find(new LocationSearchRequest(title, typeId, parentId, pageable)));
}

@GetMapping(value = "locations/search/findAsList")
Expand All @@ -101,11 +104,11 @@ public List<LocationProjection> findAsList(

@GetMapping(value = "/locations/search/findAllById")
@ResponseBody
public List<LocationProjection> findByIdIn(@Param("ids") Long[] ids) {
public List<AddressLevelContractWeb> findByIdIn(@Param("ids") Long[] ids) {
if (ids == null || ids.length == 0) {
return new ArrayList<>();
}
return locationRepository.findByIdIn(ids);
return addressLevelService.addTitleLineageToLocation(locationRepository.findByIdIn(ids));
}

@RequestMapping(value = {"/locations/search/lastModified", "/locations/search/byCatchmentAndLastModified"}, method = RequestMethod.GET)
Expand Down Expand Up @@ -157,27 +160,27 @@ public ResponseEntity voidLocation(@PathVariable("id") Long id) {
@GetMapping(value = "/locations/search/typeId/{typeId}")
@ResponseBody
public List<AddressLevelContractWeb> getLocationsByTypeId(@PathVariable("typeId") Long typeId) {
//TODO API does not appear to be in use. Remove.
accessControlService.checkPrivilege(PrivilegeType.EditLocation);
return locationRepository.findNonVoidedLocationsByTypeId(typeId).stream()
.map(AddressLevelContractWeb::fromEntity)
.collect(Collectors.toList());
return addressLevelService.addTitleLineageToLocation(locationRepository.findNonVoidedLocationsByTypeId(typeId));
}

@GetMapping(value = "locations/parents/{uuid}")
@ResponseBody
public List<LocationProjection> getParents(@PathVariable("uuid") String uuid,
@RequestParam(value = "maxLevelTypeId", required = false) Long maxLevelTypeId) {
return locationService.getParents(uuid, maxLevelTypeId);
public List<AddressLevelContractWeb> getParents(@PathVariable("uuid") String uuid,
@RequestParam(value = "maxLevelTypeId", required = false) Long maxLevelTypeId) {
return addressLevelService.addTitleLineageToLocation(locationService.getParents(uuid, maxLevelTypeId));
}


@GetMapping(value = "/locations/web")
@ResponseBody
public ResponseEntity getLocationByParam(@RequestParam("uuid") String uuid) {
public ResponseEntity<AddressLevelContractWeb> getLocationByParam(@RequestParam("uuid") String uuid) {
LocationProjection addressLevel = locationRepository.findNonVoidedLocationsByUuid(uuid);
if (addressLevel == null) {
return ResponseEntity.notFound().build();
}
return new ResponseEntity<>(AddressLevelContractWeb.fromEntity(addressLevel), HttpStatus.OK);
AddressLevelContractWeb addressLevelContract = addressLevelService.addTitleLineageToLocation(Collections.singletonList(addressLevel)).get(0);
return new ResponseEntity<>(addressLevelContract, HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ public class AddressLevelContractWeb {

private Long id;
private String name;
private String title; // set to same value as name to handle different consumers of contract
private String type;
private String typeString; // set to same value as type to handle different consumers of contract
private Long typeId;
private Double level;
private String lineage;
Expand All @@ -19,7 +21,9 @@ public static AddressLevelContractWeb fromEntity(AddressLevel addressLevel) {
AddressLevelContractWeb addressLevelContractWeb = new AddressLevelContractWeb();
addressLevelContractWeb.setId(addressLevel.getId());
addressLevelContractWeb.setName(addressLevel.getTitle());
addressLevelContractWeb.setType(addressLevel.getType().getName());
addressLevelContractWeb.setTitle(addressLevel.getTitle());
addressLevelContractWeb.setType(addressLevel.getTypeString());
addressLevelContractWeb.setTypeString(addressLevel.getTypeString());
addressLevelContractWeb.setTypeId(addressLevel.getType().getId());
addressLevelContractWeb.setLevel(addressLevel.getLevel());
addressLevelContractWeb.setParentId(addressLevel.getParentId());
Expand All @@ -32,7 +36,9 @@ public static AddressLevelContractWeb fromEntity(LocationProjection locationProj
AddressLevelContractWeb addressLevelContractWeb = new AddressLevelContractWeb();
addressLevelContractWeb.setId(locationProjection.getId());
addressLevelContractWeb.setName(locationProjection.getTitle());
addressLevelContractWeb.setTitle(locationProjection.getTitle());
addressLevelContractWeb.setType(locationProjection.getTypeString());
addressLevelContractWeb.setTypeString(locationProjection.getTypeString());
addressLevelContractWeb.setTypeId(locationProjection.getTypeId());
addressLevelContractWeb.setLevel(locationProjection.getLevel());
addressLevelContractWeb.setParentId(locationProjection.getParentId());
Expand Down Expand Up @@ -113,4 +119,20 @@ public Long getTypeId() {
public void setTypeId(Long typeId) {
this.typeId = typeId;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getTypeString() {
return typeString;
}

public void setTypeString(String typeString) {
this.typeString = typeString;
}
}

0 comments on commit 8e3a36c

Please sign in to comment.