Search in sources :

Example 21 with Transaction

use of org.folio.rest.acq.model.finance.Transaction in project mod-orders by folio-org.

the class EncumbranceService method createEncumbrances.

public CompletableFuture<Void> createEncumbrances(List<EncumbranceRelationsHolder> relationsHolders, RequestContext requestContext) {
    List<CompletableFuture<Void>> futureList = new ArrayList<>();
    CompletableFuture<Void> future = completedFuture(null);
    for (EncumbranceRelationsHolder holder : relationsHolders) {
        future = future.thenCompose(v -> transactionService.createTransaction(holder.getNewEncumbrance(), requestContext).thenAccept(transaction -> holder.getFundDistribution().setEncumbrance(transaction.getId())).exceptionally(fail -> {
            checkCustomTransactionError(fail);
            throw new CompletionException(fail);
        }));
        futureList.add(future);
    }
    return FolioVertxCompletableFuture.allOf(requestContext.getContext(), futureList.toArray(new CompletableFuture[0]));
}
Also used : OrderInvoiceRelationService(org.folio.service.orders.OrderInvoiceRelationService) FUND_CANNOT_BE_PAID(org.folio.rest.core.exceptions.ErrorCodes.FUND_CANNOT_BE_PAID) InvoiceLineService(org.folio.service.invoice.InvoiceLineService) CompletableFuture.completedFuture(java.util.concurrent.CompletableFuture.completedFuture) HttpException(org.folio.rest.core.exceptions.HttpException) FolioVertxCompletableFuture(org.folio.completablefuture.FolioVertxCompletableFuture) CompletableFuture(java.util.concurrent.CompletableFuture) HelperUtils.collectResultsOnSuccess(org.folio.orders.utils.HelperUtils.collectResultsOnSuccess) PoLine(org.folio.rest.jaxrs.model.PoLine) Transaction(org.folio.rest.acq.model.finance.Transaction) TransactionCollection(org.folio.rest.acq.model.finance.TransactionCollection) CollectionUtils(org.apache.commons.collections4.CollectionUtils) Objects.requireNonNullElse(java.util.Objects.requireNonNullElse) ArrayList(java.util.ArrayList) EncumbrancesProcessingHolder(org.folio.models.EncumbrancesProcessingHolder) CompositePurchaseOrder(org.folio.rest.jaxrs.model.CompositePurchaseOrder) RequestContext(org.folio.rest.core.models.RequestContext) Map(java.util.Map) Encumbrance(org.folio.rest.acq.model.finance.Encumbrance) LEDGER_NOT_FOUND_FOR_TRANSACTION(org.folio.rest.core.exceptions.ErrorCodes.LEDGER_NOT_FOUND_FOR_TRANSACTION) Collection(java.util.Collection) EncumbranceRelationsHolder(org.folio.models.EncumbranceRelationsHolder) ErrorCodes(org.folio.rest.core.exceptions.ErrorCodes) CompletionException(java.util.concurrent.CompletionException) FiscalYearService(org.folio.service.finance.FiscalYearService) FundDistribution(org.folio.rest.jaxrs.model.FundDistribution) BUDGET_NOT_FOUND_FOR_TRANSACTION(org.folio.rest.core.exceptions.ErrorCodes.BUDGET_NOT_FOUND_FOR_TRANSACTION) MonetaryOperators(org.javamoney.moneta.function.MonetaryOperators) Objects(java.util.Objects) Error(org.folio.rest.jaxrs.model.Error) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) Logger(org.apache.logging.log4j.Logger) CompletionStage(java.util.concurrent.CompletionStage) ERROR_REMOVING_INVOICE_LINE_ENCUMBRANCES(org.folio.rest.core.exceptions.ErrorCodes.ERROR_REMOVING_INVOICE_LINE_ENCUMBRANCES) CompositePoLine(org.folio.rest.jaxrs.model.CompositePoLine) Tags(org.folio.rest.acq.model.finance.Tags) HelperUtils.calculateEstimatedPrice(org.folio.orders.utils.HelperUtils.calculateEstimatedPrice) HttpStatus(org.folio.HttpStatus) Parameter(org.folio.rest.jaxrs.model.Parameter) BUDGET_IS_INACTIVE(org.folio.rest.core.exceptions.ErrorCodes.BUDGET_IS_INACTIVE) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) MonetaryAmount(javax.money.MonetaryAmount) FolioVertxCompletableFuture(org.folio.completablefuture.FolioVertxCompletableFuture) CompletableFuture(java.util.concurrent.CompletableFuture) CompletionException(java.util.concurrent.CompletionException) ArrayList(java.util.ArrayList) EncumbranceRelationsHolder(org.folio.models.EncumbranceRelationsHolder)

Example 22 with Transaction

use of org.folio.rest.acq.model.finance.Transaction in project mod-orders by folio-org.

the class ReEncumbranceHoldersBuilder method buildToFyEncumbrance.

private void buildToFyEncumbrance(ReEncumbranceHolder holder) {
    Optional.ofNullable(holder.getEncumbranceRollover()).ifPresent(encumbranceRollover -> {
        Transaction fromEncumbrance = holder.getPreviousFyEncumbrance();
        Transaction toEncumbrance = JsonObject.mapFrom(fromEncumbrance).mapTo(Transaction.class).withFiscalYearId(holder.getRollover().getToFiscalYearId()).withId(null);
        toEncumbrance.getEncumbrance().withStatus(Encumbrance.Status.UNRELEASED).withAmountAwaitingPayment(0d).withAmountExpended(0d);
        holder.withNewEncumbrance(toEncumbrance);
    });
}
Also used : Transaction(org.folio.rest.acq.model.finance.Transaction)

Example 23 with Transaction

use of org.folio.rest.acq.model.finance.Transaction in project mod-orders by folio-org.

the class FundsDistributionService method distributeFunds.

public <T extends EncumbranceRelationsHolder> List<T> distributeFunds(List<T> holders) {
    Map<CompositePoLine, List<EncumbranceRelationsHolder>> lineHoldersMap = holders.stream().filter(holder -> Objects.nonNull(holder.getPoLine())).collect(Collectors.groupingBy(EncumbranceRelationsHolder::getPoLine));
    lineHoldersMap.forEach((poLine, encumbranceRelationsHolders) -> {
        poLine.getCost().setPoLineEstimatedPrice(HelperUtils.calculateEstimatedPrice(poLine.getCost()).getNumber().doubleValue());
        CurrencyUnit poLineCurrency = Monetary.getCurrency(poLine.getCost().getCurrency());
        CurrencyConversion conversion = encumbranceRelationsHolders.stream().map(EncumbranceRelationsHolder::getPoLineToFyConversion).findFirst().get();
        MonetaryAmount expectedTotal = Money.of(poLine.getCost().getPoLineEstimatedPrice(), poLineCurrency).with(conversion).with(getDefaultRounding());
        MonetaryAmount calculatedTotal = encumbranceRelationsHolders.stream().map(EncumbranceRelationsHolder::getFundDistribution).map(fundDistribution -> getDistributionAmount(fundDistribution, expectedTotal, poLineCurrency, conversion)).reduce((money, money2) -> Money.from(MonetaryFunctions.sum(money, money2))).orElseGet(() -> Money.zero(poLineCurrency));
        MonetaryAmount remainder = expectedTotal.abs().subtract(calculatedTotal.abs());
        int remainderSignum = remainder.signum();
        MonetaryAmount smallestUnit = getSmallestUnit(expectedTotal, remainderSignum);
        for (ListIterator<EncumbranceRelationsHolder> iterator = getIterator(encumbranceRelationsHolders, remainderSignum); isIteratorHasNext(iterator, remainderSignum); ) {
            final EncumbranceRelationsHolder holder = iteratorNext(iterator, remainderSignum);
            CurrencyUnit fyCurrency = Monetary.getCurrency(holder.getCurrency());
            MonetaryAmount initialAmount = getDistributionAmount(holder.getFundDistribution(), expectedTotal, poLineCurrency, conversion);
            if (FundDistribution.DistributionType.PERCENTAGE.equals(holder.getFundDistribution().getDistributionType()) && !remainder.isZero()) {
                initialAmount = initialAmount.add(smallestUnit);
                remainder = remainder.abs().subtract(smallestUnit.abs()).multiply(remainderSignum);
            }
            MonetaryAmount expended = Optional.of(holder).map(EncumbranceRelationsHolder::getNewEncumbrance).map(Transaction::getEncumbrance).map(Encumbrance::getAmountExpended).map(aDouble -> Money.of(aDouble, fyCurrency)).orElse(Money.zero(fyCurrency));
            MonetaryAmount awaitingPayment = Optional.of(holder).map(EncumbranceRelationsHolder::getNewEncumbrance).map(Transaction::getEncumbrance).map(Encumbrance::getAmountAwaitingPayment).map(aDouble -> Money.of(aDouble, fyCurrency)).orElse(Money.zero(fyCurrency));
            MonetaryAmount amount = MonetaryFunctions.max().apply(initialAmount.subtract(expended).subtract(awaitingPayment), Money.zero(fyCurrency));
            holder.getNewEncumbrance().setAmount(amount.getNumber().doubleValue());
            holder.getNewEncumbrance().getEncumbrance().setInitialAmountEncumbered(initialAmount.getNumber().doubleValue());
        }
    });
    return holders;
}
Also used : Monetary(javax.money.Monetary) CurrencyConversion(javax.money.convert.CurrencyConversion) ListIterator(java.util.ListIterator) CurrencyUnit(javax.money.CurrencyUnit) HelperUtils(org.folio.orders.utils.HelperUtils) Money(org.javamoney.moneta.Money) MonetaryFunctions(org.javamoney.moneta.function.MonetaryFunctions) EncumbranceRelationsHolder(org.folio.models.EncumbranceRelationsHolder) Transaction(org.folio.rest.acq.model.finance.Transaction) FundDistribution(org.folio.rest.jaxrs.model.FundDistribution) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) MonetaryOperators(org.javamoney.moneta.function.MonetaryOperators) List(java.util.List) CompositePoLine(org.folio.rest.jaxrs.model.CompositePoLine) Map(java.util.Map) Encumbrance(org.folio.rest.acq.model.finance.Encumbrance) Monetary.getDefaultRounding(javax.money.Monetary.getDefaultRounding) Optional(java.util.Optional) MonetaryAmount(javax.money.MonetaryAmount) CurrencyUnit(javax.money.CurrencyUnit) MonetaryAmount(javax.money.MonetaryAmount) EncumbranceRelationsHolder(org.folio.models.EncumbranceRelationsHolder) Encumbrance(org.folio.rest.acq.model.finance.Encumbrance) CompositePoLine(org.folio.rest.jaxrs.model.CompositePoLine) CurrencyConversion(javax.money.convert.CurrencyConversion) List(java.util.List)

Example 24 with Transaction

use of org.folio.rest.acq.model.finance.Transaction in project mod-orders by folio-org.

the class MockServer method handleTransactionGetEntry.

private void handleTransactionGetEntry(RoutingContext ctx) {
    try {
        String query = ctx.request().params().get("query");
        String body;
        if (query.equals("id==(1e42ac94-8fba-4245-aa99-35af60108588)")) {
            body = getMockData(ENCUMBRANCE_FOR_TAGS_PATH);
        } else if (query.equals("id==(eb506834-6c70-4239-8d1a-6414a5b08015 or eb506834-6c70-4239-8d1a-6414a5b08ac3 or 0466cb77-0344-43c6-85eb-0a64aa2934e5)")) {
            body = getMockData(LISTED_PRINT_MONOGRAPH_ENCUMBRANCES_PATH);
        } else if (query.contains("encumbrance.sourcePoLineId == 50fb5514-cdf1-11e8-a8d5-f2801f1b9fd1")) {
            // for testReopenOrderUnreleasesEncumbrancesUnlessInvoiceLineHasReleaseEncumbrance
            Transaction transaction1 = new Transaction().withId(UUID.randomUUID().toString()).withFromFundId("fb7b70f1-b898-4924-a991-0e4b6312bb5f").withEncumbrance(new Encumbrance().withSourcePurchaseOrderId("477f9ca8-b295-11eb-8529-0242ac130003").withSourcePoLineId("50fb5514-cdf1-11e8-a8d5-f2801f1b9fd1").withStatus(Encumbrance.Status.RELEASED));
            List<Transaction> transactions = List.of(transaction1);
            TransactionCollection transactionCollection = new TransactionCollection().withTransactions(transactions).withTotalRecords(1);
            body = JsonObject.mapFrom(transactionCollection).encodePrettily();
        } else {
            body = getMockData(ENCUMBRANCE_PATH);
        }
        serverResponse(ctx, HttpStatus.HTTP_OK.toInt(), APPLICATION_JSON, body);
        addServerRqRsData(HttpMethod.GET, TRANSACTIONS_ENDPOINT, new JsonObject(body));
    } catch (IOException e) {
        logger.error("handleTransactionGetEntry error", e);
    }
}
Also used : TransactionCollection(org.folio.rest.acq.model.finance.TransactionCollection) Transaction(org.folio.rest.acq.model.finance.Transaction) Encumbrance(org.folio.rest.acq.model.finance.Encumbrance) JsonObject(io.vertx.core.json.JsonObject) IOException(java.io.IOException)

Example 25 with Transaction

use of org.folio.rest.acq.model.finance.Transaction in project mod-orders by folio-org.

the class PurchaseOrderLinesApiTest method testPutOrderLineWithNoTags.

@Test
void testPutOrderLineWithNoTags() {
    logger.info("=== Test PUT Order Line With No Tags ===");
    String lineId = "bb66b269-76ed-4616-8da9-730d9b817247";
    CompositePoLine body = getMockAsJson(COMP_PO_LINES_MOCK_DATA_PATH, lineId).mapTo(CompositePoLine.class);
    body.setCheckinItems(false);
    body.setIsPackage(false);
    body.setReceiptStatus(ReceiptStatus.AWAITING_RECEIPT);
    body.setReportingCodes(new ArrayList<>());
    MockServer.addMockEntry(PO_LINES_STORAGE, body);
    MockServer.addMockEntry(PURCHASE_ORDER_STORAGE, new CompositePurchaseOrder().withId(ID_FOR_PRINT_MONOGRAPH_ORDER).withWorkflowStatus(CompositePurchaseOrder.WorkflowStatus.OPEN).withOrderType(CompositePurchaseOrder.OrderType.ONE_TIME));
    String url = String.format(LINE_BY_ID_PATH, lineId);
    addMockEntry(TITLES, new Title().withId(UUID.randomUUID().toString()).withPoLineId(body.getId()).withTitle("Title"));
    // edit POLine for new encumbrance
    body.setTags(null);
    body.setFundDistribution(Collections.singletonList(new FundDistribution().withCode("EUROHIST").withFundId("e9285a1c-1dfc-4380-868c-e74073003f43").withDistributionType(FundDistribution.DistributionType.PERCENTAGE).withValue(100D)));
    verifyPut(url, JsonObject.mapFrom(body), "", 204);
    Transaction createdEncumbrance = MockServer.getCreatedEncumbrances().get(0);
    assertNull(createdEncumbrance.getTags());
    // edit POLine for encumbrance update
    body.setTags(null);
    body.setCost(new Cost().withCurrency("USD").withListUnitPrice(70.0).withQuantityPhysical(1));
    body.setFundDistribution(Collections.singletonList(new FundDistribution().withCode("EUROHIST").withFundId("a89eccf0-57a6-495e-898d-32b9b2210f2f").withDistributionType(FundDistribution.DistributionType.PERCENTAGE).withValue(100D)));
    verifyPut(url, JsonObject.mapFrom(body), "", 204);
    Transaction updatedEncumbrance = MockServer.getUpdatedTransactions().get(0);
    assertNull(updatedEncumbrance.getTags());
}
Also used : FundDistribution(org.folio.rest.jaxrs.model.FundDistribution) Transaction(org.folio.rest.acq.model.finance.Transaction) CompositePoLine(org.folio.rest.jaxrs.model.CompositePoLine) TestUtils.getMinimalContentCompositePoLine(org.folio.TestUtils.getMinimalContentCompositePoLine) Title(org.folio.rest.acq.model.Title) Matchers.containsString(org.hamcrest.Matchers.containsString) CompositePurchaseOrder(org.folio.rest.jaxrs.model.CompositePurchaseOrder) Cost(org.folio.rest.jaxrs.model.Cost) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Test(org.junit.jupiter.api.Test)

Aggregations

Transaction (org.folio.rest.acq.model.finance.Transaction)79 Test (org.junit.jupiter.api.Test)60 FundDistribution (org.folio.rest.jaxrs.model.FundDistribution)31 ArrayList (java.util.ArrayList)29 Encumbrance (org.folio.rest.acq.model.finance.Encumbrance)29 TransactionCollection (org.folio.rest.acq.model.finance.TransactionCollection)25 CompositePoLine (org.folio.rest.jaxrs.model.CompositePoLine)24 List (java.util.List)21 CompositePurchaseOrder (org.folio.rest.jaxrs.model.CompositePurchaseOrder)19 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)19 EncumbranceRelationsHolder (org.folio.models.EncumbranceRelationsHolder)16 RequestContext (org.folio.rest.core.models.RequestContext)16 Budget (org.folio.rest.acq.model.finance.Budget)15 Fund (org.folio.rest.acq.model.finance.Fund)15 RequestEntry (org.folio.rest.core.models.RequestEntry)15 MonetaryAmount (javax.money.MonetaryAmount)14 Cost (org.folio.rest.jaxrs.model.Cost)14 JsonObject (io.vertx.core.json.JsonObject)12 Collectors.toList (java.util.stream.Collectors.toList)12 Error (org.folio.rest.jaxrs.model.Error)11