MIFOSX-2358:fix for last installment overdue charge

This commit is contained in:
pramod
2015-12-24 17:34:42 +05:30
parent 0e2fba6427
commit 09df00c078
4 changed files with 51 additions and 8 deletions
@@ -836,6 +836,9 @@ public class Loan extends AbstractPersistable<Long> {
*/ */
private BigDecimal calculateAmountPercentageAppliedTo(final LoanCharge loanCharge) { private BigDecimal calculateAmountPercentageAppliedTo(final LoanCharge loanCharge) {
BigDecimal amount = BigDecimal.ZERO; BigDecimal amount = BigDecimal.ZERO;
if(loanCharge.isOverdueInstallmentCharge()){
return loanCharge.getAmountPercentageAppliedTo();
}
switch (loanCharge.getChargeCalculation()) { switch (loanCharge.getChargeCalculation()) {
case PERCENT_OF_AMOUNT: case PERCENT_OF_AMOUNT:
amount = getPrincpal().getAmount(); amount = getPrincpal().getAmount();
@@ -1482,6 +1482,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
final StringBuilder sqlBuilder = new StringBuilder(400); final StringBuilder sqlBuilder = new StringBuilder(400);
sqlBuilder.append("select ").append(rm.schema()).append(" where DATE_SUB(CURDATE(),INTERVAL ? DAY) > ls.duedate ") sqlBuilder.append("select ").append(rm.schema()).append(" where DATE_SUB(CURDATE(),INTERVAL ? DAY) > ls.duedate ")
.append(" and ls.completed_derived <> 1 and mc.charge_applies_to_enum =1 ") .append(" and ls.completed_derived <> 1 and mc.charge_applies_to_enum =1 ")
.append(" and ls.recalculated_interest_component <> 1 ")
.append(" and mc.charge_time_enum = 9 and ml.loan_status_id = 300 "); .append(" and mc.charge_time_enum = 9 and ml.loan_status_id = 300 ");
if (backdatePenalties) { return this.jdbcTemplate.query(sqlBuilder.toString(), rm, new Object[] { penaltyWaitPeriod }); } if (backdatePenalties) { return this.jdbcTemplate.query(sqlBuilder.toString(), rm, new Object[] { penaltyWaitPeriod }); }
@@ -2474,6 +2474,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final List<Long> existingReversedTransactionIds = new ArrayList<>(); final List<Long> existingReversedTransactionIds = new ArrayList<>();
boolean runInterestRecalculation = false; boolean runInterestRecalculation = false;
LocalDate recalculateFrom = DateUtils.getLocalDateOfTenant(); LocalDate recalculateFrom = DateUtils.getLocalDateOfTenant();
LocalDate lastChargeDate = null;
for (final OverdueLoanScheduleData overdueInstallment : overdueLoanScheduleDatas) { for (final OverdueLoanScheduleData overdueInstallment : overdueLoanScheduleDatas) {
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(overdueInstallment.toString()); final JsonElement parsedCommand = this.fromApiJsonHelper.parse(overdueInstallment.toString());
@@ -2486,6 +2487,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
if (recalculateFrom.isAfter(overdueDTO.getRecalculateFrom())) { if (recalculateFrom.isAfter(overdueDTO.getRecalculateFrom())) {
recalculateFrom = overdueDTO.getRecalculateFrom(); recalculateFrom = overdueDTO.getRecalculateFrom();
} }
if (lastChargeDate == null || overdueDTO.getLastChargeAppliedDate().isAfter(lastChargeDate)) {
lastChargeDate = overdueDTO.getLastChargeAppliedDate();
}
} }
if (loan != null) { if (loan != null) {
boolean reprocessRequired = true; boolean reprocessRequired = true;
@@ -2503,6 +2507,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
} }
if (reprocessRequired) { if (reprocessRequired) {
addInstallmentIfPenaltyAppliedAfterLastDueDate(loan, lastChargeDate);
ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactions(); ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactions();
if (changedTransactionDetail != null) { if (changedTransactionDetail != null) {
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
@@ -2528,6 +2533,28 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
} }
} }
private void addInstallmentIfPenaltyAppliedAfterLastDueDate(Loan loan, LocalDate lastChargeDate) {
if (lastChargeDate != null) {
List<LoanRepaymentScheduleInstallment> installments = loan.fetchRepaymentScheduleInstallments();
LoanRepaymentScheduleInstallment lastInstallment = loan.fetchRepaymentScheduleInstallment(installments.size());
if (lastChargeDate.isAfter(lastInstallment.getDueDate())) {
if (lastInstallment.isRecalculatedInterestComponent()) {
installments.remove(lastInstallment);
lastInstallment = loan.fetchRepaymentScheduleInstallment(installments.size());
}
boolean recalculatedInterestComponent = true;
BigDecimal principal = BigDecimal.ZERO;
BigDecimal interest = BigDecimal.ZERO;
BigDecimal feeCharges = BigDecimal.ZERO;
BigDecimal penaltyCharges = BigDecimal.ONE;
LoanRepaymentScheduleInstallment newEntry = new LoanRepaymentScheduleInstallment(loan, installments.size() + 1,
lastInstallment.getDueDate(), lastChargeDate, principal, interest, feeCharges, penaltyCharges,
recalculatedInterestComponent);
installments.add(newEntry);
}
}
}
public LoanOverdueDTO applyChargeToOverdueLoanInstallment(final Long loanId, final Long loanChargeId, final Integer periodNumber, public LoanOverdueDTO applyChargeToOverdueLoanInstallment(final Long loanId, final Long loanChargeId, final Integer periodNumber,
final JsonCommand command, Loan loan, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds) { final JsonCommand command, Loan loan, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds) {
boolean runInterestRecalculation = false; boolean runInterestRecalculation = false;
@@ -2565,6 +2592,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
} }
LoanRepaymentScheduleInstallment installment = null; LoanRepaymentScheduleInstallment installment = null;
LocalDate lastChargeAppliedDate = dueDate;
if (!scheduleDates.isEmpty()) { if (!scheduleDates.isEmpty()) {
if (loan == null) { if (loan == null) {
loan = this.loanAssembler.assembleFrom(loanId); loan = this.loanAssembler.assembleFrom(loanId);
@@ -2573,8 +2601,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds()); existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
} }
installment = loan.fetchRepaymentScheduleInstallment(periodNumber); installment = loan.fetchRepaymentScheduleInstallment(periodNumber);
lastChargeAppliedDate = installment.getDueDate();
} }
LocalDate recalculateFrom = DateUtils.getLocalDateOfTenant(); LocalDate recalculateFrom = DateUtils.getLocalDateOfTenant();
if (loan != null) { if (loan != null) {
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_APPLY_OVERDUE_CHARGE, this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_APPLY_OVERDUE_CHARGE,
constructEntityMap(BUSINESS_ENTITY.LOAN, loan)); constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
@@ -2591,10 +2621,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
if (entry.getValue().isBefore(recalculateFrom)) { if (entry.getValue().isBefore(recalculateFrom)) {
recalculateFrom = entry.getValue(); recalculateFrom = entry.getValue();
} }
if (entry.getValue().isAfter(lastChargeAppliedDate)) {
lastChargeAppliedDate = entry.getValue();
}
} }
} }
return new LoanOverdueDTO(loan, runInterestRecalculation, recalculateFrom); return new LoanOverdueDTO(loan, runInterestRecalculation, recalculateFrom, lastChargeAppliedDate);
} }
@Override @Override
@@ -3079,11 +3112,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
boolean isFloatingInterestRate = loan.getIsFloatingInterestRate(); boolean isFloatingInterestRate = loan.getIsFloatingInterestRate();
BigDecimal interestRateDiff = loan.getInterestRateDifferential(); BigDecimal interestRateDiff = loan.getInterestRateDifferential();
List<FloatingRatePeriodData> baseLendingRatePeriods = null; List<FloatingRatePeriodData> baseLendingRatePeriods = null;
try{ try {
baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate() baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate().getRatePeriods();
.getRatePeriods(); } catch (final FloatingRateNotFoundException ex) {
}catch(final FloatingRateNotFoundException ex){ // Do not do anything
// Do not do anything
} }
floatingRateDTO = new FloatingRateDTO(isFloatingInterestRate, loan.getDisbursementDate(), interestRateDiff, floatingRateDTO = new FloatingRateDTO(isFloatingInterestRate, loan.getDisbursementDate(), interestRateDiff,
baseLendingRatePeriods); baseLendingRatePeriods);
@@ -13,11 +13,14 @@ public class LoanOverdueDTO {
private final Loan loan; private final Loan loan;
private final boolean runInterestRecalculation; private final boolean runInterestRecalculation;
private final LocalDate recalculateFrom; private final LocalDate recalculateFrom;
private final LocalDate lastChargeAppliedDate;
public LoanOverdueDTO(final Loan loan, final boolean runInterestRecalculation, final LocalDate recalculateFrom) { public LoanOverdueDTO(final Loan loan, final boolean runInterestRecalculation, final LocalDate recalculateFrom,
final LocalDate lastChargeAppliedDate) {
this.loan = loan; this.loan = loan;
this.runInterestRecalculation = runInterestRecalculation; this.runInterestRecalculation = runInterestRecalculation;
this.recalculateFrom = recalculateFrom; this.recalculateFrom = recalculateFrom;
this.lastChargeAppliedDate = lastChargeAppliedDate;
} }
public boolean isRunInterestRecalculation() { public boolean isRunInterestRecalculation() {
@@ -28,8 +31,12 @@ public class LoanOverdueDTO {
return this.loan; return this.loan;
} }
public LocalDate getRecalculateFrom() { public LocalDate getRecalculateFrom() {
return this.recalculateFrom; return this.recalculateFrom;
} }
public LocalDate getLastChargeAppliedDate() {
return this.lastChargeAppliedDate;
}
} }