Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAM-218: Updated programId param to repeatable #60

Merged
merged 10 commits into from
Jun 26, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import static org.junit.Assert.assertThat;

import com.google.common.collect.Sets;

import java.util.Collections;
import java.util.List;
import java.util.UUID;
import javax.persistence.EntityManager;
Expand Down Expand Up @@ -93,7 +95,7 @@ public void shouldReturnValidReasonWithProgramAndFacilityTypeAndReasonAndReasonT
repository.save(newAssignment);

List<ValidReasonAssignment> validReasonAssignments = repository.search(
PROGRAM_ID, FACILITY_TYPE_ID, Sets.newHashSet(
Collections.singleton(PROGRAM_ID), FACILITY_TYPE_ID, Sets.newHashSet(
validReasonAssignment.getReason().getReasonType(),
stockCardLineItemReason.getReasonType()),
stockCardLineItemReason.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public void getValidReasonAssignments() {

@Test
public void getValidReasonAssignmentsByAllParameters() {
when(reasonAssignmentRepository.search(programId, facilityTypeId,
when(reasonAssignmentRepository.search(Collections.singleton(programId), facilityTypeId,
Sets.newHashSet(ReasonType.CREDIT, ReasonType.DEBIT), reasonId)).thenReturn(
Collections.singletonList(reasonAssignment));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package org.openlmis.stockmanagement.web;

import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static java.util.UUID.randomUUID;
import static org.hamcrest.Matchers.hasSize;
Expand Down Expand Up @@ -77,11 +78,11 @@ public void shouldGetValidSourcesOrDestinationsByProgramAndFacility()
UUID program = randomUUID();
UUID facility = randomUUID();

when(validSourceService.findSources(program, facility, false, pageRequest))
when(validSourceService.findSources(singleton(program), facility, false, pageRequest))
.thenReturn(Pagination.getPage(singletonList(sourceDestination)));

when(validDestinationService.findDestinations(program, facility, false, pageRequest))
.thenReturn(Pagination.getPage(singletonList(sourceDestination)));
when(validDestinationService.findDestinations(singleton(program), facility,
false, pageRequest)).thenReturn(Pagination.getPage(singletonList(sourceDestination)));

verifyZeroInteractions(permissionService);

Expand Down Expand Up @@ -274,4 +275,4 @@ private void performSourcesOrDestinations(
.andExpect(jsonPath("$.content[0].name", is(sourceDestinationDto.getName())))
.andExpect(jsonPath("$.content[0].isFreeTextAllowed", is(true)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public void shouldGetStockCardSummariesByAllParameters() throws Exception {
.param(ACCESS_TOKEN, ACCESS_TOKEN_VALUE)
.param(PAGE, String.valueOf(pageable.getPageNumber()))
.param(SIZE, String.valueOf(pageable.getPageSize()))
.param(PROGRAM_ID, params.getProgramId().toString())
.param(PROGRAM_ID, params.getProgramIds().get(0).toString())
.param(FACILITY_ID, params.getFacilityId().toString())
.param(AS_OF_DATE, params.getAsOfDate().toString())
.param(ORDERABLE_ID, params.getOrderableIds().get(0).toString())
Expand Down Expand Up @@ -132,7 +132,7 @@ public void shouldSetIntegerMaxValueAsDefaultPageSize() throws Exception {
ResultActions resultActions = mvc.perform(
get(API_STOCK_CARD_SUMMARIES)
.param(ACCESS_TOKEN, ACCESS_TOKEN_VALUE)
.param(PROGRAM_ID, params.getProgramId().toString())
.param(PROGRAM_ID, params.getProgramIds().get(0).toString())
.param(FACILITY_ID, params.getFacilityId().toString())
.param(AS_OF_DATE, params.getAsOfDate().toString())
.param(ORDERABLE_ID, params.getOrderableIds().get(0).toString())
Expand All @@ -157,7 +157,7 @@ public void shouldReturnBadRequestIfFacilityIdIsNotPresent() throws Exception {
.param(ACCESS_TOKEN, ACCESS_TOKEN_VALUE)
.param(PAGE, String.valueOf(pageable.getPageNumber()))
.param(SIZE, String.valueOf(pageable.getPageSize()))
.param(PROGRAM_ID, params.getProgramId().toString())
.param(PROGRAM_ID, params.getProgramIds().toString())
.param(AS_OF_DATE, params.getAsOfDate().toString())
.param(ORDERABLE_ID, params.getOrderableIds().get(0).toString())
.param(ORDERABLE_ID, params.getOrderableIds().get(1).toString()));
Expand Down Expand Up @@ -193,7 +193,7 @@ public void shouldReturnForbiddenIfNoPermission() throws Exception {
.param(ACCESS_TOKEN, ACCESS_TOKEN_VALUE)
.param(PAGE, String.valueOf(pageable.getPageNumber()))
.param(SIZE, String.valueOf(pageable.getPageSize()))
.param(PROGRAM_ID, params.getProgramId().toString())
.param(PROGRAM_ID, params.getProgramIds().get(0).toString())
.param(FACILITY_ID, params.getFacilityId().toString()));

resultActions.andExpect(status().isForbidden());
Expand All @@ -219,7 +219,7 @@ public void shouldReturnNonEmptySummariesIfFlagIsSet() throws Exception {
.param(ACCESS_TOKEN, ACCESS_TOKEN_VALUE)
.param(PAGE, String.valueOf(pageable.getPageNumber()))
.param(SIZE, String.valueOf(pageable.getPageSize()))
.param(PROGRAM_ID, params.getProgramId().toString())
.param(PROGRAM_ID, params.getProgramIds().get(0).toString())
.param(FACILITY_ID, params.getFacilityId().toString())
.param(AS_OF_DATE, params.getAsOfDate().toString())
.param(ORDERABLE_ID, params.getOrderableIds().get(0).toString())
Expand Down Expand Up @@ -256,7 +256,7 @@ public void shouldRespectSendNonEmptyCardsFlagInSubsequentRequests() throws Exce
.param(ACCESS_TOKEN, ACCESS_TOKEN_VALUE)
.param(PAGE, String.valueOf(pageable.getPageNumber()))
.param(SIZE, String.valueOf(pageable.getPageSize()))
.param(PROGRAM_ID, params.getProgramId().toString())
.param(PROGRAM_ID, params.getProgramIds().get(0).toString())
.param(FACILITY_ID, params.getFacilityId().toString())
.param(AS_OF_DATE, params.getAsOfDate().toString())
.param(ORDERABLE_ID, params.getOrderableIds().get(0).toString())
Expand Down Expand Up @@ -286,7 +286,7 @@ public void shouldRespectSendNonEmptyCardsFlagInSubsequentRequests() throws Exce
.param(ACCESS_TOKEN, ACCESS_TOKEN_VALUE)
.param(PAGE, String.valueOf(pageable.getPageNumber()))
.param(SIZE, String.valueOf(pageable.getPageSize()))
.param(PROGRAM_ID, params.getProgramId().toString())
.param(PROGRAM_ID, params.getProgramIds().get(0).toString())
.param(FACILITY_ID, params.getFacilityId().toString())
.param(AS_OF_DATE, params.getAsOfDate().toString())
.param(ORDERABLE_ID, params.getOrderableIds().get(0).toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,30 @@
package org.openlmis.stockmanagement.repository;

import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.openlmis.stockmanagement.domain.sourcedestination.SourceDestinationAssignment;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.query.Param;

@NoRepositoryBean
public interface SourceDestinationAssignmentRepository<T extends SourceDestinationAssignment>
extends JpaRepository<T, UUID> {

List<T> findByProgramIdInAndFacilityTypeId(
Set<UUID> programIds, UUID facilityTypeId,
Pageable pageable);

List<T> findByProgramIdAndFacilityTypeId(
@Param("programId") UUID programId, @Param("facilityTypeId") UUID facilityTypeId,
Pageable pageable);
UUID programId, UUID facilityTypeId,
Pageable pageable);

T findByProgramIdInAndFacilityTypeIdAndNodeId(
sradziszewski marked this conversation as resolved.
Show resolved Hide resolved
Set<UUID> programIds, UUID facilityTypeId,
UUID nodeId);

T findByProgramIdAndFacilityTypeIdAndNodeId(
@Param("programId") UUID programId, @Param("facilityTypeId") UUID facilityTypeId,
@Param("nodeId") UUID nodeId);
UUID programId, UUID facilityTypeId,
UUID nodeId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,30 @@

public interface StockCardRepository extends JpaRepository<StockCard, UUID> {

String PROGRAM_ID = "programId";
String FACILITY_ID = "facilityId";

StockCard findByProgramIdAndFacilityIdAndOrderableIdAndLotId(
@Param("programId") UUID programId,
@Param("facilityId") UUID facilityId,
@Param(PROGRAM_ID) UUID programId,
@Param(FACILITY_ID) UUID facilityId,
@Param("orderableId") UUID orderableId,
@Param("lotId") UUID lotId);

Page<StockCard> findByProgramIdAndFacilityId(
@Param("programId") UUID programId,
@Param("facilityId") UUID facilityId,
@Param(PROGRAM_ID) UUID programId,
@Param(FACILITY_ID) UUID facilityId,
Pageable pageable);

List<StockCard> findByProgramIdAndFacilityId(
@Param("programId") UUID programId,
@Param("facilityId") UUID facilityId);
@Param(PROGRAM_ID) UUID programId,
@Param(FACILITY_ID) UUID facilityId);

List<StockCard> findByProgramIdInAndFacilityId(
@Param(PROGRAM_ID) Collection<UUID> programId,
@Param(FACILITY_ID) UUID facilityId);

List<StockCard> findByOrderableIdInAndProgramIdAndFacilityId(
Collection<UUID> orderableIds, UUID programId, UUID facilityId);
List<StockCard> findByOrderableIdInAndProgramIdInAndFacilityId(
sradziszewski marked this conversation as resolved.
Show resolved Hide resolved
Collection<UUID> orderableIds, Collection<UUID> programIds, UUID facilityId);

StockCard findByOriginEvent(@Param("originEventId") StockEvent stockEvent);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

public interface ValidReasonAssignmentRepositoryCustom {

List<ValidReasonAssignment> search(UUID programId, UUID facilityTypeId,
List<ValidReasonAssignment> search(Collection<UUID> programIds, UUID facilityTypeId,
Collection<ReasonType> reasonTypes, UUID reasonId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class ValidReasonAssignmentRepositoryImpl implements ValidReasonAssignmen
* @param reasonId Valid Reason Assignment stock card line item reason id
* @return List of Valid Reason Assignments matching the parameters.
*/
public List<ValidReasonAssignment> search(UUID programId, UUID facilityTypeId,
public List<ValidReasonAssignment> search(Collection<UUID> programId, UUID facilityTypeId,
sradziszewski marked this conversation as resolved.
Show resolved Hide resolved
sradziszewski marked this conversation as resolved.
Show resolved Hide resolved
Collection<ReasonType> reasonTypes, UUID reasonId) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();

Expand All @@ -62,7 +62,7 @@ public List<ValidReasonAssignment> search(UUID programId, UUID facilityTypeId,
Predicate predicate = builder.conjunction();

if (null != programId) {
predicate = builder.and(predicate, builder.equal(root.get(PROGRAM_ID), programId));
predicate = builder.and(predicate, root.get(PROGRAM_ID).in(programId));
}

if (null != facilityTypeId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,21 @@ public class CalculatedStockOnHandService {
/**
* Returns list of stock cards with fetched Stock on Hand values.
*
* @param programId program id to find stock cards
* @param programIds program ids to find stock cards
* @param facilityId facility id to find stock cards
* @param asOfDate date used to get latest stock on hand before or equal specific date
* @param orderableIds orderable ids to find stock card
* @param lotCodeIds lot code ids to find stock card
* @return List of stock cards with SOH values, empty list if no stock cards were found.
*/
public List<StockCard> getStockCardsWithStockOnHand(
UUID programId, UUID facilityId, LocalDate asOfDate, List<UUID> orderableIds,
List<UUID> programIds, UUID facilityId, LocalDate asOfDate, List<UUID> orderableIds,
Set<UUID> lotCodeIds) {

List<StockCard> stockCards = orderableIds.isEmpty()
? stockCardRepository.findByProgramIdAndFacilityId(programId, facilityId)
: stockCardRepository.findByOrderableIdInAndProgramIdAndFacilityId(
orderableIds, programId, facilityId);
? stockCardRepository.findByProgramIdInAndFacilityId(programIds, facilityId)
: stockCardRepository.findByOrderableIdInAndProgramIdInAndFacilityId(
orderableIds, programIds, facilityId);

stockCards.forEach(stockCard ->
fetchStockOnHand(stockCard, asOfDate != null ? asOfDate : LocalDate.now()));
Expand Down Expand Up @@ -122,7 +122,7 @@ public List<StockCard> getStockCardsWithStockOnHand(
public List<StockCard> getStockCardsWithStockOnHand(
UUID programId, UUID facilityId, LocalDate asOfDate, List<UUID> orderableIds) {

return getStockCardsWithStockOnHand(programId, facilityId,
return getStockCardsWithStockOnHand(Collections.singletonList(programId), facilityId,
asOfDate, orderableIds, Collections.emptySet());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import org.openlmis.stockmanagement.domain.sourcedestination.Node;
Expand Down Expand Up @@ -129,20 +130,20 @@ protected <T extends SourceDestinationAssignment> ValidSourceDestinationDto find
* This method will return only those assignments that match the geo level affinity
* or all possible assignments (when filtering params are not provided).
*
* @param programId program id
* @param programIds program ids
* @param facilityId facility id
* @param repository assignment repository
* @param <T> assignment type
* @return a list of assignment dto or empty list if not found.
*/
protected <T extends SourceDestinationAssignment> Page<ValidSourceDestinationDto> findAssignments(
UUID programId, UUID facilityId, boolean includeDisabled,
Set<UUID> programIds, UUID facilityId, boolean includeDisabled,
SourceDestinationAssignmentRepository<T> repository,
Profiler profiler, Pageable pageable) {

profiler.start("FIND_ASSIGNMENTS");
if (programId != null && facilityId != null) {
return findFilteredAssignments(programId, facilityId, includeDisabled,
if (programIds != null && facilityId != null) {
return findFilteredAssignments(programIds, facilityId, includeDisabled,
repository, profiler, pageable);
} else if (includeDisabled) {
return findAllAssignments(repository, profiler, pageable);
Expand Down Expand Up @@ -296,7 +297,7 @@ private List<ValidSourceDestinationDto> createAssignmentDto(
}

private <T extends SourceDestinationAssignment> Page<ValidSourceDestinationDto>
findFilteredAssignments(UUID programId, UUID facilityId, boolean includeDisabled,
findFilteredAssignments(Set<UUID> programIds, UUID facilityId, boolean includeDisabled,
SourceDestinationAssignmentRepository<T> repository, Profiler profiler, Pageable pageable) {
profiler.start("FIND_FACILITY_BY_ID");
FacilityDto facility = facilityRefDataService.findOne(facilityId);
Expand All @@ -308,11 +309,14 @@ private List<ValidSourceDestinationDto> createAssignmentDto(

profiler.start("CHECK_PROGRAM_AND_FACILITY_TYPE_EXIST");
UUID facilityTypeId = facility.getType().getId();
programFacilityTypeExistenceService.checkProgramAndFacilityTypeExist(programId, facilityTypeId);
for (UUID programId : programIds) {
programFacilityTypeExistenceService
.checkProgramAndFacilityTypeExist(programId, facilityTypeId);
}

profiler.start("FIND_ASSIGNMENTS_BY_PROGRAM_AND_FACILITY_TYPE");
List<T> assignments = repository
.findByProgramIdAndFacilityTypeId(programId, facilityTypeId, Pageable.unpaged());
.findByProgramIdInAndFacilityTypeId(programIds, facilityTypeId, Pageable.unpaged());

profiler.start("FIND_FACILITY_IDS");
List<UUID> facilitiesIds = assignments.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,14 @@ public StockCardSummaries findStockCards(StockCardSummariesV2SearchParams params
if (!homeFacilityPermissionService
.checkFacilityAndHomeFacilityLinkage(params.getFacilityId())) {
profiler.start("VALIDATE_VIEW_RIGHTS");
permissionService.canViewStockCard(params.getProgramId(), params.getFacilityId());
for (UUID id : params.getProgramIds()) {
permissionService.canViewStockCard(id, params.getFacilityId());
}
}

profiler.start("GET_APPROVED_PRODUCTS");
OrderablesAggregator approvedProducts = approvedProductReferenceDataService
.getApprovedProducts(params.getFacilityId(), params.getProgramId(),
.getApprovedProducts(params.getFacilityId(), params.getProgramIds(),
params.getOrderableIds(), params.getOrderableCode(), params.getOrderableName()
);

Expand Down Expand Up @@ -194,7 +196,7 @@ public StockCardSummaries findStockCards(StockCardSummariesV2SearchParams params
// FIXME: Fix page retrieving/calculation,
// page size may be wrong when there are orderables matching not only by lot codes
List<StockCard> stockCards = calculatedStockOnHandService.getStockCardsWithStockOnHand(
params.getProgramId(), params.getFacilityId(), params.getAsOfDate(),
params.getProgramIds(), params.getFacilityId(), params.getAsOfDate(),
orderableIdsForStockCard, lotCodeIds);

Page<OrderableDto> orderablesPage = approvedProducts.getOrderablesPage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public final class StockCardSummariesV2SearchParams {
static final String ORDERABLE_NAME = "orderableName";
static final String LOT_CODE = "lotCode";

private UUID programId;
private List<UUID> programIds;
private UUID facilityId;
private List<UUID> orderableIds;
private LocalDate asOfDate;
Expand All @@ -71,14 +71,14 @@ public final class StockCardSummariesV2SearchParams {
*/
public StockCardSummariesV2SearchParams(MultiValueMap<String, String> parameters) {
if (!MapUtils.isEmpty(parameters)) {
this.programId = getId(PROGRAM_ID, parameters);
this.programIds = getIds(PROGRAM_ID, parameters);
this.facilityId = getId(FACILITY_ID, parameters);

if (null == facilityId) {
throw new ValidationMessageException(ERROR_FACILITY_ID_MISSING);
}

if (null == programId) {
if (programIds.isEmpty()) {
throw new ValidationMessageException(ERROR_PROGRAM_ID_MISSING);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,16 @@ public StockEventProcessContext buildContext(StockEventDto eventDto) {

profiler.start("CREATE_LAZY_SOURCES");
Supplier<List<ValidSourceAssignment>> sourcesSupplier = () -> validSourceAssignmentRepository
.findByProgramIdAndFacilityTypeId(
eventDto.getProgramId(), context.getFacilityTypeId(), Pageable.unpaged());
.findByProgramIdAndFacilityTypeId(eventDto.getProgramId(),
sradziszewski marked this conversation as resolved.
Show resolved Hide resolved
context.getFacilityTypeId(), Pageable.unpaged());
LazyList<ValidSourceAssignment> sources = new LazyList<>(sourcesSupplier);
context.setSources(sources);

profiler.start("CREATE_LAZY_DESTINATIONS");
Supplier<List<ValidDestinationAssignment>> destinationsSupplier = () ->
validDestinationAssignmentRepository
.findByProgramIdAndFacilityTypeId(
eventDto.getProgramId(), context.getFacilityTypeId(), Pageable.unpaged());
Supplier<List<ValidDestinationAssignment>> destinationsSupplier =
() -> validDestinationAssignmentRepository
.findByProgramIdAndFacilityTypeId(eventDto.getProgramId(),
context.getFacilityTypeId(), Pageable.unpaged());
LazyList<ValidDestinationAssignment> destinations = new LazyList<>(destinationsSupplier);
context.setDestinations(destinations);

Expand Down
Loading
Loading