public IndividualLoanCommandEvent process()

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());
  }