Skip to content

Commit

Permalink
fix(SILVA-589): fixing silviculture search (#532)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulushcgcj authored Dec 17, 2024
1 parent 64305c8 commit a90f2ee
Show file tree
Hide file tree
Showing 14 changed files with 108 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ public class SilvaOracleConstants {
public static final String TIMBER_MARK = "timberMark";
public static final String MAIN_SEARCH_TERM = "mainSearchTerm";
public static final String LOCATION_CODE = "clientLocationCode";
public static final String CLIENT_NUMBER = "clientNumber";
public static final String NOVALUE = "NOVALUE";
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class OpeningSearchFiltersDto {
// Main input, it can be one of Opening ID, Opening Number, Timber Mark ID, or File ID
private final String mainSearchTerm;
private final String clientLocationCode;
private final String clientNumber;

@Setter
private String requestUserId;
Expand All @@ -62,6 +63,7 @@ public OpeningSearchFiltersDto(
String cutBlockId,
String timberMark,
String clientLocationCode,
String clientNumber,
String mainSearchTerm) {
this.orgUnit = !CollectionUtils.isEmpty(orgUnit) ? orgUnit : List.of(
SilvaOracleConstants.NOVALUE);
Expand Down Expand Up @@ -97,6 +99,7 @@ public OpeningSearchFiltersDto(
Objects.isNull(mainSearchTerm) ? null : mainSearchTerm.toUpperCase().trim();
this.clientLocationCode =
Objects.isNull(clientLocationCode) ? null : clientLocationCode.trim();
this.clientNumber = Objects.isNull(clientNumber) ? null : clientNumber.trim();
}

/**
Expand Down Expand Up @@ -130,6 +133,7 @@ public boolean hasValue(String prop) {
case SilvaOracleConstants.TIMBER_MARK -> !Objects.isNull(this.timberMark);
case SilvaOracleConstants.MAIN_SEARCH_TERM -> !Objects.isNull(this.mainSearchTerm);
case SilvaOracleConstants.LOCATION_CODE -> !Objects.isNull(this.clientLocationCode);
case SilvaOracleConstants.CLIENT_NUMBER -> !Objects.isNull(this.clientNumber);
default -> {
log.warn("Prop not found {}", prop);
yield false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ public PaginatedResult<OpeningSearchResponseDto> openingSearch(
String cutBlockId,
@RequestParam(value = "clientLocationCode", required = false)
String clientLocationCode,
@RequestParam(value ="clientNumber", required = false)
String clientNumber,
@RequestParam(value = "timberMark", required = false)
String timberMark,
@Valid PaginationParameters paginationParameters) {
Expand All @@ -116,6 +118,7 @@ public PaginatedResult<OpeningSearchResponseDto> openingSearch(
cutBlockId,
timberMark,
clientLocationCode,
clientNumber,
mainSearchTerm);
return openingService.openingSearch(filtersDto, paginationParameters);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ LEFT JOIN THE.STOCKING_MILESTONE smfg ON (smfg.STOCKING_STANDARD_UNIT_ID = ssu.S
)
AND (
NVL(:#{#filter.clientLocationCode},'NOVALUE') = 'NOVALUE' OR client_location = :#{#filter.clientLocationCode}
)
AND (
NVL(:#{#filter.clientNumber},'NOVALUE') = 'NOVALUE' OR client_number = :#{#filter.clientNumber}
)""",
countQuery = """
SELECT count(opening_id) as total
Expand Down Expand Up @@ -308,6 +311,9 @@ LEFT JOIN THE.STOCKING_MILESTONE smfg ON (smfg.STOCKING_STANDARD_UNIT_ID = ssu.S
AND (
NVL(:#{#filter.clientLocationCode},'NOVALUE') = 'NOVALUE' OR res.CLIENT_LOCN_CODE = :#{#filter.clientLocationCode}
)
AND (
NVL(:#{#filter.clientNumber},'NOVALUE') = 'NOVALUE' OR res.CLIENT_NUMBER = :#{#filter.clientNumber}
)
GROUP BY o.OPENING_ID
)""",
nativeQuery = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ void getRecentOpenings_fetchNoUserPaginated_shouldSucceed() {
void openingSearch_fileId_shouldSucceed() {

PaginatedResult<OpeningSearchResponseDto> result =
openingService.openingSearch(new OpeningSearchFiltersDto(
openingService.openingSearch(
new OpeningSearchFiltersDto(
null,
null,
null,
null,
Expand Down Expand Up @@ -121,7 +123,8 @@ void openingSearch_fileId_shouldSucceed() {
void openingSearch_orgUnit_shouldSucceed() {

PaginatedResult<OpeningSearchResponseDto> result =
openingService.openingSearch(new OpeningSearchFiltersDto(
openingService.openingSearch(
new OpeningSearchFiltersDto(
List.of("TWO"),
null,
null,
Expand All @@ -139,7 +142,8 @@ void openingSearch_orgUnit_shouldSucceed() {
null,
null,
null,
null
null,
null
),
new PaginationParameters(0, 10)
);
Expand Down Expand Up @@ -198,6 +202,7 @@ void openingSearch_noRecordsFound_shouldSucceed() {
null,
null,
null,
null,
"ABCD"
),
new PaginationParameters(0, 10)
Expand Down Expand Up @@ -236,6 +241,7 @@ void openingSearch_maxPageException_shouldFail() {
null,
null,
null,
null,
"FTML"
),
new PaginationParameters(0, 2999)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ describe("AutocompleteClientLocation", () => {
});

it("renders both ComboBoxes and their titles", () => {
render(<AutocompleteClientLocation setValue={vi.fn()} />);
render(<AutocompleteClientLocation setLocationValue={vi.fn()} setClientValue={vi.fn()}/>);
expect(screen.getByText("Client")).toBeInTheDocument();
expect(screen.getByText("Location code")).toBeInTheDocument();
});

it("disables the Location ComboBox initially", () => {
render(<AutocompleteClientLocation setValue={vi.fn()} />);
render(<AutocompleteClientLocation setLocationValue={vi.fn()} setClientValue={vi.fn()} />);
expect(screen.getByRole("combobox", { name: /location code/i })).toBeDisabled();
});

it("calls fetchOptions when typing in the Client ComboBox", async () => {
render(<AutocompleteClientLocation setValue={vi.fn()} />);
render(<AutocompleteClientLocation setLocationValue={vi.fn()} setClientValue={vi.fn()} />);

const clientInput = screen.getByRole("combobox", { name: /client/i });
await userEvent.type(clientInput, "Client");
Expand All @@ -60,7 +60,7 @@ describe("AutocompleteClientLocation", () => {
});

it("enables the Location ComboBox when a client is selected", async () => {
render(<AutocompleteClientLocation setValue={vi.fn()} />);
render(<AutocompleteClientLocation setLocationValue={vi.fn()} setClientValue={vi.fn()} />);

const clientInput = screen.getByRole("combobox", { name: /client/i });
await userEvent.type(clientInput, "Client");
Expand All @@ -73,9 +73,10 @@ describe("AutocompleteClientLocation", () => {
});

it("clears the location selection when the client is reset", async () => {
const mockSetValue = vi.fn();
const mockSetLocationValue = vi.fn();
const mockSetClientValue = vi.fn();

render(<AutocompleteClientLocation setValue={mockSetValue} />);
render(<AutocompleteClientLocation setLocationValue={mockSetLocationValue} setClientValue={mockSetClientValue} />);

// Select a client
const clientInput = screen.getByRole("combobox", { name: /client/i });
Expand All @@ -89,21 +90,22 @@ describe("AutocompleteClientLocation", () => {
await userEvent.click(locationInput);
const locationOption = screen.getByText(mockLocations[0].label);
await userEvent.click(locationOption);
expect(mockSetValue).toHaveBeenCalledWith("A");
expect(mockSetLocationValue).toHaveBeenCalledWith("A");

// Clear client selection
const clientClearButton = screen.getAllByRole("button", { name: /clear/i });
fireEvent.click(clientClearButton[0]);

expect(mockUpdateOptions).toHaveBeenCalledWith("locations", []);
expect(mockUpdateOptions).toHaveBeenCalledWith("clients", []);
expect(mockSetValue).toHaveBeenCalledWith(null);
expect(mockSetLocationValue).toHaveBeenCalledWith(null);
});

it("calls setValue when a location is selected", async () => {
const mockSetValue = vi.fn();
const mockSetLocationValue = vi.fn();
const mockSetClientValue = vi.fn();

render(<AutocompleteClientLocation setValue={mockSetValue} />);
render(<AutocompleteClientLocation setLocationValue={mockSetLocationValue} setClientValue={mockSetClientValue} />);

// Select a client
const clientInput = screen.getByRole("combobox", { name: /client/i });
Expand All @@ -117,6 +119,6 @@ describe("AutocompleteClientLocation", () => {
await userEvent.click(locationInput);
const locationOption = screen.getByText(mockLocations[0].label);
await userEvent.click(locationOption);
expect(mockSetValue).toHaveBeenCalledWith("A");
expect(mockSetLocationValue).toHaveBeenCalledWith("A");
});
});
6 changes: 3 additions & 3 deletions frontend/src/__test__/contexts/OpeningsSearch.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('OpeningsSearchProvider', () => {

it('should initialize with default values', () => {
expect(screen.getByTestId('searchTerm').textContent).toBe('');
expect(screen.getByTestId('startDate').textContent).toBe('null');
expect(screen.getByTestId('startDate').textContent).toBe('undefined');
});

it('should update searchTerm', () => {
Expand All @@ -43,14 +43,14 @@ describe('OpeningsSearchProvider', () => {
expect(screen.getByTestId('startDate').textContent).not.toBe('null');

fireEvent.click(screen.getByTestId('clearFilters'));
expect(screen.getByTestId('startDate').textContent).toBe('null');
expect(screen.getByTestId('startDate').textContent).toBe('undefined');
});

it('should clear individual field', () => {
fireEvent.click(screen.getByTestId('setFilters'));
expect(screen.getByTestId('startDate').textContent).not.toBe('null');

fireEvent.click(screen.getByTestId('clearStartDate'));
expect(screen.getByTestId('startDate').textContent).toBe('null');
expect(screen.getByTestId('startDate').textContent).toBe('undefined');
});
});
19 changes: 14 additions & 5 deletions frontend/src/components/AutocompleteClientLocation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ interface AutocompleteComboboxProps{
}

interface AutocompleteComponentProps {
setValue: (value: string | null) => void;
setLocationValue: (value: string | null) => void;
setClientValue: (value: string | null) => void;
}

export interface AutocompleteComponentRefProps {
Expand Down Expand Up @@ -67,7 +68,7 @@ export const fetchValues = async (query: string, key: string) => {
};

const AutocompleteClientLocation: React.ForwardRefExoticComponent<AutocompleteComponentProps & React.RefAttributes<AutocompleteComponentRefProps>> = forwardRef<AutocompleteComponentRefProps, AutocompleteComponentProps>(
({ setValue }, ref) =>
({ setLocationValue, setClientValue }, ref) =>
{
const { options, fetchOptions, updateOptions } = useAutocomplete();
const [isActive, setIsActive] = useState(false);
Expand All @@ -80,16 +81,23 @@ const AutocompleteClientLocation: React.ForwardRefExoticComponent<AutocompleteCo
updateOptions("locations", []);
updateOptions("clients", []);
setClient(null);
setValue(null);
setLocationValue(null);
setIsActive(false);
setLocation(null);
};

const clearValues = () => {
setClient(null);
setClient(null);
setLocation(null);
}

const selectClient = (selectedItem: AutocompleteProps) => {
if (selectedItem) {
setIsActive(true);
setClient(selectedItem);
fetchOptions(selectedItem.id, "locations");
setClientValue(selectedItem.id);
}else{
clearClient();
}
Expand Down Expand Up @@ -127,12 +135,12 @@ const AutocompleteClientLocation: React.ForwardRefExoticComponent<AutocompleteCo
}, [locationName]);

useImperativeHandle(ref, () => ({
reset: () => setLocation(null)
reset: () => clearValues()
}));

// Why do we keep this then? Because of the onChange start to work, this will work as it was intended
useEffect(() => {
setValue(location?.id ?? null);
setLocationValue(location?.id ?? null);
}, [location]);

return (
Expand All @@ -153,6 +161,7 @@ const AutocompleteClientLocation: React.ForwardRefExoticComponent<AutocompleteCo
disabled={!isActive}
id="client-location"
className="flex-fill"
selectedItem={location}
onInputChange={setLocationName}
onChange={(item: AutocompleteComboboxProps) => setLocation(item.selectedItem)}
itemToElement={(item: AutocompleteProps) => item.label}
Expand Down
1 change: 0 additions & 1 deletion frontend/src/components/BarChartGrouped/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ const BarChartGrouped = (): JSX.Element => {
return (
<Grid condensed>
<Column sm={4} md={3} lg={5}>
<p>{searchParameters}</p>
<FilterableMultiSelect
label="District"
id="district-dropdown"
Expand Down
Loading

0 comments on commit a90f2ee

Please sign in to comment.