Skip to content

Commit

Permalink
[MODINVOICE-533] - Change restricted expenditures calculations (#473)
Browse files Browse the repository at this point in the history
  • Loading branch information
Abdulkhakimov authored Mar 7, 2024
1 parent 4d20573 commit f2f7875
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -44,9 +43,8 @@ public void validate(List<InvoiceWorkflowDataHolder> 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)
Expand Down Expand Up @@ -79,59 +77,18 @@ private MonetaryAmount calculateTotalExpendedAmount(List<InvoiceWorkflowDataHold
.orElseGet(() -> 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<InvoiceWorkflowDataHolder> 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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down

0 comments on commit f2f7875

Please sign in to comment.