Merge pull request #1049 from pramodn02/develop
MIFOSX-1418 : added regeneration of accrual entries
This commit is contained in:
+1
-1
@@ -810,7 +810,7 @@ public class AccountingScenarioIntegrationTest {
|
|||||||
.withRepaymentAfterEvery(this.LP_REPAYMENT_PERIOD).withNumberOfRepayments(this.LP_REPAYMENTS).withRepaymentTypeAsMonth()
|
.withRepaymentAfterEvery(this.LP_REPAYMENT_PERIOD).withNumberOfRepayments(this.LP_REPAYMENTS).withRepaymentTypeAsMonth()
|
||||||
.withinterestRatePerPeriod(this.LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
|
.withinterestRatePerPeriod(this.LP_INTEREST_RATE).withInterestRateFrequencyTypeAsMonths()
|
||||||
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRulePeriodicAccrual(accounts)
|
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRulePeriodicAccrual(accounts)
|
||||||
.build(null);
|
.withDaysInMonth("30").withDaysInYear("365").build(null);
|
||||||
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
return this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-1
@@ -31,7 +31,7 @@ public class LoanProductTestBuilder {
|
|||||||
public static final String MIFOS_STANDARD_STRATEGY = "1";
|
public static final String MIFOS_STANDARD_STRATEGY = "1";
|
||||||
// private static final String HEAVENS_FAMILY_STRATEGY ="2";
|
// private static final String HEAVENS_FAMILY_STRATEGY ="2";
|
||||||
// private static final String CREO_CORE_STRATEGY ="3";
|
// private static final String CREO_CORE_STRATEGY ="3";
|
||||||
public static final String RBI_INDIA_STRATEGY ="4";
|
public static final String RBI_INDIA_STRATEGY = "4";
|
||||||
private static final String NONE = "1";
|
private static final String NONE = "1";
|
||||||
private static final String CASH_BASED = "2";
|
private static final String CASH_BASED = "2";
|
||||||
private static final String ACCRUAL_PERIODIC = "3";
|
private static final String ACCRUAL_PERIODIC = "3";
|
||||||
@@ -328,4 +328,13 @@ public class LoanProductTestBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanProductTestBuilder withDaysInMonth(final String daysInMonthType) {
|
||||||
|
this.daysInMonthType = daysInMonthType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoanProductTestBuilder withDaysInYear(final String daysInYearType) {
|
||||||
|
this.daysInYearType = daysInYearType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-2
@@ -984,9 +984,36 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
updateLoanScheduleDependentDerivedFields();
|
updateLoanScheduleDependentDerivedFields();
|
||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
|
resetAccruals();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* method to reverse all the accrual entries
|
||||||
|
*/
|
||||||
|
private void resetAccruals() {
|
||||||
|
if (!this.repaymentScheduleDetail().isInterestRecalculationEnabled()) { return; }
|
||||||
|
List<LoanTransaction> transactions = this.getLoanTransactions();
|
||||||
|
for (final LoanTransaction transaction : transactions) {
|
||||||
|
if (transaction.isAccrual()) {
|
||||||
|
transaction.reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAccrualsPresent() {
|
||||||
|
boolean isAccrualsPresent = false;
|
||||||
|
if (!this.repaymentScheduleDetail().isInterestRecalculationEnabled()) { return isAccrualsPresent; }
|
||||||
|
List<LoanTransaction> transactions = this.getLoanTransactions();
|
||||||
|
for (final LoanTransaction transaction : transactions) {
|
||||||
|
if (transaction.isAccrual() && transaction.isNotReversed()) {
|
||||||
|
isAccrualsPresent = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isAccrualsPresent;
|
||||||
|
}
|
||||||
|
|
||||||
private void updateLoanScheduleDependentDerivedFields() {
|
private void updateLoanScheduleDependentDerivedFields() {
|
||||||
this.expectedMaturityDate = determineExpectedMaturityDate().toDate();
|
this.expectedMaturityDate = determineExpectedMaturityDate().toDate();
|
||||||
this.actualMaturityDate = determineExpectedMaturityDate().toDate();
|
this.actualMaturityDate = determineExpectedMaturityDate().toDate();
|
||||||
@@ -3218,7 +3245,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return matchesCurrentLoanOfficer;
|
return matchesCurrentLoanOfficer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDate getInterestChargedFromDate() {
|
public LocalDate getInterestChargedFromDate() {
|
||||||
LocalDate interestChargedFrom = null;
|
LocalDate interestChargedFrom = null;
|
||||||
if (this.interestChargedFromDate != null) {
|
if (this.interestChargedFromDate != null) {
|
||||||
interestChargedFrom = new LocalDate(this.interestChargedFromDate);
|
interestChargedFrom = new LocalDate(this.interestChargedFromDate);
|
||||||
@@ -3415,7 +3442,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return this.loanProduct.isPeriodicAccrualAccountingEnabled();
|
return this.loanProduct.isPeriodicAccrualAccountingEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Long productId() {
|
public Long productId() {
|
||||||
return this.loanProduct.getId();
|
return this.loanProduct.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4170,4 +4197,12 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
public List<LoanRepaymentScheduleInstallment> fetchRepaymentScheduleInstallments() {
|
public List<LoanRepaymentScheduleInstallment> fetchRepaymentScheduleInstallments() {
|
||||||
return this.repaymentScheduleInstallments;
|
return this.repaymentScheduleInstallments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalDate getAccruedTill() {
|
||||||
|
LocalDate accruedTill = null;
|
||||||
|
if (this.accruedTill != null) {
|
||||||
|
accruedTill = new LocalDate(this.accruedTill);
|
||||||
|
}
|
||||||
|
return accruedTill;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+9
@@ -30,4 +30,13 @@ public interface LoanAccountDomainService {
|
|||||||
PaymentDetail paymentDetail, String noteText, String txnExternalId);
|
PaymentDetail paymentDetail, String noteText, String txnExternalId);
|
||||||
|
|
||||||
LocalDate getCalculatedRepaymentsStartingFromDate(LocalDate actualDisbursementDate, Loan loan, CalendarInstance calendarInstance);
|
LocalDate getCalculatedRepaymentsStartingFromDate(LocalDate actualDisbursementDate, Loan loan, CalendarInstance calendarInstance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to recalculate and accrue the income till the last accrued
|
||||||
|
* date. this method is used when the schedule changes due to interest
|
||||||
|
* recalculation
|
||||||
|
*
|
||||||
|
* @param loan
|
||||||
|
*/
|
||||||
|
void recalculateAccruals(Loan loan);
|
||||||
}
|
}
|
||||||
|
|||||||
+75
-2
@@ -8,8 +8,10 @@ package org.mifosplatform.portfolio.loanaccount.domain;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
@@ -22,6 +24,7 @@ import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidation
|
|||||||
import org.mifosplatform.organisation.holiday.domain.Holiday;
|
import org.mifosplatform.organisation.holiday.domain.Holiday;
|
||||||
import org.mifosplatform.organisation.holiday.domain.HolidayRepository;
|
import org.mifosplatform.organisation.holiday.domain.HolidayRepository;
|
||||||
import org.mifosplatform.organisation.holiday.domain.HolidayStatusType;
|
import org.mifosplatform.organisation.holiday.domain.HolidayStatusType;
|
||||||
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
@@ -37,9 +40,14 @@ import org.mifosplatform.portfolio.calendar.domain.CalendarInstanceRepository;
|
|||||||
import org.mifosplatform.portfolio.calendar.service.CalendarUtils;
|
import org.mifosplatform.portfolio.calendar.service.CalendarUtils;
|
||||||
import org.mifosplatform.portfolio.client.domain.Client;
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
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.domain.Group;
|
||||||
import org.mifosplatform.portfolio.group.exception.GroupNotActiveException;
|
import org.mifosplatform.portfolio.group.exception.GroupNotActiveException;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.data.LoanScheduleAccrualData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.service.LoanAccrualWritePlatformService;
|
||||||
import org.mifosplatform.portfolio.loanaccount.service.LoanAssembler;
|
import org.mifosplatform.portfolio.loanaccount.service.LoanAssembler;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||||
import org.mifosplatform.portfolio.note.domain.Note;
|
import org.mifosplatform.portfolio.note.domain.Note;
|
||||||
@@ -68,6 +76,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
|
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
|
||||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||||
private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository;
|
private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository;
|
||||||
|
private final LoanAccrualWritePlatformService accrualWritePlatformService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanAccountDomainServiceJpa(final LoanAssembler loanAccountAssembler, final LoanRepository loanRepository,
|
public LoanAccountDomainServiceJpa(final LoanAssembler loanAccountAssembler, final LoanRepository loanRepository,
|
||||||
@@ -79,7 +88,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
final AccountTransferRepository accountTransferRepository, final LoanScheduleGeneratorFactory loanScheduleFactory,
|
final AccountTransferRepository accountTransferRepository, final LoanScheduleGeneratorFactory loanScheduleFactory,
|
||||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
||||||
final CalendarInstanceRepository calendarInstanceRepository,
|
final CalendarInstanceRepository calendarInstanceRepository,
|
||||||
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository) {
|
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository,
|
||||||
|
final LoanAccrualWritePlatformService accrualWritePlatformService) {
|
||||||
this.loanAccountAssembler = loanAccountAssembler;
|
this.loanAccountAssembler = loanAccountAssembler;
|
||||||
this.loanRepository = loanRepository;
|
this.loanRepository = loanRepository;
|
||||||
this.loanTransactionRepository = loanTransactionRepository;
|
this.loanTransactionRepository = loanTransactionRepository;
|
||||||
@@ -94,6 +104,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
this.applicationCurrencyRepository = applicationCurrencyRepository;
|
this.applicationCurrencyRepository = applicationCurrencyRepository;
|
||||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||||
this.repaymentScheduleInstallmentRepository = repaymentScheduleInstallmentRepository;
|
this.repaymentScheduleInstallmentRepository = repaymentScheduleInstallmentRepository;
|
||||||
|
this.accrualWritePlatformService = accrualWritePlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -187,6 +198,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
|
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
||||||
|
|
||||||
|
recalculateAccruals(loan);
|
||||||
builderResult.withEntityId(newRepaymentTransaction.getId()) //
|
builderResult.withEntityId(newRepaymentTransaction.getId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
@@ -270,6 +282,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
||||||
|
recalculateAccruals(loan);
|
||||||
return newPaymentTransaction;
|
return newPaymentTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +377,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
||||||
|
|
||||||
return disbursementTransaction;
|
return disbursementTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,6 +414,67 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
return calculatedRepaymentsStartingFromDate;
|
return calculatedRepaymentsStartingFromDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.mifosplatform.portfolio.loanaccount.domain.LoanAccountDomainService#recalculateAccruals(org.mifosplatform.portfolio.loanaccount.domain.Loan)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void recalculateAccruals(Loan loan) {
|
||||||
|
LocalDate accruedTill = loan.getAccruedTill();
|
||||||
|
if (!loan.repaymentScheduleDetail().isInterestRecalculationEnabled() || accruedTill == null || loan.isAccrualsPresent()) { return; }
|
||||||
|
Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas = new ArrayList<>();
|
||||||
|
List<LoanRepaymentScheduleInstallment> 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();
|
||||||
|
Integer repayEvery = loan.repaymentScheduleDetail().getRepayEvery();
|
||||||
|
LocalDate interestCalculatedFrom = loan.getInterestChargedFromDate();
|
||||||
|
Long loanProductId = loan.productId();
|
||||||
|
MonetaryCurrency currency = loan.getCurrency();
|
||||||
|
ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
||||||
|
CurrencyData currencyData = applicationCurrency.toData();
|
||||||
|
Set<LoanCharge> loanCharges = loan.charges();
|
||||||
|
BigDecimal accruedInterestIncome = null;
|
||||||
|
BigDecimal accruedFeeIncome = null;
|
||||||
|
BigDecimal accruedPenaltyIncome = null;
|
||||||
|
|
||||||
|
for (LoanRepaymentScheduleInstallment installment : installments) {
|
||||||
|
if (!accruedTill.isBefore(installment.getDueDate())
|
||||||
|
|| (accruedTill.isAfter(installment.getFromDate()) && !accruedTill.isAfter(installment.getDueDate()))) {
|
||||||
|
BigDecimal dueDateFeeIncome = BigDecimal.ZERO;
|
||||||
|
BigDecimal dueDatePenaltyIncome = BigDecimal.ZERO;
|
||||||
|
LocalDate chargesTillDate = installment.getDueDate();
|
||||||
|
if (!accruedTill.isAfter(installment.getDueDate())) {
|
||||||
|
chargesTillDate = accruedTill;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final LoanCharge loanCharge : loanCharges) {
|
||||||
|
if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(installment.getFromDate(), chargesTillDate)) {
|
||||||
|
if (loanCharge.isFeeCharge()) {
|
||||||
|
dueDateFeeIncome = dueDateFeeIncome.add(loanCharge.amount());
|
||||||
|
} else if (loanCharge.isPenaltyCharge()) {
|
||||||
|
dueDatePenaltyIncome = dueDatePenaltyIncome.add(loanCharge.amount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
loanScheduleAccrualDatas.add(accrualData);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loanScheduleAccrualDatas.isEmpty()) {
|
||||||
|
this.accrualWritePlatformService.addPeriodicAccruals(accruedTill, loanScheduleAccrualDatas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateLoanTransaction(final Long loanTransactionId, final LoanTransaction newLoanTransaction) {
|
private void updateLoanTransaction(final Long loanTransactionId, final LoanTransaction newLoanTransaction) {
|
||||||
final AccountTransferTransaction transferTransaction = this.accountTransferRepository.findByToLoanTransactionId(loanTransactionId);
|
final AccountTransferTransaction transferTransaction = this.accountTransferRepository.findByToLoanTransactionId(loanTransactionId);
|
||||||
if (transferTransaction != null) {
|
if (transferTransaction != null) {
|
||||||
|
|||||||
+36
-1
@@ -146,6 +146,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
loanApplicationTerms.getInterestChargedFromLocalDate(), loanApplicationTerms.getLoanTermPeriodFrequencyType(),
|
loanApplicationTerms.getInterestChargedFromLocalDate(), loanApplicationTerms.getLoanTermPeriodFrequencyType(),
|
||||||
loanApplicationTerms.getRepaymentEvery());
|
loanApplicationTerms.getRepaymentEvery());
|
||||||
Money balanceForcalculation = outstandingBalance;
|
Money balanceForcalculation = outstandingBalance;
|
||||||
|
// reduce principal is the early payment, will processed as per the
|
||||||
|
// reschedule strategy
|
||||||
if (reducePrincipal.isGreaterThanZero()) {
|
if (reducePrincipal.isGreaterThanZero()) {
|
||||||
switch (loanApplicationTerms.getRescheduleStrategyMethod()) {
|
switch (loanApplicationTerms.getRescheduleStrategyMethod()) {
|
||||||
case REDUCE_EMI_AMOUNT:
|
case REDUCE_EMI_AMOUNT:
|
||||||
@@ -211,10 +213,14 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
fixedEmiAmount = principalForThisPeriod.plus(interestForThisinstallment);
|
fixedEmiAmount = principalForThisPeriod.plus(interestForThisinstallment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this block is to identify interest based on late/early payment
|
||||||
if (diffAmt != null && !diffAmt.isEmpty()) {
|
if (diffAmt != null && !diffAmt.isEmpty()) {
|
||||||
BigDecimal interestDueToLatePayment = BigDecimal.ZERO;
|
BigDecimal interestDueToLatePayment = BigDecimal.ZERO;
|
||||||
BigDecimal interestReducedDueToEarlyPayment = BigDecimal.ZERO;
|
BigDecimal interestReducedDueToEarlyPayment = BigDecimal.ZERO;
|
||||||
for (RecalculationDetail detail : diffAmt) {
|
for (RecalculationDetail detail : diffAmt) {
|
||||||
|
// will increase the principal portion and reduces interest
|
||||||
|
// as per the number of days. and also identifies reduce
|
||||||
|
// principal for reschedule strategy
|
||||||
if (!detail.isLatePayment() && detail.getStartDate().isAfter(periodStartDate)
|
if (!detail.isLatePayment() && detail.getStartDate().isAfter(periodStartDate)
|
||||||
&& !detail.getStartDate().isAfter(scheduledDueDate)) {
|
&& !detail.getStartDate().isAfter(scheduledDueDate)) {
|
||||||
reducePrincipal = reducePrincipal.plus(detail.getAmount());
|
reducePrincipal = reducePrincipal.plus(detail.getAmount());
|
||||||
@@ -234,7 +240,10 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
interestReducedDueToEarlyPayment = interestReducedDueToEarlyPayment.add(loanApplicationTerms.interestRateFor(
|
interestReducedDueToEarlyPayment = interestReducedDueToEarlyPayment.add(loanApplicationTerms.interestRateFor(
|
||||||
this.paymentPeriodsInOneYearCalculator, mc, detail.getAmount(), detail.getStartDate(), scheduledDueDate));
|
this.paymentPeriodsInOneYearCalculator, mc, detail.getAmount(), detail.getStartDate(), scheduledDueDate));
|
||||||
|
|
||||||
} else if (detail.isLatePayment() && detail.isOverlapping(periodStartDate, scheduledDueDate)
|
}
|
||||||
|
// calculates the interest for late payment and increase
|
||||||
|
// the interest for the installment
|
||||||
|
else if (detail.isLatePayment() && detail.isOverlapping(periodStartDate, scheduledDueDate)
|
||||||
&& periodStartDate.isBefore(LocalDate.now())) {
|
&& periodStartDate.isBefore(LocalDate.now())) {
|
||||||
LocalDate fromDate = periodStartDate;
|
LocalDate fromDate = periodStartDate;
|
||||||
LocalDate toDate = scheduledDueDate;
|
LocalDate toDate = scheduledDueDate;
|
||||||
@@ -312,6 +321,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this block is to add extra re-payment schedules with interest portion
|
||||||
|
// if the last payment is missed
|
||||||
if (diffAmt != null && !diffAmt.isEmpty() && !periodStartDate.isAfter(LocalDate.now())) {
|
if (diffAmt != null && !diffAmt.isEmpty() && !periodStartDate.isAfter(LocalDate.now())) {
|
||||||
Map<LocalDate, RecalculationDetail> processDetails = new TreeMap<>();
|
Map<LocalDate, RecalculationDetail> processDetails = new TreeMap<>();
|
||||||
for (RecalculationDetail detail : diffAmt) {
|
for (RecalculationDetail detail : diffAmt) {
|
||||||
@@ -518,6 +529,11 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
return cumulative;
|
return cumulative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method calls schedule regeneration by passing transactions one after
|
||||||
|
* another(this is done mainly to handle the scenario where interest or fee
|
||||||
|
* of over due installment should be collected before collecting principal )
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public LoanScheduleModel rescheduleNextInstallments(final MathContext mc, final ApplicationCurrency applicationCurrency,
|
public LoanScheduleModel rescheduleNextInstallments(final MathContext mc, final ApplicationCurrency applicationCurrency,
|
||||||
final LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final boolean isHolidayEnabled,
|
final LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final boolean isHolidayEnabled,
|
||||||
@@ -570,6 +586,11 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
return recalculateFrom;
|
return recalculateFrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method calls regenerate schedule for a particular set of transactions
|
||||||
|
* till all the installments are processed to identify early or late
|
||||||
|
* payments and will be used in regeneration of schedule
|
||||||
|
*/
|
||||||
private LoanScheduleModel recalculateInstallment(final MathContext mc, final ApplicationCurrency applicationCurrency,
|
private LoanScheduleModel recalculateInstallment(final MathContext mc, final ApplicationCurrency applicationCurrency,
|
||||||
final LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final boolean isHolidayEnabled,
|
final LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final boolean isHolidayEnabled,
|
||||||
final List<Holiday> holidays, final WorkingDays workingDays,
|
final List<Holiday> holidays, final WorkingDays workingDays,
|
||||||
@@ -593,6 +614,9 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
return loanScheduleModel;
|
return loanScheduleModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method identifies late or early payments for schedule recalculation.
|
||||||
|
*/
|
||||||
private RecalculatedSchedule recalculateInterest(final MathContext mc, final ApplicationCurrency applicationCurrency,
|
private RecalculatedSchedule recalculateInterest(final MathContext mc, final ApplicationCurrency applicationCurrency,
|
||||||
final LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final boolean isHolidayEnabled,
|
final LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final boolean isHolidayEnabled,
|
||||||
final List<Holiday> holidays, final WorkingDays workingDays, final List<LoanTransaction> transactions,
|
final List<Holiday> holidays, final WorkingDays workingDays, final List<LoanTransaction> transactions,
|
||||||
@@ -638,6 +662,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
Map<LocalDate, Money> earlyPaymentMap = loanRepaymentScheduleTransactionProcessor.handleRepaymentSchedule(
|
Map<LocalDate, Money> earlyPaymentMap = loanRepaymentScheduleTransactionProcessor.handleRepaymentSchedule(
|
||||||
transactionsForInstallment, currency, processinstallmets, installment, recalculationDates);
|
transactionsForInstallment, currency, processinstallmets, installment, recalculationDates);
|
||||||
|
|
||||||
|
// this block is to create early payment entries for schedule
|
||||||
|
// generation
|
||||||
for (Map.Entry<LocalDate, Money> entry : earlyPaymentMap.entrySet()) {
|
for (Map.Entry<LocalDate, Money> entry : earlyPaymentMap.entrySet()) {
|
||||||
LocalDate startDate = entry.getKey();
|
LocalDate startDate = entry.getKey();
|
||||||
if (unpaidPricipal.isGreaterThan(entry.getValue())) {
|
if (unpaidPricipal.isGreaterThan(entry.getValue())) {
|
||||||
@@ -655,6 +681,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
Money totalOutstanding = installment.getTotalOutstanding(currency);
|
Money totalOutstanding = installment.getTotalOutstanding(currency);
|
||||||
boolean reduceStartDate = false;
|
boolean reduceStartDate = false;
|
||||||
|
|
||||||
|
// this block is to identify late payment based on the rest
|
||||||
|
// calculation date
|
||||||
while (totalOutstanding.isGreaterThanZero() && startDate.isBefore(LocalDate.now())) {
|
while (totalOutstanding.isGreaterThanZero() && startDate.isBefore(LocalDate.now())) {
|
||||||
LocalDate recalculateFrom = getNextRestScheduleDate(startDate.minusDays(1), loanApplicationTerms, isHolidayEnabled,
|
LocalDate recalculateFrom = getNextRestScheduleDate(startDate.minusDays(1), loanApplicationTerms, isHolidayEnabled,
|
||||||
holidays, workingDays);
|
holidays, workingDays);
|
||||||
@@ -725,6 +753,10 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
return installments;
|
return installments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to identify which transaction did the payment for current
|
||||||
|
* installment
|
||||||
|
*/
|
||||||
private void applyRest(List<LoanTransaction> loanTransactions, LocalDate from, LocalDate to,
|
private void applyRest(List<LoanTransaction> loanTransactions, LocalDate from, LocalDate to,
|
||||||
LoanRepaymentScheduleInstallment installment,
|
LoanRepaymentScheduleInstallment installment,
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, MonetaryCurrency currency,
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, MonetaryCurrency currency,
|
||||||
@@ -760,6 +792,9 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
return nextScheduleDate;
|
return nextScheduleDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method returns the amount payable to close the loan account as of today.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Money fetchPrepaymentAmount(final List<LoanRepaymentScheduleInstallment> installments, MonetaryCurrency currency,
|
public Money fetchPrepaymentAmount(final List<LoanRepaymentScheduleInstallment> installments, MonetaryCurrency currency,
|
||||||
final LoanApplicationTerms applicationTerms, final MathContext mc) {
|
final LoanApplicationTerms applicationTerms, final MathContext mc) {
|
||||||
|
|||||||
+5
@@ -5,8 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.loanaccount.service;
|
package org.mifosplatform.portfolio.loanaccount.service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException;
|
import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.data.LoanScheduleAccrualData;
|
||||||
|
|
||||||
|
|
||||||
public interface LoanAccrualWritePlatformService {
|
public interface LoanAccrualWritePlatformService {
|
||||||
@@ -17,4 +20,6 @@ public interface LoanAccrualWritePlatformService {
|
|||||||
|
|
||||||
String addPeriodicAccruals(LocalDate tilldate);
|
String addPeriodicAccruals(LocalDate tilldate);
|
||||||
|
|
||||||
|
String addPeriodicAccruals(LocalDate tilldate, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-4
@@ -95,7 +95,8 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
return addPeriodicAccruals(tilldate, loanScheduleAccrualDatas);
|
return addPeriodicAccruals(tilldate, loanScheduleAccrualDatas);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String addPeriodicAccruals(final LocalDate tilldate, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas) {
|
@Override
|
||||||
|
public String addPeriodicAccruals(final LocalDate tilldate, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
Set<Long> loansIds = new HashSet<>();
|
Set<Long> loansIds = new HashSet<>();
|
||||||
LocalDate accruredTill = null;
|
LocalDate accruredTill = null;
|
||||||
@@ -129,9 +130,11 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
|
|
||||||
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 {
|
||||||
LocalDate interestStartDate = accrualData.getFromDateAsLocaldate();
|
LocalDate interestStartDate = accrualData.getFromDateAsLocaldate();
|
||||||
|
boolean isInterestStartDateEqulsInstallmentStartdate = true;
|
||||||
if (accrualData.getInterestCalculatedFrom() != null
|
if (accrualData.getInterestCalculatedFrom() != null
|
||||||
&& accrualData.getFromDateAsLocaldate().isBefore(accrualData.getInterestCalculatedFrom())) {
|
&& accrualData.getFromDateAsLocaldate().isBefore(accrualData.getInterestCalculatedFrom())) {
|
||||||
|
isInterestStartDateEqulsInstallmentStartdate = false;
|
||||||
if (accrualData.getInterestCalculatedFrom().isBefore(accrualData.getDueDateAsLocaldate())) {
|
if (accrualData.getInterestCalculatedFrom().isBefore(accrualData.getDueDateAsLocaldate())) {
|
||||||
interestStartDate = accrualData.getInterestCalculatedFrom();
|
interestStartDate = accrualData.getInterestCalculatedFrom();
|
||||||
} else {
|
} else {
|
||||||
@@ -156,10 +159,16 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
int daysInSchedule = Days.daysBetween(interestStartDate, tilldate).getDays();
|
int daysInSchedule = Days.daysBetween(interestStartDate, tilldate).getDays();
|
||||||
switch (accrualData.getRepaymentFrequency()) {
|
switch (accrualData.getRepaymentFrequency()) {
|
||||||
case MONTHS:
|
case MONTHS:
|
||||||
totalNumberOfDays = calculateTotalNumberOfDaysForMonth(totalNumberOfDays, accrualData);
|
int numberOfDaysInMonth = calculateTotalNumberOfDaysForMonth(totalNumberOfDays, accrualData);
|
||||||
|
if (!(!isInterestStartDateEqulsInstallmentStartdate && totalNumberOfDays < numberOfDaysInMonth)) {
|
||||||
|
totalNumberOfDays = numberOfDaysInMonth;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case YEARS:
|
case YEARS:
|
||||||
totalNumberOfDays = calculateTotalNumberOfDaysForYear(totalNumberOfDays, accrualData);
|
int numberOfDaysinYear = calculateTotalNumberOfDaysForYear(totalNumberOfDays, accrualData);
|
||||||
|
if (!(!isInterestStartDateEqulsInstallmentStartdate && totalNumberOfDays < numberOfDaysinYear)) {
|
||||||
|
totalNumberOfDays = numberOfDaysinYear;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
+4
-2
@@ -1424,6 +1424,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.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.accrued_till as accruedTill, loan.repayment_period_frequency_enum as frequencyEnum, ")
|
||||||
.append("loan.interest_calculated_from_date as interestCalculatedFrom, ")
|
.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("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,")
|
||||||
@@ -1448,8 +1450,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
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 LocalDate interestCalculatedFrom = JdbcSupport.getLocalDate(rs, "interestCalculatedFrom");
|
||||||
final Integer numberOfDaysInMonth = 30;
|
final Integer numberOfDaysInMonth = JdbcSupport.getInteger(rs, "daysInMonth");;
|
||||||
final Integer numberOfDaysInYear = 360;
|
final Integer numberOfDaysInYear = JdbcSupport.getInteger(rs, "daysInYear");;
|
||||||
final Integer frequencyEnum = JdbcSupport.getInteger(rs, "frequencyEnum");
|
final Integer frequencyEnum = JdbcSupport.getInteger(rs, "frequencyEnum");
|
||||||
final Integer repayEvery = JdbcSupport.getInteger(rs, "repayEvery");
|
final Integer repayEvery = JdbcSupport.getInteger(rs, "repayEvery");
|
||||||
final PeriodFrequencyType frequency = PeriodFrequencyType.fromInt(frequencyEnum);
|
final PeriodFrequencyType frequency = PeriodFrequencyType.fromInt(frequencyEnum);
|
||||||
|
|||||||
+14
-7
@@ -315,6 +315,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<LoanCharge> loanCharges = loan.charges();
|
final Set<LoanCharge> loanCharges = loan.charges();
|
||||||
@@ -340,7 +341,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateRecurringCalendarDatesForInterestRecalculation(loan);
|
updateRecurringCalendarDatesForInterestRecalculation(loan);
|
||||||
|
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loan.getId()) //
|
.withEntityId(loan.getId()) //
|
||||||
@@ -526,7 +527,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
|
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
|
||||||
}
|
}
|
||||||
updateRecurringCalendarDatesForInterestRecalculation(loan);
|
updateRecurringCalendarDatesForInterestRecalculation(loan);
|
||||||
|
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||||
}
|
}
|
||||||
|
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,6 +769,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
|
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(transactionId) //
|
.withEntityId(transactionId) //
|
||||||
@@ -857,7 +862,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(waiveInterestTransaction.getId()) //
|
.withEntityId(waiveInterestTransaction.getId()) //
|
||||||
@@ -925,7 +930,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(writeoff.getId()) //
|
.withEntityId(writeoff.getId()) //
|
||||||
@@ -998,7 +1003,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
if (possibleClosingTransaction != null) {
|
if (possibleClosingTransaction != null) {
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
}
|
}
|
||||||
|
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||||
CommandProcessingResult result = null;
|
CommandProcessingResult result = null;
|
||||||
if (possibleClosingTransaction != null) {
|
if (possibleClosingTransaction != null) {
|
||||||
|
|
||||||
@@ -2043,6 +2048,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||||
|
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
@@ -2091,7 +2097,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
@@ -2205,8 +2211,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate().toDate());
|
holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate().toDate());
|
||||||
workingDays = this.workingDaysRepository.findOne();
|
workingDays = this.workingDaysRepository.findOne();
|
||||||
}
|
}
|
||||||
ChangedTransactionDetail changedTransactionDetail = loan.recalculateScheduleFromLastTransaction(loanScheduleFactory, applicationCurrency,
|
ChangedTransactionDetail changedTransactionDetail = loan.recalculateScheduleFromLastTransaction(loanScheduleFactory,
|
||||||
calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, workingDays, restCalendarInstance,
|
applicationCurrency, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, workingDays, restCalendarInstance,
|
||||||
existingTransactionIds, existingReversedTransactionIds);
|
existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||||
@@ -2218,6 +2224,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLoanTransaction(final Long loanTransactionId, final LoanTransaction newLoanTransaction) {
|
private void updateLoanTransaction(final Long loanTransactionId, final LoanTransaction newLoanTransaction) {
|
||||||
|
|||||||
Reference in New Issue
Block a user