MIFOSX-1487 : changed logic to fetch accrued till
This commit is contained in:
+9
-1
@@ -34,13 +34,15 @@ public class LoanScheduleAccrualData {
|
|||||||
private final CurrencyData currencyData;
|
private final CurrencyData currencyData;
|
||||||
private final BigDecimal dueDateFeeIncome;
|
private final BigDecimal dueDateFeeIncome;
|
||||||
private final BigDecimal dueDatePenaltyIncome;
|
private final BigDecimal dueDatePenaltyIncome;
|
||||||
|
private final LocalDate interestCalculatedFrom;
|
||||||
|
|
||||||
public LoanScheduleAccrualData(final Long loanId, final Long officeId, final LocalDate accruedTill, final Integer numberOfDaysInMonth,
|
public LoanScheduleAccrualData(final Long loanId, final Long officeId, final LocalDate accruedTill, final Integer numberOfDaysInMonth,
|
||||||
final Integer numberOfDaysInYear, final PeriodFrequencyType repaymentFrequency, final Integer repayEvery,
|
final Integer numberOfDaysInYear, final PeriodFrequencyType repaymentFrequency, final Integer repayEvery,
|
||||||
final LocalDate dueDate, final LocalDate fromDate, final Long repaymentScheduleId, final Long loanProductId,
|
final LocalDate dueDate, final LocalDate fromDate, final Long repaymentScheduleId, final Long loanProductId,
|
||||||
final BigDecimal interestIncome, final BigDecimal feeIncome, final BigDecimal penaltyIncome,
|
final BigDecimal interestIncome, final BigDecimal feeIncome, final BigDecimal penaltyIncome,
|
||||||
final BigDecimal accruedInterestIncome, final BigDecimal accruedFeeIncome, final BigDecimal accruedPenaltyIncome,
|
final BigDecimal accruedInterestIncome, final BigDecimal accruedFeeIncome, final BigDecimal accruedPenaltyIncome,
|
||||||
final CurrencyData currencyData, final BigDecimal dueDateFeeIncome, final BigDecimal dueDatePenaltyIncome) {
|
final CurrencyData currencyData, final BigDecimal dueDateFeeIncome, final BigDecimal dueDatePenaltyIncome,
|
||||||
|
final LocalDate interestCalculatedFrom) {
|
||||||
this.loanId = loanId;
|
this.loanId = loanId;
|
||||||
this.officeId = officeId;
|
this.officeId = officeId;
|
||||||
this.accruedTill = accruedTill;
|
this.accruedTill = accruedTill;
|
||||||
@@ -61,6 +63,7 @@ public class LoanScheduleAccrualData {
|
|||||||
this.repayEvery = repayEvery;
|
this.repayEvery = repayEvery;
|
||||||
this.dueDateFeeIncome = dueDateFeeIncome;
|
this.dueDateFeeIncome = dueDateFeeIncome;
|
||||||
this.dueDatePenaltyIncome = dueDatePenaltyIncome;
|
this.dueDatePenaltyIncome = dueDatePenaltyIncome;
|
||||||
|
this.interestCalculatedFrom = interestCalculatedFrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getLoanId() {
|
public Long getLoanId() {
|
||||||
@@ -147,4 +150,9 @@ public class LoanScheduleAccrualData {
|
|||||||
return this.dueDatePenaltyIncome;
|
return this.dueDatePenaltyIncome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public LocalDate getInterestCalculatedFrom() {
|
||||||
|
return this.interestCalculatedFrom;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -314,6 +314,10 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
@Column(name = "is_npa", nullable = false)
|
@Column(name = "is_npa", nullable = false)
|
||||||
private boolean isNpa;
|
private boolean isNpa;
|
||||||
|
|
||||||
|
@Temporal(TemporalType.DATE)
|
||||||
|
@Column(name = "accrued_till")
|
||||||
|
private Date accruedTill;
|
||||||
|
|
||||||
public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final Integer loanType,
|
public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final Integer loanType,
|
||||||
final LoanProduct loanProduct, final Fund fund, final Staff officer, final CodeValue loanPurpose,
|
final LoanProduct loanProduct, final Fund fund, final Staff officer, final CodeValue loanPurpose,
|
||||||
final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
||||||
@@ -2138,7 +2142,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
|
this.accruedTill = null;
|
||||||
reverseExistingTransactions();
|
reverseExistingTransactions();
|
||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
|
|
||||||
|
|||||||
+38
-11
@@ -99,13 +99,14 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
Set<Long> loansIds = new HashSet<>();
|
Set<Long> loansIds = new HashSet<>();
|
||||||
LocalDate accruredTill = null;
|
LocalDate accruredTill = null;
|
||||||
|
Long lastLoanId = null;
|
||||||
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
|
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
|
||||||
try {
|
try {
|
||||||
if (!loansIds.contains(accrualData.getLoanId())) {
|
if (!loansIds.contains(accrualData.getLoanId())) {
|
||||||
if (accrualData.getDueDateAsLocaldate().isAfter(tilldate)) {
|
if (accrualData.getDueDateAsLocaldate().isAfter(tilldate)) {
|
||||||
//if (accruredTill == null) {
|
if (accruredTill == null || lastLoanId == null || !lastLoanId.equals(accrualData.getLoanId())) {
|
||||||
accruredTill = accrualData.getAccruedTill();
|
accruredTill = accrualData.getAccruedTill();
|
||||||
//}
|
}
|
||||||
addAccrualTillSpecificDate(tilldate, accrualData, accruredTill);
|
addAccrualTillSpecificDate(tilldate, accrualData, accruredTill);
|
||||||
} else {
|
} else {
|
||||||
addAccrualAccounting(accrualData);
|
addAccrualAccounting(accrualData);
|
||||||
@@ -121,20 +122,38 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
sb.append("failed to add accural transaction for repayment with id " + accrualData.getRepaymentScheduleId()
|
sb.append("failed to add accural transaction for repayment with id " + accrualData.getRepaymentScheduleId()
|
||||||
+ " with message " + realCause.getMessage());
|
+ " with message " + realCause.getMessage());
|
||||||
}
|
}
|
||||||
|
lastLoanId = accrualData.getLoanId();
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAccrualTillSpecificDate(final LocalDate tilldate, final LoanScheduleAccrualData accrualData,
|
private void addAccrualTillSpecificDate(final LocalDate tilldate, final LoanScheduleAccrualData accrualData,
|
||||||
final LocalDate accruredTill) throws Exception {
|
final LocalDate accruredTill) throws Exception {
|
||||||
int totalNumberOfDays = Days.daysBetween(accrualData.getFromDateAsLocaldate(), accrualData.getDueDateAsLocaldate()).getDays();
|
LocalDate interestStartDate = accrualData.getFromDateAsLocaldate();
|
||||||
|
if (accrualData.getInterestCalculatedFrom() != null
|
||||||
|
&& accrualData.getFromDateAsLocaldate().isBefore(accrualData.getInterestCalculatedFrom())) {
|
||||||
|
if (accrualData.getInterestCalculatedFrom().isBefore(accrualData.getDueDateAsLocaldate())) {
|
||||||
|
interestStartDate = accrualData.getInterestCalculatedFrom();
|
||||||
|
} else {
|
||||||
|
interestStartDate = accrualData.getDueDateAsLocaldate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int totalNumberOfDays = Days.daysBetween(interestStartDate, accrualData.getDueDateAsLocaldate()).getDays();
|
||||||
LocalDate startDate = accruredTill;
|
LocalDate startDate = accruredTill;
|
||||||
if (startDate == null) {
|
if (startDate == null) {
|
||||||
startDate = accrualData.getFromDateAsLocaldate();
|
startDate = accrualData.getFromDateAsLocaldate();
|
||||||
}
|
}
|
||||||
|
if (accrualData.getInterestCalculatedFrom() != null && startDate.isBefore(accrualData.getInterestCalculatedFrom())) {
|
||||||
|
if (accrualData.getInterestCalculatedFrom().isBefore(tilldate)) {
|
||||||
|
startDate = accrualData.getInterestCalculatedFrom();
|
||||||
|
} else {
|
||||||
|
startDate = tilldate;
|
||||||
|
}
|
||||||
|
}
|
||||||
int daysToBeAccrued = Days.daysBetween(startDate, tilldate).getDays();
|
int daysToBeAccrued = Days.daysBetween(startDate, tilldate).getDays();
|
||||||
if (daysToBeAccrued < 1) { return; }
|
// if (daysToBeAccrued < 1) { return; }
|
||||||
int daysInSchedule = Days.daysBetween(accrualData.getFromDateAsLocaldate(), tilldate).getDays();
|
int daysInSchedule = Days.daysBetween(interestStartDate, tilldate).getDays();
|
||||||
switch (accrualData.getRepaymentFrequency()) {
|
switch (accrualData.getRepaymentFrequency()) {
|
||||||
case MONTHS:
|
case MONTHS:
|
||||||
totalNumberOfDays = calculateTotalNumberOfDaysForMonth(totalNumberOfDays, accrualData);
|
totalNumberOfDays = calculateTotalNumberOfDaysForMonth(totalNumberOfDays, accrualData);
|
||||||
@@ -161,11 +180,19 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
amount = amount.add(interestportion);
|
amount = amount.add(interestportion);
|
||||||
|
|
||||||
BigDecimal totalAccInterest = accrualData.getAccruedInterestIncome();
|
BigDecimal totalAccInterest = accrualData.getAccruedInterestIncome();
|
||||||
|
BigDecimal totalAccPenalty = accrualData.getAccruedPenaltyIncome();
|
||||||
|
BigDecimal totalAccFee = accrualData.getAccruedFeeIncome();
|
||||||
|
|
||||||
|
if (startDate.isEqual(accrualData.getFromDateAsLocaldate())) {
|
||||||
|
totalAccInterest = null;
|
||||||
|
totalAccPenalty = null;
|
||||||
|
totalAccFee = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (totalAccInterest == null) {
|
if (totalAccInterest == null) {
|
||||||
totalAccInterest = BigDecimal.ZERO;
|
totalAccInterest = BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
totalAccInterest = totalAccInterest.add(interestportion);
|
totalAccInterest = totalAccInterest.add(interestportion);
|
||||||
BigDecimal totalAccFee = accrualData.getAccruedFeeIncome();
|
|
||||||
|
|
||||||
if (feeportion != null) {
|
if (feeportion != null) {
|
||||||
if (totalAccFee == null) {
|
if (totalAccFee == null) {
|
||||||
@@ -178,19 +205,19 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
feeportion = null;
|
feeportion = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BigDecimal totalAccPenalty = accrualData.getAccruedPenaltyIncome();
|
|
||||||
if (penaltyportion != null) {
|
if (penaltyportion != null) {
|
||||||
if (totalAccPenalty == null) {
|
if (totalAccPenalty == null) {
|
||||||
totalAccPenalty = BigDecimal.ZERO;
|
totalAccPenalty = BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
penaltyportion = penaltyportion.subtract(totalAccPenalty);
|
penaltyportion = penaltyportion.subtract(totalAccPenalty);
|
||||||
amount = amount.add(penaltyportion);
|
amount = amount.add(penaltyportion);
|
||||||
totalAccPenalty = totalAccFee.add(penaltyportion);
|
totalAccPenalty = totalAccPenalty.add(penaltyportion);
|
||||||
if (penaltyportion.compareTo(BigDecimal.ZERO) == 0) {
|
if (penaltyportion.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
penaltyportion = null;
|
penaltyportion = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (amount.compareTo(BigDecimal.ZERO) != 0) {
|
if (amount.compareTo(BigDecimal.ZERO) == 1) {
|
||||||
addAccrualAccounting(accrualData, amount, interestportion, totalAccInterest, feeportion, totalAccFee, penaltyportion,
|
addAccrualAccounting(accrualData, amount, interestportion, totalAccInterest, feeportion, totalAccFee, penaltyportion,
|
||||||
totalAccPenalty, tilldate);
|
totalAccPenalty, tilldate);
|
||||||
}
|
}
|
||||||
@@ -252,7 +279,7 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
feeportion = scheduleAccrualData.getFeeIncome();
|
feeportion = scheduleAccrualData.getFeeIncome();
|
||||||
totalAccFee = feeportion;
|
totalAccFee = feeportion;
|
||||||
if (scheduleAccrualData.getAccruedFeeIncome() != null) {
|
if (scheduleAccrualData.getAccruedFeeIncome() != null) {
|
||||||
feeportion.subtract(scheduleAccrualData.getAccruedFeeIncome());
|
feeportion = feeportion.subtract(scheduleAccrualData.getAccruedFeeIncome());
|
||||||
}
|
}
|
||||||
amount = amount.add(feeportion);
|
amount = amount.add(feeportion);
|
||||||
if (feeportion.compareTo(BigDecimal.ZERO) == 0) {
|
if (feeportion.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
@@ -266,7 +293,7 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
penaltyportion = scheduleAccrualData.getPenaltyIncome();
|
penaltyportion = scheduleAccrualData.getPenaltyIncome();
|
||||||
totalAccPenalty = penaltyportion;
|
totalAccPenalty = penaltyportion;
|
||||||
if (scheduleAccrualData.getAccruedPenaltyIncome() != null) {
|
if (scheduleAccrualData.getAccruedPenaltyIncome() != null) {
|
||||||
penaltyportion.subtract(scheduleAccrualData.getAccruedPenaltyIncome());
|
penaltyportion = penaltyportion.subtract(scheduleAccrualData.getAccruedPenaltyIncome());
|
||||||
}
|
}
|
||||||
amount = amount.add(penaltyportion);
|
amount = amount.add(penaltyportion);
|
||||||
if (penaltyportion.compareTo(BigDecimal.ZERO) == 0) {
|
if (penaltyportion.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
|
|||||||
+10
-5
@@ -1422,8 +1422,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||||
sqlBuilder
|
sqlBuilder
|
||||||
.append("loan.id as loanId ,if(loan.client_id is null,mg.office_id,mc.office_id) as officeId,")
|
.append("loan.id as loanId ,if(loan.client_id is null,mg.office_id,mc.office_id) as officeId,")
|
||||||
.append("ifnull(loan.accrued_till, ifnull(loan.interest_calculated_from_date, loan.disbursedon_date)) as accruedTill, ")
|
.append("loan.accrued_till as accruedTill, loan.repayment_period_frequency_enum as frequencyEnum, ")
|
||||||
.append("loan.repayment_period_frequency_enum as frequencyEnum, ")
|
.append("loan.interest_calculated_from_date as interestCalculatedFrom, ")
|
||||||
.append("loan.repay_every as repayEvery,")
|
.append("loan.repay_every as repayEvery,")
|
||||||
.append("(select sum(lc.amount) as dueamount from m_loan_charge lc where lc.loan_id = loan.id and lc.is_active = 1 and lc.waived = 0 and lc.is_penalty = 0 and lc.due_for_collection_as_of_date > ls.fromdate and lc.due_for_collection_as_of_date<= if(:tilldate < ls.duedate, :tilldate , ls.duedate)) as feedueIn,")
|
.append("(select sum(lc.amount) as dueamount from m_loan_charge lc where lc.loan_id = loan.id and lc.is_active = 1 and lc.waived = 0 and lc.is_penalty = 0 and lc.due_for_collection_as_of_date > ls.fromdate and lc.due_for_collection_as_of_date<= if(:tilldate < ls.duedate, :tilldate , ls.duedate)) as feedueIn,")
|
||||||
.append("(select sum(lc.amount) as dueamount from m_loan_charge lc where lc.loan_id = loan.id and lc.is_active = 1 and lc.waived = 0 and lc.is_penalty = 1 and lc.due_for_collection_as_of_date > ls.fromdate and lc.due_for_collection_as_of_date<= if(:tilldate < ls.duedate, :tilldate , ls.duedate)) as penalitydueIn,")
|
.append("(select sum(lc.amount) as dueamount from m_loan_charge lc where lc.loan_id = loan.id and lc.is_active = 1 and lc.waived = 0 and lc.is_penalty = 1 and lc.due_for_collection_as_of_date > ls.fromdate and lc.due_for_collection_as_of_date<= if(:tilldate < ls.duedate, :tilldate , ls.duedate)) as penalitydueIn,")
|
||||||
@@ -1447,6 +1447,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final Long loanId = rs.getLong("loanId");
|
final Long loanId = rs.getLong("loanId");
|
||||||
final Long officeId = rs.getLong("officeId");
|
final Long officeId = rs.getLong("officeId");
|
||||||
final LocalDate accruedTill = JdbcSupport.getLocalDate(rs, "accruedTill");
|
final LocalDate accruedTill = JdbcSupport.getLocalDate(rs, "accruedTill");
|
||||||
|
final LocalDate interestCalculatedFrom = JdbcSupport.getLocalDate(rs, "interestCalculatedFrom");
|
||||||
final Integer numberOfDaysInMonth = 30;
|
final Integer numberOfDaysInMonth = 30;
|
||||||
final Integer numberOfDaysInYear = 360;
|
final Integer numberOfDaysInYear = 360;
|
||||||
final Integer frequencyEnum = JdbcSupport.getInteger(rs, "frequencyEnum");
|
final Integer frequencyEnum = JdbcSupport.getInteger(rs, "frequencyEnum");
|
||||||
@@ -1476,7 +1477,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final BigDecimal dueDatePenaltyIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "penalitydueIn");
|
final BigDecimal dueDatePenaltyIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "penalitydueIn");
|
||||||
return new LoanScheduleAccrualData(loanId, officeId, accruedTill, numberOfDaysInMonth, numberOfDaysInYear, frequency,
|
return new LoanScheduleAccrualData(loanId, officeId, accruedTill, numberOfDaysInMonth, numberOfDaysInYear, frequency,
|
||||||
repayEvery, dueDate, fromDate, repaymentScheduleId, loanProductId, interestIncome, feeIncome, penaltyIncome,
|
repayEvery, dueDate, fromDate, repaymentScheduleId, loanProductId, interestIncome, feeIncome, penaltyIncome,
|
||||||
accruedInterestIncome, accruedFeeIncome, accruedPenaltyIncome, currencyData, dueDateFeeIncome, dueDatePenaltyIncome);
|
accruedInterestIncome, accruedFeeIncome, accruedPenaltyIncome, currencyData, dueDateFeeIncome, dueDatePenaltyIncome,
|
||||||
|
interestCalculatedFrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1532,9 +1534,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final LocalDate fromDate = null;
|
final LocalDate fromDate = null;
|
||||||
final BigDecimal dueDateFeeincome = null;
|
final BigDecimal dueDateFeeincome = null;
|
||||||
final BigDecimal dueDatePenaltyIncome = null;
|
final BigDecimal dueDatePenaltyIncome = null;
|
||||||
|
final LocalDate interestCalculatedFrom = null;
|
||||||
return new LoanScheduleAccrualData(loanId, officeId, accruedTill, numberOfDaysInMonth, numberOfDaysInYear, frequency,
|
return new LoanScheduleAccrualData(loanId, officeId, accruedTill, numberOfDaysInMonth, numberOfDaysInYear, frequency,
|
||||||
repayEvery, dueDate, fromDate, repaymentScheduleId, loanProductId, interestIncome, feeIncome, penaltyIncome,
|
repayEvery, dueDate, fromDate, repaymentScheduleId, loanProductId, interestIncome, feeIncome, penaltyIncome,
|
||||||
accruedInterestIncome, accruedFeeIncome, accruedPenaltyIncome, currencyData, dueDateFeeincome, dueDatePenaltyIncome);
|
accruedInterestIncome, accruedFeeIncome, accruedPenaltyIncome, currencyData, dueDateFeeincome, dueDatePenaltyIncome,
|
||||||
|
interestCalculatedFrom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1572,7 +1576,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
sqlBuilder.append(" and mr.duedate < ? ");
|
sqlBuilder.append(" and mr.duedate < ? ");
|
||||||
sqlBuilder.append(" group by ml.id");
|
sqlBuilder.append(" group by ml.id");
|
||||||
try {
|
try {
|
||||||
return this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class, new Object[] { LoanStatus.ACTIVE.getValue(), formatter.print(LocalDate.now()) });
|
return this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class,
|
||||||
|
new Object[] { LoanStatus.ACTIVE.getValue(), formatter.print(LocalDate.now()) });
|
||||||
} catch (final EmptyResultDataAccessException e) {
|
} catch (final EmptyResultDataAccessException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user