use of org.folio.models.InvoiceWorkflowDataHolder in project mod-invoice by folio-org.
the class FundAvailabilityHolderValidatorTest method shouldCountAdjustmentsFundDistributionsDuringBudgetRemainingAmountValidation.
@Test
void shouldCountAdjustmentsFundDistributionsDuringBudgetRemainingAmountValidation() {
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(210d).withUnavailable(50d).withAwaitingPayment(50d).withAllowableExpenditure(100d);
List<InvoiceWorkflowDataHolder> holders = new ArrayList<>();
Transaction adjustmentPendingPayment = new Transaction().withAmount(20d).withCurrency("USD");
Transaction linePendingPayment = new Transaction().withAmount(200d).withCurrency("USD");
InvoiceWorkflowDataHolder holder1 = new InvoiceWorkflowDataHolder().withFund(fund).withBudget(budget).withRestrictExpenditures(true).withFiscalYear(fiscalYear).withNewTransaction(linePendingPayment);
InvoiceWorkflowDataHolder holder2 = new InvoiceWorkflowDataHolder().withFund(fund).withBudget(budget).withRestrictExpenditures(true).withFiscalYear(fiscalYear).withNewTransaction(adjustmentPendingPayment);
holders.add(holder1);
holders.add(holder2);
HttpException httpException = assertThrows(HttpException.class, () -> fundAvailabilityValidator.validate(holders));
assertEquals(422, httpException.getCode());
Error error = httpException.getErrors().getErrors().get(0);
assertEquals(FUND_CANNOT_BE_PAID.getCode(), error.getCode());
assertEquals(Collections.singletonList("FC").toString(), error.getParameters().get(0).getValue());
}
use of org.folio.models.InvoiceWorkflowDataHolder in project mod-invoice by folio-org.
the class FundsDistributionService method distributeFunds.
public static <T extends InvoiceWorkflowDataHolder> List<T> distributeFunds(List<T> holders) {
Map<InvoiceLine, List<InvoiceWorkflowDataHolder>> lineHoldersMap = holders.stream().filter(holder -> Objects.nonNull(holder.getInvoiceLine())).collect(Collectors.groupingBy(InvoiceWorkflowDataHolder::getInvoiceLine));
lineHoldersMap.forEach((invoiceLine, invoiceWorkflowDataHolder) -> {
CurrencyUnit invoiceCurrency = Monetary.getCurrency(holders.get(0).getInvoiceCurrency());
CurrencyConversion conversion = invoiceWorkflowDataHolder.stream().map(InvoiceWorkflowDataHolder::getConversion).findFirst().get();
MonetaryAmount expectedTotal = Money.of(invoiceLine.getTotal(), invoiceCurrency).with(conversion).with(getDefaultRounding());
MonetaryAmount calculatedTotal = invoiceWorkflowDataHolder.stream().map(h -> h.getNewTransaction().getAmount()).map(aDouble -> Money.of(aDouble, conversion.getCurrency())).reduce(Money::add).orElse(Money.zero(conversion.getCurrency()));
int calculatedTotalSignum = calculatedTotal.signum();
final MonetaryAmount remainder = expectedTotal.abs().subtract(calculatedTotal.abs());
Optional<Transaction> resultTransaction = Optional.of(invoiceWorkflowDataHolder).map(holder -> {
if (remainder.isNegative()) {
return holder.get(0);
} else if (remainder.isPositiveOrZero()) {
return holder.get(holder.size() - 1);
}
return null;
}).map(InvoiceWorkflowDataHolder::getNewTransaction);
resultTransaction.ifPresent(tr -> {
MonetaryAmount resultReminder = tr.getTransactionType().equals(TransactionType.CREDIT) ? remainder : remainder.multiply(calculatedTotalSignum);
tr.setAmount(Money.of(tr.getAmount(), conversion.getCurrency()).add(resultReminder).getNumber().doubleValue());
});
});
return holders;
}
Aggregations