use of org.folio.rest.acq.model.finance.Fund in project mod-invoice by folio-org.
the class InvoicesApiTest method testTransitionFromOpenToApprovedWithMixedTypesFundDistributionsAndWithLockTotalWhichEqualToTotal.
@Test
void testTransitionFromOpenToApprovedWithMixedTypesFundDistributionsAndWithLockTotalWhichEqualToTotal() {
Invoice reqData = getMockAsJson(OPEN_INVOICE_SAMPLE_PATH).mapTo(Invoice.class);
String id = reqData.getId();
InvoiceLine invoiceLine = getMinimalContentInvoiceLine(id);
invoiceLine.setSubTotal(100d);
invoiceLine.setId(UUID.randomUUID().toString());
FundDistribution percentageDistribution = new FundDistribution().withFundId(EXISTING_FUND_ID).withCode(null).withDistributionType(FundDistribution.DistributionType.PERCENTAGE).withValue(50d);
FundDistribution amountDistribution = new FundDistribution().withFundId(EXISTING_FUND_ID).withDistributionType(AMOUNT).withValue(50d);
invoiceLine.getFundDistributions().addAll(Arrays.asList(percentageDistribution, amountDistribution));
addMockEntry(INVOICE_LINES, JsonObject.mapFrom(invoiceLine));
reqData.setStatus(Invoice.Status.APPROVED);
reqData.setLockTotal(100d);
String jsonBody = JsonObject.mapFrom(reqData).encode();
Headers headers = prepareHeaders(X_OKAPI_URL, X_OKAPI_TENANT, X_OKAPI_TOKEN, X_OKAPI_USER_ID);
verifyPut(String.format(INVOICE_ID_PATH, id), jsonBody, headers, "", 204);
// Verify that expected number of external calls made
assertThat(getInvoiceRetrievals(), hasSize(1));
assertThat(getInvoiceLineSearches(), hasSize(1));
Invoice updatedInvoice = serverRqRs.get(INVOICES, HttpMethod.PUT).get(0).mapTo(Invoice.class);
List<JsonObject> vouchersCreated = serverRqRs.get(VOUCHERS_STORAGE, HttpMethod.POST);
assertThat(vouchersCreated, notNullValue());
assertThat(vouchersCreated, hasSize(1));
Voucher voucherCreated = vouchersCreated.get(0).mapTo(Voucher.class);
assertThat(voucherCreated.getVoucherNumber(), equalTo(TEST_PREFIX + VOUCHER_NUMBER_VALUE));
assertThat(voucherCreated.getSystemCurrency(), equalTo(DEFAULT_SYSTEM_CURRENCY));
List<JsonObject> fundsSearches = serverRqRs.get(FUNDS, HttpMethod.GET);
List<Fund> funds = fundsSearches.get(0).mapTo(FundCollection.class).getFunds();
verifyTransitionToApproved(voucherCreated, Collections.singletonList(invoiceLine), updatedInvoice, getExpectedVoucherLinesQuantity(funds));
checkVoucherAcqUnitIdsList(voucherCreated, reqData);
}
use of org.folio.rest.acq.model.finance.Fund in project mod-invoice by folio-org.
the class MockServer method handleFundById.
private void handleFundById(RoutingContext ctx) {
logger.info("handleFund got: GET " + ctx.request().path());
String id = ctx.request().getParam(AbstractHelper.ID);
logger.info("id: " + id);
if (ID_DOES_NOT_EXIST.equals(id)) {
serverResponse(ctx, 404, APPLICATION_JSON, Response.Status.NOT_FOUND.getReasonPhrase());
} else if (ID_FOR_INTERNAL_SERVER_ERROR.equals(id)) {
serverResponse(ctx, 500, APPLICATION_JSON, INTERNAL_SERVER_ERROR.getReasonPhrase());
} else {
Fund fund = new Fund().withId(UUID.randomUUID().toString()).withLedgerId(UUID.randomUUID().toString()).withCode("TEST").withName("TEST");
List<CompositeFund> funds = getMockEntries(FUNDS, Fund.class).map(funds1 -> funds1.stream().map(fund1 -> new CompositeFund().withFund(fund1)).collect(toList())).orElse(Collections.singletonList(new CompositeFund().withFund(fund)));
addServerRqRsData(HttpMethod.GET, FUNDS, JsonObject.mapFrom(funds.get(0)));
serverResponse(ctx, 200, APPLICATION_JSON, JsonObject.mapFrom(funds.get(0)).encodePrettily());
}
}
use of org.folio.rest.acq.model.finance.Fund in project mod-invoice by folio-org.
the class BudgetExpenseClassTest method shouldThrowExceptionWithBudgetExpenseClassNotFoundCodeWhenCheckExpenseClassesWithoutExpenseClasses.
@Test
void shouldThrowExceptionWithBudgetExpenseClassNotFoundCodeWhenCheckExpenseClassesWithoutExpenseClasses() {
String notAssignedExpenseClassId = UUID.randomUUID().toString();
String activeExpenseClassId = UUID.randomUUID().toString();
FundDistribution fundDistributionWithActiveExpenseClass = new FundDistribution().withFundId(UUID.randomUUID().toString()).withExpenseClassId(activeExpenseClassId);
FundDistribution fundDistributionWithNotAssignedExpenseClass = new FundDistribution().withFundId(UUID.randomUUID().toString()).withExpenseClassId(notAssignedExpenseClassId);
FundDistribution fundDistributionWithoutExpenseClass = new FundDistribution().withFundId(UUID.randomUUID().toString());
InvoiceLine invoiceLine = new InvoiceLine().withFundDistributions(Arrays.asList(fundDistributionWithActiveExpenseClass, fundDistributionWithoutExpenseClass));
List<InvoiceLine> invoiceLines = Collections.singletonList(invoiceLine);
Adjustment adjustment = new Adjustment().withFundDistributions(Collections.singletonList(fundDistributionWithNotAssignedExpenseClass));
Invoice invoice = new Invoice().withAdjustments(Collections.singletonList(adjustment));
BudgetExpenseClass active = new BudgetExpenseClass().withBudgetId(UUID.randomUUID().toString()).withExpenseClassId(activeExpenseClassId).withStatus(BudgetExpenseClass.Status.ACTIVE).withId(UUID.randomUUID().toString());
Fund noExpenseClassFund = new Fund().withCode("no expense class fund");
ExpenseClass notAssignedExpenseClass = new ExpenseClass().withName("not assigned class");
List<InvoiceWorkflowDataHolder> holders = new ArrayList<>();
InvoiceWorkflowDataHolder holder1 = new InvoiceWorkflowDataHolder().withInvoice(invoice).withInvoiceLine(invoiceLine).withFundDistribution(fundDistributionWithActiveExpenseClass).withBudget(new Budget().withFundId(UUID.randomUUID().toString())).withExpenseClass(new ExpenseClass().withId(activeExpenseClassId));
InvoiceWorkflowDataHolder holder2 = new InvoiceWorkflowDataHolder().withInvoice(invoice).withInvoiceLine(invoiceLine).withBudget(new Budget().withFundId(UUID.randomUUID().toString())).withFundDistribution(fundDistributionWithoutExpenseClass);
InvoiceWorkflowDataHolder holder3 = new InvoiceWorkflowDataHolder().withInvoice(invoice).withAdjustment(adjustment).withFundDistribution(fundDistributionWithNotAssignedExpenseClass).withExpenseClass(notAssignedExpenseClass).withBudget(new Budget().withFundId(UUID.randomUUID().toString())).withFund(noExpenseClassFund);
holders.add(holder1);
holders.add(holder2);
holders.add(holder3);
when(restClient.get(any(RequestEntry.class), any(), any())).thenAnswer(invocation -> {
RequestEntry requestEntry = invocation.getArgument(0);
List<BudgetExpenseClass> budgetExpenseClasses = requestEntry.buildEndpoint().contains(notAssignedExpenseClassId) ? Collections.emptyList() : Collections.singletonList(active);
return CompletableFuture.completedFuture(new BudgetExpenseClassCollection().withBudgetExpenseClasses(budgetExpenseClasses).withTotalRecords(1));
});
when(requestContext.getContext()).thenReturn(Vertx.vertx().getOrCreateContext());
CompletableFuture<List<InvoiceWorkflowDataHolder>> future = budgetExpenseClassService.checkExpenseClasses(holders, requestContext);
ExecutionException executionException = assertThrows(ExecutionException.class, future::get);
assertThat(executionException.getCause(), instanceOf(HttpException.class));
HttpException exception = (HttpException) executionException.getCause();
assertEquals(400, exception.getCode());
Errors errors = exception.getErrors();
Error error = errors.getErrors().get(0);
assertEquals(BUDGET_EXPENSE_CLASS_NOT_FOUND.getCode(), error.getCode());
String expenseClassNameFromError = error.getParameters().stream().filter(parameter -> parameter.getKey().equals(EXPENSE_CLASS_NAME)).findFirst().get().getValue();
assertEquals(notAssignedExpenseClass.getName(), expenseClassNameFromError);
String fundCodeFromError = error.getParameters().stream().filter(parameter -> parameter.getKey().equals(FUND_CODE)).findFirst().get().getValue();
assertEquals(noExpenseClassFund.getCode(), fundCodeFromError);
}
use of org.folio.rest.acq.model.finance.Fund in project mod-invoice by folio-org.
the class CurrentFiscalYearServiceTest method shouldReturnErrorResponseIfFundDoesNotExist.
@Test
void shouldReturnErrorResponseIfFundDoesNotExist() {
// Given
String fundId = UUID.randomUUID().toString();
CompletableFuture<Fund> failedFuture = new CompletableFuture<>();
failedFuture.completeExceptionally(new HttpException(404, FUNDS_NOT_FOUND));
doReturn(failedFuture).when(fundService).getFundById(fundId, requestContextMock);
CompletableFuture<FiscalYear> resultFuture = currentFiscalYearService.getCurrentFiscalYearByFund(fundId, requestContextMock);
// When
ExecutionException e = assertThrows(ExecutionException.class, resultFuture::get);
// Then
assertThat(e.getCause(), instanceOf(HttpException.class));
HttpException httpException = (HttpException) e.getCause();
Assertions.assertEquals(404, httpException.getCode());
Error error = httpException.getErrors().getErrors().get(0);
Assertions.assertEquals(FUNDS_NOT_FOUND.toError().getMessage(), error.getMessage());
Assertions.assertEquals(FUNDS_NOT_FOUND.toError().getCode(), error.getCode());
}
use of org.folio.rest.acq.model.finance.Fund in project mod-orders by folio-org.
the class PurchaseOrderLinesApiTest method testShouldReleaseEncumbrancesAfterCancelledPoLine.
@Test
void testShouldReleaseEncumbrancesAfterCancelledPoLine() {
logger.info("=== Test release encumbrances after cancelled PoLine ===");
CompositePoLine lineFromStorage = getMockAsJson(COMP_PO_LINES_MOCK_DATA_PATH, "740809a1-84ca-45d7-a7a8-accc21efd5bd").mapTo(CompositePoLine.class);
CompositePoLine reqData = getMockAsJson(COMP_PO_LINES_MOCK_DATA_PATH, "740809a1-84ca-45d7-a7a8-accc21efd5bd").mapTo(CompositePoLine.class);
reqData.setReceiptStatus(ReceiptStatus.CANCELLED);
reqData.setPaymentStatus(PaymentStatus.CANCELLED);
Fund fund = new Fund().withId("7fbd5d84-62d1-44c6-9c45-6cb173998bbd").withName("Fund").withExternalAccountNo("externalNo").withLedgerId("133a7916-f05e-4df4-8f7f-09eb2a7076d1");
addMockEntry(PIECES_STORAGE, new Piece().withPoLineId(reqData.getId()).withLocationId(reqData.getLocations().get(0).getLocationId()));
addMockEntry(PO_LINES_STORAGE, lineFromStorage);
addMockEntry(FUNDS, fund);
verifyPut(String.format(LINE_BY_ID_PATH, reqData.getId()), JsonObject.mapFrom(reqData).encode(), prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, X_OKAPI_USER_ID), "", 204);
}
Aggregations