From f2f7875ef47579d1da0a66cb1f3b608e205ca223 Mon Sep 17 00:00:00 2001 From: Abdulkhakimov <89521577+Abdulkhakimov@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:10:45 +0500 Subject: [PATCH] [MODINVOICE-533] - Change restricted expenditures calculations (#473) --- .../FundAvailabilityHolderValidator.java | 55 ++----------------- .../FundAvailabilityHolderValidatorTest.java | 2 +- 2 files changed, 7 insertions(+), 50 deletions(-) diff --git a/src/main/java/org/folio/services/validator/FundAvailabilityHolderValidator.java b/src/main/java/org/folio/services/validator/FundAvailabilityHolderValidator.java index 0d8488e4c..22dde24f0 100644 --- a/src/main/java/org/folio/services/validator/FundAvailabilityHolderValidator.java +++ b/src/main/java/org/folio/services/validator/FundAvailabilityHolderValidator.java @@ -19,7 +19,6 @@ import org.folio.invoices.rest.exceptions.HttpException; import org.folio.models.InvoiceWorkflowDataHolder; -import org.folio.rest.acq.model.finance.AwaitingPayment; import org.folio.rest.acq.model.finance.Budget; import org.folio.rest.acq.model.finance.Fund; import org.folio.rest.jaxrs.model.Parameter; @@ -44,9 +43,8 @@ public void validate(List dataHolders) { .filter(entry -> Objects.nonNull(entry.getKey() .getAllowableExpenditure())) .filter(entry -> { - MonetaryAmount newExpendedAmount = calculateNewExpendedAmount(entry.getValue()); MonetaryAmount totalExpendedAmount = calculateTotalExpendedAmount(entry.getValue()); - return isRemainingAmountExceed(entry.getKey(), newExpendedAmount, totalExpendedAmount); + return isRemainingAmountExceed(entry.getKey(), totalExpendedAmount); }) .map(Map.Entry::getKey) .map(Budget::getFundId) @@ -79,59 +77,18 @@ private MonetaryAmount calculateTotalExpendedAmount(List Money.zero(currency)); } - private boolean isRemainingAmountExceed(Budget budget, MonetaryAmount newExpendedAmount, MonetaryAmount totalExpendedAmount) { - // [remaining amount we can expend] = (totalFunding * allowableExpenditure) - unavailable - // where unavailable = awaitingPayment + encumbered + expenditure - CurrencyUnit currency = newExpendedAmount.getCurrency(); + private boolean isRemainingAmountExceed(Budget budget, MonetaryAmount totalExpendedAmount) { + // [remaining amount we can expend] = (totalFunding * allowableExpenditure) - expended + // where expended = awaitingPayment + expenditure + CurrencyUnit currency = totalExpendedAmount.getCurrency(); Money totalFundings = Money.of(budget.getTotalFunding(), currency); Money expended = Money.of(budget.getAwaitingPayment(), currency) .add(Money.of(budget.getExpenditures(), currency)); BigDecimal allowableExpenditures = BigDecimal.valueOf(budget.getAllowableExpenditure()) .movePointLeft(2); - Money unavailable = Money.of(budget.getUnavailable(), currency); Money totalAmountCanBeExpended = totalFundings.multiply(allowableExpenditures); - Money amountCanBeExpended; - if (totalAmountCanBeExpended.subtract(unavailable).isNegative()) { - amountCanBeExpended = totalAmountCanBeExpended.subtract(newExpendedAmount); - } else { - amountCanBeExpended = totalAmountCanBeExpended.subtract(unavailable); - } Money afterApproveExpended = expended.add(totalExpendedAmount); - - return newExpendedAmount.isGreaterThan(amountCanBeExpended) || afterApproveExpended.isGreaterThan(totalAmountCanBeExpended); - } - - private MonetaryAmount calculateNewExpendedAmount(List dataHolders) { - CurrencyUnit currency = Monetary.getCurrency(dataHolders.get(0).getFyCurrency()); - return dataHolders.stream() - .map(holder -> { - MonetaryAmount newTransactionAmount = Money.of(holder.getNewTransaction().getAmount(), holder.getFyCurrency()); - - MonetaryAmount existingTransactionAmount = Optional.ofNullable(holder.getExistingTransaction()) - .map(transaction -> Money.of(transaction.getAmount(), transaction.getCurrency())) - .orElseGet(() -> Money.zero(Monetary.getCurrency(holder.getFyCurrency()))); - MonetaryAmount encumbranceAmount = Optional.ofNullable(holder.getEncumbrance()) - .map(transaction -> Money.of(transaction.getAmount(), transaction.getCurrency())) - .orElseGet(() -> Money.zero(Monetary.getCurrency(holder.getFyCurrency()))); - - MonetaryAmount transactionAmountDif = newTransactionAmount.subtract(existingTransactionAmount); - MonetaryAmount newExpendedAmount = transactionAmountDif; - boolean isReleaseEncumbrance = Optional.ofNullable(holder.getNewTransaction().getAwaitingPayment()) - .map(AwaitingPayment::getReleaseEncumbrance) - .orElse(false); - if (transactionAmountDif.isPositive()) { - newExpendedAmount = transactionAmountDif.subtract(encumbranceAmount); - if (newExpendedAmount.isNegative()) { - newExpendedAmount = isReleaseEncumbrance ? Money.of(0, transactionAmountDif.getCurrency()) : transactionAmountDif; - } - MonetaryAmount encumbranceReminder = MonetaryFunctions.max().apply(encumbranceAmount.subtract(newExpendedAmount).add(existingTransactionAmount), Money.zero(currency)); - Optional.ofNullable(holder.getEncumbrance()).ifPresent(transaction -> transaction.setAmount(encumbranceReminder.getNumber().doubleValue())); - } - - return newExpendedAmount; - }) - .reduce(MonetaryFunctions::sum) - .orElseGet(() -> Money.zero(currency)); + return afterApproveExpended.isGreaterThan(totalAmountCanBeExpended); } } diff --git a/src/test/java/org/folio/services/validator/FundAvailabilityHolderValidatorTest.java b/src/test/java/org/folio/services/validator/FundAvailabilityHolderValidatorTest.java index 40e04d8e6..236f88045 100644 --- a/src/test/java/org/folio/services/validator/FundAvailabilityHolderValidatorTest.java +++ b/src/test/java/org/folio/services/validator/FundAvailabilityHolderValidatorTest.java @@ -371,7 +371,7 @@ void shouldPassValidationWhenBudgetRestrictedAndFinalExpendedValueGreaterThenMax .withAmount(250d) .withCurrency("USD"); - Transaction linePendingPayment = new Transaction().withAmount(245d) + Transaction linePendingPayment = new Transaction().withAmount(247d) .withAwaitingPayment(new AwaitingPayment().withEncumbranceId(encumbrance.getId()).withReleaseEncumbrance(false)) .withCurrency("USD");