Skip to content

Commit

Permalink
Merge pull request #101 from OpenLMIS/OAM-184
Browse files Browse the repository at this point in the history
OAM-184: Added validation for Wards/Services in requisition functions
  • Loading branch information
pwargulak authored Jun 13, 2024
2 parents 6d125a9 + 6ce3098 commit 107d10f
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@ public abstract class BaseWebIntegrationTest {
@MockBean
protected ConfigurationSettingService configurationSettingService;

@MockBean
protected FacilityTypeHelper facilityTypeHelper;

/**
* Method called to initialize basic resources after the object is created.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import static org.mockito.Matchers.anySet;
import static org.mockito.Matchers.anySetOf;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
Expand Down Expand Up @@ -223,6 +225,9 @@ public void setUp() {
.search(anySetOf(UUID.class));

mockSearchSupervisoryNodeByProgramAndFacility();

doNothing().when(facilityTypeHelper).checkIfFacilityHasSupportedType(
anySet(), anyString());
}

@Test
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/openlmis/requisition/i18n/MessageKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ public abstract class MessageKeys {
ERROR_PREFIX + ".duplication";
public static final String ERROR_REQUISITION_DUPLICATION_WITH_NODE =
ERROR_PREFIX + ".duplicationWithNode";
public static final String ERROR_FACILITY_CANNOT_BE_WARD_SERVICE_TYPE =
ERROR_PREFIX + ".facilityCannotBeWardServiceType";

public static final String REQUISITION_EMAIL_CONVERT_TO_ORDER_SUBJECT
= "requisition.email.convertToOrder.subject";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ public abstract class BaseRequisitionController extends BaseController {
@Autowired
private ReasonsValidator reasonsValidator;

@Autowired
FacilityTypeHelper facilityTypeHelper;

InitiateResult doInitiate(UUID programId, UUID facilityId, UUID suggestedPeriod,
boolean emergency, HttpServletRequest request, Profiler profiler) {
if (null == facilityId || null == programId) {
Expand All @@ -214,6 +217,9 @@ InitiateResult doInitiate(UUID programId, UUID facilityId, UUID suggestedPeriod,

FacilityDto facility = findFacility(facilityId, profiler);

profiler.start("CHECK_FACILITY_TYPE_SUPPORTED");
facilityTypeHelper.checkIfFacilityHasSupportedType(facility, "Requisitioning facility");

profiler.start("CHECK_FACILITY_SUPPORTS_PROGRAM");
facilitySupportsProgramHelper.checkIfFacilitySupportsProgram(facility, programId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.openlmis.requisition.dto.OrderableDto;
import org.openlmis.requisition.dto.ProcessingPeriodDto;
import org.openlmis.requisition.dto.ReleasableRequisitionBatchDto;
import org.openlmis.requisition.dto.ReleasableRequisitionDto;
import org.openlmis.requisition.dto.RequisitionDto;
import org.openlmis.requisition.dto.RequisitionErrorMessage;
import org.openlmis.requisition.dto.RequisitionsProcessingStatusDto;
Expand Down Expand Up @@ -86,7 +87,6 @@
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;


@Controller
@Transactional
@SuppressWarnings("PMD.TooManyMethods")
Expand Down Expand Up @@ -322,6 +322,9 @@ public ResponseEntity batchReleaseRequisitions(
.getRequisitionsToRelease());
ResponseEntity response;

profiler.start("CHECK_SUPPLYING_DEPOTS_TYPE");
checkRequisitionsSupplyingDepotsTypes(releaseDto.getRequisitionsToRelease());

if (addValidationErrors(processingStatus, result, null)) {
response = ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(localizeMessage(result.getError().getMessage()));
Expand Down Expand Up @@ -591,4 +594,15 @@ private Map<VersionIdentityDto, ApprovedProductDto> getApprovedProducts(
.stream()
.collect(toMap(ApprovedProductDto::getIdentity, Function.identity()));
}

private void checkRequisitionsSupplyingDepotsTypes(
List<ReleasableRequisitionDto> releasableRequisitions) {
Set<UUID> supplyingDepotUuids = releasableRequisitions
.stream()
.map(ReleasableRequisitionDto::getSupplyingDepotId)
.collect(Collectors.toSet());

facilityTypeHelper.checkIfFacilityHasSupportedType(supplyingDepotUuids, "Supplying depot");
}

}
68 changes: 68 additions & 0 deletions src/main/java/org/openlmis/requisition/web/FacilityTypeHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* This program is part of the OpenLMIS logistics management information system platform software.
* Copyright © 2017 VillageReach
*
* This program is free software: you can redistribute it and/or modify it under the terms
* of the GNU Affero General Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details. You should have received a copy of
* the GNU Affero General Public License along with this program. If not, see
* http://www.gnu.org/licenses.  For additional information contact [email protected].
*/

package org.openlmis.requisition.web;

import static org.openlmis.requisition.i18n.MessageKeys.ERROR_FACILITY_CANNOT_BE_WARD_SERVICE_TYPE;

import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.openlmis.requisition.dto.FacilityDto;
import org.openlmis.requisition.dto.FacilityTypeDto;
import org.openlmis.requisition.exception.ValidationMessageException;
import org.openlmis.requisition.service.referencedata.FacilityReferenceDataService;
import org.openlmis.requisition.utils.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class FacilityTypeHelper {

public static final String WARD_SERVICE_TYPE_CODE = "WS";

@Autowired
private FacilityReferenceDataService facilityReferenceDataService;

/**
* Method check if facility has type ward/service.
*
* @param facility Facility.
* @param facilityFunction the function of the facility being checked (e.g. supplying facility,
* requesting facility)
*/
public void checkIfFacilityHasSupportedType(FacilityDto facility, String facilityFunction) {
FacilityTypeDto type = facility.getType();
if (type != null && type.getCode().equals(WARD_SERVICE_TYPE_CODE)) {
throw new ValidationMessageException(
new Message(ERROR_FACILITY_CANNOT_BE_WARD_SERVICE_TYPE, facilityFunction)
);
}
}

/**
* Method check if facilities has type ward/service.
*
* @param facilitiesUuids UUIDs of facilities.
* @param facilityFunction the function of the facility being checked (e.g. supplying facility,
* requesting facility)
*/
public void checkIfFacilityHasSupportedType(Set<UUID> facilitiesUuids,
String facilityFunction) {
List<FacilityDto> facilities = facilityReferenceDataService.search(facilitiesUuids);
facilities.forEach(facility -> checkIfFacilityHasSupportedType(facility, facilityFunction));
}

}
1 change: 1 addition & 0 deletions src/main/resources/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ requisition.lineItem.suppliedByOtherPartner=Supplied by other warehouse/partner.

requisition.error.authorize.mustBeSubmittedToBeAuthorize=Cannot authorize requisition: {0}, requisition must have status 'SUBMITTED' to be authorized.
requisition.error.facilityDoesNotSupportProgram=Facility with ID {0} does not support program with ID {1}.
requisition.error.facilityCannotBeWardServiceType={0} cannot be type Ward/Service.
requisition.error.initiate.missingParameters=Facility and program must be specified when initiating a requisition.
requisition.error.initiate.finishPreviousRequisition=Please finish previous requisition.
requisition.error.submit.mustBeInitiatedToBeSubmitted=Cannot submit requisition: {0}, requisition must have status 'INITIATED' or 'REJECTED' to be submitted.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@

package org.openlmis.requisition.web;

import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyList;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
Expand All @@ -29,6 +32,7 @@
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.openlmis.requisition.dto.FacilityDto;
import org.openlmis.requisition.dto.ReleasableRequisitionBatchDto;
import org.openlmis.requisition.dto.UserDto;
import org.openlmis.requisition.errorhandling.ValidationResult;
Expand All @@ -49,6 +53,9 @@ public class BatchRequisitionControllerTest {
@Mock
PermissionService permissionService;

@Mock
FacilityTypeHelper facilityTypeHelper;

@InjectMocks
BatchRequisitionController batchRequisitionController;

Expand All @@ -58,6 +65,10 @@ public void setUp() {

UserDto currentUser = DtoGenerator.of(UserDto.class);
when(authenticationHelper.getCurrentUser()).thenReturn(currentUser);
doNothing().when(facilityTypeHelper).checkIfFacilityHasSupportedType(
any(FacilityDto.class), anyString());
doNothing().when(facilityTypeHelper).checkIfFacilityHasSupportedType(
anySet(), anyString());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.junit.MockitoJUnitRunner;
import org.openlmis.requisition.dto.FacilityDto;
import org.openlmis.requisition.dto.SupportedProgramDto;
import org.openlmis.requisition.exception.ValidationMessageException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* This program is part of the OpenLMIS logistics management information system platform software.
* Copyright © 2017 VillageReach
*
* This program is free software: you can redistribute it and/or modify it under the terms
* of the GNU Affero General Public License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details. You should have received a copy of
* the GNU Affero General Public License along with this program. If not, see
* http://www.gnu.org/licenses.  For additional information contact [email protected].
*/

package org.openlmis.requisition.web;

import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.Mockito.when;
import static org.openlmis.requisition.web.FacilityTypeHelper.WARD_SERVICE_TYPE_CODE;

import java.util.HashSet;
import java.util.List;
import org.javers.common.collections.Lists;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.openlmis.requisition.dto.FacilityDto;
import org.openlmis.requisition.dto.FacilityTypeDto;
import org.openlmis.requisition.exception.ValidationMessageException;
import org.openlmis.requisition.service.referencedata.FacilityReferenceDataService;
import org.openlmis.requisition.testutils.FacilityDtoDataBuilder;
import org.openlmis.requisition.testutils.FacilityTypeDtoDataBuilder;

@RunWith(MockitoJUnitRunner.class)
public class FacilityTypeHelperTest {

public static final String TEST_FACILITY = "Test facility";
public static final String TEST_CODE_TYPE = "TEST";

@Mock
FacilityReferenceDataService facilityReferenceDataService;

@InjectMocks
FacilityTypeHelper facilityTypeHelper;

private FacilityDto facility;

@Before
public void setUp() {
facility = generateInstance(TEST_CODE_TYPE);
}

@Test(expected = ValidationMessageException.class)
public void shouldThrowExceptionWhenFacilityIsWardServiceType() {
FacilityDto ward = generateInstance(WARD_SERVICE_TYPE_CODE);

facilityTypeHelper.checkIfFacilityHasSupportedType(ward, TEST_FACILITY);
}

@Test
public void shouldPassWhenFacilityIsOtherTypeThanWardService() {
facilityTypeHelper.checkIfFacilityHasSupportedType(facility, TEST_FACILITY);
}

@Test(expected = ValidationMessageException.class)
public void shouldThrowExceptionWhenOneOfTheFacilitiesIsWardServiceType() {
FacilityDto ward = generateInstance(WARD_SERVICE_TYPE_CODE);
List<FacilityDto> facilities = Lists.asList(ward, facility);

when(facilityReferenceDataService.search(anySet())).thenReturn(facilities);

facilityTypeHelper.checkIfFacilityHasSupportedType(new HashSet<>(), TEST_FACILITY);
}

@Test
public void shouldPassWhenNoneOfTheFacilitiesAreWardServiceType() {
FacilityDto anotherFacility = generateInstance("Code2");
List<FacilityDto> facilities = Lists.asList(anotherFacility, facility);

when(facilityReferenceDataService.search(anySet())).thenReturn(facilities);

facilityTypeHelper.checkIfFacilityHasSupportedType(new HashSet<>(), TEST_FACILITY);
}

private FacilityDto generateInstance(String typeCode) {
FacilityTypeDto facilityType = new FacilityTypeDtoDataBuilder()
.withCode(typeCode)
.buildAsDto();

return new FacilityDtoDataBuilder()
.withType(facilityType)
.buildAsDto();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
Expand Down Expand Up @@ -279,6 +281,9 @@ public class RequisitionControllerTest {
@Mock
private RejectionDto rejectionDto;

@Mock
private FacilityTypeHelper facilityTypeHelper;

private UUID programUuid = UUID.randomUUID();
private UUID facilityUuid = UUID.randomUUID();
private UUID uuid1 = UUID.fromString("00000000-0000-0000-0000-000000000001");
Expand Down Expand Up @@ -362,6 +367,10 @@ public void setUp() {

when(approvedProductReferenceDataService.getApprovedProducts(any(), any()))
.thenReturn(new ApproveProductsAggregator(emptyList(), UUID.randomUUID()));
doNothing().when(facilityTypeHelper).checkIfFacilityHasSupportedType(
any(FacilityDto.class), anyString());
doNothing().when(facilityTypeHelper).checkIfFacilityHasSupportedType(
anySet(), anyString());
}

private void stubValidations(Requisition... requisitions) {
Expand Down

0 comments on commit 107d10f

Please sign in to comment.