Skip to content

Commit

Permalink
OAM-184: Added validation for requisitionless order facilities types (#…
Browse files Browse the repository at this point in the history
…31)

* OAM-184: Added validation for requisitionless order facilities types

* OAM-184: Removed redundant empty lines
  • Loading branch information
sradziszewski committed Jun 13, 2024
1 parent ab22466 commit 9619c90
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyCollectionOf;
import static org.mockito.ArgumentMatchers.anySetOf;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyCollectionOf;
import static org.mockito.Matchers.anySetOf;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.anyMap;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -106,6 +108,7 @@
import org.openlmis.fulfillment.testutils.UserDataBuilder;
import org.openlmis.fulfillment.util.AuthenticationHelper;
import org.openlmis.fulfillment.util.DateHelper;
import org.openlmis.fulfillment.util.FacilityTypeHelper;
import org.openlmis.fulfillment.web.util.BasicOrderDto;
import org.openlmis.fulfillment.web.util.OrderDto;
import org.openlmis.fulfillment.web.util.StatusChangeDto;
Expand Down Expand Up @@ -195,6 +198,9 @@ public class OrderControllerIntegrationTest extends BaseWebIntegrationTest {
@MockBean
private OrderService orderService;

@MockBean
private FacilityTypeHelper facilityTypeHelper;

@Autowired
private ShipmentService shipmentService;

Expand Down Expand Up @@ -497,6 +503,7 @@ public void shouldCreateOrder() {
public void shouldCreateRequisitionLessOrder() {
given(orderService.createRequisitionLessOrder(any(OrderDto.class), eq(user.getId())))
.willReturn(firstOrder);
doNothing().when(facilityTypeHelper).checkIfFacilityHasSupportedType(anyMap());

restAssured.given()
.header(HttpHeaders.AUTHORIZATION, getTokenHeader())
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/openlmis/fulfillment/i18n/MessageKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ public abstract class MessageKeys {
public static final String ERROR_ORDER_LINE_ITEMS_QUANTITY_MUST_BE_POSITIVE =
join(VALIDATION_ERROR, ORDER, LINE_ITEMS, QUANTITY, MUST_BE_POSITIVE);

public static final String ERROR_FACILITY_CANNOT_BE_WARD_SERVICE_TYPE =
join(VALIDATION_ERROR, ORDER, "facilityCannotBeWardServiceType");

private static String join(String... params) {
return String.join(DELIMITER, Arrays.asList(params));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.fulfillment.util;

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

import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import org.openlmis.fulfillment.service.referencedata.FacilityDto;
import org.openlmis.fulfillment.service.referencedata.FacilityReferenceDataService;
import org.openlmis.fulfillment.service.referencedata.FacilityTypeDto;
import org.openlmis.fulfillment.web.ValidationException;
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 ValidationException(
ERROR_FACILITY_CANNOT_BE_WARD_SERVICE_TYPE, facilityFunction
);
}
}

/**
* Method check if facilities has type ward/service.
*
* @param facilitiesFunctionsMap Map of UUIDs of facilities and their functions (e.g.
* supplying facility, requesting facility)
*/
public void checkIfFacilityHasSupportedType(Map<UUID, String> facilitiesFunctionsMap) {
Collection<FacilityDto> facilities = facilityReferenceDataService
.findByIds(facilitiesFunctionsMap.keySet());
facilities.forEach(facility -> checkIfFacilityHasSupportedType(facility, facilitiesFunctionsMap
.get(facility.getId())));
}

}
14 changes: 14 additions & 0 deletions src/main/java/org/openlmis/fulfillment/web/OrderController.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.openlmis.fulfillment.service.TemplateService;
import org.openlmis.fulfillment.service.referencedata.UserDto;
import org.openlmis.fulfillment.util.AuthenticationHelper;
import org.openlmis.fulfillment.util.FacilityTypeHelper;
import org.openlmis.fulfillment.web.util.BasicOrderDto;
import org.openlmis.fulfillment.web.util.BasicOrderDtoBuilder;
import org.openlmis.fulfillment.web.util.OrderDto;
Expand Down Expand Up @@ -133,6 +134,9 @@ public class OrderController extends BaseController {
@Autowired
private ExporterBuilder exporter;

@Autowired
private FacilityTypeHelper facilityTypeHelper;

@Value("${groupingSeparator}")
private String groupingSeparator;

Expand Down Expand Up @@ -177,6 +181,8 @@ public OrderDto createOrder(@RequestBody OrderDto orderDto, OAuth2Authentication
public OrderDto createRequisitionLessOrder(@RequestBody OrderDto orderDto) {
permissionService.canCreateOrder(orderDto);

checkOrderFacilityTypes(orderDto);

orderDto.setId(null);
orderDto.setExternalId(null);
orderDto.setQuotedCost(BigDecimal.ZERO);
Expand Down Expand Up @@ -550,6 +556,14 @@ order, new CreationDetails(order.getCreatedById(), order.getCreatedDate()),
return order;
}

private void checkOrderFacilityTypes(OrderDto orderDto) {
Map<UUID, String> orderFacilities = new HashMap<>();
orderFacilities.put(orderDto.getReceivingFacility().getId(), "Receiving facility");
orderFacilities.put(orderDto.getRequestingFacility().getId(), "Requesting facility");
orderFacilities.put(orderDto.getSupplyingFacility().getId(), "Supplying facility");
facilityTypeHelper.checkIfFacilityHasSupportedType(orderFacilities);
}

void stopProfiler(Profiler profiler, Object... exitArgs) {
profiler.stop().log();
XLOGGER.exit(exitArgs);
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ fulfillment.validationError.mustBeGreaterThanOrEqualToZero={0} must contain a va
fulfillment.validationError.orderables.mustBeUnique=Order contains duplicated products
fulfillment.validationError.order.lineItems.quantity.required=Order item quantity is required
fulfillment.validationError.order.lineItems.quantity.mustBePositive=Order item quantity cannot be negative
fulfillment.validationError.order.facilityCannotBeWardServiceType={0} cannot be type Ward/Service.

fulfillment.email.orderCreation.subject=New order
fulfillment.email.orderCreation.body=Create an order: {id} with status: {status}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,10 @@ public FacilityDataBuilder withSupportedPrograms(List<ProgramDto> supportedProgr
this.supportedPrograms = supportedPrograms;
return this;
}

public FacilityDataBuilder withType(FacilityTypeDto type) {
this.type = type;
return this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,10 @@ public FacilityTypeDto build() {
type.setId(id);
return type;
}

public FacilityTypeDataBuilder withCode(String code) {
this.code = code;
return this;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* 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.fulfillment.util;

import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.Mockito.when;
import static org.openlmis.fulfillment.util.FacilityTypeHelper.WARD_SERVICE_TYPE_CODE;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
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.fulfillment.service.referencedata.FacilityDto;
import org.openlmis.fulfillment.service.referencedata.FacilityReferenceDataService;
import org.openlmis.fulfillment.service.referencedata.FacilityTypeDto;
import org.openlmis.fulfillment.testutils.FacilityDataBuilder;
import org.openlmis.fulfillment.testutils.FacilityTypeDataBuilder;
import org.openlmis.fulfillment.web.ValidationException;

@RunWith(MockitoJUnitRunner.class)
public class FacilityTypeHelperTest {

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

@Mock
FacilityReferenceDataService facilityReferenceDataService;

@InjectMocks
FacilityTypeHelper facilityTypeHelper;

private FacilityDto facility;

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

@Test(expected = ValidationException.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 = ValidationException.class)
public void shouldThrowExceptionWhenOneOfTheFacilitiesIsWardServiceType() {
FacilityDto ward = generateInstance(WARD_SERVICE_TYPE_CODE);
List<FacilityDto> facilities = Lists.asList(ward, facility);

Map<UUID, String> facilitiesMap = new HashMap<>();
facilitiesMap.put(ward.getId(), TEST_FACILITY_FUNCTION);
facilitiesMap.put(facility.getId(), TEST_FACILITY_FUNCTION);

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

facilityTypeHelper.checkIfFacilityHasSupportedType(facilitiesMap);
}

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

Map<UUID, String> facilitiesMap = new HashMap<>();
facilitiesMap.put(anotherFacility.getId(), TEST_FACILITY_FUNCTION);
facilitiesMap.put(facility.getId(), TEST_FACILITY_FUNCTION);

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

facilityTypeHelper.checkIfFacilityHasSupportedType(facilitiesMap);
}

private FacilityDto generateInstance(String typeCode) {
FacilityTypeDto facilityType = new FacilityTypeDataBuilder()
.withCode(typeCode)
.build();

return new FacilityDataBuilder()
.withType(facilityType)
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand All @@ -33,7 +35,7 @@
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.junit.MockitoJUnitRunner;
import org.openlmis.fulfillment.OrderDataBuilder;
import org.openlmis.fulfillment.domain.Order;
import org.openlmis.fulfillment.domain.OrderStatus;
Expand All @@ -47,8 +49,10 @@
import org.openlmis.fulfillment.service.referencedata.PeriodReferenceDataService;
import org.openlmis.fulfillment.service.referencedata.ProgramReferenceDataService;
import org.openlmis.fulfillment.service.referencedata.UserReferenceDataService;
import org.openlmis.fulfillment.testutils.FacilityDataBuilder;
import org.openlmis.fulfillment.testutils.UpdateDetailsDataBuilder;
import org.openlmis.fulfillment.util.AuthenticationHelper;
import org.openlmis.fulfillment.util.FacilityTypeHelper;
import org.openlmis.fulfillment.web.util.OrderDto;
import org.openlmis.fulfillment.web.util.OrderDtoBuilder;
import org.openlmis.fulfillment.web.validator.OrderValidator;
Expand Down Expand Up @@ -96,6 +100,9 @@ public class OrderControllerTest {
@Mock
private OrderValidator orderValidator;

@Mock
private FacilityTypeHelper facilityTypeHelper;

private static final String SERVICE_URL = "localhost";

private UUID lastUpdaterId = UUID.fromString("35316636-6264-6331-2d34-3933322d3462");
Expand Down Expand Up @@ -151,6 +158,10 @@ public void shouldGetLastUpdaterFromDtoIfCurrentUserIsNullWhenUpdatingOrder() {
@Test
public void shouldGetLastUpdaterFromDtoIfCurrentUserIsNullWhenCreatingRequisitionLessOrder() {
when(authenticationHelper.getCurrentUser()).thenReturn(null);
doNothing().when(facilityTypeHelper).checkIfFacilityHasSupportedType(anyMap());
orderDto.setReceivingFacility(new FacilityDataBuilder().build());
orderDto.setRequestingFacility(new FacilityDataBuilder().build());
orderDto.setSupplyingFacility(new FacilityDataBuilder().build());

orderController.createRequisitionLessOrder(orderDto);

Expand Down

0 comments on commit 9619c90

Please sign in to comment.