Search in sources :

Example 11 with ReEncumbranceHolder

use of org.folio.models.ReEncumbranceHolder in project mod-orders by folio-org.

the class OrderReEncumberServiceTest method testPopulateNeedReEncumberField.

@Test
void testPopulateNeedReEncumberField() {
    // given
    CompositePurchaseOrder order = getMockAsJson(ORDER_PATH).mapTo(CompositePurchaseOrder.class);
    String ledgerId = UUID.randomUUID().toString();
    Fund sampleFund = new Fund().withLedgerId(UUID.randomUUID().toString()).withFundStatus(Fund.FundStatus.ACTIVE).withCode(UUID.randomUUID().toString());
    LedgerFiscalYearRollover rollover = new LedgerFiscalYearRollover().withId(UUID.randomUUID().toString()).withLedgerId(ledgerId);
    LedgerFiscalYearRolloverErrorCollection ledgerFiscalYearRolloverErrors = new LedgerFiscalYearRolloverErrorCollection().withLedgerFiscalYearRolloverErrors(Collections.singletonList(new LedgerFiscalYearRolloverError()));
    CompositePoLine line = order.getCompositePoLines().get(0);
    FundDistribution fundDistribution1 = line.getFundDistribution().get(0);
    String fiscalYearId = UUID.randomUUID().toString();
    ReEncumbranceHolder holder1 = new ReEncumbranceHolder().withPurchaseOrder(order).withPoLine(line).withFundDistribution(fundDistribution1).withRollover(rollover).withLedgerId(ledgerId).withCurrentFiscalYearId(fiscalYearId);
    FundDistribution fundDistribution2 = line.getFundDistribution().get(1);
    ReEncumbranceHolder holder2 = new ReEncumbranceHolder().withPurchaseOrder(order).withPoLine(order.getCompositePoLines().get(0)).withFundDistribution(fundDistribution2).withRollover(rollover).withLedgerId(ledgerId).withCurrentFiscalYearId(fiscalYearId);
    FundDistribution fundDistribution3 = line.getFundDistribution().get(1);
    ReEncumbranceHolder holder3 = new ReEncumbranceHolder().withPurchaseOrder(order).withPoLine(order.getCompositePoLines().get(0)).withFundDistribution(fundDistribution3).withRollover(rollover).withLedgerId(ledgerId).withCurrentFiscalYearId(fiscalYearId);
    List<LedgerFiscalYearRolloverProgress> progresses = Collections.singletonList(success);
    List<ReEncumbranceHolder> holders = List.of(holder1, holder2, holder3);
    // LedgerFiscalYearRolloverErrorCollection is not empty. Expected "needReEncumber" = true
    doReturn(holders).when(spyReEncumbranceHoldersBuilder).buildReEncumbranceHoldersWithOrdersData(any());
    doReturn(completedFuture(holders)).when(spyReEncumbranceHoldersBuilder).withFundsData(any(), any());
    doReturn(completedFuture(holders)).when(spyReEncumbranceHoldersBuilder).withCurrentFiscalYearData(any(), any());
    doReturn(completedFuture(holders)).when(spyReEncumbranceHoldersBuilder).withRollovers(any(), any());
    doReturn(completedFuture(progresses)).when(rolloverRetrieveService).getRolloversProgress(anyString(), any());
    doReturn(completedFuture(ledgerFiscalYearRolloverErrors)).when(rolloverErrorService).getLedgerFyRolloverErrors(any(), any());
    CompositeOrderRetrieveHolder holder = new CompositeOrderRetrieveHolder(order);
    CompositePurchaseOrder compOrder = orderReEncumberService.populate(holder, requestContext).join().getOrder();
    assertTrue(compOrder.getNeedReEncumber());
    // LedgerFiscalYearRolloverErrorCollection is empty. Expected "needReEncumber" = false
    doReturn(completedFuture(new LedgerFiscalYearRolloverErrorCollection())).when(rolloverErrorService).getLedgerFyRolloverErrors(any(), any());
    compOrder = orderReEncumberService.populate(holder, requestContext).join().getOrder();
    assertFalse(compOrder.getNeedReEncumber());
    // LedgerFyRollover not exists. Expected "needReEncumber" = false
    doReturn(completedFuture(new LedgerFiscalYearRolloverCollection())).when(rolloverRetrieveService).getLedgerFyRollovers(anyString(), anyString(), any());
    compOrder = orderReEncumberService.populate(holder, requestContext).join().getOrder();
    assertFalse(compOrder.getNeedReEncumber());
}
Also used : LedgerFiscalYearRolloverErrorCollection(org.folio.rest.acq.model.finance.LedgerFiscalYearRolloverErrorCollection) Fund(org.folio.rest.acq.model.finance.Fund) ReEncumbranceHolder(org.folio.models.ReEncumbranceHolder) CompositePoLine(org.folio.rest.jaxrs.model.CompositePoLine) Matchers.containsString(org.hamcrest.Matchers.containsString) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) CompositePurchaseOrder(org.folio.rest.jaxrs.model.CompositePurchaseOrder) LedgerFiscalYearRollover(org.folio.rest.jaxrs.model.LedgerFiscalYearRollover) CompositeOrderRetrieveHolder(org.folio.models.CompositeOrderRetrieveHolder) FundDistribution(org.folio.rest.jaxrs.model.FundDistribution) LedgerFiscalYearRolloverCollection(org.folio.rest.jaxrs.model.LedgerFiscalYearRolloverCollection) LedgerFiscalYearRolloverProgress(org.folio.rest.acq.model.finance.LedgerFiscalYearRolloverProgress) LedgerFiscalYearRolloverError(org.folio.rest.acq.model.finance.LedgerFiscalYearRolloverError) Test(org.junit.jupiter.api.Test)

Example 12 with ReEncumbranceHolder

use of org.folio.models.ReEncumbranceHolder in project mod-orders by folio-org.

the class OrderReEncumberServiceTest method shouldThrowHttpExceptionWithRolloverNotCompletedCodeWhenAtLeastOneRolloverHasNoProgress.

@Test
void shouldThrowHttpExceptionWithRolloverNotCompletedCodeWhenAtLeastOneRolloverHasNoProgress() {
    String orderId = UUID.randomUUID().toString();
    String fundId1 = UUID.randomUUID().toString();
    String fundId2 = UUID.randomUUID().toString();
    String fundId3 = UUID.randomUUID().toString();
    String ledgerId1 = UUID.randomUUID().toString();
    String ledgerId2 = UUID.randomUUID().toString();
    String ledgerId3 = UUID.randomUUID().toString();
    String rolloverId1 = UUID.randomUUID().toString();
    String rolloverId2 = UUID.randomUUID().toString();
    String rolloverId3 = UUID.randomUUID().toString();
    ReEncumbranceHolder holder1 = new ReEncumbranceHolder().withLedgerId(ledgerId1).withRollover(new LedgerFiscalYearRollover().withId(rolloverId1).withLedgerId(ledgerId1)).withFundDistribution(new FundDistribution().withFundId(fundId1));
    ReEncumbranceHolder holder2 = new ReEncumbranceHolder().withLedgerId(ledgerId2).withRollover(new LedgerFiscalYearRollover().withId(rolloverId2).withLedgerId(ledgerId2)).withFundDistribution(new FundDistribution().withFundId(fundId2));
    ReEncumbranceHolder holder3 = new ReEncumbranceHolder().withLedgerId(ledgerId3).withRollover(new LedgerFiscalYearRollover().withId(rolloverId3).withLedgerId(ledgerId3)).withFundDistribution(new FundDistribution().withFundId(fundId3));
    List<ReEncumbranceHolder> holders = List.of(holder1, holder2, holder3);
    when(purchaseOrderStorageService.getCompositeOrderById(anyString(), any())).thenReturn(completedFuture(new CompositePurchaseOrder()));
    when(spyReEncumbranceHoldersBuilder.buildReEncumbranceHoldersWithOrdersData(any())).thenReturn(holders);
    when(spyReEncumbranceHoldersBuilder.withFundsData(any(), any())).thenReturn(completedFuture(holders));
    when(spyReEncumbranceHoldersBuilder.withLedgersData(any(), any())).thenReturn(completedFuture(holders));
    when(spyReEncumbranceHoldersBuilder.withCurrentFiscalYearData(any(), any())).thenReturn(completedFuture(holders));
    when(spyReEncumbranceHoldersBuilder.withRollovers(any(), any())).thenReturn(completedFuture(holders));
    when(spyReEncumbranceHoldersBuilder.withEncumbranceRollover(any())).thenReturn(holders);
    when(rolloverRetrieveService.getRolloversProgress(eq(rolloverId3), any())).thenReturn(completedFuture(Collections.singletonList(error)));
    when(rolloverRetrieveService.getRolloversProgress(AdditionalMatchers.not(eq(rolloverId3)), any())).thenReturn(completedFuture(Collections.emptyList()));
    CompletionException completionException = assertThrows(CompletionException.class, () -> orderReEncumberService.reEncumber(orderId, requestContext).join());
    assertNotNull(completionException.getCause());
    assertThat(completionException.getCause(), instanceOf(HttpException.class));
    HttpException e = (HttpException) completionException.getCause();
    assertEquals(ROLLOVER_NOT_COMPLETED.getCode(), e.getError().getCode());
    assertEquals(e.getError().getParameters(), Collections.singletonList(new Parameter().withKey("ledgerIds").withValue(ledgerId1 + ", " + ledgerId2)));
}
Also used : FundDistribution(org.folio.rest.jaxrs.model.FundDistribution) CompletionException(java.util.concurrent.CompletionException) ReEncumbranceHolder(org.folio.models.ReEncumbranceHolder) Parameter(org.folio.rest.jaxrs.model.Parameter) HttpException(org.folio.rest.core.exceptions.HttpException) Matchers.containsString(org.hamcrest.Matchers.containsString) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) LedgerFiscalYearRollover(org.folio.rest.jaxrs.model.LedgerFiscalYearRollover) CompositePurchaseOrder(org.folio.rest.jaxrs.model.CompositePurchaseOrder) Test(org.junit.jupiter.api.Test)

Example 13 with ReEncumbranceHolder

use of org.folio.models.ReEncumbranceHolder in project mod-orders by folio-org.

the class OrderReEncumberServiceTest method shouldFilterReEncumberHoldersWithEmptyEncumbranceRollover.

@Test
void shouldFilterReEncumberHoldersWithEmptyEncumbranceRollover() {
    CompositePoLine line = new CompositePoLine().withCost(new Cost().withCurrency("USD").withListUnitPrice(1d));
    String orderId = UUID.randomUUID().toString();
    ReEncumbranceHolder holder1 = new ReEncumbranceHolder().withPoLine(line).withLedgerId(UUID.randomUUID().toString());
    ReEncumbranceHolder holder2 = new ReEncumbranceHolder().withPoLine(line).withLedgerId(UUID.randomUUID().toString());
    List<ReEncumbranceHolder> holders = List.of(holder1, holder2);
    when(purchaseOrderStorageService.getCompositeOrderById(eq(orderId), eq(requestContext))).thenReturn(completedFuture(new CompositePurchaseOrder().withId(orderId)));
    when(spyReEncumbranceHoldersBuilder.buildReEncumbranceHoldersWithOrdersData(any())).thenReturn(holders);
    when(spyReEncumbranceHoldersBuilder.withFundsData(any(), any())).thenReturn(completedFuture(holders));
    when(spyReEncumbranceHoldersBuilder.withLedgersData(any(), any())).thenReturn(completedFuture(holders));
    when(spyReEncumbranceHoldersBuilder.withCurrentFiscalYearData(any(), any())).thenReturn(completedFuture(holders));
    when(spyReEncumbranceHoldersBuilder.withRollovers(any(), any())).thenReturn(completedFuture(holders));
    when(spyReEncumbranceHoldersBuilder.withEncumbranceRollover(any())).thenReturn(holders);
    when(spyReEncumbranceHoldersBuilder.withBudgets(any(), any())).thenReturn(completedFuture(holders));
    when(spyReEncumbranceHoldersBuilder.withConversions(any(), any())).thenReturn(completedFuture(holders));
    when(spyReEncumbranceHoldersBuilder.withPreviousFyEncumbrances(any(), any())).thenAnswer(invocation -> completedFuture(invocation.getArgument(0)));
    when(spyReEncumbranceHoldersBuilder.withToEncumbrances(any(), any())).thenAnswer(invocation -> completedFuture(invocation.getArgument(0)));
    doNothing().when(budgetRestrictionService).checkEncumbranceRestrictions(anyList());
    when(rolloverErrorService.getLedgerFyRolloverErrors(anyString(), any())).thenReturn(completedFuture(new LedgerFiscalYearRolloverErrorCollection()));
    when(rolloverErrorService.deleteRolloverErrors(anyList(), any())).thenReturn(completedFuture(null));
    when(purchaseOrderLineService.saveOrderLines(anyList(), any())).thenReturn(completedFuture(null));
    CompletableFuture<Void> future = orderReEncumberService.reEncumber(orderId, requestContext);
    TransactionCollection toTransactionCollection = new TransactionCollection().withTransactions(Collections.EMPTY_LIST).withTotalRecords(0);
    when(transactionService.getTransactions(anyString(), eq(0), eq(Integer.MAX_VALUE), eq(requestContext))).thenReturn(completedFuture(toTransactionCollection));
    when(transactionSummaryService.updateOrderTransactionSummary(eq(orderId), anyInt(), eq(requestContext))).thenReturn(completedFuture(null));
    when(transactionService.createTransaction(any(), eq(requestContext))).thenReturn(completedFuture(new Transaction()));
    future.join();
    assertFalse(future.isCompletedExceptionally());
    ArgumentCaptor<List<ReEncumbranceHolder>> argumentCaptor = ArgumentCaptor.forClass(List.class);
    verify(spyReEncumbranceHoldersBuilder).withPreviousFyEncumbrances(argumentCaptor.capture(), any());
    List<ReEncumbranceHolder> argumentHolders = argumentCaptor.getValue();
    assertThat(argumentHolders, hasSize(0));
}
Also used : LedgerFiscalYearRolloverErrorCollection(org.folio.rest.acq.model.finance.LedgerFiscalYearRolloverErrorCollection) TransactionCollection(org.folio.rest.acq.model.finance.TransactionCollection) ReEncumbranceHolder(org.folio.models.ReEncumbranceHolder) CompositePoLine(org.folio.rest.jaxrs.model.CompositePoLine) Matchers.containsString(org.hamcrest.Matchers.containsString) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) CompositePurchaseOrder(org.folio.rest.jaxrs.model.CompositePurchaseOrder) Cost(org.folio.rest.jaxrs.model.Cost) Transaction(org.folio.rest.acq.model.finance.Transaction) ArgumentMatchers.anyList(org.mockito.ArgumentMatchers.anyList) List(java.util.List) Test(org.junit.jupiter.api.Test)

Example 14 with ReEncumbranceHolder

use of org.folio.models.ReEncumbranceHolder in project mod-orders by folio-org.

the class ReEncumbranceHoldersBuilder method withConversions.

public CompletableFuture<List<ReEncumbranceHolder>> withConversions(List<ReEncumbranceHolder> reEncumbranceHolders, RequestContext requestContext) {
    Optional<String> fyCurrency = reEncumbranceHolders.stream().map(ReEncumbranceHolder::getCurrency).filter(Objects::nonNull).findFirst();
    if (fyCurrency.isEmpty()) {
        return CompletableFuture.completedFuture(reEncumbranceHolders);
    }
    return AsyncUtil.executeBlocking(requestContext.getContext(), false, () -> {
        Map<String, List<ReEncumbranceHolder>> currencyHoldersMap = reEncumbranceHolders.stream().collect(groupingBy(reEncumbranceHolder -> reEncumbranceHolder.getPoLine().getCost().getCurrency()));
        currencyHoldersMap.forEach((poLineCurrency, holders) -> {
            Double exchangeRate = holders.stream().map(ReEncumbranceHolder::getPoLine).map(CompositePoLine::getCost).map(Cost::getExchangeRate).filter(Objects::nonNull).findFirst().orElse(null);
            ConversionQuery poLineToFYConversionQuery = HelperUtils.getConversionQuery(exchangeRate, poLineCurrency, fyCurrency.get());
            ExchangeRateProvider exchangeRateProvider = exchangeRateProviderResolver.resolve(poLineToFYConversionQuery, requestContext);
            CurrencyConversion poLineToFYConversion = exchangeRateProvider.getCurrencyConversion(poLineToFYConversionQuery);
            exchangeRate = poLineToFYConversion.getExchangeRate(Money.of(0d, poLineCurrency)).getFactor().doubleValue();
            double reverseRate = BigDecimal.ONE.divide(BigDecimal.valueOf(exchangeRate), DECIMAL64).doubleValue();
            ConversionQuery fyToPoLineConversionQuery = HelperUtils.getConversionQuery(reverseRate, fyCurrency.get(), poLineCurrency);
            CurrencyConversion fyToPoLineConversion = exchangeRateProvider.getCurrencyConversion(fyToPoLineConversionQuery);
            holders.forEach(holder -> holder.withPoLineToFyConversion(poLineToFYConversion).withFyToPoLineConversion(fyToPoLineConversion));
        });
        return reEncumbranceHolders;
    });
}
Also used : Cost(org.folio.rest.jaxrs.model.Cost) CurrencyConversion(javax.money.convert.CurrencyConversion) BudgetService(org.folio.service.finance.budget.BudgetService) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) CompletableFuture(java.util.concurrent.CompletableFuture) TransactionService(org.folio.service.finance.transaction.TransactionService) Transaction(org.folio.rest.acq.model.finance.Transaction) Function(java.util.function.Function) TransactionCollection(org.folio.rest.acq.model.finance.TransactionCollection) BigDecimal(java.math.BigDecimal) AsyncUtil(org.folio.completablefuture.AsyncUtil) Collectors.toMap(java.util.stream.Collectors.toMap) CompositePurchaseOrder(org.folio.rest.jaxrs.model.CompositePurchaseOrder) Map(java.util.Map) RequestContext(org.folio.rest.core.models.RequestContext) Encumbrance(org.folio.rest.acq.model.finance.Encumbrance) JsonObject(io.vertx.core.json.JsonObject) FundService(org.folio.service.finance.FundService) Budget(org.folio.rest.acq.model.finance.Budget) ExchangeRateProviderResolver(org.folio.service.exchange.ExchangeRateProviderResolver) RolloverRetrieveService(org.folio.service.finance.rollover.RolloverRetrieveService) EncumbranceRollover(org.folio.rest.jaxrs.model.EncumbranceRollover) ReEncumbranceHolder(org.folio.models.ReEncumbranceHolder) HelperUtils(org.folio.orders.utils.HelperUtils) Money(org.javamoney.moneta.Money) ConversionQuery(javax.money.convert.ConversionQuery) Ledger(org.folio.rest.acq.model.finance.Ledger) FiscalYearService(org.folio.service.finance.FiscalYearService) Fund(org.folio.rest.acq.model.finance.Fund) FundsDistributionService(org.folio.service.FundsDistributionService) Objects(java.util.Objects) DECIMAL64(java.math.MathContext.DECIMAL64) Collectors.toList(java.util.stream.Collectors.toList) List(java.util.List) LedgerService(org.folio.service.finance.LedgerService) ExchangeRateProvider(javax.money.convert.ExchangeRateProvider) CompositePoLine(org.folio.rest.jaxrs.model.CompositePoLine) Optional(java.util.Optional) LedgerFiscalYearRollover(org.folio.rest.jaxrs.model.LedgerFiscalYearRollover) ExchangeRateProvider(javax.money.convert.ExchangeRateProvider) ReEncumbranceHolder(org.folio.models.ReEncumbranceHolder) CompositePoLine(org.folio.rest.jaxrs.model.CompositePoLine) CurrencyConversion(javax.money.convert.CurrencyConversion) ConversionQuery(javax.money.convert.ConversionQuery) Objects(java.util.Objects) Collectors.toList(java.util.stream.Collectors.toList) List(java.util.List)

Example 15 with ReEncumbranceHolder

use of org.folio.models.ReEncumbranceHolder in project mod-orders by folio-org.

the class ReEncumbranceHoldersBuilder method withToTransactions.

private CompletableFuture<List<ReEncumbranceHolder>> withToTransactions(List<ReEncumbranceHolder> holders, RequestContext requestContext) {
    ReEncumbranceHolder reEncumbranceHolder = holders.get(0);
    String toQuery = String.format(GET_ORDER_TRANSACTIONS_QUERY_TEMPLATE, reEncumbranceHolder.getRollover().getToFiscalYearId(), reEncumbranceHolder.getPurchaseOrder().getId());
    return transactionService.getTransactions(toQuery, 0, Integer.MAX_VALUE, requestContext).thenApply(TransactionCollection::getTransactions).thenApply(transactions -> {
        populateExistingToFYEncumbrances(holders, transactions);
        populateNonExistingToFYEncumbrances(holders);
        return holders;
    });
}
Also used : ReEncumbranceHolder(org.folio.models.ReEncumbranceHolder)

Aggregations

ReEncumbranceHolder (org.folio.models.ReEncumbranceHolder)31 Test (org.junit.jupiter.api.Test)28 CompositePurchaseOrder (org.folio.rest.jaxrs.model.CompositePurchaseOrder)16 FundDistribution (org.folio.rest.jaxrs.model.FundDistribution)14 LedgerFiscalYearRollover (org.folio.rest.jaxrs.model.LedgerFiscalYearRollover)14 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)13 Fund (org.folio.rest.acq.model.finance.Fund)11 EncumbranceRollover (org.folio.rest.jaxrs.model.EncumbranceRollover)10 CompositePoLine (org.folio.rest.jaxrs.model.CompositePoLine)9 Transaction (org.folio.rest.acq.model.finance.Transaction)7 Matchers.containsString (org.hamcrest.Matchers.containsString)7 TransactionCollection (org.folio.rest.acq.model.finance.TransactionCollection)6 Encumbrance (org.folio.rest.acq.model.finance.Encumbrance)5 Cost (org.folio.rest.jaxrs.model.Cost)5 CompletionException (java.util.concurrent.CompletionException)4 FiscalYear (org.folio.rest.acq.model.finance.FiscalYear)4 Ledger (org.folio.rest.acq.model.finance.Ledger)4 HttpException (org.folio.rest.core.exceptions.HttpException)4 Parameter (org.folio.rest.jaxrs.model.Parameter)4 ConversionQuery (javax.money.convert.ConversionQuery)3