diff --git a/src/integration-test/java/org/openlmis/requisition/web/BaseWebIntegrationTest.java b/src/integration-test/java/org/openlmis/requisition/web/BaseWebIntegrationTest.java index 134465f98..0f6bae5a5 100644 --- a/src/integration-test/java/org/openlmis/requisition/web/BaseWebIntegrationTest.java +++ b/src/integration-test/java/org/openlmis/requisition/web/BaseWebIntegrationTest.java @@ -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. */ diff --git a/src/integration-test/java/org/openlmis/requisition/web/BatchRequisitionControllerIntegrationTest.java b/src/integration-test/java/org/openlmis/requisition/web/BatchRequisitionControllerIntegrationTest.java index 9e196831d..f31fe028a 100644 --- a/src/integration-test/java/org/openlmis/requisition/web/BatchRequisitionControllerIntegrationTest.java +++ b/src/integration-test/java/org/openlmis/requisition/web/BatchRequisitionControllerIntegrationTest.java @@ -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; @@ -223,6 +225,9 @@ public void setUp() { .search(anySetOf(UUID.class)); mockSearchSupervisoryNodeByProgramAndFacility(); + + doNothing().when(facilityTypeHelper).checkIfFacilityHasSupportedType( + anySet(), anyString()); } @Test diff --git a/src/main/java/org/openlmis/requisition/i18n/MessageKeys.java b/src/main/java/org/openlmis/requisition/i18n/MessageKeys.java index 03e40cb81..b8e228d65 100644 --- a/src/main/java/org/openlmis/requisition/i18n/MessageKeys.java +++ b/src/main/java/org/openlmis/requisition/i18n/MessageKeys.java @@ -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"; diff --git a/src/main/java/org/openlmis/requisition/web/BaseRequisitionController.java b/src/main/java/org/openlmis/requisition/web/BaseRequisitionController.java index 7e5d7856a..11dccc0c2 100644 --- a/src/main/java/org/openlmis/requisition/web/BaseRequisitionController.java +++ b/src/main/java/org/openlmis/requisition/web/BaseRequisitionController.java @@ -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) { @@ -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); diff --git a/src/main/java/org/openlmis/requisition/web/BatchRequisitionController.java b/src/main/java/org/openlmis/requisition/web/BatchRequisitionController.java index 8334b3723..19fe1055a 100644 --- a/src/main/java/org/openlmis/requisition/web/BatchRequisitionController.java +++ b/src/main/java/org/openlmis/requisition/web/BatchRequisitionController.java @@ -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; @@ -86,7 +87,6 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; - @Controller @Transactional @SuppressWarnings("PMD.TooManyMethods") @@ -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())); @@ -591,4 +594,15 @@ private Map getApprovedProducts( .stream() .collect(toMap(ApprovedProductDto::getIdentity, Function.identity())); } + + private void checkRequisitionsSupplyingDepotsTypes( + List releasableRequisitions) { + Set supplyingDepotUuids = releasableRequisitions + .stream() + .map(ReleasableRequisitionDto::getSupplyingDepotId) + .collect(Collectors.toSet()); + + facilityTypeHelper.checkIfFacilityHasSupportedType(supplyingDepotUuids, "Supplying depot"); + } + } diff --git a/src/main/java/org/openlmis/requisition/web/FacilityTypeHelper.java b/src/main/java/org/openlmis/requisition/web/FacilityTypeHelper.java new file mode 100644 index 000000000..bb39236a5 --- /dev/null +++ b/src/main/java/org/openlmis/requisition/web/FacilityTypeHelper.java @@ -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 info@OpenLMIS.org. + */ + +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 facilitiesUuids, + String facilityFunction) { + List facilities = facilityReferenceDataService.search(facilitiesUuids); + facilities.forEach(facility -> checkIfFacilityHasSupportedType(facility, facilityFunction)); + } + +} diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 03ab6ce42..3d75ffa67 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -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. diff --git a/src/test/java/org/openlmis/requisition/web/BatchRequisitionControllerTest.java b/src/test/java/org/openlmis/requisition/web/BatchRequisitionControllerTest.java index 9c0773f53..54ef68093 100644 --- a/src/test/java/org/openlmis/requisition/web/BatchRequisitionControllerTest.java +++ b/src/test/java/org/openlmis/requisition/web/BatchRequisitionControllerTest.java @@ -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; @@ -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; @@ -49,6 +53,9 @@ public class BatchRequisitionControllerTest { @Mock PermissionService permissionService; + @Mock + FacilityTypeHelper facilityTypeHelper; + @InjectMocks BatchRequisitionController batchRequisitionController; @@ -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 diff --git a/src/test/java/org/openlmis/requisition/web/FacilitySupportsProgramHelperTest.java b/src/test/java/org/openlmis/requisition/web/FacilitySupportsProgramHelperTest.java index 639c2e858..ffa1a9212 100644 --- a/src/test/java/org/openlmis/requisition/web/FacilitySupportsProgramHelperTest.java +++ b/src/test/java/org/openlmis/requisition/web/FacilitySupportsProgramHelperTest.java @@ -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; diff --git a/src/test/java/org/openlmis/requisition/web/FacilityTypeHelperTest.java b/src/test/java/org/openlmis/requisition/web/FacilityTypeHelperTest.java new file mode 100644 index 000000000..dec032fd3 --- /dev/null +++ b/src/test/java/org/openlmis/requisition/web/FacilityTypeHelperTest.java @@ -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 info@OpenLMIS.org. + */ + +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 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 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(); + } + +} \ No newline at end of file diff --git a/src/test/java/org/openlmis/requisition/web/RequisitionControllerTest.java b/src/test/java/org/openlmis/requisition/web/RequisitionControllerTest.java index 841f2d5b1..3b98e5576 100644 --- a/src/test/java/org/openlmis/requisition/web/RequisitionControllerTest.java +++ b/src/test/java/org/openlmis/requisition/web/RequisitionControllerTest.java @@ -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; @@ -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"); @@ -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) {