From 24ab6d851e3c963382cc18f85b9127df67a66a2e Mon Sep 17 00:00:00 2001 From: michaldev0 <125133223+michaldev0@users.noreply.github.com> Date: Mon, 25 May 2026 11:10:36 +0200 Subject: [PATCH 1/2] OLMIS-7779: Add supplyingFacility query parameter to /api/requisitions/search External integrations (MSupply) can now filter requisitions by supplyingFacility server-side instead of pulling all and filtering client-side. --- CHANGELOG.md | 1 + .../RequisitionRepositoryIntegrationTest.java | 1 + .../DefaultRequisitionSearchParams.java | 1 + .../custom/RequisitionSearchParams.java | 2 ++ .../impl/RequisitionRepositoryImpl.java | 3 +++ .../service/JasperReportsViewService.java | 2 +- .../web/QueryRequisitionSearchParams.java | 17 ++++++++++++++++- .../web/RequisitionController.java | 2 +- src/main/resources/api-definition.yaml | 5 +++++ .../service/JasperReportsViewServiceTest.java | 2 +- .../service/RequisitionServiceTest.java | 2 ++ ...ultRequisitionSearchParamsDataBuilder.java | 7 +++++++ .../web/QueryRequisitionSearchParamsTest.java | 19 ++++++++++++++++++- 13 files changed, 59 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85e70edee..4826f19c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Improvements: to ensure notifications are returned in the correct language. * [ODRC-101](https://openlmis.atlassian.net/browse/ODRC-101): Panel 'Number of Requisitions to be created this month' on home page should not count emergency requisitions +* [OLMIS-7779](https://openlmis.atlassian.net/browse/OLMIS-7779): Add supplyingFacility query parameter to /api/requisitions/search. Bug fixes: * [MALAWISUP-7022](https://openlmis.atlassian.net/browse/MALAWISUP-7022): Fix /api/requisitions/search failing for users with many permissions (Postgres bind-parameter limit). diff --git a/src/integration-test/java/org/openlmis/requisition/repository/RequisitionRepositoryIntegrationTest.java b/src/integration-test/java/org/openlmis/requisition/repository/RequisitionRepositoryIntegrationTest.java index 8a9d5bca4..fe0b0d793 100644 --- a/src/integration-test/java/org/openlmis/requisition/repository/RequisitionRepositoryIntegrationTest.java +++ b/src/integration-test/java/org/openlmis/requisition/repository/RequisitionRepositoryIntegrationTest.java @@ -1016,6 +1016,7 @@ public void searchShouldUseSortProperties() { RequisitionSearchParams searchParams = new DefaultRequisitionSearchParams( requisitionToCopy.getFacilityId(), requisitionToCopy.getProgramId(), requisitionToCopy.getProcessingPeriodId(), requisitionToCopy.getSupervisoryNodeId(), + null, requisitionToCopy.getEmergency(), null, null, null, null, EnumSet.of(requisitionToCopy.getStatus())); diff --git a/src/main/java/org/openlmis/requisition/repository/custom/DefaultRequisitionSearchParams.java b/src/main/java/org/openlmis/requisition/repository/custom/DefaultRequisitionSearchParams.java index e4442f794..d0afae305 100644 --- a/src/main/java/org/openlmis/requisition/repository/custom/DefaultRequisitionSearchParams.java +++ b/src/main/java/org/openlmis/requisition/repository/custom/DefaultRequisitionSearchParams.java @@ -36,6 +36,7 @@ public final class DefaultRequisitionSearchParams implements RequisitionSearchPa private UUID program; private UUID processingPeriod; private UUID supervisoryNode; + private UUID supplyingFacility; private Boolean emergency; diff --git a/src/main/java/org/openlmis/requisition/repository/custom/RequisitionSearchParams.java b/src/main/java/org/openlmis/requisition/repository/custom/RequisitionSearchParams.java index 3e65d10fc..f05fc064e 100644 --- a/src/main/java/org/openlmis/requisition/repository/custom/RequisitionSearchParams.java +++ b/src/main/java/org/openlmis/requisition/repository/custom/RequisitionSearchParams.java @@ -31,6 +31,8 @@ public interface RequisitionSearchParams { UUID getSupervisoryNode(); + UUID getSupplyingFacility(); + Boolean getEmergency(); LocalDate getInitiatedDateFrom(); diff --git a/src/main/java/org/openlmis/requisition/repository/custom/impl/RequisitionRepositoryImpl.java b/src/main/java/org/openlmis/requisition/repository/custom/impl/RequisitionRepositoryImpl.java index 90e8aa379..7d58aa6c6 100644 --- a/src/main/java/org/openlmis/requisition/repository/custom/impl/RequisitionRepositoryImpl.java +++ b/src/main/java/org/openlmis/requisition/repository/custom/impl/RequisitionRepositoryImpl.java @@ -99,6 +99,7 @@ public class RequisitionRepositoryImpl private static final String CREATED_DATE = "createdDate"; private static final String PROCESSING_PERIOD_ID = "processingPeriodId"; private static final String SUPERVISORY_NODE_ID = "supervisoryNodeId"; + private static final String SUPPLYING_FACILITY_ID = "supplyingFacilityId"; private static final String AUTHORIZED_DATE = "authorizedDate"; private static final String MODIFIED_DATE = "modifiedDate"; @@ -476,6 +477,8 @@ private CriteriaQuery prepareQuery(CriteriaBuilder builder, CriteriaQuery PROCESSING_PERIOD_ID, params.getProcessingPeriod()); predicate = addEqualFilter(predicate, builder, root, SUPERVISORY_NODE_ID, params.getSupervisoryNode()); + predicate = addEqualFilter(predicate, builder, root, + SUPPLYING_FACILITY_ID, params.getSupplyingFacility()); predicate = addInFilter(predicate, builder, root, STATUS, params.getRequisitionStatuses()); predicate = addEqualFilter(predicate, builder, root, EMERGENCY, params.getEmergency()); diff --git a/src/main/java/org/openlmis/requisition/service/JasperReportsViewService.java b/src/main/java/org/openlmis/requisition/service/JasperReportsViewService.java index 62d45548b..ae81c9fa0 100644 --- a/src/main/java/org/openlmis/requisition/service/JasperReportsViewService.java +++ b/src/main/java/org/openlmis/requisition/service/JasperReportsViewService.java @@ -347,7 +347,7 @@ private List getFacilitiesForTimelinessReport( if (facility.getActive()) { RequisitionSearchParams params = new DefaultRequisitionSearchParams( facility.getId(), program.getId(), processingPeriod.getId(), - null, null, null, null, null, null, validStatuses); + null, null, null, null, null, null, null, validStatuses); PageRequest pageRequest = PageRequest.of(Pagination.DEFAULT_PAGE_NUMBER, Pagination.NO_PAGINATION); diff --git a/src/main/java/org/openlmis/requisition/web/QueryRequisitionSearchParams.java b/src/main/java/org/openlmis/requisition/web/QueryRequisitionSearchParams.java index ee31f908b..ddca0032f 100644 --- a/src/main/java/org/openlmis/requisition/web/QueryRequisitionSearchParams.java +++ b/src/main/java/org/openlmis/requisition/web/QueryRequisitionSearchParams.java @@ -45,6 +45,7 @@ final class QueryRequisitionSearchParams implements RequisitionSearchParams { private static final String INITIATED_DATE_TO = "initiatedDateTo"; private static final String PROCESSING_PERIOD = "processingPeriod"; private static final String SUPERVISORY_NODE = "supervisoryNode"; + private static final String SUPPLYING_FACILITY = "supplyingFacility"; private static final String REQUISITION_STATUS = "requisitionStatus"; private static final String EMERGENCY = "emergency"; private static final String MODIFIED_DATE_FROM = "modifiedDateFrom"; @@ -52,7 +53,7 @@ final class QueryRequisitionSearchParams implements RequisitionSearchParams { private static final List ALL_PARAMETERS = asList(FACILITY, PROGRAM, INITIATED_DATE_FROM, INITIATED_DATE_TO, MODIFIED_DATE_FROM, MODIFIED_DATE_TO, PROCESSING_PERIOD, - SUPERVISORY_NODE, REQUISITION_STATUS, EMERGENCY); + SUPERVISORY_NODE, SUPPLYING_FACILITY, REQUISITION_STATUS, EMERGENCY); private SearchParams queryParams; @@ -146,6 +147,20 @@ public UUID getSupervisoryNode() { return queryParams.getUuid(SUPERVISORY_NODE); } + /** + * Gets {@link UUID} for "supplyingFacility" key from params. + * + * @return UUID value of supplyingFacility id + * or null if params doesn't contain "supplyingFacility" key. + */ + @Override + public UUID getSupplyingFacility() { + if (!queryParams.containsKey(SUPPLYING_FACILITY)) { + return null; + } + return queryParams.getUuid(SUPPLYING_FACILITY); + } + /** * Gets {@link RequisitionStatus} for "requisitionStatus" key from params. * diff --git a/src/main/java/org/openlmis/requisition/web/RequisitionController.java b/src/main/java/org/openlmis/requisition/web/RequisitionController.java index d8f13add2..ded7991da 100644 --- a/src/main/java/org/openlmis/requisition/web/RequisitionController.java +++ b/src/main/java/org/openlmis/requisition/web/RequisitionController.java @@ -558,7 +558,7 @@ public Page getSubmittedRequisitions(Pageable pageable) { profiler.start("SEARCH_REQUISITIONS"); RequisitionSearchParams params = new DefaultRequisitionSearchParams( - null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, EnumSet.of(RequisitionStatus.SUBMITTED)); Page submittedRequisitions = requisitionService diff --git a/src/main/resources/api-definition.yaml b/src/main/resources/api-definition.yaml index 4cac92181..ace10d940 100644 --- a/src/main/resources/api-definition.yaml +++ b/src/main/resources/api-definition.yaml @@ -743,6 +743,11 @@ resourceTypes: type: string required: false repeat: false + supplyingFacility: + displayName: supplyingFacility + type: string + required: false + repeat: false requisitionStatus: displayName: supervisoryNode type: string diff --git a/src/test/java/org/openlmis/requisition/service/JasperReportsViewServiceTest.java b/src/test/java/org/openlmis/requisition/service/JasperReportsViewServiceTest.java index 386731700..16115a354 100644 --- a/src/test/java/org/openlmis/requisition/service/JasperReportsViewServiceTest.java +++ b/src/test/java/org/openlmis/requisition/service/JasperReportsViewServiceTest.java @@ -519,7 +519,7 @@ private GeographicZoneDto mockGeographicZone(UUID districtId, String districtNam (isMissingRnR) ? Collections.emptyList() : singletonList(mockRequisition)); RequisitionSearchParams params = new DefaultRequisitionSearchParams( - facilityId, program.getId(), period.getId(), null, null, null, null, + facilityId, program.getId(), period.getId(), null, null, null, null, null, null, null, EnumSet.of(APPROVED, RELEASED, RELEASED_WITHOUT_ORDER)); when(requisitionService.searchRequisitions(eq(params), any())) diff --git a/src/test/java/org/openlmis/requisition/service/RequisitionServiceTest.java b/src/test/java/org/openlmis/requisition/service/RequisitionServiceTest.java index fe5487d7b..3c467925a 100644 --- a/src/test/java/org/openlmis/requisition/service/RequisitionServiceTest.java +++ b/src/test/java/org/openlmis/requisition/service/RequisitionServiceTest.java @@ -1297,6 +1297,7 @@ public void shouldFindRequisitionIfItExists() { RequisitionSearchParams params = new DefaultRequisitionSearchParams( requisition.getFacilityId(), requisition.getProgramId(), requisition.getProcessingPeriodId(), requisition.getSupervisoryNodeId(), + null, requisition.getEmergency(), requisition.getCreatedDate().minusDays(2).toLocalDate(), requisition.getCreatedDate().plusDays(2).toLocalDate(), requisition.getModifiedDate().minusDays(2), requisition.getModifiedDate().plusDays(2), @@ -1359,6 +1360,7 @@ public void searchShouldReturnEmptyListIfPermissionStringsIsEmptyAndUserHasNoRol final RequisitionSearchParams params = new DefaultRequisitionSearchParams( requisition.getFacilityId(), requisition.getProgramId(), requisition.getProcessingPeriodId(), requisition.getSupervisoryNodeId(), + null, requisition.getEmergency(), requisition.getCreatedDate().minusDays(2).toLocalDate(), requisition.getCreatedDate().plusDays(2).toLocalDate(), requisition.getModifiedDate().minusDays(2), requisition.getModifiedDate().plusDays(2), diff --git a/src/test/java/org/openlmis/requisition/testutils/DefaultRequisitionSearchParamsDataBuilder.java b/src/test/java/org/openlmis/requisition/testutils/DefaultRequisitionSearchParamsDataBuilder.java index b8eb793dc..1c1799470 100644 --- a/src/test/java/org/openlmis/requisition/testutils/DefaultRequisitionSearchParamsDataBuilder.java +++ b/src/test/java/org/openlmis/requisition/testutils/DefaultRequisitionSearchParamsDataBuilder.java @@ -31,6 +31,7 @@ public class DefaultRequisitionSearchParamsDataBuilder implements private UUID program; private UUID processingPeriod; private UUID supervisoryNode; + private UUID supplyingFacility; private Boolean emergency; @@ -52,6 +53,7 @@ public DefaultRequisitionSearchParams build() { program, processingPeriod, supervisoryNode, + supplyingFacility, emergency, initiatedDateFrom, initiatedDateTo, @@ -81,6 +83,11 @@ public DefaultRequisitionSearchParamsDataBuilder withSupervisoryNode(UUID superv return this; } + public DefaultRequisitionSearchParamsDataBuilder withSupplyingFacility(UUID supplyingFacility) { + this.supplyingFacility = supplyingFacility; + return this; + } + public DefaultRequisitionSearchParamsDataBuilder withEmergency(Boolean emergency) { this.emergency = emergency; return this; diff --git a/src/test/java/org/openlmis/requisition/web/QueryRequisitionSearchParamsTest.java b/src/test/java/org/openlmis/requisition/web/QueryRequisitionSearchParamsTest.java index 9f961240a..8f0c757ae 100644 --- a/src/test/java/org/openlmis/requisition/web/QueryRequisitionSearchParamsTest.java +++ b/src/test/java/org/openlmis/requisition/web/QueryRequisitionSearchParamsTest.java @@ -53,6 +53,7 @@ public class QueryRequisitionSearchParamsTest private static final String INITIATED_DATE_TO = "initiatedDateTo"; private static final String PROCESSING_PERIOD = "processingPeriod"; private static final String SUPERVISORY_NODE = "supervisoryNode"; + private static final String SUPPLYING_FACILITY = "supplyingFacility"; private static final String REQUISITION_STATUS = "requisitionStatus"; private static final String EMERGENCY = "emergency"; private static final String MODIFIED_DATE_FROM = "modifiedDateFrom"; @@ -160,6 +161,21 @@ public void shouldGetNullIfMapHasNoSupervisoryNodeProperty() { assertNull(params.getSupervisoryNode()); } + @Test + public void shouldGetSupplyingFacilityValueFromParameters() { + queryMap.add(SUPPLYING_FACILITY, id.toString()); + QueryRequisitionSearchParams params = new QueryRequisitionSearchParams(queryMap); + + assertEquals(id, params.getSupplyingFacility()); + } + + @Test + public void shouldGetNullIfMapHasNoSupplyingFacilityProperty() { + QueryRequisitionSearchParams params = new QueryRequisitionSearchParams(queryMap); + + assertNull(params.getSupplyingFacility()); + } + @Test public void shouldGetRequisitionStatusValueFromParameters() { queryMap.add(REQUISITION_STATUS, RequisitionStatus.APPROVED.toString()); @@ -262,6 +278,7 @@ protected Optional getInstance() { protected void prepare(ToStringVerifier verifier) { verifier.ignore("FACILITY", "PROGRAM", "INITIATED_DATE_FROM", "INITIATED_DATE_TO", "MODIFIED_DATE_FROM", "MODIFIED_DATE_TO", "PROCESSING_PERIOD", - "SUPERVISORY_NODE", "REQUISITION_STATUS", "EMERGENCY", "ALL_PARAMETERS"); + "SUPERVISORY_NODE", "SUPPLYING_FACILITY", "REQUISITION_STATUS", "EMERGENCY", + "ALL_PARAMETERS"); } } From 143ad591b66798090e4f9618f82eb8e32cb2b8a9 Mon Sep 17 00:00:00 2001 From: michaldev0 <125133223+michaldev0@users.noreply.github.com> Date: Tue, 26 May 2026 16:58:51 +0200 Subject: [PATCH 2/2] OLMIS-7779: Add supplyingFacility filter test --- .../RequisitionRepositoryIntegrationTest.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/integration-test/java/org/openlmis/requisition/repository/RequisitionRepositoryIntegrationTest.java b/src/integration-test/java/org/openlmis/requisition/repository/RequisitionRepositoryIntegrationTest.java index fe0b0d793..94ffc2aa6 100644 --- a/src/integration-test/java/org/openlmis/requisition/repository/RequisitionRepositoryIntegrationTest.java +++ b/src/integration-test/java/org/openlmis/requisition/repository/RequisitionRepositoryIntegrationTest.java @@ -309,6 +309,62 @@ public void testSearchRequisitionsByFacilityAndProgram() { } } + @Test + public void testSearchRequisitionsBySupplyingFacility() { + UUID matchingSupplyingFacility = UUID.randomUUID(); + UUID otherSupplyingFacility = UUID.randomUUID(); + Requisition requisitionToCopy = requisitions.get(0); + + Requisition matchingRequisition = new RequisitionDataBuilder() + .withFacilityId(requisitionToCopy.getFacilityId()) + .withProgramId(requisitionToCopy.getProgramId()) + .withStatus(requisitionToCopy.getStatus()) + .withSupervisoryNodeId(requisitionToCopy.getSupervisoryNodeId()) + .withSupplyingFacilityId(matchingSupplyingFacility) + .withTemplate(testTemplate) + .withNumberOfMonthsInPeriod(1) + .withEmergency(true) + .buildAsNew(); + matchingRequisition.setStatusChanges( + singletonList(new StatusChangeDataBuilder() + .withRequisition(matchingRequisition) + .buildAsNew() + ) + ); + repository.save(matchingRequisition); + + Requisition otherRequisition = new RequisitionDataBuilder() + .withFacilityId(requisitionToCopy.getFacilityId()) + .withProgramId(requisitionToCopy.getProgramId()) + .withStatus(requisitionToCopy.getStatus()) + .withSupervisoryNodeId(requisitionToCopy.getSupervisoryNodeId()) + .withSupplyingFacilityId(otherSupplyingFacility) + .withTemplate(testTemplate) + .withNumberOfMonthsInPeriod(1) + .withEmergency(false) + .buildAsNew(); + otherRequisition.setStatusChanges( + singletonList(new StatusChangeDataBuilder() + .withRequisition(otherRequisition) + .buildAsNew() + ) + ); + repository.save(otherRequisition); + + RequisitionSearchParams searchParams = new DefaultRequisitionSearchParamsDataBuilder() + .withSupplyingFacility(matchingSupplyingFacility) + .build(); + + List receivedRequisitions = repository + .searchRequisitions(searchParams, userPermissionStrings, programNodePairs, pageRequest) + .getContent(); + + assertEquals(1, receivedRequisitions.size()); + assertEquals( + matchingSupplyingFacility, + receivedRequisitions.get(0).getSupplyingFacilityId()); + } + @Test public void testSearchRequisitionsByAllParametersNull() { RequisitionSearchParams searchParams = new DefaultRequisitionSearchParams();