in service/src/main/java/org/apache/fineract/cn/individuallending/internal/command/handler/BeatPublishCommandHandler.java [149:225]
public IndividualLoanCommandEvent process(final CheckLateCommand command) {
final String productIdentifier = command.getProductIdentifier();
final String caseIdentifier = command.getCaseIdentifier();
final LocalDateTime forDateTime = DateConverter.fromIsoString(command.getForTime());
final LocalDate forDate = forDateTime.toLocalDate();
final DataContextOfAction dataContextOfAction = dataContextService.checkedGetDataContext(
productIdentifier, caseIdentifier, Collections.emptyList());
final RealRunningBalances balances = new RealRunningBalances(accountingAdapter, dataContextOfAction);
final BigDecimal currentBalance = balances.getAccountBalance(AccountDesignators.CUSTOMER_LOAN_PRINCIPAL).orElse(BigDecimal.ZERO);
if (currentBalance.compareTo(BigDecimal.ZERO) == 0) //No late fees if the current balance is zilch.
return new IndividualLoanCommandEvent(productIdentifier, caseIdentifier, command.getForTime());
final LocalDateTime dateOfMostRecentDisbursement = dateOfMostRecentDisburse(dataContextOfAction.getCustomerCaseEntity().getId())
.orElseThrow(() ->
ServiceException
.badRequest("No last disbursal date for ''{0}.{1}'' could be determined. " +
"Therefore it cannot be checked for lateness.", productIdentifier, caseIdentifier));
final List<Period> repaymentPeriods = ScheduledActionHelpers.generateRepaymentPeriods(
dateOfMostRecentDisbursement.toLocalDate(),
forDate,
dataContextOfAction.getCaseParameters())
.collect(Collectors.toList());
final long repaymentPeriodsBetweenBeginningAndToday = repaymentPeriods.size() - 1;
final BigDecimal expectedPaymentSum = dataContextOfAction
.getCaseParametersEntity()
.getPaymentSize()
.multiply(BigDecimal.valueOf(repaymentPeriodsBetweenBeginningAndToday));
final BigDecimal principalPaymentSum = balances.getSumOfChargesForActionSinceDate(
AccountDesignators.CUSTOMER_LOAN_PRINCIPAL,
Action.ACCEPT_PAYMENT,
dateOfMostRecentDisbursement);
final BigDecimal interestPaymentSum = balances.getSumOfChargesForActionSinceDate(
AccountDesignators.CUSTOMER_LOAN_INTEREST,
Action.ACCEPT_PAYMENT,
dateOfMostRecentDisbursement);
final BigDecimal feesPaymentSum = balances.getSumOfChargesForActionSinceDate(
AccountDesignators.CUSTOMER_LOAN_FEES,
Action.ACCEPT_PAYMENT,
dateOfMostRecentDisbursement);
final BigDecimal lateFeesSum = balances.getSumOfChargesForActionSinceDate(
AccountDesignators.LATE_FEE_INCOME,
Action.ACCEPT_PAYMENT,
dateOfMostRecentDisbursement);
final BigDecimal paymentsSum = principalPaymentSum.add(interestPaymentSum).add(feesPaymentSum.subtract(lateFeesSum));
if (paymentsSum.compareTo(expectedPaymentSum) < 0) {
final Optional<LocalDateTime> dateLateSince = dateLateSince(dataContextOfAction.getCustomerCaseEntity().getId());
if (!dateLateSince.isPresent()) {
commandBus.dispatch(new MarkLateCommand(productIdentifier, caseIdentifier, command.getForTime()));
}
if (dateLateSince.isPresent()) {
int daysLate;
try {
daysLate = Math.toIntExact(dateLateSince.get().until(forDateTime, ChronoUnit.DAYS)) + 1;
}
catch (ArithmeticException e) {
daysLate = -1;
}
if (daysLate > 1) {
final Optional<LossProvisionStepEntity> lossStepEntity = lossProvisionStepRepository.findByProductIdAndDaysLate(dataContextOfAction.getProductEntity().getId(), daysLate);
if (lossStepEntity.isPresent()) {
commandBus.dispatch(new MarkInArrearsCommand(productIdentifier, caseIdentifier, command.getForTime(), daysLate));
}
}
}
}
return new IndividualLoanCommandEvent(productIdentifier, caseIdentifier, command.getForTime());
}