diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java index 204d30d46..aa4179f58 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccountingProcessorHelper.java @@ -237,6 +237,67 @@ public class AccountingProcessorHelper { loanId, transactionId, transactionDate, amount); } + /** + * Convenience method that creates a pair of related Debits and Credits for + * Accrual Based accounting. + * + * The target accounts for debits and credits are switched in case of a + * reversal + * + * @param office + * @param accountTypeToBeDebited + * Enum of the placeholder GLAccount to be debited + * @param accountTypeToBeCredited + * Enum of the placeholder of the GLAccount to be credited + * @param loanProductId + * @param paymentTypeId + * @param loanId + * @param transactionId + * @param transactionDate + * @param amount + * @param isReversal + */ + public void createAccrualBasedJournalEntriesAndReversalsForLoanCharges(final Office office, final String currencyCode, + final Integer accountTypeToBeDebited, final Integer accountTypeToBeCredited, final Long loanProductId, final Long loanId, + final String transactionId, final Date transactionDate, final BigDecimal totalAmount, final Boolean isReversal, + final List chargePaymentDTOs) { + + GLAccount receivableAccount = getLinkedGLAccountForLoanCharges(loanProductId, accountTypeToBeDebited, null); + final Map creditDetailsMap = new LinkedHashMap<>(); + for (final ChargePaymentDTO chargePaymentDTO : chargePaymentDTOs) { + final Long chargeId = chargePaymentDTO.getChargeId(); + final GLAccount chargeSpecificAccount = getLinkedGLAccountForLoanCharges(loanProductId, accountTypeToBeCredited, chargeId); + BigDecimal chargeSpecificAmount = chargePaymentDTO.getAmount(); + + // adjust net credit amount if the account is already present in the + // map + if (creditDetailsMap.containsKey(chargeSpecificAccount)) { + final BigDecimal existingAmount = creditDetailsMap.get(chargeSpecificAccount); + chargeSpecificAmount = chargeSpecificAmount.add(existingAmount); + } + creditDetailsMap.put(chargeSpecificAccount, chargeSpecificAmount); + } + + BigDecimal totalCreditedAmount = BigDecimal.ZERO; + for (final Map.Entry entry : creditDetailsMap.entrySet()) { + final GLAccount account = entry.getKey(); + final BigDecimal amount = entry.getValue(); + totalCreditedAmount = totalCreditedAmount.add(amount); + if (isReversal) { + createDebitJournalEntryForLoan(office, currencyCode, account, loanId, transactionId, transactionDate, amount); + createCreditJournalEntryForLoan(office, currencyCode, receivableAccount, loanId, transactionId, transactionDate, amount); + } else { + createDebitJournalEntryForLoan(office, currencyCode, receivableAccount, loanId, transactionId, transactionDate, amount); + createCreditJournalEntryForLoan(office, currencyCode, account, loanId, transactionId, transactionDate, amount); + } + } + + if (totalAmount.compareTo(totalCreditedAmount) != 0) { throw new PlatformDataIntegrityException( + "Meltdown in advanced accounting...sum of all charges is not equal to the fee charge for a transaction", + "Meltdown in advanced accounting...sum of all charges is not equal to the fee charge for a transaction", + totalCreditedAmount, totalAmount); } + } + /** * Convenience method that creates a pair of related Debits and Credits for * Cash Based accounting. diff --git a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java index 74e53f32d..67a30545b 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java @@ -294,15 +294,17 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess } // create journal entries for the fees application (or reversal) if (feesAmount != null && !(feesAmount.compareTo(BigDecimal.ZERO) == 0)) { - this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, currencyCode, + this.helper.createAccrualBasedJournalEntriesAndReversalsForLoanCharges(office, currencyCode, ACCRUAL_ACCOUNTS_FOR_LOAN.FEES_RECEIVABLE.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_FEES.getValue(), - loanProductId, paymentTypeId, loanId, transactionId, transactionDate, feesAmount, isReversed); + loanProductId, loanId, transactionId, transactionDate, feesAmount, isReversed, loanTransactionDTO.getFeePayments()); } // create journal entries for the penalties application (or reversal) if (penaltiesAmount != null && !(penaltiesAmount.compareTo(BigDecimal.ZERO) == 0)) { - this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, currencyCode, + + this.helper.createAccrualBasedJournalEntriesAndReversalsForLoanCharges(office, currencyCode, ACCRUAL_ACCOUNTS_FOR_LOAN.PENALTIES_RECEIVABLE.getValue(), ACCRUAL_ACCOUNTS_FOR_LOAN.INCOME_FROM_PENALTIES.getValue(), - loanProductId, paymentTypeId, loanId, transactionId, transactionDate, penaltiesAmount, isReversed); + loanProductId, loanId, transactionId, transactionDate, penaltiesAmount, isReversed, + loanTransactionDTO.getPenaltyPayments()); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanChargeData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanChargeData.java index 254a4717b..0877d1ae6 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanChargeData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanChargeData.java @@ -63,9 +63,10 @@ public class LoanChargeData { private final BigDecimal maxCap; - @SuppressWarnings("unused") private final Collection installmentChargeData; + private BigDecimal amountAccrued; + public static LoanChargeData template(final Collection chargeOptions) { return new LoanChargeData(null, null, null, null, null, null, null, null, chargeOptions, false, null, false, false, null, null, null, null, null); @@ -124,6 +125,7 @@ public class LoanChargeData { this.chargePayable = isChargePayable(); this.loanId = loanId; this.installmentChargeData = installmentChargeData; + this.amountAccrued = null; } private LoanChargeData(final Long id, final Long chargeId, final String name, final CurrencyData currency, final BigDecimal amount, @@ -166,6 +168,7 @@ public class LoanChargeData { this.minCap = minCap; this.maxCap = maxCap; this.installmentChargeData = installmentChargeData; + this.amountAccrued = null; } public LoanChargeData(final Long id, final LocalDate dueAsOfDate, final BigDecimal amountOutstanding, EnumOptionData chargeTimeType, @@ -195,6 +198,37 @@ public class LoanChargeData { this.minCap = null; this.maxCap = null; this.installmentChargeData = installmentChargeData; + this.amountAccrued = null; + } + + public LoanChargeData(final Long id, final Long chargeId, final LocalDate dueAsOfDate, EnumOptionData chargeTimeType, + final BigDecimal amount, final BigDecimal amountAccrued, final BigDecimal amountWaived, final boolean penalty) { + this.id = id; + this.chargeId = chargeId; + this.name = null; + this.currency = null; + this.amount = amount; + this.amountPaid = null; + this.amountWaived = amountWaived; + this.amountWrittenOff = null; + this.amountOutstanding = null; + this.chargeTimeType = chargeTimeType; + this.dueDate = dueAsOfDate; + this.chargeCalculationType = null; + this.percentage = null; + this.amountPercentageAppliedTo = null; + this.penalty = penalty; + this.chargePaymentMode = null; + this.paid = false; + this.waived = false; + this.amountOrPercentage = null; + this.chargeOptions = null; + this.chargePayable = false; + this.loanId = null; + this.minCap = null; + this.maxCap = null; + this.installmentChargeData = null; + this.amountAccrued = amountAccrued; } public LoanChargeData(LoanChargeData chargeData, Collection installmentChargeData) { @@ -223,6 +257,7 @@ public class LoanChargeData { this.chargePayable = chargeData.chargePayable; this.loanId = chargeData.loanId; this.installmentChargeData = installmentChargeData; + this.amountAccrued = chargeData.amountAccrued; } public LoanChargeData(final Long id, final LocalDate dueAsOfDate, final BigDecimal amountOrPercentage) { @@ -251,6 +286,7 @@ public class LoanChargeData { this.minCap = null; this.maxCap = null; this.installmentChargeData = null; + this.amountAccrued = null; } public boolean isChargePayable() { @@ -288,4 +324,33 @@ public class LoanChargeData { public BigDecimal amountOrPercentage() { return this.amountOrPercentage; } + + public Collection getInstallmentChargeData() { + return this.installmentChargeData; + } + + public boolean isPenalty() { + return this.penalty; + } + + public BigDecimal getAmount() { + return this.amount; + } + + public BigDecimal getAmountAccrued() { + return this.amountAccrued; + } + + public void updateAmountAccrued(BigDecimal amountAccrued) { + this.amountAccrued = amountAccrued; + } + + public Long getChargeId() { + return this.chargeId; + } + + + public BigDecimal getAmountWaived() { + return this.amountWaived; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanInstallmentChargeData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanInstallmentChargeData.java index c0158d009..0a98443d7 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanInstallmentChargeData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanInstallmentChargeData.java @@ -13,20 +13,21 @@ public class LoanInstallmentChargeData { private final Integer installmentNumber; private final LocalDate dueDate; - @SuppressWarnings("unused") private final BigDecimal amount; private final BigDecimal amountOutstanding; + private final BigDecimal amountWaived; private final boolean paid; private final boolean waived; public LoanInstallmentChargeData(final Integer installmentNumber, final LocalDate dueDate, final BigDecimal amount, - final BigDecimal amountOutstanding, final boolean paid, final boolean waived) { + final BigDecimal amountOutstanding, BigDecimal amountWaived, final boolean paid, final boolean waived) { this.installmentNumber = installmentNumber; this.dueDate = dueDate; this.amount = amount; this.amountOutstanding = amountOutstanding; this.paid = paid; this.waived = waived; + this.amountWaived = amountWaived; } public Integer getInstallmentNumber() { @@ -45,4 +46,12 @@ public class LoanInstallmentChargeData { return this.amountOutstanding; } + public BigDecimal getAmount() { + return this.amount; + } + + public BigDecimal getAmountWaived() { + return this.amountWaived; + } + } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanScheduleAccrualData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanScheduleAccrualData.java index 7d53d34a2..7602c5064 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanScheduleAccrualData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanScheduleAccrualData.java @@ -7,6 +7,7 @@ package org.mifosplatform.portfolio.loanaccount.data; import java.math.BigDecimal; import java.util.Date; +import java.util.Map; import org.joda.time.LocalDate; import org.mifosplatform.organisation.monetary.data.CurrencyData; @@ -19,8 +20,7 @@ public class LoanScheduleAccrualData { private final LocalDate accruedTill; private final PeriodFrequencyType repaymentFrequency; private final Integer repayEvery; - private final Integer numberOfDaysInYear; - private final Integer numberOfDaysInMonth; + private final Integer installmentNumber; private final LocalDate dueDate; private final LocalDate fromDate; private final Long repaymentScheduleId; @@ -32,22 +32,21 @@ public class LoanScheduleAccrualData { private final BigDecimal accruedFeeIncome; private final BigDecimal accruedPenaltyIncome; private final CurrencyData currencyData; - private final BigDecimal dueDateFeeIncome; - private final BigDecimal dueDatePenaltyIncome; private final LocalDate interestCalculatedFrom; - public LoanScheduleAccrualData(final Long loanId, final Long officeId, final LocalDate accruedTill, final Integer numberOfDaysInMonth, - final Integer numberOfDaysInYear, final PeriodFrequencyType repaymentFrequency, final Integer repayEvery, - final LocalDate dueDate, final LocalDate fromDate, final Long repaymentScheduleId, final Long loanProductId, - final BigDecimal interestIncome, final BigDecimal feeIncome, final BigDecimal penaltyIncome, - final BigDecimal accruedInterestIncome, final BigDecimal accruedFeeIncome, final BigDecimal accruedPenaltyIncome, - final CurrencyData currencyData, final BigDecimal dueDateFeeIncome, final BigDecimal dueDatePenaltyIncome, - final LocalDate interestCalculatedFrom) { + private Map applicableCharges; + private BigDecimal dueDateFeeIncome; + private BigDecimal dueDatePenaltyIncome; + + public LoanScheduleAccrualData(final Long loanId, final Long officeId, final Integer installmentNumber, final LocalDate accruedTill, + final PeriodFrequencyType repaymentFrequency, final Integer repayEvery, final LocalDate dueDate, final LocalDate fromDate, + final Long repaymentScheduleId, final Long loanProductId, final BigDecimal interestIncome, final BigDecimal feeIncome, + final BigDecimal penaltyIncome, final BigDecimal accruedInterestIncome, final BigDecimal accruedFeeIncome, + final BigDecimal accruedPenaltyIncome, final CurrencyData currencyData, final LocalDate interestCalculatedFrom) { this.loanId = loanId; + this.installmentNumber = installmentNumber; this.officeId = officeId; this.accruedTill = accruedTill; - this.numberOfDaysInMonth = numberOfDaysInMonth; - this.numberOfDaysInYear = numberOfDaysInYear; this.dueDate = dueDate; this.fromDate = fromDate; this.repaymentScheduleId = repaymentScheduleId; @@ -61,8 +60,6 @@ public class LoanScheduleAccrualData { this.currencyData = currencyData; this.repaymentFrequency = repaymentFrequency; this.repayEvery = repayEvery; - this.dueDateFeeIncome = dueDateFeeIncome; - this.dueDatePenaltyIncome = dueDatePenaltyIncome; this.interestCalculatedFrom = interestCalculatedFrom; } @@ -122,14 +119,6 @@ public class LoanScheduleAccrualData { return this.accruedTill; } - public Integer getNumberOfDaysInYear() { - return this.numberOfDaysInYear; - } - - public Integer getNumberOfDaysInMonth() { - return this.numberOfDaysInMonth; - } - public LocalDate getFromDateAsLocaldate() { return this.fromDate; } @@ -142,6 +131,18 @@ public class LoanScheduleAccrualData { return this.repayEvery; } + public LocalDate getInterestCalculatedFrom() { + return this.interestCalculatedFrom; + } + + public Integer getInstallmentNumber() { + return this.installmentNumber; + } + + public Map getApplicableCharges() { + return this.applicableCharges; + } + public BigDecimal getDueDateFeeIncome() { return this.dueDateFeeIncome; } @@ -150,9 +151,11 @@ public class LoanScheduleAccrualData { return this.dueDatePenaltyIncome; } - - public LocalDate getInterestCalculatedFrom() { - return this.interestCalculatedFrom; + public void updateChargeDetails(final Map applicableCharges, final BigDecimal dueDateFeeIncome, + final BigDecimal dueDatePenaltyIncome) { + this.applicableCharges = applicableCharges; + this.dueDateFeeIncome = dueDateFeeIncome; + this.dueDatePenaltyIncome = dueDatePenaltyIncome; } } 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 0dc50aa1d..45ef75b45 100755 --- 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 @@ -592,6 +592,9 @@ public class Loan extends AbstractPersistable { final LoanTransaction applyLoanChargeTransaction = LoanTransaction.accrueLoanCharge(this, getOffice(), chargeAmount, transactionDate, feeCharges, penaltyCharges); + final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(applyLoanChargeTransaction, loanCharge, loanCharge.getAmount( + getCurrency()).getAmount()); + applyLoanChargeTransaction.getLoanChargesPaid().add(loanChargePaidBy); this.loanTransactions.add(applyLoanChargeTransaction); return applyLoanChargeTransaction; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java index ad8d7793e..b3528ddf8 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java @@ -40,8 +40,6 @@ import org.mifosplatform.portfolio.calendar.domain.CalendarInstanceRepository; import org.mifosplatform.portfolio.calendar.service.CalendarUtils; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.exception.ClientNotActiveException; -import org.mifosplatform.portfolio.common.domain.DaysInMonthType; -import org.mifosplatform.portfolio.common.domain.DaysInYearType; import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.exception.GroupNotActiveException; @@ -414,8 +412,12 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { return calculatedRepaymentsStartingFromDate; } - /* (non-Javadoc) - * @see org.mifosplatform.portfolio.loanaccount.domain.LoanAccountDomainService#recalculateAccruals(org.mifosplatform.portfolio.loanaccount.domain.Loan) + /* + * (non-Javadoc) + * + * @see + * org.mifosplatform.portfolio.loanaccount.domain.LoanAccountDomainService + * #recalculateAccruals(org.mifosplatform.portfolio.loanaccount.domain.Loan) */ @Override public void recalculateAccruals(Loan loan) { @@ -424,8 +426,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { Collection loanScheduleAccrualDatas = new ArrayList<>(); List installments = loan.fetchRepaymentScheduleInstallments(); Long loanId = loan.getId(); - DaysInMonthType daysInMonth = loan.repaymentScheduleDetail().fetchDaysInMonthType(); - DaysInYearType daysInYear = loan.repaymentScheduleDetail().fetchDaysInYearType(); Long officeId = loan.getOfficeId(); LocalDate accrualStartDate = null; PeriodFrequencyType repaymentFrequency = loan.repaymentScheduleDetail().getRepaymentPeriodFrequencyType(); @@ -459,12 +459,11 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } } } - LoanScheduleAccrualData accrualData = new LoanScheduleAccrualData(loanId, officeId, accrualStartDate, - daysInMonth.getValue(), daysInYear.getValue(), repaymentFrequency, repayEvery, installment.getDueDate(), - installment.getFromDate(), installment.getId(), loanProductId, - installment.getInterestCharged(currency).getAmount(), installment.getFeeChargesCharged(currency).getAmount(), - installment.getPenaltyChargesCharged(currency).getAmount(), accruedInterestIncome, accruedFeeIncome, - accruedPenaltyIncome, currencyData, dueDateFeeIncome, dueDatePenaltyIncome, interestCalculatedFrom); + LoanScheduleAccrualData accrualData = new LoanScheduleAccrualData(loanId, officeId, installment.getInstallmentNumber(), + accrualStartDate, repaymentFrequency, repayEvery, installment.getDueDate(), installment.getFromDate(), + installment.getId(), loanProductId, installment.getInterestCharged(currency).getAmount(), installment + .getFeeChargesCharged(currency).getAmount(), installment.getPenaltyChargesCharged(currency).getAmount(), + accruedInterestIncome, accruedFeeIncome, accruedPenaltyIncome, currencyData, interestCalculatedFrom); loanScheduleAccrualDatas.add(accrualData); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java index 583094ae8..4d3b7418a 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java @@ -9,6 +9,7 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -24,6 +25,8 @@ import org.mifosplatform.infrastructure.core.service.RoutingDataSource; import org.mifosplatform.infrastructure.jobs.annotation.CronTarget; import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException; import org.mifosplatform.infrastructure.jobs.service.JobName; +import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData; +import org.mifosplatform.portfolio.loanaccount.data.LoanInstallmentChargeData; import org.mifosplatform.portfolio.loanaccount.data.LoanScheduleAccrualData; import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData; import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType; @@ -40,6 +43,7 @@ import org.springframework.transaction.support.DefaultTransactionDefinition; public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlatformService { private final LoanReadPlatformService loanReadPlatformService; + private final LoanChargeReadPlatformService loanChargeReadPlatformService; private final JdbcTemplate jdbcTemplate; private final DataSource dataSource; private final JournalEntryWritePlatformService journalEntryWritePlatformService; @@ -47,12 +51,14 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat @Autowired public LoanAccrualWritePlatformServiceImpl(final RoutingDataSource dataSource, final LoanReadPlatformService loanReadPlatformService, - final JournalEntryWritePlatformService journalEntryWritePlatformService, final JpaTransactionManager transactionManager) { + final JournalEntryWritePlatformService journalEntryWritePlatformService, final JpaTransactionManager transactionManager, + final LoanChargeReadPlatformService loanChargeReadPlatformService) { this.loanReadPlatformService = loanReadPlatformService; this.dataSource = dataSource; this.jdbcTemplate = new JdbcTemplate(this.dataSource); this.journalEntryWritePlatformService = journalEntryWritePlatformService; this.transactionManager = transactionManager; + this.loanChargeReadPlatformService = loanChargeReadPlatformService; } @Override @@ -61,9 +67,17 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat Collection loanScheduleAccrualDatas = this.loanReadPlatformService.retriveScheduleAccrualData(); StringBuilder sb = new StringBuilder(); Set loansIds = new HashSet<>(); + Map> loanChargeMap = new HashMap<>(); for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) { try { if (!loansIds.contains(accrualData.getLoanId())) { + if (!loanChargeMap.containsKey(accrualData.getLoanId())) { + Collection chargeData = this.loanChargeReadPlatformService + .retrieveLoanChargesForAccural(accrualData.getLoanId()); + loanChargeMap.put(accrualData.getLoanId(), chargeData); + } + updateCharges(loanChargeMap.get(accrualData.getLoanId()), accrualData, accrualData.getFromDateAsLocaldate(), + accrualData.getDueDateAsLocaldate()); addAccrualAccounting(accrualData); } } catch (Exception e) { @@ -99,17 +113,27 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat Set loansIds = new HashSet<>(); LocalDate accruredTill = null; Long lastLoanId = null; + Map> loanChargeMap = new HashMap<>(); for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) { try { if (!loansIds.contains(accrualData.getLoanId())) { + if (!loanChargeMap.containsKey(accrualData.getLoanId())) { + Collection chargeData = this.loanChargeReadPlatformService + .retrieveLoanChargesForAccural(accrualData.getLoanId()); + loanChargeMap.put(accrualData.getLoanId(), chargeData); + } if (accrualData.getDueDateAsLocaldate().isAfter(tilldate)) { if (accruredTill == null || lastLoanId == null || !lastLoanId.equals(accrualData.getLoanId())) { accruredTill = accrualData.getAccruedTill(); } - if (accruredTill == null || accruredTill.isBefore(tilldate)) { + if (accruredTill == null || accruredTill.isBefore(tilldate)) { + updateCharges(loanChargeMap.get(accrualData.getLoanId()), accrualData, accrualData.getFromDateAsLocaldate(), + tilldate); addAccrualTillSpecificDate(tilldate, accrualData, accruredTill); } } else { + updateCharges(loanChargeMap.get(accrualData.getLoanId()), accrualData, accrualData.getFromDateAsLocaldate(), + accrualData.getDueDateAsLocaldate()); addAccrualAccounting(accrualData); accruredTill = accrualData.getDueDateAsLocaldate(); } @@ -131,10 +155,8 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat private void addAccrualTillSpecificDate(final LocalDate tilldate, final LoanScheduleAccrualData accrualData, final LocalDate accruredTill) throws Exception { LocalDate interestStartDate = accrualData.getFromDateAsLocaldate(); - // boolean isInterestStartDateEqulsInstallmentStartdate = true; if (accrualData.getInterestCalculatedFrom() != null && accrualData.getFromDateAsLocaldate().isBefore(accrualData.getInterestCalculatedFrom())) { - // isInterestStartDateEqulsInstallmentStartdate = false; if (accrualData.getInterestCalculatedFrom().isBefore(accrualData.getDueDateAsLocaldate())) { interestStartDate = accrualData.getInterestCalculatedFrom(); } else { @@ -155,21 +177,6 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat } } int daysToBeAccrued = Days.daysBetween(startDate, tilldate).getDays(); - // if (daysToBeAccrued < 1) { return; } -// int daysInSchedule = Days.daysBetween(interestStartDate, tilldate).getDays(); - /* - * switch (accrualData.getRepaymentFrequency()) { case MONTHS: int - * numberOfDaysInMonth = - * calculateTotalNumberOfDaysForMonth(totalNumberOfDays, accrualData); - * if (!(!isInterestStartDateEqulsInstallmentStartdate && - * totalNumberOfDays < numberOfDaysInMonth)) { totalNumberOfDays = - * numberOfDaysInMonth; } break; case YEARS: int numberOfDaysinYear = - * calculateTotalNumberOfDaysForYear(totalNumberOfDays, accrualData); if - * (!(!isInterestStartDateEqulsInstallmentStartdate && totalNumberOfDays - * < numberOfDaysinYear)) { totalNumberOfDays = numberOfDaysinYear; } - * break; default: break; } - */ - double interestPerDay = accrualData.getInterestIncome().doubleValue() / totalNumberOfDays; BigDecimal amount = BigDecimal.ZERO; BigDecimal interestportion = null; @@ -182,23 +189,22 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat interestportion = BigDecimal.valueOf(iterest); } interestportion = interestportion.setScale(accrualData.getCurrencyData().decimalPlaces(), RoundingMode.HALF_EVEN); - amount = amount.add(interestportion); BigDecimal totalAccInterest = accrualData.getAccruedInterestIncome(); BigDecimal totalAccPenalty = accrualData.getAccruedPenaltyIncome(); BigDecimal totalAccFee = accrualData.getAccruedFeeIncome(); - if (startDate.isEqual(accrualData.getFromDateAsLocaldate())) { - totalAccInterest = null; - totalAccPenalty = null; - totalAccFee = null; + if (interestportion != null) { + if (totalAccInterest == null) { + totalAccInterest = BigDecimal.ZERO; + } + interestportion = interestportion.subtract(totalAccInterest); + amount = amount.add(interestportion); + totalAccInterest = totalAccInterest.add(interestportion); + if (interestportion.compareTo(BigDecimal.ZERO) == 0) { + interestportion = null; + } } - - if (totalAccInterest == null) { - totalAccInterest = BigDecimal.ZERO; - } - totalAccInterest = totalAccInterest.add(interestportion); - if (feeportion != null) { if (totalAccFee == null) { totalAccFee = BigDecimal.ZERO; @@ -228,24 +234,6 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat } } - /* - * private int calculateTotalNumberOfDaysForMonth(final int - * totalNumberOfDays, final LoanScheduleAccrualData accrualData) { int - * numberOfDays = totalNumberOfDays; DaysInMonthType type = - * DaysInMonthType.fromInt(accrualData.getNumberOfDaysInMonth()); switch - * (type) { case DAYS_30: numberOfDays = 30 * accrualData.getRepayEvery(); - * break; default: break; } return numberOfDays; } - * - * private int calculateTotalNumberOfDaysForYear(final int - * totalNumberOfDays, final LoanScheduleAccrualData accrualData) { int - * numberOfDays = totalNumberOfDays; DaysInYearType type = - * DaysInYearType.fromInt(accrualData.getNumberOfDaysInMonth()); switch - * (type) { case DAYS_360: numberOfDays = 360 * accrualData.getRepayEvery(); - * break; case DAYS_364: numberOfDays = 364 * accrualData.getRepayEvery(); - * break; case DAYS_365: numberOfDays = 365 * accrualData.getRepayEvery(); - * break; default: break; } return numberOfDays; } - */ - @Transactional public void addAccrualAccounting(LoanScheduleAccrualData scheduleAccrualData) throws Exception { @@ -306,6 +294,13 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat LoanTransactionType.ACCRUAL.getValue(), accruredTill.toDate(), amount, interestportion, feeportion, penaltyportion); final Long transactonId = this.jdbcTemplate.queryForLong("SELECT LAST_INSERT_ID()"); + Map applicableCharges = scheduleAccrualData.getApplicableCharges(); + String chargespaidSql = "INSERT INTO m_loan_charge_paid_by (loan_transaction_id, loan_charge_id, amount) VALUES (?,?,?)"; + for (Map.Entry entry : applicableCharges.entrySet()) { + LoanChargeData chargeData = entry.getKey(); + this.jdbcTemplate.update(chargespaidSql, transactonId, chargeData.getId(), entry.getValue()); + } + Map transactionMap = toMapData(transactonId, amount, interestportion, feeportion, penaltyportion, scheduleAccrualData, accruredTill); @@ -365,7 +360,86 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat thisTransactionData.put("penaltyChargesPortion", penaltyportion); thisTransactionData.put("overPaymentPortion", null); + Map applicableCharges = loanScheduleAccrualData.getApplicableCharges(); + if (applicableCharges != null && !applicableCharges.isEmpty()) { + final List> loanChargesPaidData = new ArrayList<>(); + for (Map.Entry entry : applicableCharges.entrySet()) { + LoanChargeData chargeData = entry.getKey(); + final Map loanChargePaidData = new LinkedHashMap<>(); + loanChargePaidData.put("chargeId", chargeData.getChargeId()); + loanChargePaidData.put("isPenalty", chargeData.isPenalty()); + loanChargePaidData.put("loanChargeId", chargeData.getId()); + loanChargePaidData.put("amount", entry.getValue()); + + loanChargesPaidData.add(loanChargePaidData); + } + thisTransactionData.put("loanChargesPaid", loanChargesPaidData); + } + return thisTransactionData; } + private void updateCharges(final Collection chargesData, final LoanScheduleAccrualData accrualData, + final LocalDate startDate, final LocalDate endDate) { + + final Map applicableCharges = new HashMap<>(); + BigDecimal dueDateFeeIncome = BigDecimal.ZERO; + BigDecimal dueDatePenaltyIncome = BigDecimal.ZERO; + for (LoanChargeData loanCharge : chargesData) { + BigDecimal chargeAmount = BigDecimal.ZERO; + if (loanCharge.getDueDate() == null) { + if (loanCharge.isInstallmentFee() && accrualData.getDueDateAsLocaldate().isEqual(endDate)) { + BigDecimal accruedAmount = BigDecimal.ZERO; + Collection installmentData = loanCharge.getInstallmentChargeData(); + for (LoanInstallmentChargeData installmentChargeData : installmentData) { + BigDecimal accruableForInstallment = installmentChargeData.getAmount(); + if (installmentChargeData.getAmountWaived() != null) { + accruableForInstallment = accruableForInstallment.subtract(installmentChargeData.getAmountWaived()); + } + + if (installmentChargeData.getInstallmentNumber().equals(accrualData.getInstallmentNumber())) { + chargeAmount = accruableForInstallment; + boolean canAddCharge = chargeAmount.compareTo(BigDecimal.ZERO) == 1; + if (canAddCharge + && (loanCharge.getAmountAccrued() == null || loanCharge.getAmountAccrued().compareTo(accruedAmount) == 0)) { + applicableCharges.put(loanCharge, chargeAmount); + BigDecimal amountAccrued = chargeAmount; + if (loanCharge.getAmountAccrued() != null) { + amountAccrued = amountAccrued.add(loanCharge.getAmountAccrued()); + } + loanCharge.updateAmountAccrued(amountAccrued); + } + break; + } + accruedAmount = accruedAmount.add(accruableForInstallment); + } + } + } else if (loanCharge.getDueDate().isAfter(startDate) && !loanCharge.getDueDate().isAfter(endDate)) { + chargeAmount = loanCharge.getAmount(); + if (loanCharge.getAmountWaived() != null) { + chargeAmount = chargeAmount.subtract(loanCharge.getAmountWaived()); + } + boolean canAddCharge = chargeAmount.compareTo(BigDecimal.ZERO) == 1; + if (canAddCharge && loanCharge.getAmountAccrued() == null) { + applicableCharges.put(loanCharge, chargeAmount); + } + } + + if (loanCharge.isPenalty()) { + dueDatePenaltyIncome = dueDatePenaltyIncome.add(chargeAmount); + } else { + dueDateFeeIncome = dueDateFeeIncome.add(chargeAmount); + } + } + + if (dueDateFeeIncome.compareTo(BigDecimal.ZERO) == 0) { + dueDateFeeIncome = null; + } + + if (dueDatePenaltyIncome.compareTo(BigDecimal.ZERO) == 0) { + dueDatePenaltyIncome = null; + } + + accrualData.updateChargeDetails(applicableCharges, dueDateFeeIncome, dueDatePenaltyIncome); + } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformService.java index 722d1b829..0f6edd50b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformService.java @@ -24,4 +24,6 @@ public interface LoanChargeReadPlatformService { Collection retrieveInstallmentLoanCharges(Long loanChargeId, boolean onlyPaymentPendingCharges); Collection retrieveOverdueInstallmentChargeFrequencyNumber(Long loanId, Long chargeId, Integer periodNumber); + + Collection retrieveLoanChargesForAccural(Long loanId); } 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 c7553cdc0..d27fe7fc7 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 @@ -8,6 +8,7 @@ package org.mifosplatform.portfolio.loanaccount.service; import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -23,6 +24,7 @@ import org.mifosplatform.portfolio.charge.service.ChargeEnumerations; import org.mifosplatform.portfolio.common.service.DropdownReadPlatformService; import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData; import org.mifosplatform.portfolio.loanaccount.data.LoanInstallmentChargeData; +import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; @@ -208,7 +210,7 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform public String schema() { return " lsi.installment as installmentNumber, lsi.duedate as dueAsOfDate, " + "lic.amount_outstanding_derived as amountOutstanding," + "lic.amount as amount, " + "lic.is_paid_derived as paid, " - + "lic.waived as waied " + "from m_loan_installment_charge lic " + + "lic.amount_waived_derived as amountWaived, " + "lic.waived as waied " + "from m_loan_installment_charge lic " + "join m_loan_repayment_schedule lsi on lsi.id = lic.loan_schedule_id "; } @@ -218,10 +220,11 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform final LocalDate dueAsOfDate = JdbcSupport.getLocalDate(rs, "dueAsOfDate"); final BigDecimal amountOutstanding = rs.getBigDecimal("amountOutstanding"); final BigDecimal amount = rs.getBigDecimal("amount"); + final BigDecimal amountWaived = rs.getBigDecimal("amountWaived"); final boolean paid = rs.getBoolean("paid"); final boolean waived = rs.getBoolean("waied"); - return new LoanInstallmentChargeData(installmentNumber, dueAsOfDate, amount, amountOutstanding, paid, waived); + return new LoanInstallmentChargeData(installmentNumber, dueAsOfDate, amount, amountOutstanding, amountWaived, paid, waived); } } @@ -237,4 +240,80 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform } return this.jdbcTemplate.queryForList(sql, Integer.class, params); } + + @Override + public Collection retrieveLoanChargesForAccural(final Long loanId) { + + final LoanChargeAccrualMapper rm = new LoanChargeAccrualMapper(); + + final String sql = "select " + rm.schema() + " where lc.loan_id=? AND lc.is_active = 1 group by lc.id " + + " order by lc.charge_time_enum ASC, lc.due_for_collection_as_of_date ASC, lc.is_penalty ASC"; + + Collection charges = this.jdbcTemplate.query(sql, rm, + new Object[] { LoanTransactionType.ACCRUAL.getValue(), loanId }); + + Collection removeCharges = new ArrayList<>(); + for (LoanChargeData loanChargeData : charges) { + if (loanChargeData.isInstallmentFee()) { + removeCharges.add(loanChargeData); + } + } + charges.removeAll(removeCharges); + for (LoanChargeData loanChargeData : removeCharges) { + if (loanChargeData.isInstallmentFee()) { + Collection installmentChargeDatas = retrieveInstallmentLoanCharges(loanChargeData.getId(), false); + LoanChargeData modifiedChargeData = new LoanChargeData(loanChargeData, installmentChargeDatas); + charges.add(modifiedChargeData); + } + } + + return charges; + } + + private static final class LoanChargeAccrualMapper implements RowMapper { + + private final String schemaSql; + + public LoanChargeAccrualMapper() { + StringBuilder sb = new StringBuilder(50); + sb.append("lc.id as id, lc.charge_id as chargeId, "); + sb.append("lc.amount as amountDue, "); + sb.append("lc.amount_waived_derived as amountWaived, "); + sb.append("lc.charge_time_enum as chargeTime, "); + sb.append(" sum(cp.amount) as amountAccrued, "); + sb.append("lc.is_penalty as penalty, "); + sb.append("lc.due_for_collection_as_of_date as dueAsOfDate "); + sb.append(" from m_loan_charge lc "); + sb.append("left join ("); + sb.append("select lcp.loan_charge_id, lcp.amount"); + sb.append(" from m_loan_charge_paid_by lcp "); + sb.append("inner join m_loan_transaction lt on lt.id = lcp.loan_transaction_id and lt.is_reversed = 0 and lt.transaction_type_enum = ?"); + sb.append(") cp on cp.loan_charge_id= lc.id "); + + schemaSql = sb.toString(); + } + + public String schema() { + return this.schemaSql; + } + + @Override + public LoanChargeData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = rs.getLong("id"); + final Long chargeId = rs.getLong("chargeId"); + final BigDecimal amount = rs.getBigDecimal("amountDue"); + final BigDecimal amountAccrued = rs.getBigDecimal("amountAccrued"); + final BigDecimal amountWaived = rs.getBigDecimal("amountWaived"); + + final int chargeTime = rs.getInt("chargeTime"); + final EnumOptionData chargeTimeType = ChargeEnumerations.chargeTimeType(chargeTime); + + final LocalDate dueAsOfDate = JdbcSupport.getLocalDate(rs, "dueAsOfDate"); + final boolean penalty = rs.getBoolean("penalty"); + + return new LoanChargeData(id, chargeId, dueAsOfDate, chargeTimeType, amount, amountAccrued, amountWaived, penalty); + } + } + } 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 ce3223ad3..dac4f822a 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 @@ -1448,11 +1448,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { .append("loan.id as loanId ,if(loan.client_id is null,mg.office_id,mc.office_id) as officeId,") .append("loan.accrued_till as accruedTill, loan.repayment_period_frequency_enum as frequencyEnum, ") .append("loan.interest_calculated_from_date as interestCalculatedFrom, ") - .append("loan.days_in_month_enum as daysInMonth, ") - .append("loan.days_in_year_enum as daysInYear, ") .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 = 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("ls.installment as installmentNumber, ") .append("ls.duedate as duedate,ls.fromdate as fromdate ,ls.id as scheduleId,loan.product_id as productId,") .append("if(ls.interest_waived_derived is null,ls.interest_amount,(ls.interest_amount-ls.interest_waived_derived)) as interest,") .append("if(ls.penalty_charges_waived_derived is null , ls.penalty_charges_amount,(ls.penalty_charges_amount-ls.penalty_charges_waived_derived)) as penalty,") @@ -1474,10 +1471,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final Long officeId = rs.getLong("officeId"); final LocalDate accruedTill = JdbcSupport.getLocalDate(rs, "accruedTill"); final LocalDate interestCalculatedFrom = JdbcSupport.getLocalDate(rs, "interestCalculatedFrom"); - final Integer numberOfDaysInMonth = JdbcSupport.getInteger(rs, "daysInMonth"); - ; - final Integer numberOfDaysInYear = JdbcSupport.getInteger(rs, "daysInYear"); - ; + final Integer installmentNumber = JdbcSupport.getInteger(rs, "installmentNumber"); + final Integer frequencyEnum = JdbcSupport.getInteger(rs, "frequencyEnum"); final Integer repayEvery = JdbcSupport.getInteger(rs, "repayEvery"); final PeriodFrequencyType frequency = PeriodFrequencyType.fromInt(frequencyEnum); @@ -1501,12 +1496,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final CurrencyData currencyData = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, currencyDisplaySymbol, currencyNameCode); - final BigDecimal dueDateFeeIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "feedueIn"); - final BigDecimal dueDatePenaltyIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "penalitydueIn"); - return new LoanScheduleAccrualData(loanId, officeId, accruedTill, numberOfDaysInMonth, numberOfDaysInYear, frequency, - repayEvery, dueDate, fromDate, repaymentScheduleId, loanProductId, interestIncome, feeIncome, penaltyIncome, - accruedInterestIncome, accruedFeeIncome, accruedPenaltyIncome, currencyData, dueDateFeeIncome, dueDatePenaltyIncome, - interestCalculatedFrom); + return new LoanScheduleAccrualData(loanId, officeId, installmentNumber, accruedTill, frequency, repayEvery, dueDate, fromDate, + repaymentScheduleId, loanProductId, interestIncome, feeIncome, penaltyIncome, accruedInterestIncome, accruedFeeIncome, + accruedPenaltyIncome, currencyData, interestCalculatedFrom); } } @@ -1517,7 +1509,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final StringBuilder sqlBuilder = new StringBuilder(400); sqlBuilder .append("loan.id as loanId ,if(loan.client_id is null,mg.office_id,mc.office_id) as officeId,") - .append("ls.duedate as duedate,ls.id as scheduleId,loan.product_id as productId,") + .append("ls.duedate as duedate,ls.fromdate as fromdate,ls.id as scheduleId,loan.product_id as productId,") + .append("ls.installment as installmentNumber, ") .append("if(ls.interest_waived_derived is null,ls.interest_amount,(ls.interest_amount-ls.interest_waived_derived)) as interest,") .append("if(ls.penalty_charges_waived_derived is null , ls.penalty_charges_amount,(ls.penalty_charges_amount-ls.penalty_charges_waived_derived)) as penalty,") .append("if(ls.fee_charges_waived_derived is null , ls.fee_charges_amount,(ls.fee_charges_amount-ls.fee_charges_waived_derived)) as charges,") @@ -1536,7 +1529,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final Long loanId = rs.getLong("loanId"); final Long officeId = rs.getLong("officeId"); + final Integer installmentNumber = JdbcSupport.getInteger(rs, "installmentNumber"); final LocalDate dueDate = JdbcSupport.getLocalDate(rs, "duedate"); + final LocalDate fromdate = JdbcSupport.getLocalDate(rs, "fromdate"); final Long repaymentScheduleId = rs.getLong("scheduleId"); final Long loanProductId = rs.getLong("productId"); final BigDecimal interestIncome = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "interest"); @@ -1555,18 +1550,12 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final CurrencyData currencyData = new CurrencyData(currencyCode, currencyName, currencyDigits, inMultiplesOf, currencyDisplaySymbol, currencyNameCode); final LocalDate accruedTill = null; - final Integer numberOfDaysInMonth = null; - final Integer numberOfDaysInYear = null; final PeriodFrequencyType frequency = null; final Integer repayEvery = null; - final LocalDate fromDate = null; - final BigDecimal dueDateFeeincome = null; - final BigDecimal dueDatePenaltyIncome = null; final LocalDate interestCalculatedFrom = null; - return new LoanScheduleAccrualData(loanId, officeId, accruedTill, numberOfDaysInMonth, numberOfDaysInYear, frequency, - repayEvery, dueDate, fromDate, repaymentScheduleId, loanProductId, interestIncome, feeIncome, penaltyIncome, - accruedInterestIncome, accruedFeeIncome, accruedPenaltyIncome, currencyData, dueDateFeeincome, dueDatePenaltyIncome, - interestCalculatedFrom); + return new LoanScheduleAccrualData(loanId, officeId, installmentNumber, accruedTill, frequency, repayEvery, dueDate, fromdate, + repaymentScheduleId, loanProductId, interestIncome, feeIncome, penaltyIncome, accruedInterestIncome, accruedFeeIncome, + accruedPenaltyIncome, currencyData, interestCalculatedFrom); } } @@ -1609,7 +1598,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { sqlBuilder.append(" group by ml.id"); try { return this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class, - new Object[] { LoanStatus.ACTIVE.getValue(), formatter.print(LocalDate.now()),formatter.print(LocalDate.now()) }); + new Object[] { LoanStatus.ACTIVE.getValue(), formatter.print(LocalDate.now()), formatter.print(LocalDate.now()) }); } catch (final EmptyResultDataAccessException e) { return null; }