Skip to content

Commit 1e0a9a5

Browse files
authored
feat: 1165 activity search endpoint (#1186)
1 parent 982db11 commit 1e0a9a5

22 files changed

+1283
-31
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package ca.bc.gov.restapi.results.common.dto.activity;
2+
3+
import ca.bc.gov.restapi.results.common.SilvaConstants;
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
import java.util.List;
6+
import java.util.Objects;
7+
import lombok.Getter;
8+
import lombok.ToString;
9+
import org.springframework.util.CollectionUtils;
10+
11+
/** This class contains all possible filters when using the Activity Search API. */
12+
@Getter
13+
@ToString
14+
public class ActivitySearchFiltersDto {
15+
16+
@Schema(type = "array", nullable = true)
17+
private final List<String> bases;
18+
19+
@Schema(type = "array", nullable = true)
20+
private final List<String> techniques;
21+
22+
@Schema(type = "array", nullable = true)
23+
private final List<String> methods;
24+
25+
@Schema(type = "boolean", nullable = true)
26+
private final Boolean isComplete;
27+
28+
@Schema(type = "array", nullable = true)
29+
private final List<String> objectives;
30+
31+
@Schema(type = "array", nullable = true)
32+
private final List<String> fundingSources;
33+
34+
@Schema(type = "array", nullable = true)
35+
private final List<String> orgUnits;
36+
37+
@Schema(type = "array", nullable = true)
38+
private final List<String> openingCategories;
39+
40+
@Schema(type = "string")
41+
private final String fileId;
42+
43+
@Schema(type = "array", nullable = true)
44+
private final List<String> clientNumbers;
45+
46+
@Schema(type = "array", nullable = true)
47+
private final List<String> openingStatuses;
48+
49+
@Schema(type = "string", format = "date", nullable = true)
50+
private final String updateDateStart;
51+
52+
@Schema(type = "string", format = "date", nullable = true)
53+
private final String updateDateEnd;
54+
55+
/**
56+
* Creates a no-arg instance with all fields set to null, delegating to the all-args constructor
57+
* to apply defaults.
58+
*/
59+
public ActivitySearchFiltersDto() {
60+
this(null, null, null, null, null, null, null, null, null, null, null, null, null);
61+
}
62+
63+
/** Creates an instance of the activity search filter dto. */
64+
public ActivitySearchFiltersDto(
65+
List<String> bases,
66+
List<String> techniques,
67+
List<String> methods,
68+
Boolean isComplete,
69+
List<String> objectives,
70+
List<String> fundingSources,
71+
List<String> orgUnits,
72+
List<String> openingCategories,
73+
String fileId,
74+
List<String> clientNumbers,
75+
List<String> openingStatuses,
76+
String updateDateStart,
77+
String updateDateEnd) {
78+
this.bases = !CollectionUtils.isEmpty(bases) ? bases : List.of(SilvaConstants.NOVALUE);
79+
this.techniques =
80+
!CollectionUtils.isEmpty(techniques) ? techniques : List.of(SilvaConstants.NOVALUE);
81+
this.methods = !CollectionUtils.isEmpty(methods) ? methods : List.of(SilvaConstants.NOVALUE);
82+
this.isComplete = isComplete;
83+
this.objectives =
84+
!CollectionUtils.isEmpty(objectives) ? objectives : List.of(SilvaConstants.NOVALUE);
85+
this.fundingSources =
86+
!CollectionUtils.isEmpty(fundingSources) ? fundingSources : List.of(SilvaConstants.NOVALUE);
87+
this.orgUnits = !CollectionUtils.isEmpty(orgUnits) ? orgUnits : List.of(SilvaConstants.NOVALUE);
88+
this.openingCategories =
89+
!CollectionUtils.isEmpty(openingCategories)
90+
? openingCategories
91+
: List.of(SilvaConstants.NOVALUE);
92+
this.fileId = Objects.isNull(fileId) ? null : fileId.trim();
93+
this.clientNumbers =
94+
!CollectionUtils.isEmpty(clientNumbers) ? clientNumbers : List.of(SilvaConstants.NOVALUE);
95+
this.openingStatuses =
96+
!CollectionUtils.isEmpty(openingStatuses)
97+
? openingStatuses
98+
: List.of(SilvaConstants.NOVALUE);
99+
this.updateDateStart = Objects.isNull(updateDateStart) ? null : updateDateStart.trim();
100+
this.updateDateEnd = Objects.isNull(updateDateEnd) ? null : updateDateEnd.trim();
101+
}
102+
103+
public boolean hasAnyFilter() {
104+
return !SilvaConstants.NOVALUE.equals(bases.get(0))
105+
|| !SilvaConstants.NOVALUE.equals(techniques.get(0))
106+
|| !SilvaConstants.NOVALUE.equals(methods.get(0))
107+
|| isComplete != null
108+
|| !SilvaConstants.NOVALUE.equals(objectives.get(0))
109+
|| !SilvaConstants.NOVALUE.equals(fundingSources.get(0))
110+
|| !SilvaConstants.NOVALUE.equals(orgUnits.get(0))
111+
|| !SilvaConstants.NOVALUE.equals(openingCategories.get(0))
112+
|| (fileId != null && !fileId.isBlank())
113+
|| !SilvaConstants.NOVALUE.equals(clientNumbers.get(0))
114+
|| !SilvaConstants.NOVALUE.equals(openingStatuses.get(0))
115+
|| (updateDateStart != null && !updateDateStart.isBlank())
116+
|| (updateDateEnd != null && !updateDateEnd.isBlank());
117+
}
118+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package ca.bc.gov.restapi.results.common.dto.activity;
2+
3+
import ca.bc.gov.restapi.results.common.dto.CodeDescriptionDto;
4+
import ca.bc.gov.restapi.results.common.dto.ForestClientDto;
5+
import java.math.BigDecimal;
6+
import java.time.LocalDateTime;
7+
8+
public record ActivitySearchResponseDto(
9+
Long activityId,
10+
CodeDescriptionDto base,
11+
CodeDescriptionDto technique,
12+
CodeDescriptionDto method,
13+
boolean isComplete,
14+
CodeDescriptionDto fundingSource,
15+
String fileId,
16+
String cutBlock,
17+
Long openingId,
18+
String cuttingPermit,
19+
BigDecimal treatmentAmountArea,
20+
String intraAgencyNumber,
21+
CodeDescriptionDto openingCategory,
22+
CodeDescriptionDto orgUnit,
23+
ForestClientDto openingClient,
24+
LocalDateTime updateTimestamp) {}

backend/src/main/java/ca/bc/gov/restapi/results/common/endpoint/SearchEndpoint.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package ca.bc.gov.restapi.results.common.endpoint;
22

3+
import ca.bc.gov.restapi.results.common.dto.activity.ActivitySearchFiltersDto;
4+
import ca.bc.gov.restapi.results.common.dto.activity.ActivitySearchResponseDto;
35
import ca.bc.gov.restapi.results.common.dto.opening.OpeningSearchExactFiltersDto;
46
import ca.bc.gov.restapi.results.common.dto.opening.OpeningSearchResponseDto;
57
import ca.bc.gov.restapi.results.common.exception.MissingSearchParameterException;
8+
import ca.bc.gov.restapi.results.common.service.ActivityService;
69
import ca.bc.gov.restapi.results.common.service.OpeningSearchService;
710
import ca.bc.gov.restapi.results.oracle.SilvaOracleConstants;
811
import java.util.List;
@@ -24,6 +27,8 @@ public class SearchEndpoint {
2427

2528
private final OpeningSearchService openingSearchService;
2629

30+
private final ActivityService activityService;
31+
2732
/**
2833
* Exact search for Openings with direct value matching on provided filters.
2934
*
@@ -121,4 +126,44 @@ public Page<OpeningSearchResponseDto> openingSearchExact(
121126

122127
return openingSearchService.openingSearchExact(filtersDto, paginationParameters);
123128
}
129+
130+
@GetMapping("/activities")
131+
public Page<ActivitySearchResponseDto> activitySearch(
132+
@RequestParam(value = "bases", required = false) List<String> bases,
133+
@RequestParam(value = "techniques", required = false) List<String> techniques,
134+
@RequestParam(value = "methods", required = false) List<String> methods,
135+
@RequestParam(value = "isComplete", required = false) Boolean isComplete,
136+
@RequestParam(value = "objectives", required = false) List<String> objectives,
137+
@RequestParam(value = "fundingSources", required = false) List<String> fundingSources,
138+
@RequestParam(value = "orgUnits", required = false) List<String> orgUnits,
139+
@RequestParam(value = "openingCategories", required = false) List<String> openingCategories,
140+
@RequestParam(value = "fileId", required = false) String fileId,
141+
@RequestParam(value = "clientNumbers", required = false) List<String> clientNumbers,
142+
@RequestParam(value = "openingStatuses", required = false) List<String> openingStatuses,
143+
@RequestParam(value = "updateDateStart", required = false) String updateDateStart,
144+
@RequestParam(value = "updateDateEnd", required = false) String updateDateEnd,
145+
@ParameterObject Pageable paginationParameters) {
146+
147+
ActivitySearchFiltersDto filters =
148+
new ActivitySearchFiltersDto(
149+
bases,
150+
techniques,
151+
methods,
152+
isComplete,
153+
objectives,
154+
fundingSources,
155+
orgUnits,
156+
openingCategories,
157+
fileId,
158+
clientNumbers,
159+
openingStatuses,
160+
updateDateStart,
161+
updateDateEnd);
162+
163+
if (!filters.hasAnyFilter()) {
164+
throw new MissingSearchParameterException();
165+
}
166+
167+
return activityService.activitySearch(filters, paginationParameters);
168+
}
124169
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package ca.bc.gov.restapi.results.common.projection;
2+
3+
import java.math.BigDecimal;
4+
import java.time.LocalDateTime;
5+
6+
/** Projection interface used for activity search native queries. */
7+
public interface ActivitySearchProjection {
8+
9+
Long getActivityId();
10+
11+
String getBaseCode();
12+
13+
String getBaseDescription();
14+
15+
String getTechniqueCode();
16+
17+
String getTechniqueDescription();
18+
19+
String getMethodCode();
20+
21+
String getMethodDescription();
22+
23+
Long getIsComplete();
24+
25+
String getFundingSourceCode();
26+
27+
String getFundingSourceDescription();
28+
29+
String getFileId();
30+
31+
String getCutBlock();
32+
33+
Long getOpeningId();
34+
35+
String getCuttingPermit();
36+
37+
BigDecimal getTreatmentAmountArea();
38+
39+
String getIntraAgencyNumber();
40+
41+
String getOpeningCategoryCode();
42+
43+
String getOpeningCategoryDescription();
44+
45+
String getOrgUnitCode();
46+
47+
String getOrgUnitDescription();
48+
49+
String getOpeningClientCode();
50+
51+
Long getTotalCount();
52+
53+
LocalDateTime getUpdateTimestamp();
54+
}

backend/src/main/java/ca/bc/gov/restapi/results/common/repository/ActivityTreatmentUnitRepository.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package ca.bc.gov.restapi.results.common.repository;
22

3+
import ca.bc.gov.restapi.results.common.dto.activity.ActivitySearchFiltersDto;
4+
import ca.bc.gov.restapi.results.common.projection.ActivitySearchProjection;
35
import ca.bc.gov.restapi.results.common.projection.activity.*;
46
import ca.bc.gov.restapi.results.common.projection.opening.OpeningActivitiesActivitiesProjection;
57
import ca.bc.gov.restapi.results.common.projection.opening.OpeningActivitiesDisturbanceProjection;
6-
import org.springframework.data.domain.Page;
7-
import org.springframework.data.domain.Pageable;
8-
98
import java.util.List;
109
import java.util.Optional;
10+
import org.springframework.data.domain.Page;
11+
import org.springframework.data.domain.Pageable;
1112

1213
public interface ActivityTreatmentUnitRepository {
1314
Page<OpeningActivitiesDisturbanceProjection> getOpeningActivitiesDisturbanceByOpeningId(
@@ -27,4 +28,7 @@ Page<OpeningActivitiesActivitiesProjection> getOpeningActivitiesActivitiesByOpen
2728
Optional<OpeningActivityPruningProjection> getOpeningActivityPR(Long openingId, Long atuId);
2829

2930
Optional<Long> getOpeningActivitySP(Long openingId, Long atuId);
31+
32+
List<ActivitySearchProjection> activitySearch(
33+
ActivitySearchFiltersDto filters, long offset, long size);
3034
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package ca.bc.gov.restapi.results.common.service;
2+
3+
import ca.bc.gov.restapi.results.common.dto.activity.ActivitySearchFiltersDto;
4+
import ca.bc.gov.restapi.results.common.dto.activity.ActivitySearchResponseDto;
5+
import org.springframework.data.domain.Page;
6+
import org.springframework.data.domain.Pageable;
7+
8+
public interface ActivityService {
9+
Page<ActivitySearchResponseDto> activitySearch(
10+
ActivitySearchFiltersDto filters, Pageable pagination);
11+
}

0 commit comments

Comments
 (0)