From 8b5eab1d87205058659db0e9d2e11950ace6dadd Mon Sep 17 00:00:00 2001 From: Pramod Nuthakki Date: Thu, 2 Jan 2014 13:14:54 +0530 Subject: [PATCH] added status for charges --- .../V139__added_loan_charge_status.sql | 2 + ...ollectionSheetReadPlatformServiceImpl.java | 2 +- .../portfolio/loanaccount/domain/Loan.java | 115 +++++++++++------- .../loanaccount/domain/LoanCharge.java | 13 ++ .../LoanChargeReadPlatformServiceImpl.java | 4 +- .../service/LoanReadPlatformServiceImpl.java | 2 +- 6 files changed, 93 insertions(+), 45 deletions(-) create mode 100755 mifosng-db/migrations/core_db/V139__added_loan_charge_status.sql diff --git a/mifosng-db/migrations/core_db/V139__added_loan_charge_status.sql b/mifosng-db/migrations/core_db/V139__added_loan_charge_status.sql new file mode 100755 index 000000000..3536ffab9 --- /dev/null +++ b/mifosng-db/migrations/core_db/V139__added_loan_charge_status.sql @@ -0,0 +1,2 @@ +ALTER TABLE `m_loan_charge` + ADD COLUMN `is_active` TINYINT(1) NOT NULL DEFAULT '1' AFTER `max_cap`; \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java index 1a83c949d..9f0b45cc2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java @@ -217,7 +217,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe sql.append("and (gp.status_enum = 300 or (gp.status_enum = 600 and gp.closedon_date >= :dueDate)) ") .append("and (cl.status_enum = 300 or (cl.status_enum = 600 and cl.closedon_date >= :dueDate)) ") .append("GROUP BY gp.id ,cl.id , ln.id ORDER BY gp.id , cl.id , ln.id ").append(") loandata ") - .append("LEFT JOIN m_loan_charge lc ON lc.loan_id = loandata.loanId AND lc.is_paid_derived = 0 ") + .append("LEFT JOIN m_loan_charge lc ON lc.loan_id = loandata.loanId AND lc.is_paid_derived = 0 AND lc.is_active = 1") .append("AND ( lc.due_for_collection_as_of_date <= :dueDate OR lc.charge_time_enum = 1) ") .append("GROUP BY loandata.groupId, ").append("loandata.clientId, ").append("loandata.loanId ") .append("ORDER BY loandata.groupId, ").append("loandata.clientId, ").append("loandata.loanId "); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java index 76bed1d11..6b1a8aa83 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/Loan.java @@ -83,6 +83,7 @@ import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleM import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod; import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod; import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct; +import org.mifosplatform.portfolio.loanproduct.domain.LoanProductBorrowerCycleVariations; import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail; import org.mifosplatform.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; @@ -374,7 +375,7 @@ public class Loan extends AbstractPersistable { Money chargesDue = Money.of(getCurrency(), BigDecimal.ZERO); - for (final LoanCharge charge : setOfLoanCharges()) { + for (final LoanCharge charge : charges()) { if (charge.isDueAtDisbursement()) { chargesDue = chargesDue.plus(charge.amount()); } @@ -453,7 +454,7 @@ public class Loan extends AbstractPersistable { // NOTE: must add new loan charge to set of loan charges before // reporcessing the repayment schedule. - setOfLoanCharges().add(loanCharge); + charges().add(loanCharge); final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory .determineProcessor(this.transactionProcessingStrategy); @@ -463,11 +464,11 @@ public class Loan extends AbstractPersistable { existingTransactionIds.addAll(findExistingTransactionIds()); existingReversedTransactionIds.addAll(findExistingReversedTransactionIds()); final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper(); - wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, setOfLoanCharges()); + wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges()); if (!loanCharge.isDueAtDisbursement()) { final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), - allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, setOfLoanCharges()); + allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, charges()); for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { mapEntry.getValue().updateLoan(this); } @@ -591,10 +592,12 @@ public class Loan extends AbstractPersistable { // if you want ability to remove loan charges that are waived. validateLoanChargeIsNotWaived(loanCharge); - final boolean removed = setOfLoanCharges().remove(loanCharge); + LoanCharge charge = fetchLoanChargesById(loanCharge.getId()); + final boolean removed = charge.isActive(); if (removed) { + charge.setActive(false); final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper(); - wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, setOfLoanCharges()); + wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges()); updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement()); } @@ -613,7 +616,7 @@ public class Loan extends AbstractPersistable { ***/ final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), allNonContraTransactionsPostDisbursement, - getCurrency(), this.repaymentScheduleInstallments, setOfLoanCharges()); + getCurrency(), this.repaymentScheduleInstallments, charges()); } updateLoanSummaryDerivedFields(); @@ -651,7 +654,7 @@ public class Loan extends AbstractPersistable { final Map actualChanges = new LinkedHashMap(3); validateLoanIsNotClosed(loanCharge); - if (setOfLoanCharges().contains(loanCharge)) { + if (charges().contains(loanCharge)) { final BigDecimal amount = calculateAmountPercentageAppliedTo(loanCharge); final Map loanChargeChanges = loanCharge.update(command, amount); actualChanges.putAll(loanChargeChanges); @@ -671,11 +674,11 @@ public class Loan extends AbstractPersistable { ***/ final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), allNonContraTransactionsPostDisbursement, - getCurrency(), this.repaymentScheduleInstallments, setOfLoanCharges()); + getCurrency(), this.repaymentScheduleInstallments, charges()); } else { // reprocess loan schedule based on charge been waived. final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper(); - wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, setOfLoanCharges()); + wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges()); } updateLoanSummaryDerivedFields(); @@ -798,11 +801,11 @@ public class Loan extends AbstractPersistable { ***/ final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), allNonContraTransactionsPostDisbursement, - getCurrency(), this.repaymentScheduleInstallments, setOfLoanCharges()); + getCurrency(), this.repaymentScheduleInstallments, charges()); } else { // reprocess loan schedule based on charge been waived. final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper(); - wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, setOfLoanCharges()); + wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges()); } updateLoanSummaryDerivedFields(); @@ -861,9 +864,16 @@ public class Loan extends AbstractPersistable { } public void updateLoanCharges(final Set loanCharges) { - setOfLoanCharges().clear(); + List existingCharges = fetchAllLoanChargeIds(); for (final LoanCharge loanCharge : loanCharges) { - loanCharge.update(this); + LoanCharge charge = loanCharge; + if(loanCharge.getId() == null){ + loanCharge.update(this); + this.charges.add(loanCharge); + }else{ + charge = fetchLoanChargesById(charge.getId()); + existingCharges.remove(charge.getId()); + } final BigDecimal amount = calculateAmountPercentageAppliedTo(loanCharge); BigDecimal chargeAmt = BigDecimal.ZERO; BigDecimal totalChargeAmt = BigDecimal.ZERO; @@ -878,10 +888,12 @@ public class Loan extends AbstractPersistable { chargeAmt = chargeAmt.divide(BigDecimal.valueOf(repaymentScheduleDetail().getNumberOfRepayments())); } } - loanCharge.update(chargeAmt, loanCharge.getDueLocalDate(), amount, repaymentScheduleDetail().getNumberOfRepayments(), + charge.update(chargeAmt, loanCharge.getDueLocalDate(), amount, repaymentScheduleDetail().getNumberOfRepayments(), totalChargeAmt); } - setOfLoanCharges().addAll(loanCharges); + for(Long id:existingCharges){ + fetchLoanChargesById(id).setActive(false); + } updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement()); } @@ -915,7 +927,7 @@ public class Loan extends AbstractPersistable { } private void clearInstallmentLoanCharge() { - for (final LoanCharge loanCharge : setOfLoanCharges()) { + for (final LoanCharge loanCharge : charges()) { if (loanCharge.isInstalmentFee()) { loanCharge.clearLoanInstallmentCharges(); } @@ -1129,7 +1141,7 @@ public class Loan extends AbstractPersistable { final String chargesParamName = "charges"; if (command.parameterExists(chargesParamName)) { - final Set existingLoanCharges = setOfLoanCharges(); + final Set existingLoanCharges = charges(); if (!possiblyModifedLoanCharges.equals(existingLoanCharges)) { actualChanges.put(chargesParamName, getLoanCharges(possiblyModifedLoanCharges)); @@ -1185,14 +1197,6 @@ public class Loan extends AbstractPersistable { return actualChanges; } - private Set setOfLoanCharges() { - Set loanCharges = this.charges; - if (this.charges == null) { - loanCharges = new HashSet(); - } - return loanCharges; - } - private CollateralData[] listOfLoanCollateralData(final Set setOfLoanCollateral) { CollateralData[] existingLoanCollateral = null; @@ -1284,7 +1288,7 @@ public class Loan extends AbstractPersistable { } // charges are optional - for (final LoanCharge loanCharge : setOfLoanCharges()) { + for (final LoanCharge loanCharge : charges()) { final BigDecimal amount = calculateAmountPercentageAppliedTo(loanCharge); BigDecimal chargeAmt = BigDecimal.ZERO; BigDecimal totalChargeAmt = BigDecimal.ZERO; @@ -1588,7 +1592,7 @@ public class Loan extends AbstractPersistable { loanTermPeriodFrequencyType, getDisbursementDate(), getExpectedFirstRepaymentOnDate(), calculatedRepaymentsStartingFromDate, getInArrearsTolerance(), this.loanRepaymentScheduleDetail); - final LoanScheduleModel loanSchedule = loanScheduleGenerator.generate(mc, applicationCurrency, loanApplicationTerms, this.charges, + final LoanScheduleModel loanSchedule = loanScheduleGenerator.generate(mc, applicationCurrency, loanApplicationTerms,charges(), isHolidayEnabled, holidays, workingDays); updateLoanSchedule(loanSchedule); @@ -1618,7 +1622,7 @@ public class Loan extends AbstractPersistable { Money disbursentMoney = Money.zero(getCurrency()); final LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(getOffice(), disbursentMoney, null, disbursedOn, null); - for (final LoanCharge charge : setOfLoanCharges()) { + for (final LoanCharge charge : charges()) { if (charge.isDueAtDisbursement()) { if (totalFeeChargesDueAtDisbursement.isGreaterThanZero() && !charge.getChargePaymentMode().isPaymentModeAccountTransfer()) { charge.markAsFullyPaid(); @@ -1662,7 +1666,7 @@ public class Loan extends AbstractPersistable { existingReversedTransactionIds.addAll(findExistingReversedTransactionIds()); LoanCharge charge = null; for (final LoanCharge loanCharge : this.charges) { - if (chargeId.equals(loanCharge.getId())) { + if (loanCharge.isActive() && chargeId.equals(loanCharge.getId())) { charge = loanCharge; } } @@ -1728,7 +1732,7 @@ public class Loan extends AbstractPersistable { private void updateLoanToPreDisbursalState() { this.actualDisbursementDate = null; - for (final LoanCharge charge : setOfLoanCharges()) { + for (final LoanCharge charge : charges()) { charge.resetToOriginal(loanCurrency()); } @@ -1737,7 +1741,7 @@ public class Loan extends AbstractPersistable { } final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper(); - wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, setOfLoanCharges()); + wrapper.reprocess(getCurrency(), getDisbursementDate(), this.repaymentScheduleInstallments, charges()); updateLoanSummaryDerivedFields(); } @@ -1799,7 +1803,7 @@ public class Loan extends AbstractPersistable { existingReversedTransactionIds.addAll(findExistingReversedTransactionIds()); LoanCharge charge = null; for (final LoanCharge loanCharge : this.charges) { - if (chargeId.equals(loanCharge.getId())) { + if (loanCharge.isActive() && chargeId.equals(loanCharge.getId())) { charge = loanCharge; } } @@ -1890,11 +1894,11 @@ public class Loan extends AbstractPersistable { .determineProcessor(this.transactionProcessingStrategy); if (isTransactionChronologicallyLatest && adjustedTransaction == null) { loanRepaymentScheduleTransactionProcessor.handleTransaction(loanTransaction, getCurrency(), this.repaymentScheduleInstallments, - setOfLoanCharges()); + charges()); } else { final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), - allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, setOfLoanCharges()); + allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, charges()); for (final Map.Entry mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { mapEntry.getValue().updateLoan(this); } @@ -1939,7 +1943,8 @@ public class Loan extends AbstractPersistable { boolean isAllChargesPaid = true; for (final LoanCharge loanCharge : this.charges) { - if (!(loanCharge.isPaid() || loanCharge.isWaived())) { + if (loanCharge.isActive() + && !(loanCharge.isPaid() || loanCharge.isWaived())) { isAllChargesPaid = false; break; } @@ -2138,7 +2143,7 @@ public class Loan extends AbstractPersistable { .determineProcessor(this.transactionProcessingStrategy); final List allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement(); ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), - allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, setOfLoanCharges()); + allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, charges()); updateLoanSummaryDerivedFields(); return changedTransactionDetail; } @@ -3046,7 +3051,15 @@ public class Loan extends AbstractPersistable { } public Set charges() { - return this.charges; + Set loanCharges = new HashSet(); + if(this.charges != null){ + for(LoanCharge charge:this.charges){ + if(charge.isActive()){ + loanCharges.add(charge); + } + } + } + return loanCharges; } public Set generateInstallmentLoanCharges(final LoanCharge loanCharge) { @@ -3115,7 +3128,7 @@ public class Loan extends AbstractPersistable { } break; case LOAN_REJECTED: - if (!isClosedWrittenOff()) { + if (!isSubmittedAndPendingApproval()) { final String defaultUserMessage = "Loan application cannot be rejected. Loan Account is not in Submitted and Pending approval state."; final ApiParameterError error = ApiParameterError.generalError( "error.msg.loan.reject.account.is.not.submitted.pending.approval.state", defaultUserMessage); @@ -3149,7 +3162,7 @@ public class Loan extends AbstractPersistable { case REPAID_IN_FULL: break; case LOAN_CHARGE_PAYMENT: - if (!isClosedWrittenOff()) { + if (!isOpen()) { final String defaultUserMessage = "Charge payment is not allowed. Loan Account is not Active."; final ApiParameterError error = ApiParameterError.generalError("error.msg.loan.charge.payment.account.is.not.active", defaultUserMessage); @@ -3157,7 +3170,7 @@ public class Loan extends AbstractPersistable { } break; case LOAN_CLOSED: - if (!isClosedWrittenOff()) { + if (!isOpen()) { final String defaultUserMessage = "Closing Loan Account is not allowed. Loan Account is not Active."; final ApiParameterError error = ApiParameterError.generalError("error.msg.loan.close.account.is.not.active", defaultUserMessage); @@ -3171,4 +3184,24 @@ public class Loan extends AbstractPersistable { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } } + + public LoanCharge fetchLoanChargesById(Long id) { + LoanCharge charge = null; + for (LoanCharge loanCharge : this.charges) { + if (id.equals(loanCharge.getId())) { + charge = loanCharge; + break; + } + } + return charge; + } + + private List fetchAllLoanChargeIds() { + List list = new ArrayList(); + for (LoanCharge loanCharge : this.charges) { + list.add(loanCharge.getId()); + } + return list; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCharge.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCharge.java index 2e348d1f3..e4bb29174 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCharge.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanCharge.java @@ -108,6 +108,10 @@ public class LoanCharge extends AbstractPersistable { @LazyCollection(LazyCollectionOption.FALSE) @OneToMany(cascade = CascadeType.ALL, mappedBy = "loancharge", orphanRemoval = true) private final Set loanInstallmentCharge = new HashSet(); + + @Column(name = "is_active", nullable = false) + private boolean active = true; + public static LoanCharge createNewFromJson(final Loan loan, final Charge chargeDefinition, final JsonCommand command) { @@ -769,4 +773,13 @@ public class LoanCharge extends AbstractPersistable { } return null; } + + public boolean isActive(){ + return this.active; + } + + + public void setActive(boolean active) { + this.active = active; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformServiceImpl.java index 38d29d941..4e1bf0ba3 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformServiceImpl.java @@ -151,7 +151,7 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform final LoanChargeMapper rm = new LoanChargeMapper(); - final String sql = "select " + rm.schema() + " where lc.loan_id=? " + final String sql = "select " + rm.schema() + " where lc.loan_id=? AND lc.is_active = 1" + " order by lc.charge_time_enum ASC, lc.due_for_collection_as_of_date ASC, lc.is_penalty ASC"; return this.jdbcTemplate.query(sql, rm, new Object[] { loanId }); @@ -161,7 +161,7 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform public Collection retrieveLoanChargesForFeePayment(final Integer paymentMode, final Integer loanStatus) { final LoanChargeMapperWithLoanId rm = new LoanChargeMapperWithLoanId(); final String sql = "select " + rm.schema() - + "where loan.loan_status_id= ? and lc.charge_payment_mode_enum=? and lc.waived =0 and lc.is_paid_derived=0"; + + "where loan.loan_status_id= ? and lc.charge_payment_mode_enum=? and lc.waived =0 and lc.is_paid_derived=0 and lc.is_active = 1"; return this.jdbcTemplate.query(sql, rm, new Object[] { loanStatus, paymentMode }); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index e1af7f225..35e19aec5 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -1156,7 +1156,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { + " where DATE_SUB(CURDATE(),INTERVAL ? DAY) > ls.duedate " + " and ls.completed_derived <> 1 and mc.charge_applies_to_enum =1 " + " and mc.charge_time_enum = 9 and ml.loan_status_id = 300 " - + " and plc.charge_id not in (SELECT charge_id from m_loan_charge as mlc where mlc.loan_id = ml.id and mlc.charge_id = plc.charge_id and mlc.due_for_collection_as_of_date > fromdate AND mlc.due_for_collection_as_of_date <= duedate) "; + + " and plc.charge_id not in (SELECT charge_id from m_loan_charge as mlc where mlc.loan_id = ml.id and mlc.charge_id = plc.charge_id and mlc.is_active = 1 and mlc.due_for_collection_as_of_date > fromdate AND mlc.due_for_collection_as_of_date <= duedate) "; return this.jdbcTemplate.query(sql, rm, new Object[] { penaltyWaitPeriod }); }