Search in sources :

Example 21 with FiscalYear

use of org.folio.rest.acq.model.finance.FiscalYear in project mod-invoice by folio-org.

the class PendingPaymentWorkflowServiceTest method updatePendingPayments.

@Test
void updatePendingPayments() {
    String fiscalYearId = UUID.randomUUID().toString();
    String fundId = UUID.randomUUID().toString();
    String invoiceId = UUID.randomUUID().toString();
    String invoiceLineId = UUID.randomUUID().toString();
    double exchangeRate = 1.3;
    FiscalYear fiscalYear = new FiscalYear().withId(fiscalYearId).withCurrency("USD");
    Transaction existingInvoiceLineTransaction = new Transaction().withId(UUID.randomUUID().toString()).withCurrency("USD").withFromFundId(fundId).withFiscalYearId(fiscalYearId).withSourceInvoiceId(invoiceId).withSourceInvoiceLineId(invoiceLineId).withAmount(50d);
    Transaction existingInvoiceTransaction = new Transaction().withId(UUID.randomUUID().toString()).withCurrency("USD").withFromFundId(fundId).withFiscalYearId(fiscalYearId).withSourceInvoiceId(invoiceId).withAmount(10d);
    FundDistribution invoiceFundDistribution = new FundDistribution().withDistributionType(FundDistribution.DistributionType.AMOUNT).withFundId(fundId).withValue(30.5);
    Adjustment adjustment = new Adjustment().withFundDistributions(Collections.singletonList(invoiceFundDistribution)).withProrate(Adjustment.Prorate.NOT_PRORATED).withValue(30.5).withType(Adjustment.Type.AMOUNT);
    Invoice invoice = new Invoice().withAdjustments(Collections.singletonList(adjustment)).withId(invoiceId).withSubTotal(50d).withExchangeRate(exchangeRate).withCurrency("EUR");
    InvoiceLine invoiceLine = new InvoiceLine().withSubTotal(60d).withTotal(60d).withId(invoiceLineId);
    FundDistribution invoiceLineFundDistribution = new FundDistribution().withDistributionType(FundDistribution.DistributionType.AMOUNT).withFundId(fundId).withValue(60d);
    invoiceLine.getFundDistributions().add(invoiceLineFundDistribution);
    ConversionQuery conversionQuery = ConversionQueryBuilder.of().setTermCurrency(DEFAULT_SYSTEM_CURRENCY).set(RATE_KEY, exchangeRate).build();
    ExchangeRateProvider exchangeRateProvider = new ExchangeRateProviderResolver().resolve(conversionQuery, new RequestContext(Vertx.currentContext(), Collections.emptyMap()));
    CurrencyConversion conversion = exchangeRateProvider.getCurrencyConversion(conversionQuery);
    List<InvoiceWorkflowDataHolder> holders = new ArrayList<>();
    InvoiceWorkflowDataHolder holder1 = new InvoiceWorkflowDataHolder().withInvoice(invoice).withInvoiceLine(invoiceLine).withFundDistribution(invoiceLineFundDistribution).withFiscalYear(fiscalYear).withExistingTransaction(existingInvoiceLineTransaction).withConversion(conversion);
    InvoiceWorkflowDataHolder holder2 = new InvoiceWorkflowDataHolder().withInvoice(invoice).withAdjustment(adjustment).withFundDistribution(invoiceFundDistribution).withFiscalYear(fiscalYear).withExistingTransaction(existingInvoiceTransaction).withConversion(conversion);
    holders.add(holder1);
    holders.add(holder2);
    doNothing().when(fundAvailabilityValidator).validate(anyList());
    when(invoiceTransactionSummaryService.updateInvoiceTransactionSummary(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
    when(baseTransactionService.updateTransaction(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
    when(requestContext.getContext()).thenReturn(Vertx.vertx().getOrCreateContext());
    pendingPaymentWorkflowService.handlePendingPaymentsUpdate(holders, requestContext);
    ArgumentCaptor<List<InvoiceWorkflowDataHolder>> argumentCaptor = ArgumentCaptor.forClass(List.class);
    verify(fundAvailabilityValidator).validate(argumentCaptor.capture());
    assertThat(argumentCaptor.getValue(), hasSize(2));
    List<InvoiceWorkflowDataHolder> holdersWithNewTransactions = argumentCaptor.getValue();
    Transaction newInvoiceTransaction = holdersWithNewTransactions.stream().map(InvoiceWorkflowDataHolder::getNewTransaction).filter(transaction -> Objects.isNull(transaction.getSourceInvoiceLineId())).findFirst().get();
    Transaction newInvoiceLineTransaction = holdersWithNewTransactions.stream().map(InvoiceWorkflowDataHolder::getNewTransaction).filter(transaction -> Objects.nonNull(transaction.getSourceInvoiceLineId())).findFirst().get();
    double expectedInvoiceLineTransactionAmount = BigDecimal.valueOf(60).multiply(BigDecimal.valueOf(exchangeRate)).doubleValue();
    assertEquals(expectedInvoiceLineTransactionAmount, newInvoiceLineTransaction.getAmount());
    assertEquals(fundId, newInvoiceLineTransaction.getFromFundId());
    assertEquals(fiscalYearId, newInvoiceLineTransaction.getFiscalYearId());
    assertEquals(invoiceId, newInvoiceLineTransaction.getSourceInvoiceId());
    assertEquals(invoiceLineId, newInvoiceLineTransaction.getSourceInvoiceLineId());
    assertEquals(Transaction.TransactionType.PENDING_PAYMENT, newInvoiceLineTransaction.getTransactionType());
    assertEquals(Transaction.Source.INVOICE, newInvoiceLineTransaction.getSource());
    double expectedInvoiceTransactionAmount = BigDecimal.valueOf(30.5).multiply(BigDecimal.valueOf(exchangeRate)).doubleValue();
    assertEquals(expectedInvoiceTransactionAmount, newInvoiceTransaction.getAmount());
    assertEquals(fundId, newInvoiceTransaction.getFromFundId());
    assertEquals(fiscalYearId, newInvoiceTransaction.getFiscalYearId());
    assertEquals(invoiceId, newInvoiceTransaction.getSourceInvoiceId());
    assertNull(newInvoiceTransaction.getSourceInvoiceLineId());
    assertEquals(Transaction.TransactionType.PENDING_PAYMENT, newInvoiceTransaction.getTransactionType());
    assertEquals(Transaction.Source.INVOICE, newInvoiceTransaction.getSource());
    InvoiceTransactionSummary expectedSummary = new InvoiceTransactionSummary().withId(invoiceId).withNumPaymentsCredits(2).withNumPendingPayments(2);
    verify(invoiceTransactionSummaryService).updateInvoiceTransactionSummary(eq(expectedSummary), eq(requestContext));
    ArgumentCaptor<Transaction> transactionArgumentCaptor = ArgumentCaptor.forClass(Transaction.class);
    verify(baseTransactionService, times(2)).updateTransaction(transactionArgumentCaptor.capture(), eq(requestContext));
    Transaction updateArgumentInvoiceTransaction = transactionArgumentCaptor.getAllValues().stream().filter(transaction -> Objects.isNull(transaction.getSourceInvoiceLineId())).findFirst().get();
    assertEquals(existingInvoiceTransaction.getId(), updateArgumentInvoiceTransaction.getId());
    assertEquals(expectedInvoiceTransactionAmount, updateArgumentInvoiceTransaction.getAmount());
    Transaction updateArgumentInvoiceLineTransaction = transactionArgumentCaptor.getAllValues().stream().filter(transaction -> Objects.nonNull(transaction.getSourceInvoiceLineId())).findFirst().get();
    assertEquals(existingInvoiceLineTransaction.getId(), updateArgumentInvoiceLineTransaction.getId());
    assertEquals(expectedInvoiceLineTransactionAmount, updateArgumentInvoiceLineTransaction.getAmount());
}
Also used : FiscalYear(org.folio.rest.acq.model.finance.FiscalYear) Invoice(org.folio.rest.jaxrs.model.Invoice) ExchangeRateProvider(javax.money.convert.ExchangeRateProvider) Adjustment(org.folio.rest.jaxrs.model.Adjustment) InvoiceLine(org.folio.rest.jaxrs.model.InvoiceLine) ArrayList(java.util.ArrayList) CurrencyConversion(javax.money.convert.CurrencyConversion) ManualCurrencyConversion(org.folio.services.exchange.ManualCurrencyConversion) ExchangeRateProviderResolver(org.folio.services.exchange.ExchangeRateProviderResolver) FundDistribution(org.folio.rest.jaxrs.model.FundDistribution) ConversionQuery(javax.money.convert.ConversionQuery) Transaction(org.folio.rest.acq.model.finance.Transaction) InvoiceWorkflowDataHolder(org.folio.models.InvoiceWorkflowDataHolder) ArrayList(java.util.ArrayList) ArgumentMatchers.anyList(org.mockito.ArgumentMatchers.anyList) List(java.util.List) RequestContext(org.folio.rest.core.models.RequestContext) InvoiceTransactionSummary(org.folio.rest.acq.model.finance.InvoiceTransactionSummary) Test(org.junit.jupiter.api.Test)

Example 22 with FiscalYear

use of org.folio.rest.acq.model.finance.FiscalYear in project mod-invoice by folio-org.

the class CurrentFiscalYearServiceTest method shouldReturnCurrentFiscalYear.

@Test
void shouldReturnCurrentFiscalYear() {
    // Given
    String ledgerId = UUID.randomUUID().toString();
    String fiscalYearId = UUID.randomUUID().toString();
    Date startDate = new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime();
    LocalDate localDate = LocalDate.now().plusDays(1);
    Date endDate = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    FiscalYear fiscalYear = new FiscalYear().withId(fiscalYearId).withPeriodStart(startDate).withPeriodEnd(endDate);
    doReturn(completedFuture(fiscalYear)).when(currentFiscalYearRestClient).get(any(), any(), any());
    // When
    FiscalYear currentFiscalYear = currentFiscalYearService.getCurrentFiscalYear(ledgerId, requestContextMock).join();
    // Then
    Assertions.assertEquals(fiscalYearId, currentFiscalYear.getId());
}
Also used : FiscalYear(org.folio.rest.acq.model.finance.FiscalYear) GregorianCalendar(java.util.GregorianCalendar) LocalDate(java.time.LocalDate) Date(java.util.Date) LocalDate(java.time.LocalDate) Test(org.junit.jupiter.api.Test)

Example 23 with FiscalYear

use of org.folio.rest.acq.model.finance.FiscalYear in project mod-invoice by folio-org.

the class CurrentFiscalYearServiceTest method shouldReturnCurrentFiscalYearByFundId.

@Test
void shouldReturnCurrentFiscalYearByFundId() {
    // Given
    String fundId = UUID.randomUUID().toString();
    String ledgerId = UUID.randomUUID().toString();
    String fiscalYearId = UUID.randomUUID().toString();
    Date startDate = new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime();
    LocalDate localDate = LocalDate.now().plusDays(1);
    Date endDate = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    Fund fund = new Fund().withId(fundId).withLedgerId(ledgerId);
    FiscalYear fiscalYear = new FiscalYear().withId(fiscalYearId).withPeriodStart(startDate).withPeriodEnd(endDate);
    doReturn(completedFuture(fund)).when(fundService).getFundById(fundId, requestContextMock);
    doReturn(completedFuture(fiscalYear)).when(currentFiscalYearRestClient).get(any(), any(), any());
    // When
    FiscalYear currentFiscalYear = currentFiscalYearService.getCurrentFiscalYearByFund(fundId, requestContextMock).join();
    // Then
    Assertions.assertEquals(fiscalYearId, currentFiscalYear.getId());
}
Also used : FiscalYear(org.folio.rest.acq.model.finance.FiscalYear) Fund(org.folio.rest.acq.model.finance.Fund) GregorianCalendar(java.util.GregorianCalendar) LocalDate(java.time.LocalDate) Date(java.util.Date) LocalDate(java.time.LocalDate) Test(org.junit.jupiter.api.Test)

Example 24 with FiscalYear

use of org.folio.rest.acq.model.finance.FiscalYear in project mod-invoice by folio-org.

the class FundAvailabilityHolderValidatorTest method checkEnoughMoneyInBudgetShouldPassIfTransactionsAmountDifferenceLessThanBudgetRemainingAmount.

@Test
void checkEnoughMoneyInBudgetShouldPassIfTransactionsAmountDifferenceLessThanBudgetRemainingAmount() {
    String fiscalYearId = UUID.randomUUID().toString();
    String fundId = UUID.randomUUID().toString();
    String ledgerId = UUID.randomUUID().toString();
    String budgetId = UUID.randomUUID().toString();
    Transaction existingTransaction = new Transaction().withTransactionType(Transaction.TransactionType.PENDING_PAYMENT).withAmount(50d).withFiscalYearId(fiscalYearId).withFromFundId(fundId).withCurrency("USD");
    Transaction newTransaction = new Transaction().withTransactionType(Transaction.TransactionType.PENDING_PAYMENT).withAmount(60d).withFiscalYearId(fiscalYearId).withFromFundId(fundId).withCurrency("USD");
    Budget budget = new Budget().withId(budgetId).withFiscalYearId(fiscalYearId).withFundId(fundId).withAllocated(59d).withAvailable(9d).withTotalFunding(59d).withUnavailable(50d).withAwaitingPayment(50D).withAllowableExpenditure(150d);
    Fund fund = new Fund().withId(fundId).withLedgerId(ledgerId).withCode("FC").withFundStatus(Fund.FundStatus.ACTIVE);
    Ledger ledger = new Ledger().withId(ledgerId).withRestrictExpenditures(true);
    List<InvoiceWorkflowDataHolder> holders = new ArrayList<>();
    InvoiceWorkflowDataHolder holder = new InvoiceWorkflowDataHolder().withExistingTransaction(existingTransaction).withNewTransaction(newTransaction).withBudget(budget).withFund(fund).withRestrictExpenditures(ledger.getRestrictExpenditures()).withFiscalYear(new FiscalYear().withId(fiscalYearId).withCurrency("USD"));
    holders.add(holder);
    assertDoesNotThrow(() -> fundAvailabilityValidator.validate(holders));
}
Also used : FiscalYear(org.folio.rest.acq.model.finance.FiscalYear) Transaction(org.folio.rest.acq.model.finance.Transaction) Fund(org.folio.rest.acq.model.finance.Fund) Ledger(org.folio.rest.acq.model.finance.Ledger) InvoiceWorkflowDataHolder(org.folio.models.InvoiceWorkflowDataHolder) ArrayList(java.util.ArrayList) Budget(org.folio.rest.acq.model.finance.Budget) Test(org.junit.jupiter.api.Test)

Example 25 with FiscalYear

use of org.folio.rest.acq.model.finance.FiscalYear in project mod-invoice by folio-org.

the class FundAvailabilityHolderValidatorTest method shouldPassValidationWhenBudgetRestrictedAndAmountGreaterThanAvailableAndRequiredAmountEncumbered.

@Test
void shouldPassValidationWhenBudgetRestrictedAndAmountGreaterThanAvailableAndRequiredAmountEncumbered() {
    String fiscalYearId = UUID.randomUUID().toString();
    String fundId = UUID.randomUUID().toString();
    String budgetId = UUID.randomUUID().toString();
    String ledgerId = UUID.randomUUID().toString();
    FiscalYear fiscalYear = new FiscalYear().withCurrency("USD").withId(fiscalYearId);
    Fund fund = new Fund().withId(fundId).withName("TestFund").withLedgerId(ledgerId).withCode("FC").withFundStatus(Fund.FundStatus.ACTIVE);
    Budget budget = new Budget().withId(budgetId).withFiscalYearId(fiscalYearId).withFundId(fundId).withAllocated(260d).withTotalFunding(260d).withAvailable(20d).withUnavailable(240d).withEncumbered(200d).withAwaitingPayment(40d).withAllowableExpenditure(100d);
    List<InvoiceWorkflowDataHolder> holders = new ArrayList<>();
    Transaction adjustmentPendingPayment = new Transaction().withAmount(20d).withCurrency("USD");
    Transaction encumbrance = new Transaction().withId(UUID.randomUUID().toString()).withAmount(200d).withCurrency("USD");
    Transaction linePendingPayment = new Transaction().withAmount(200d).withAwaitingPayment(new AwaitingPayment().withEncumbranceId(encumbrance.getId()).withReleaseEncumbrance(false)).withCurrency("USD");
    InvoiceWorkflowDataHolder holder1 = new InvoiceWorkflowDataHolder().withFund(fund).withBudget(budget).withRestrictExpenditures(true).withFiscalYear(fiscalYear).withNewTransaction(linePendingPayment).withEncumbrance(encumbrance);
    InvoiceWorkflowDataHolder holder2 = new InvoiceWorkflowDataHolder().withFund(fund).withBudget(budget).withRestrictExpenditures(true).withFiscalYear(fiscalYear).withNewTransaction(adjustmentPendingPayment);
    holders.add(holder1);
    holders.add(holder2);
    assertDoesNotThrow(() -> fundAvailabilityValidator.validate(holders));
}
Also used : FiscalYear(org.folio.rest.acq.model.finance.FiscalYear) Fund(org.folio.rest.acq.model.finance.Fund) Transaction(org.folio.rest.acq.model.finance.Transaction) InvoiceWorkflowDataHolder(org.folio.models.InvoiceWorkflowDataHolder) ArrayList(java.util.ArrayList) Budget(org.folio.rest.acq.model.finance.Budget) AwaitingPayment(org.folio.rest.acq.model.finance.AwaitingPayment) Test(org.junit.jupiter.api.Test)

Aggregations

FiscalYear (org.folio.rest.acq.model.finance.FiscalYear)26 Test (org.junit.jupiter.api.Test)22 Fund (org.folio.rest.acq.model.finance.Fund)11 ArrayList (java.util.ArrayList)9 Transaction (org.folio.rest.acq.model.finance.Transaction)9 InvoiceWorkflowDataHolder (org.folio.models.InvoiceWorkflowDataHolder)7 Budget (org.folio.rest.acq.model.finance.Budget)7 HttpException (org.folio.invoices.rest.exceptions.HttpException)4 CompositeOrderRetrieveHolder (org.folio.models.CompositeOrderRetrieveHolder)4 ReEncumbranceHolder (org.folio.models.ReEncumbranceHolder)4 CompositePoLine (org.folio.rest.jaxrs.model.CompositePoLine)4 CompositePurchaseOrder (org.folio.rest.jaxrs.model.CompositePurchaseOrder)4 Error (org.folio.rest.jaxrs.model.Error)4 FundDistribution (org.folio.rest.jaxrs.model.FundDistribution)4 CompletableFuture (java.util.concurrent.CompletableFuture)3 TransactionCollection (org.folio.rest.acq.model.finance.TransactionCollection)3 HttpException (org.folio.rest.core.exceptions.HttpException)3 JsonObject (io.vertx.core.json.JsonObject)2 LocalDate (java.time.LocalDate)2 Date (java.util.Date)2