MIFOSX-1487 : changed logic to fetch accrued till

This commit is contained in:
Pramod Nuthakki
2014-08-15 18:17:05 +05:30
parent df4a070123
commit debd298a13
4 changed files with 62 additions and 18 deletions
@@ -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;
}
} }
@@ -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();
@@ -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) {
@@ -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;
} }