in service/src/main/java/org/apache/fineract/cn/deposit/service/internal/command/handler/InterestCalculator.java [243:336]
public String process(final DividendDistributionCommand dividendDistributionCommand) {
final Optional<ProductDefinitionEntity> optionalProductDefinition =
this.productDefinitionRepository.findByIdentifier(dividendDistributionCommand.productDefinition());
if (optionalProductDefinition.isPresent()) {
final ProductDefinitionEntity productDefinitionEntity = optionalProductDefinition.get();
if (productDefinitionEntity.getActive()) {
final BigDecimal rate = BigDecimal.valueOf(dividendDistributionCommand.rate());
final TermEntity term = this.termRepository.findByProductDefinition(productDefinitionEntity);
final List<String> dateRanges = this.dateRanges(dividendDistributionCommand.dueDate(), term.getInterestPayable());
final List<ProductInstanceEntity> productInstanceEntities =
this.productInstanceRepository.findByProductDefinition(productDefinitionEntity);
productInstanceEntities.forEach((ProductInstanceEntity productInstanceEntity) -> {
if (productInstanceEntity.getState().equals(ACTIVE)) {
final Account account =
this.accountingService.findAccount(productInstanceEntity.getAccountIdentifier());
final LocalDate startDate = dividendDistributionCommand.dueDate().plusDays(1);
final LocalDate now = LocalDate.now(Clock.systemUTC());
final String findCurrentEntries = DateConverter.toIsoString(startDate) + ".." + DateConverter.toIsoString(now);
final List<AccountEntry> currentAccountEntries =
this.accountingService.fetchEntries(account.getIdentifier(), findCurrentEntries, Sort.Direction.ASC.name());
final BalanceHolder balanceHolder;
if (currentAccountEntries.isEmpty()) {
balanceHolder = new BalanceHolder(BigDecimal.valueOf(account.getBalance()));
} else {
final AccountEntry accountEntry = currentAccountEntries.get(0);
balanceHolder = new BalanceHolder(BigDecimal.valueOf(accountEntry.getBalance()).subtract(BigDecimal.valueOf(accountEntry.getAmount())));
}
final DividendHolder dividendHolder = new DividendHolder();
dateRanges.forEach(dateRange -> {
final List<AccountEntry> accountEntries =
this.accountingService.fetchEntries(account.getIdentifier(), dateRange, Sort.Direction.DESC.name());
if (!accountEntries.isEmpty()) {
balanceHolder.setBalance(BigDecimal.valueOf(accountEntries.get(0).getBalance()));
}
final BigDecimal currentBalance = balanceHolder.getBalance();
dividendHolder.addAmount(
accruedInterest(currentBalance, rate, 12, dividendDistributionCommand.dueDate().lengthOfYear())
);
});
if (dividendHolder.getAmount().compareTo(BigDecimal.ZERO) > 0) {
final String roundedAmount =
dividendHolder.getAmount()
.setScale(2, BigDecimal.ROUND_HALF_EVEN).toString();
final JournalEntry cashToExpenseJournalEntry = new JournalEntry();
cashToExpenseJournalEntry.setTransactionIdentifier(RandomStringUtils.randomAlphanumeric(32));
cashToExpenseJournalEntry.setTransactionDate(DateConverter.toIsoString(now));
cashToExpenseJournalEntry.setTransactionType("INTR");
cashToExpenseJournalEntry.setClerk(UserContextHolder.checkedGetUser());
cashToExpenseJournalEntry.setNote("Dividend distribution.");
final Debtor cashDebtor = new Debtor();
cashDebtor.setAccountNumber(productDefinitionEntity.getCashAccountIdentifier());
cashDebtor.setAmount(roundedAmount);
cashToExpenseJournalEntry.setDebtors(Sets.newHashSet(cashDebtor));
final Creditor expenseCreditor = new Creditor();
expenseCreditor.setAccountNumber(productDefinitionEntity.getExpenseAccountIdentifier());
expenseCreditor.setAmount(roundedAmount);
cashToExpenseJournalEntry.setCreditors(Sets.newHashSet(expenseCreditor));
this.accountingService.post(cashToExpenseJournalEntry);
this.payoutInterest(
productDefinitionEntity.getExpenseAccountIdentifier(),
account.getIdentifier(),
roundedAmount
);
}
}
});
}
final DividendDistributionEntity dividendDistributionEntity = new DividendDistributionEntity();
dividendDistributionEntity.setProductDefinition(productDefinitionEntity);
dividendDistributionEntity.setDueDate(Date.valueOf(dividendDistributionCommand.dueDate()));
dividendDistributionEntity.setRate(dividendDistributionCommand.rate());
dividendDistributionEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
dividendDistributionEntity.setCreatedBy(UserContextHolder.checkedGetUser());
this.dividendDistributionRepository.save(dividendDistributionEntity);
}
return dividendDistributionCommand.productDefinition();
}