FINERACT-2321: Adding arrears days to loan/at-date api

This commit is contained in:
soticsenge
2025-07-10 16:24:32 +02:00
committed by GitHub
parent 5a0115e6ec
commit 93bfc6fb66
7 changed files with 189 additions and 5 deletions
@@ -0,0 +1,37 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.portfolio.loanaccount.domain.arrears;
import java.math.BigDecimal;
import java.time.LocalDate;
import lombok.Data;
@Data
public class LoanArrearsData {
private BigDecimal principalOverdue;
private BigDecimal interestOverdue;
private BigDecimal feeOverdue;
private BigDecimal penaltyOverdue;
private BigDecimal totalOverdue;
private LocalDate overDueSince;
private boolean isOverdue;
}
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.service;
import java.util.List;
import java.util.Map;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.arrears.LoanArrearsData;
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
public interface LoanArrearsAgingService {
@@ -35,4 +36,6 @@ public interface LoanArrearsAgingService {
boolean isInsertStatement);
void updateScheduleWithPaidDetail(Map<Long, List<LoanSchedulePeriodData>> scheduleDate, List<Map<String, Object>> loanSummary);
LoanArrearsData calculateArrearsForLoan(Loan loan);
}
@@ -55,6 +55,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanSummary;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
import org.apache.fineract.portfolio.loanaccount.domain.arrears.LoanArrearsData;
import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -138,8 +139,8 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
}
}
private String constructUpdateStatement(final Loan loan, boolean isInsertStatement) {
String updateSql = null;
@Override
public LoanArrearsData calculateArrearsForLoan(Loan loan) {
List<LoanRepaymentScheduleInstallment> installments = loan.getRepaymentScheduleInstallments();
BigDecimal principalOverdue = BigDecimal.ZERO;
BigDecimal interestOverdue = BigDecimal.ZERO;
@@ -158,9 +159,33 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
}
}
}
BigDecimal totalOverDue = principalOverdue.add(interestOverdue).add(feeOverdue).add(penaltyOverdue);
if (totalOverDue.compareTo(BigDecimal.ZERO) > 0) {
boolean isOverdue = totalOverDue.compareTo(BigDecimal.ZERO) > 0;
if (!isOverdue) {
overDueSince = null;
}
LoanArrearsData result = new LoanArrearsData();
result.setPrincipalOverdue(principalOverdue);
result.setInterestOverdue(interestOverdue);
result.setFeeOverdue(feeOverdue);
result.setPenaltyOverdue(penaltyOverdue);
result.setTotalOverdue(totalOverDue);
result.setOverDueSince(overDueSince);
result.setOverdue(isOverdue);
return result;
}
private String constructUpdateStatement(final Loan loan, boolean isInsertStatement) {
String updateSql = null;
LoanArrearsData arrearsData = calculateArrearsForLoan(loan);
BigDecimal principalOverdue = arrearsData.getPrincipalOverdue();
BigDecimal interestOverdue = arrearsData.getInterestOverdue();
BigDecimal feeOverdue = arrearsData.getFeeOverdue();
BigDecimal penaltyOverdue = arrearsData.getPenaltyOverdue();
LocalDate overDueSince = arrearsData.getOverDueSince();
if (arrearsData.isOverdue()) {
if (isInsertStatement) {
updateSql = constructInsertStatement(loan.getId(), principalOverdue, interestOverdue, feeOverdue, penaltyOverdue,
overDueSince);
@@ -201,6 +226,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
BigDecimal penaltyOverdue = BigDecimal.ZERO;
LocalDate overDueSince = DateUtils.getBusinessLocalDate();
// TODO: this needs to be refactored to use the calculateArrearsForLoan method.
for (LoanSchedulePeriodData loanSchedulePeriodData : entry.getValue()) {
if (!loanSchedulePeriodData.getComplete()) {
principalOverdue = principalOverdue