Merge pull request #1591 from pramodn02/preclosefix
MIFOSX-2437: fix for prepay of loan
This commit is contained in:
-18
@@ -23,23 +23,6 @@ public class ScheduleGeneratorDTO {
|
|||||||
final Long overdurPenaltyWaitPeriod;
|
final Long overdurPenaltyWaitPeriod;
|
||||||
final FloatingRateDTO floatingRateDTO;
|
final FloatingRateDTO floatingRateDTO;
|
||||||
|
|
||||||
public ScheduleGeneratorDTO(final LoanScheduleGeneratorFactory loanScheduleFactory, final ApplicationCurrency applicationCurrency,
|
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate, final HolidayDetailDTO holidayDetailDTO,
|
|
||||||
final CalendarInstance calendarInstanceForInterestRecalculation, final CalendarInstance compoundingCalendarInstance,
|
|
||||||
final FloatingRateDTO floatingRateDTO) {
|
|
||||||
|
|
||||||
this.loanScheduleFactory = loanScheduleFactory;
|
|
||||||
this.applicationCurrency = applicationCurrency;
|
|
||||||
this.calculatedRepaymentsStartingFromDate = calculatedRepaymentsStartingFromDate;
|
|
||||||
this.calendarInstanceForInterestRecalculation = calendarInstanceForInterestRecalculation;
|
|
||||||
this.compoundingCalendarInstance = compoundingCalendarInstance;
|
|
||||||
this.recalculateFrom = null;
|
|
||||||
this.overdurPenaltyWaitPeriod = null;
|
|
||||||
this.holidayDetailDTO = holidayDetailDTO;
|
|
||||||
this.floatingRateDTO = floatingRateDTO;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScheduleGeneratorDTO(final LoanScheduleGeneratorFactory loanScheduleFactory, final ApplicationCurrency applicationCurrency,
|
public ScheduleGeneratorDTO(final LoanScheduleGeneratorFactory loanScheduleFactory, final ApplicationCurrency applicationCurrency,
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate, final HolidayDetailDTO holidayDetailDTO,
|
final LocalDate calculatedRepaymentsStartingFromDate, final HolidayDetailDTO holidayDetailDTO,
|
||||||
final CalendarInstance calendarInstanceForInterestRecalculation, final CalendarInstance compoundingCalendarInstance,
|
final CalendarInstance calendarInstanceForInterestRecalculation, final CalendarInstance compoundingCalendarInstance,
|
||||||
@@ -100,7 +83,6 @@ public class ScheduleGeneratorDTO {
|
|||||||
return this.compoundingCalendarInstance;
|
return this.compoundingCalendarInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public FloatingRateDTO getFloatingRateDTO() {
|
public FloatingRateDTO getFloatingRateDTO() {
|
||||||
return this.floatingRateDTO;
|
return this.floatingRateDTO;
|
||||||
}
|
}
|
||||||
|
|||||||
+130
-194
@@ -103,10 +103,8 @@ import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleDTO
|
|||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.AprCalculator;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
||||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
|
|
||||||
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
|
import org.mifosplatform.portfolio.loanproduct.LoanProductConstants;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.AmortizationMethod;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestCalculationPeriodMethod;
|
||||||
@@ -838,9 +836,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
*/
|
*/
|
||||||
private BigDecimal calculateAmountPercentageAppliedTo(final LoanCharge loanCharge) {
|
private BigDecimal calculateAmountPercentageAppliedTo(final LoanCharge loanCharge) {
|
||||||
BigDecimal amount = BigDecimal.ZERO;
|
BigDecimal amount = BigDecimal.ZERO;
|
||||||
if(loanCharge.isOverdueInstallmentCharge()){
|
if (loanCharge.isOverdueInstallmentCharge()) { return loanCharge.getAmountPercentageAppliedTo(); }
|
||||||
return loanCharge.getAmountPercentageAppliedTo();
|
|
||||||
}
|
|
||||||
switch (loanCharge.getChargeCalculation()) {
|
switch (loanCharge.getChargeCalculation()) {
|
||||||
case PERCENT_OF_AMOUNT:
|
case PERCENT_OF_AMOUNT:
|
||||||
amount = getPrincpal().getAmount();
|
amount = getPrincpal().getAmount();
|
||||||
@@ -2561,50 +2557,14 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LoanScheduleModel regenerateScheduleModel(final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
public LoanScheduleModel regenerateScheduleModel(final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
final InterestMethod interestMethod = this.loanRepaymentScheduleDetail.getInterestMethod();
|
|
||||||
final LoanScheduleGenerator loanScheduleGenerator = scheduleGeneratorDTO.getLoanScheduleFactory().create(interestMethod);
|
|
||||||
|
|
||||||
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
|
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
|
||||||
final MathContext mc = new MathContext(8, roundingMode);
|
final MathContext mc = new MathContext(8, roundingMode);
|
||||||
|
|
||||||
final Integer loanTermFrequency = this.termFrequency;
|
final InterestMethod interestMethod = this.loanRepaymentScheduleDetail.getInterestMethod();
|
||||||
final PeriodFrequencyType loanTermPeriodFrequencyType = PeriodFrequencyType.fromInt(this.termPeriodFrequencyType);
|
final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(scheduleGeneratorDTO);
|
||||||
final NthDayType nthDayType = NthDayType.fromInt(this.repaymentFrequencyNthDayType);
|
|
||||||
final DayOfWeekType dayOfWeekType = DayOfWeekType.fromInt(this.repaymentFrequencyDayOfWeekType);
|
|
||||||
final List<DisbursementData> disbursementData = new ArrayList<>();
|
|
||||||
for (LoanDisbursementDetails disbursementDetails : this.disbursementDetails) {
|
|
||||||
disbursementData.add(disbursementDetails.toData());
|
|
||||||
}
|
|
||||||
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
RecalculationFrequencyType recalculationFrequencyType = null;
|
|
||||||
InterestRecalculationCompoundingMethod compoundingMethod = null;
|
|
||||||
RecalculationFrequencyType compoundingFrequencyType = null;
|
|
||||||
LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
|
|
||||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = scheduleGeneratorDTO.getCalendarInstanceForInterestRecalculation();
|
|
||||||
compoundingCalendarInstance = scheduleGeneratorDTO.getCompoundingCalendarInstance();
|
|
||||||
recalculationFrequencyType = this.loanInterestRecalculationDetails.getRestFrequencyType();
|
|
||||||
compoundingMethod = this.loanInterestRecalculationDetails.getInterestRecalculationCompoundingMethod();
|
|
||||||
compoundingFrequencyType = this.loanInterestRecalculationDetails.getCompoundingFrequencyType();
|
|
||||||
rescheduleStrategyMethod = this.loanInterestRecalculationDetails.getRescheduleStrategyMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
BigDecimal annualNominalInterestRate = this.loanRepaymentScheduleDetail.getAnnualNominalInterestRate();
|
|
||||||
FloatingRateDTO floatingRateDTO = scheduleGeneratorDTO.getFloatingRateDTO();
|
|
||||||
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
|
|
||||||
annualNominalInterestRate = constructLoanTermVariations(floatingRateDTO, annualNominalInterestRate, loanTermVariations);
|
|
||||||
|
|
||||||
final LoanApplicationTerms loanApplicationTerms = LoanApplicationTerms.assembleFrom(scheduleGeneratorDTO.getApplicationCurrency(),
|
|
||||||
loanTermFrequency, loanTermPeriodFrequencyType, nthDayType, dayOfWeekType, getDisbursementDate(),
|
|
||||||
getExpectedFirstRepaymentOnDate(), scheduleGeneratorDTO.getCalculatedRepaymentsStartingFromDate(), getInArrearsTolerance(),
|
|
||||||
this.loanRepaymentScheduleDetail, this.loanProduct.isMultiDisburseLoan(), this.fixedEmiAmount, disbursementData,
|
|
||||||
this.maxOutstandingLoanBalance, getInterestChargedFromDate(), this.loanProduct.getPrincipalThresholdForLastInstallment(),
|
|
||||||
this.loanProduct.getInstallmentAmountInMultiplesOf(), recalculationFrequencyType, restCalendarInstance, compoundingMethod,
|
|
||||||
compoundingCalendarInstance, compoundingFrequencyType, this.loanProduct.preCloseInterestCalculationStrategy(),
|
|
||||||
rescheduleStrategyMethod, getApprovedPrincipal(), annualNominalInterestRate, loanTermVariations);
|
|
||||||
|
|
||||||
|
final LoanScheduleGenerator loanScheduleGenerator = scheduleGeneratorDTO.getLoanScheduleFactory().create(interestMethod);
|
||||||
final LoanScheduleModel loanSchedule = loanScheduleGenerator.generate(mc, loanApplicationTerms, charges(),
|
final LoanScheduleModel loanSchedule = loanScheduleGenerator.generate(mc, loanApplicationTerms, charges(),
|
||||||
scheduleGeneratorDTO.getHolidayDetailDTO());
|
scheduleGeneratorDTO.getHolidayDetailDTO());
|
||||||
return loanSchedule;
|
return loanSchedule;
|
||||||
@@ -2837,6 +2797,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return changedTransactionDetail;
|
return changedTransactionDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("null")
|
||||||
public ChangedTransactionDetail makeRepayment(final LoanTransaction repaymentTransaction,
|
public ChangedTransactionDetail makeRepayment(final LoanTransaction repaymentTransaction,
|
||||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final List<Long> existingTransactionIds,
|
final LoanLifecycleStateMachine loanLifecycleStateMachine, final List<Long> existingTransactionIds,
|
||||||
final List<Long> existingReversedTransactionIds, boolean isRecoveryRepayment, final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
final List<Long> existingReversedTransactionIds, boolean isRecoveryRepayment, final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
||||||
@@ -3087,9 +3048,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
private List<LoanTransaction> retreiveListOfTransactionsPostDisbursement() {
|
private List<LoanTransaction> retreiveListOfTransactionsPostDisbursement() {
|
||||||
final List<LoanTransaction> repaymentsOrWaivers = new ArrayList<>();
|
final List<LoanTransaction> repaymentsOrWaivers = new ArrayList<>();
|
||||||
for (final LoanTransaction transaction : this.loanTransactions) {
|
for (final LoanTransaction transaction : this.loanTransactions) {
|
||||||
if (transaction.isNotReversed()
|
if (transaction.isNotReversed() && !(transaction.isDisbursement() || transaction.isNonMonetaryTransaction())) {
|
||||||
&& !(transaction.isDisbursement()
|
|
||||||
|| transaction.isNonMonetaryTransaction())) {
|
|
||||||
repaymentsOrWaivers.add(transaction);
|
repaymentsOrWaivers.add(transaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3101,11 +3060,9 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
public List<LoanTransaction> retreiveListOfTransactionsPostDisbursementExcludeAccruals() {
|
public List<LoanTransaction> retreiveListOfTransactionsPostDisbursementExcludeAccruals() {
|
||||||
final List<LoanTransaction> repaymentsOrWaivers = new ArrayList<>();
|
final List<LoanTransaction> repaymentsOrWaivers = new ArrayList<>();
|
||||||
for (final LoanTransaction transaction : this.loanTransactions) {
|
for (final LoanTransaction transaction : this.loanTransactions) {
|
||||||
if (transaction.isNotReversed()
|
if (transaction.isNotReversed()
|
||||||
&& !(transaction.isDisbursement()
|
&& !(transaction.isDisbursement() || transaction.isAccrual() || transaction.isRepaymentAtDisbursement() || transaction
|
||||||
|| transaction.isAccrual()
|
.isNonMonetaryTransaction())) {
|
||||||
|| transaction.isRepaymentAtDisbursement()
|
|
||||||
|| transaction.isNonMonetaryTransaction())) {
|
|
||||||
repaymentsOrWaivers.add(transaction);
|
repaymentsOrWaivers.add(transaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3117,9 +3074,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
private List<LoanTransaction> retreiveListOfTransactionsExcludeAccruals() {
|
private List<LoanTransaction> retreiveListOfTransactionsExcludeAccruals() {
|
||||||
final List<LoanTransaction> repaymentsOrWaivers = new ArrayList<>();
|
final List<LoanTransaction> repaymentsOrWaivers = new ArrayList<>();
|
||||||
for (final LoanTransaction transaction : this.loanTransactions) {
|
for (final LoanTransaction transaction : this.loanTransactions) {
|
||||||
if (transaction.isNotReversed()
|
if (transaction.isNotReversed() && !(transaction.isAccrual() || transaction.isNonMonetaryTransaction())) {
|
||||||
&& !(transaction.isAccrual()
|
|
||||||
|| transaction.isNonMonetaryTransaction())) {
|
|
||||||
repaymentsOrWaivers.add(transaction);
|
repaymentsOrWaivers.add(transaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4520,9 +4475,10 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
postfix = "cannot.be.made.before.client.transfer.date";
|
postfix = "cannot.be.made.before.client.transfer.date";
|
||||||
break;
|
break;
|
||||||
case LOAN_DISBURSAL_UNDO_LAST:
|
case LOAN_DISBURSAL_UNDO_LAST:
|
||||||
errorMessage = "Cannot undo a last disbursal in another branch";
|
errorMessage = "Cannot undo a last disbursal in another branch";
|
||||||
action = "disbursal";
|
action = "disbursal";
|
||||||
postfix = "cannot.be.undone.before.client.transfer.date";
|
postfix = "cannot.be.undone.before.client.transfer.date";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4573,7 +4529,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
return currentTransactionDate;
|
return currentTransactionDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getLastRepaymentDate() {
|
public LocalDate getLastRepaymentDate() {
|
||||||
LocalDate currentTransactionDate = getDisbursementDate();
|
LocalDate currentTransactionDate = getDisbursementDate();
|
||||||
for (final LoanTransaction previousTransaction : this.loanTransactions) {
|
for (final LoanTransaction previousTransaction : this.loanTransactions) {
|
||||||
@@ -4756,13 +4712,14 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOAN_DISBURSAL_UNDO_LAST:
|
case LOAN_DISBURSAL_UNDO_LAST:
|
||||||
if (!isOpen()) {
|
if (!isOpen()) {
|
||||||
final String defaultUserMessage = "Loan Undo last disbursal is not allowed. Loan Account is not active.";
|
final String defaultUserMessage = "Loan Undo last disbursal is not allowed. Loan Account is not active.";
|
||||||
final ApiParameterError error = ApiParameterError.generalError("error.msg.loan.undo.last.disbursal.account.is.not.active",
|
final ApiParameterError error = ApiParameterError.generalError(
|
||||||
defaultUserMessage);
|
"error.msg.loan.undo.last.disbursal.account.is.not.active", defaultUserMessage);
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5007,9 +4964,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
|
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
|
||||||
final MathContext mc = new MathContext(8, roundingMode);
|
final MathContext mc = new MathContext(8, roundingMode);
|
||||||
|
|
||||||
final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(generatorDTO.getApplicationCurrency(),
|
final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(generatorDTO);
|
||||||
generatorDTO.getCalculatedRepaymentsStartingFromDate(), generatorDTO.getCalendarInstanceForInterestRecalculation(),
|
|
||||||
generatorDTO.getCompoundingCalendarInstance(), generatorDTO.getFloatingRateDTO());
|
|
||||||
|
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||||
.determineProcessor(this.transactionProcessingStrategy);
|
.determineProcessor(this.transactionProcessingStrategy);
|
||||||
@@ -5019,91 +4974,69 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
repaymentScheduleInstallments, generatorDTO.getRecalculateFrom());
|
repaymentScheduleInstallments, generatorDTO.getRecalculateFrom());
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoanApplicationTerms constructLoanApplicationTerms(final ApplicationCurrency applicationCurrency,
|
public LoanRepaymentScheduleInstallment fetchPrepaymentDetail(final ScheduleGeneratorDTO scheduleGeneratorDTO, final LocalDate onDate) {
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate, final CalendarInstance calendarInstanceForInterestRecalculation,
|
LoanRepaymentScheduleInstallment installment = null;
|
||||||
final CalendarInstance compoundingCalendarInstance, final FloatingRateDTO floatingRateDTO) {
|
|
||||||
|
if (this.loanRepaymentScheduleDetail.isInterestRecalculationEnabled()) {
|
||||||
|
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
|
||||||
|
final MathContext mc = new MathContext(8, roundingMode);
|
||||||
|
|
||||||
|
final InterestMethod interestMethod = this.loanRepaymentScheduleDetail.getInterestMethod();
|
||||||
|
final LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(scheduleGeneratorDTO);
|
||||||
|
|
||||||
|
final LoanScheduleGenerator loanScheduleGenerator = scheduleGeneratorDTO.getLoanScheduleFactory().create(interestMethod);
|
||||||
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||||
|
.determineProcessor(this.transactionProcessingStrategy);
|
||||||
|
installment = loanScheduleGenerator.calculatePrepaymentAmount(getCurrency(), onDate, loanApplicationTerms, mc, charges(),
|
||||||
|
scheduleGeneratorDTO.getHolidayDetailDTO(), retreiveListOfTransactionsPostDisbursementExcludeAccruals(),
|
||||||
|
loanRepaymentScheduleTransactionProcessor, this.fetchRepaymentScheduleInstallments());
|
||||||
|
} else {
|
||||||
|
installment = this.getTotalOutstandingOnLoan();
|
||||||
|
}
|
||||||
|
return installment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoanApplicationTerms constructLoanApplicationTerms(final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
final Integer loanTermFrequency = this.termFrequency;
|
final Integer loanTermFrequency = this.termFrequency;
|
||||||
final PeriodFrequencyType loanTermPeriodFrequencyType = PeriodFrequencyType.fromInt(this.termPeriodFrequencyType);
|
final PeriodFrequencyType loanTermPeriodFrequencyType = PeriodFrequencyType.fromInt(this.termPeriodFrequencyType);
|
||||||
|
final NthDayType nthDayType = NthDayType.fromInt(this.repaymentFrequencyNthDayType);
|
||||||
|
final DayOfWeekType dayOfWeekType = DayOfWeekType.fromInt(this.repaymentFrequencyDayOfWeekType);
|
||||||
final List<DisbursementData> disbursementData = new ArrayList<>();
|
final List<DisbursementData> disbursementData = new ArrayList<>();
|
||||||
for (LoanDisbursementDetails disbursementDetails : this.disbursementDetails) {
|
for (LoanDisbursementDetails disbursementDetails : this.disbursementDetails) {
|
||||||
disbursementData.add(disbursementDetails.toData());
|
disbursementData.add(disbursementDetails.toData());
|
||||||
}
|
}
|
||||||
|
|
||||||
RecalculationFrequencyType recalculationFrequencyType = this.loanInterestRecalculationDetails().getRestFrequencyType();
|
CalendarInstance restCalendarInstance = null;
|
||||||
RecalculationFrequencyType compoundingFrequencyType = this.loanInterestRecalculationDetails().getCompoundingFrequencyType();
|
CalendarInstance compoundingCalendarInstance = null;
|
||||||
|
RecalculationFrequencyType recalculationFrequencyType = null;
|
||||||
|
InterestRecalculationCompoundingMethod compoundingMethod = null;
|
||||||
|
RecalculationFrequencyType compoundingFrequencyType = null;
|
||||||
|
LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
|
||||||
|
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
|
restCalendarInstance = scheduleGeneratorDTO.getCalendarInstanceForInterestRecalculation();
|
||||||
|
compoundingCalendarInstance = scheduleGeneratorDTO.getCompoundingCalendarInstance();
|
||||||
|
recalculationFrequencyType = this.loanInterestRecalculationDetails.getRestFrequencyType();
|
||||||
|
compoundingMethod = this.loanInterestRecalculationDetails.getInterestRecalculationCompoundingMethod();
|
||||||
|
compoundingFrequencyType = this.loanInterestRecalculationDetails.getCompoundingFrequencyType();
|
||||||
|
rescheduleStrategyMethod = this.loanInterestRecalculationDetails.getRescheduleStrategyMethod();
|
||||||
|
}
|
||||||
|
|
||||||
BigDecimal annualNominalInterestRate = this.loanRepaymentScheduleDetail.getAnnualNominalInterestRate();
|
BigDecimal annualNominalInterestRate = this.loanRepaymentScheduleDetail.getAnnualNominalInterestRate();
|
||||||
|
FloatingRateDTO floatingRateDTO = scheduleGeneratorDTO.getFloatingRateDTO();
|
||||||
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
|
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
|
||||||
annualNominalInterestRate = constructLoanTermVariations(floatingRateDTO, annualNominalInterestRate, loanTermVariations);
|
annualNominalInterestRate = constructLoanTermVariations(floatingRateDTO, annualNominalInterestRate, loanTermVariations);
|
||||||
|
|
||||||
final LoanApplicationTerms loanApplicationTerms = LoanApplicationTerms.assembleFrom(applicationCurrency, loanTermFrequency,
|
final LoanApplicationTerms loanApplicationTerms = LoanApplicationTerms.assembleFrom(scheduleGeneratorDTO.getApplicationCurrency(),
|
||||||
loanTermPeriodFrequencyType, getDisbursementDate(), getExpectedFirstRepaymentOnDate(),
|
loanTermFrequency, loanTermPeriodFrequencyType, nthDayType, dayOfWeekType, getDisbursementDate(),
|
||||||
calculatedRepaymentsStartingFromDate, getInArrearsTolerance(), this.loanRepaymentScheduleDetail,
|
getExpectedFirstRepaymentOnDate(), scheduleGeneratorDTO.getCalculatedRepaymentsStartingFromDate(), getInArrearsTolerance(),
|
||||||
this.loanProduct.isMultiDisburseLoan(), this.fixedEmiAmount, disbursementData, this.maxOutstandingLoanBalance,
|
this.loanRepaymentScheduleDetail, this.loanProduct.isMultiDisburseLoan(), this.fixedEmiAmount, disbursementData,
|
||||||
getInterestChargedFromDate(), this.loanInterestRecalculationDetails, calendarInstanceForInterestRecalculation,
|
this.maxOutstandingLoanBalance, getInterestChargedFromDate(), this.loanProduct.getPrincipalThresholdForLastInstallment(),
|
||||||
recalculationFrequencyType, compoundingCalendarInstance, compoundingFrequencyType,
|
this.loanProduct.getInstallmentAmountInMultiplesOf(), recalculationFrequencyType, restCalendarInstance, compoundingMethod,
|
||||||
this.loanProduct.getPrincipalThresholdForLastInstallment(), this.loanProduct.getInstallmentAmountInMultiplesOf(),
|
compoundingCalendarInstance, compoundingFrequencyType, this.loanProduct.preCloseInterestCalculationStrategy(),
|
||||||
this.loanProduct.preCloseInterestCalculationStrategy(), getApprovedPrincipal(), annualNominalInterestRate,
|
rescheduleStrategyMethod, getApprovedPrincipal(), annualNominalInterestRate, loanTermVariations);
|
||||||
loanTermVariations);
|
|
||||||
return loanApplicationTerms;
|
return loanApplicationTerms;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoanRepaymentScheduleInstallment fetchPrepaymentDetail(final LoanScheduleGeneratorFactory loanScheduleFactory,
|
|
||||||
final CalendarInstance restCalendarInstance, final CalendarInstance compoundingCalendarInstance,
|
|
||||||
final HolidayDetailDTO holidayDetailDTO, final LocalDate onDate, FloatingRateDTO floatingRateDTO) {
|
|
||||||
LoanRepaymentScheduleInstallment installment = null;
|
|
||||||
|
|
||||||
if (this.loanRepaymentScheduleDetail.isInterestRecalculationEnabled()) {
|
|
||||||
final InterestMethod interestMethod = this.loanRepaymentScheduleDetail.getInterestMethod();
|
|
||||||
final LoanScheduleGenerator loanScheduleGenerator = loanScheduleFactory.create(interestMethod);
|
|
||||||
|
|
||||||
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
|
|
||||||
final MathContext mc = new MathContext(8, roundingMode);
|
|
||||||
|
|
||||||
final Integer loanTermFrequency = this.termFrequency;
|
|
||||||
final PeriodFrequencyType loanTermPeriodFrequencyType = PeriodFrequencyType.fromInt(this.termPeriodFrequencyType);
|
|
||||||
final NthDayType nthDayType = NthDayType.fromInt(this.repaymentFrequencyNthDayType);
|
|
||||||
final DayOfWeekType dayOfWeekType = DayOfWeekType.fromInt(this.repaymentFrequencyDayOfWeekType);
|
|
||||||
|
|
||||||
final List<DisbursementData> disbursementData = new ArrayList<>();
|
|
||||||
for (LoanDisbursementDetails disbursementDetails : this.disbursementDetails) {
|
|
||||||
disbursementData.add(disbursementDetails.toData());
|
|
||||||
}
|
|
||||||
|
|
||||||
RecalculationFrequencyType recalculationFrequencyType = null;
|
|
||||||
InterestRecalculationCompoundingMethod compoundingMethod = null;
|
|
||||||
RecalculationFrequencyType compoundingFrequencyType = null;
|
|
||||||
LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
|
|
||||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
recalculationFrequencyType = this.loanInterestRecalculationDetails.getRestFrequencyType();
|
|
||||||
compoundingMethod = this.loanInterestRecalculationDetails.getInterestRecalculationCompoundingMethod();
|
|
||||||
compoundingFrequencyType = this.loanInterestRecalculationDetails.getCompoundingFrequencyType();
|
|
||||||
rescheduleStrategyMethod = this.loanInterestRecalculationDetails.getRescheduleStrategyMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
BigDecimal annualNominalInterestRate = this.loanRepaymentScheduleDetail.getAnnualNominalInterestRate();
|
|
||||||
List<LoanTermVariationsData> loanTermVariations = new ArrayList<>();
|
|
||||||
annualNominalInterestRate = constructLoanTermVariations(floatingRateDTO, annualNominalInterestRate, loanTermVariations);
|
|
||||||
|
|
||||||
final LoanApplicationTerms loanApplicationTerms = LoanApplicationTerms.assembleFrom(null, loanTermFrequency,
|
|
||||||
loanTermPeriodFrequencyType, nthDayType, dayOfWeekType, getDisbursementDate(), getExpectedFirstRepaymentOnDate(), null,
|
|
||||||
getInArrearsTolerance(), this.loanRepaymentScheduleDetail, this.loanProduct.isMultiDisburseLoan(), this.fixedEmiAmount,
|
|
||||||
disbursementData, this.maxOutstandingLoanBalance, getInterestChargedFromDate(),
|
|
||||||
this.loanProduct.getPrincipalThresholdForLastInstallment(), this.loanProduct.getInstallmentAmountInMultiplesOf(),
|
|
||||||
recalculationFrequencyType, restCalendarInstance, compoundingMethod, compoundingCalendarInstance,
|
|
||||||
compoundingFrequencyType, this.loanProduct.preCloseInterestCalculationStrategy(), rescheduleStrategyMethod,
|
|
||||||
getApprovedPrincipal(), annualNominalInterestRate, loanTermVariations);
|
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
|
||||||
.determineProcessor(this.transactionProcessingStrategy);
|
|
||||||
installment = loanScheduleGenerator.calculatePrepaymentAmount(getCurrency(), onDate, loanApplicationTerms, mc, charges(),
|
|
||||||
holidayDetailDTO, retreiveListOfTransactionsPostDisbursementExcludeAccruals(),
|
|
||||||
loanRepaymentScheduleTransactionProcessor);
|
|
||||||
} else {
|
|
||||||
installment = this.getTotalOutstandingOnLoan();
|
|
||||||
}
|
|
||||||
return installment;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BigDecimal constructLoanTermVariations(FloatingRateDTO floatingRateDTO, BigDecimal annualNominalInterestRate,
|
private BigDecimal constructLoanTermVariations(FloatingRateDTO floatingRateDTO, BigDecimal annualNominalInterestRate,
|
||||||
List<LoanTermVariationsData> loanTermVariations) {
|
List<LoanTermVariationsData> loanTermVariations) {
|
||||||
for (LoanTermVariations variationTerms : this.loanTermVariations) {
|
for (LoanTermVariations variationTerms : this.loanTermVariations) {
|
||||||
@@ -5575,76 +5508,79 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
trancheCharges.add(new LoanTrancheCharge(charge, this));
|
trancheCharges.add(new LoanTrancheCharge(charge, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> undoLastDisbursal(ScheduleGeneratorDTO scheduleGeneratorDTO, List<Long> existingTransactionIds,
|
|
||||||
List<Long> existingReversedTransactionIds, AppUser currentUser, Loan loan) {
|
|
||||||
|
|
||||||
validateAccountStatus(LoanEvent.LOAN_DISBURSAL_UNDO_LAST);
|
public Map<String, Object> undoLastDisbursal(ScheduleGeneratorDTO scheduleGeneratorDTO, List<Long> existingTransactionIds,
|
||||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
List<Long> existingReversedTransactionIds, AppUser currentUser, Loan loan) {
|
||||||
|
|
||||||
|
validateAccountStatus(LoanEvent.LOAN_DISBURSAL_UNDO_LAST);
|
||||||
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
final Map<String, Object> actualChanges = new LinkedHashMap<>();
|
final Map<String, Object> actualChanges = new LinkedHashMap<>();
|
||||||
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_DISBURSAL_UNDO_LAST, getDisbursementDate());
|
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_DISBURSAL_UNDO_LAST, getDisbursementDate());
|
||||||
LocalDate actualDisbursementDate = null;
|
LocalDate actualDisbursementDate = null;
|
||||||
LocalDate lastTransactionDate = getDisbursementDate();
|
LocalDate lastTransactionDate = getDisbursementDate();
|
||||||
List<LoanTransaction> loanTransactions = retreiveListOfTransactionsExcludeAccruals();
|
List<LoanTransaction> loanTransactions = retreiveListOfTransactionsExcludeAccruals();
|
||||||
Collections.reverse(loanTransactions);
|
Collections.reverse(loanTransactions);
|
||||||
for (final LoanTransaction previousTransaction : loanTransactions) {
|
for (final LoanTransaction previousTransaction : loanTransactions) {
|
||||||
if (lastTransactionDate.isBefore(previousTransaction.getTransactionDate())) {
|
if (lastTransactionDate.isBefore(previousTransaction.getTransactionDate())) {
|
||||||
if(previousTransaction.isRepayment() || previousTransaction.isWaiver() ||
|
if (previousTransaction.isRepayment() || previousTransaction.isWaiver() || previousTransaction.isChargePayment()) { throw new UndoLastTrancheDisbursementException(
|
||||||
previousTransaction.isChargePayment()){
|
previousTransaction.getId()); }
|
||||||
throw new UndoLastTrancheDisbursementException(previousTransaction.getId()); }
|
}
|
||||||
}
|
if (previousTransaction.isDisbursement()) {
|
||||||
if(previousTransaction.isDisbursement()){
|
lastTransactionDate = previousTransaction.getTransactionDate();
|
||||||
lastTransactionDate = previousTransaction.getTransactionDate();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
actualDisbursementDate = lastTransactionDate;
|
actualDisbursementDate = lastTransactionDate;
|
||||||
updateLoanToLastDisbursalState(actualDisbursementDate);
|
updateLoanToLastDisbursalState(actualDisbursementDate);
|
||||||
reverseExistingTransactionsTillLastDisbursal(actualDisbursementDate);
|
reverseExistingTransactionsTillLastDisbursal(actualDisbursementDate);
|
||||||
loan.recalculateScheduleFromLastTransaction(scheduleGeneratorDTO,
|
loan.recalculateScheduleFromLastTransaction(scheduleGeneratorDTO, existingTransactionIds, existingReversedTransactionIds,
|
||||||
existingTransactionIds, existingReversedTransactionIds, currentUser);
|
currentUser);
|
||||||
actualChanges.put("undolastdisbursal","true");
|
actualChanges.put("undolastdisbursal", "true");
|
||||||
actualChanges.put("disbursedAmount",this.getDisbursedAmount());
|
actualChanges.put("disbursedAmount", this.getDisbursedAmount());
|
||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Reverse only disbursement, accruals, and repayments at disbursal transactions
|
|
||||||
* @param actualDisbursementDate
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public List<LoanTransaction> reverseExistingTransactionsTillLastDisbursal(LocalDate actualDisbursementDate) {
|
|
||||||
final List<LoanTransaction> reversedTransactions = new ArrayList<>();
|
|
||||||
for (final LoanTransaction transaction : this.loanTransactions) {
|
|
||||||
if((actualDisbursementDate.equals(transaction.getTransactionDate()) || actualDisbursementDate.isBefore(transaction.getTransactionDate()))
|
|
||||||
&& transaction.isAllowTypeTransactionAtTheTimeOfLastUndo()){
|
|
||||||
reversedTransactions.add(transaction);
|
|
||||||
transaction.reverse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return reversedTransactions;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateLoanToLastDisbursalState(LocalDate actualDisbursementDate) {
|
/**
|
||||||
|
* Reverse only disbursement, accruals, and repayments at disbursal
|
||||||
for (final LoanCharge charge : charges()) {
|
* transactions
|
||||||
if (charge.isOverdueInstallmentCharge()) {
|
*
|
||||||
charge.setActive(false);
|
* @param actualDisbursementDate
|
||||||
} else if (charge.isTrancheDisbursementCharge() && actualDisbursementDate.equals(new LocalDate
|
* @return
|
||||||
(charge.getTrancheDisbursementCharge().getloanDisbursementDetails().actualDisbursementDate()))) {
|
*/
|
||||||
charge.resetToOriginal(loanCurrency());
|
public List<LoanTransaction> reverseExistingTransactionsTillLastDisbursal(LocalDate actualDisbursementDate) {
|
||||||
}
|
final List<LoanTransaction> reversedTransactions = new ArrayList<>();
|
||||||
}
|
for (final LoanTransaction transaction : this.loanTransactions) {
|
||||||
for (final LoanDisbursementDetails details : this.disbursementDetails) {
|
if ((actualDisbursementDate.equals(transaction.getTransactionDate()) || actualDisbursementDate.isBefore(transaction
|
||||||
if (actualDisbursementDate.equals(new LocalDate(details.actualDisbursementDate()))) {
|
.getTransactionDate())) && transaction.isAllowTypeTransactionAtTheTimeOfLastUndo()) {
|
||||||
this.loanRepaymentScheduleDetail.setPrincipal(getDisbursedAmount().subtract(details.principal()));
|
reversedTransactions.add(transaction);
|
||||||
details.updateActualDisbursementDate(null);
|
transaction.reverse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateLoanSummaryDerivedFields();
|
return reversedTransactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateLoanToLastDisbursalState(LocalDate actualDisbursementDate) {
|
||||||
|
|
||||||
|
for (final LoanCharge charge : charges()) {
|
||||||
|
if (charge.isOverdueInstallmentCharge()) {
|
||||||
|
charge.setActive(false);
|
||||||
|
} else if (charge.isTrancheDisbursementCharge()
|
||||||
|
&& actualDisbursementDate.equals(new LocalDate(charge.getTrancheDisbursementCharge().getloanDisbursementDetails()
|
||||||
|
.actualDisbursementDate()))) {
|
||||||
|
charge.resetToOriginal(loanCurrency());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final LoanDisbursementDetails details : this.disbursementDetails) {
|
||||||
|
if (actualDisbursementDate.equals(new LocalDate(details.actualDisbursementDate()))) {
|
||||||
|
this.loanRepaymentScheduleDetail.setPrincipal(getDisbursedAmount().subtract(details.principal()));
|
||||||
|
details.updateActualDisbursementDate(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateLoanSummaryDerivedFields();
|
||||||
|
}
|
||||||
|
|
||||||
public Boolean getIsFloatingInterestRate() {
|
public Boolean getIsFloatingInterestRate() {
|
||||||
return this.isFloatingInterestRate;
|
return this.isFloatingInterestRate;
|
||||||
@@ -5685,5 +5621,5 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
public void setExpectedFirstRepaymentOnDate(Date expectedFirstRepaymentOnDate) {
|
public void setExpectedFirstRepaymentOnDate(Date expectedFirstRepaymentOnDate) {
|
||||||
this.expectedFirstRepaymentOnDate = expectedFirstRepaymentOnDate;
|
this.expectedFirstRepaymentOnDate = expectedFirstRepaymentOnDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-18
@@ -9,9 +9,7 @@ import java.math.BigDecimal;
|
|||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
|
||||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
|
|
||||||
public interface LoanAccountDomainService {
|
public interface LoanAccountDomainService {
|
||||||
@@ -31,11 +29,8 @@ public interface LoanAccountDomainService {
|
|||||||
LoanTransaction makeDisburseTransaction(Long loanId, LocalDate transactionDate, BigDecimal transactionAmount,
|
LoanTransaction makeDisburseTransaction(Long loanId, LocalDate transactionDate, BigDecimal transactionAmount,
|
||||||
PaymentDetail paymentDetail, String noteText, String txnExternalId);
|
PaymentDetail paymentDetail, String noteText, String txnExternalId);
|
||||||
|
|
||||||
LocalDate getCalculatedRepaymentsStartingFromDate(LocalDate actualDisbursementDate, Loan loan, CalendarInstance calendarInstance);
|
LoanTransaction makeRefundForActiveLoan(Long accountId, CommandProcessingResultBuilder builderResult, LocalDate transactionDate,
|
||||||
|
BigDecimal transactionAmount, PaymentDetail paymentDetail, String noteText, String txnExternalId);
|
||||||
LoanTransaction makeRefundForActiveLoan(Long accountId, CommandProcessingResultBuilder builderResult,
|
|
||||||
LocalDate transactionDate, BigDecimal transactionAmount,
|
|
||||||
PaymentDetail paymentDetail, String noteText, String txnExternalId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is to recalculate and accrue the income till the last accrued
|
* This method is to recalculate and accrue the income till the last accrued
|
||||||
@@ -46,17 +41,6 @@ public interface LoanAccountDomainService {
|
|||||||
*/
|
*/
|
||||||
void recalculateAccruals(Loan loan);
|
void recalculateAccruals(Loan loan);
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is used for building ScheduleGeneratorDTO from loan, usages
|
|
||||||
* are as, if have loan and some of the terms are modified which may impact
|
|
||||||
* the schedule, in that case need to recompute the schedule, so this method
|
|
||||||
* helps to build the ScheduleGeneratorDTO from modified loan.
|
|
||||||
*
|
|
||||||
* @param loan
|
|
||||||
*/
|
|
||||||
|
|
||||||
public ScheduleGeneratorDTO buildScheduleGeneratorDTO(final Loan loan);
|
|
||||||
|
|
||||||
void saveLoanWithDataIntegrityViolationChecks(Loan loan);
|
void saveLoanWithDataIntegrityViolationChecks(Loan loan);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-149
@@ -38,30 +38,20 @@ import org.mifosplatform.organisation.workingdays.domain.WorkingDays;
|
|||||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
||||||
import org.mifosplatform.portfolio.account.domain.AccountTransferRepository;
|
import org.mifosplatform.portfolio.account.domain.AccountTransferRepository;
|
||||||
import org.mifosplatform.portfolio.account.domain.AccountTransferTransaction;
|
import org.mifosplatform.portfolio.account.domain.AccountTransferTransaction;
|
||||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
|
||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
|
||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
|
||||||
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.domain.Client;
|
||||||
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
import org.mifosplatform.portfolio.client.exception.ClientNotActiveException;
|
||||||
import org.mifosplatform.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
|
import org.mifosplatform.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
|
||||||
import org.mifosplatform.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
|
import org.mifosplatform.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
|
||||||
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
|
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
|
||||||
import org.mifosplatform.portfolio.common.service.BusinessEventNotifierService;
|
import org.mifosplatform.portfolio.common.service.BusinessEventNotifierService;
|
||||||
import org.mifosplatform.portfolio.floatingrates.data.FloatingRateDTO;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.data.FloatingRatePeriodData;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.exception.FloatingRateNotFoundException;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.service.FloatingRatesReadPlatformService;
|
|
||||||
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.HolidayDetailDTO;
|
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.LoanScheduleAccrualData;
|
import org.mifosplatform.portfolio.loanaccount.data.LoanScheduleAccrualData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
|
||||||
import org.mifosplatform.portfolio.loanaccount.service.LoanAccrualPlatformService;
|
import org.mifosplatform.portfolio.loanaccount.service.LoanAccrualPlatformService;
|
||||||
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.loanaccount.service.LoanUtilService;
|
||||||
import org.mifosplatform.portfolio.note.domain.Note;
|
import org.mifosplatform.portfolio.note.domain.Note;
|
||||||
import org.mifosplatform.portfolio.note.domain.NoteRepository;
|
import org.mifosplatform.portfolio.note.domain.NoteRepository;
|
||||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
@@ -85,14 +75,12 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||||
private final NoteRepository noteRepository;
|
private final NoteRepository noteRepository;
|
||||||
private final AccountTransferRepository accountTransferRepository;
|
private final AccountTransferRepository accountTransferRepository;
|
||||||
private final LoanScheduleGeneratorFactory loanScheduleFactory;
|
|
||||||
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
|
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
|
||||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
|
||||||
private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository;
|
private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository;
|
||||||
private final LoanAccrualPlatformService loanAccrualPlatformService;
|
private final LoanAccrualPlatformService loanAccrualPlatformService;
|
||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final BusinessEventNotifierService businessEventNotifierService;
|
private final BusinessEventNotifierService businessEventNotifierService;
|
||||||
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
|
private final LoanUtilService loanUtilService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanAccountDomainServiceJpa(final LoanAssembler loanAccountAssembler, final LoanRepository loanRepository,
|
public LoanAccountDomainServiceJpa(final LoanAssembler loanAccountAssembler, final LoanRepository loanRepository,
|
||||||
@@ -101,13 +89,11 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
final WorkingDaysRepositoryWrapper workingDaysRepository,
|
final WorkingDaysRepositoryWrapper workingDaysRepository,
|
||||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
|
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
|
||||||
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
||||||
final AccountTransferRepository accountTransferRepository, final LoanScheduleGeneratorFactory loanScheduleFactory,
|
final AccountTransferRepository accountTransferRepository,
|
||||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
||||||
final CalendarInstanceRepository calendarInstanceRepository,
|
|
||||||
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository,
|
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository,
|
||||||
final LoanAccrualPlatformService loanAccrualPlatformService, final PlatformSecurityContext context,
|
final LoanAccrualPlatformService loanAccrualPlatformService, final PlatformSecurityContext context,
|
||||||
final BusinessEventNotifierService businessEventNotifierService,
|
final BusinessEventNotifierService businessEventNotifierService, final LoanUtilService loanUtilService) {
|
||||||
final FloatingRatesReadPlatformService floatingRatesReadPlatformService) {
|
|
||||||
this.loanAccountAssembler = loanAccountAssembler;
|
this.loanAccountAssembler = loanAccountAssembler;
|
||||||
this.loanRepository = loanRepository;
|
this.loanRepository = loanRepository;
|
||||||
this.loanTransactionRepository = loanTransactionRepository;
|
this.loanTransactionRepository = loanTransactionRepository;
|
||||||
@@ -118,31 +104,22 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
|
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
|
||||||
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
||||||
this.accountTransferRepository = accountTransferRepository;
|
this.accountTransferRepository = accountTransferRepository;
|
||||||
this.loanScheduleFactory = loanScheduleFactory;
|
|
||||||
this.applicationCurrencyRepository = applicationCurrencyRepository;
|
this.applicationCurrencyRepository = applicationCurrencyRepository;
|
||||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
|
||||||
this.repaymentScheduleInstallmentRepository = repaymentScheduleInstallmentRepository;
|
this.repaymentScheduleInstallmentRepository = repaymentScheduleInstallmentRepository;
|
||||||
this.loanAccrualPlatformService = loanAccrualPlatformService;
|
this.loanAccrualPlatformService = loanAccrualPlatformService;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.businessEventNotifierService = businessEventNotifierService;
|
this.businessEventNotifierService = businessEventNotifierService;
|
||||||
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
|
this.loanUtilService = loanUtilService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public LoanTransaction makeRepayment(final Loan loan, final CommandProcessingResultBuilder builderResult,
|
public LoanTransaction makeRepayment(final Loan loan, final CommandProcessingResultBuilder builderResult,
|
||||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText,
|
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText,
|
||||||
final String txnExternalId, final boolean isRecoveryRepayment, boolean isAccountTransfer, HolidayDetailDTO holidayDetailDto, Boolean isHolidayValidationDone) {
|
final String txnExternalId, final boolean isRecoveryRepayment, boolean isAccountTransfer, HolidayDetailDTO holidayDetailDto,
|
||||||
|
Boolean isHolidayValidationDone) {
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
AppUser currentUser = getAppUserIfPresent();
|
||||||
checkClientOrGroupActive(loan);
|
checkClientOrGroupActive(loan);
|
||||||
List<Holiday> holidays = null;
|
|
||||||
WorkingDays workingDays = null;
|
|
||||||
boolean allowTransactionsOnHoliday = false;
|
|
||||||
boolean allowTransactionsOnNonWorkingDay = false;
|
|
||||||
HolidayDetailDTO holidayDetailDTO = null;
|
|
||||||
if(holidayDetailDto != null){
|
|
||||||
holidayDetailDTO = holidayDetailDto;
|
|
||||||
}
|
|
||||||
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_MAKE_REPAYMENT,
|
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_MAKE_REPAYMENT,
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
||||||
|
|
||||||
@@ -173,48 +150,12 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
txnExternalId, currentDateTime, currentUser);
|
txnExternalId, currentDateTime, currentUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isHolidayValidationDone){
|
|
||||||
allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
|
||||||
holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
|
|
||||||
transactionDate.toDate(), HolidayStatusType.ACTIVE.getValue());
|
|
||||||
workingDays = this.workingDaysRepository.findOne();
|
|
||||||
allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled();
|
|
||||||
}
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
ApplicationCurrency applicationCurrency = null;
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = null;
|
|
||||||
boolean isHolidayEnabled = false;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
calculatedRepaymentsStartingFromDate = getCalculatedRepaymentsStartingFromDate(loan.getDisbursementDate(), loan,
|
|
||||||
calendarInstance);
|
|
||||||
|
|
||||||
if(!isHolidayValidationDone){
|
|
||||||
isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
}
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
recalculateFrom = transactionDate;
|
recalculateFrom = transactionDate;
|
||||||
}
|
}
|
||||||
if(!isHolidayValidationDone){
|
final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom,
|
||||||
holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday,
|
holidayDetailDto);
|
||||||
allowTransactionsOnNonWorkingDay);
|
|
||||||
}
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
final ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
|
||||||
overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
|
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loan.makeRepayment(newRepaymentTransaction,
|
final ChangedTransactionDetail changedTransactionDetail = loan.makeRepayment(newRepaymentTransaction,
|
||||||
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, isRecoveryRepayment,
|
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, isRecoveryRepayment,
|
||||||
@@ -261,25 +202,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
return newRepaymentTransaction;
|
return newRepaymentTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
private FloatingRateDTO constructFloatingRateDTO(final Loan loan) {
|
|
||||||
FloatingRateDTO floatingRateDTO = null;
|
|
||||||
if (loan.loanProduct().isLinkedToFloatingInterestRate()) {
|
|
||||||
boolean isFloatingInterestRate = loan.getIsFloatingInterestRate();
|
|
||||||
BigDecimal interestRateDiff = loan.getInterestRateDifferential();
|
|
||||||
List<FloatingRatePeriodData> baseLendingRatePeriods = null;
|
|
||||||
try{
|
|
||||||
baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate()
|
|
||||||
.getRatePeriods();
|
|
||||||
}catch(final FloatingRateNotFoundException ex){
|
|
||||||
// Do not do anything
|
|
||||||
}
|
|
||||||
|
|
||||||
floatingRateDTO = new FloatingRateDTO(isFloatingInterestRate, loan.getDisbursementDate(), interestRateDiff,
|
|
||||||
baseLendingRatePeriods);
|
|
||||||
}
|
|
||||||
return floatingRateDTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveLoanTransactionWithDataIntegrityViolationChecks(LoanTransaction newRepaymentTransaction) {
|
private void saveLoanTransactionWithDataIntegrityViolationChecks(LoanTransaction newRepaymentTransaction) {
|
||||||
try {
|
try {
|
||||||
this.loanTransactionRepository.save(newRepaymentTransaction);
|
this.loanTransactionRepository.save(newRepaymentTransaction);
|
||||||
@@ -316,7 +238,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
"Validation errors exist.", dataValidationErrors); }
|
"Validation errors exist.", dataValidationErrors); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveLoanWithDataIntegrityViolationChecks(final Loan loan) {
|
public void saveLoanWithDataIntegrityViolationChecks(final Loan loan) {
|
||||||
try {
|
try {
|
||||||
@@ -492,34 +414,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
saveLoanTransactionWithDataIntegrityViolationChecks(loanTransaction);
|
saveLoanTransactionWithDataIntegrityViolationChecks(loanTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocalDate getCalculatedRepaymentsStartingFromDate(final LocalDate actualDisbursementDate, final Loan loan,
|
|
||||||
final CalendarInstance calendarInstance) {
|
|
||||||
final Calendar calendar = calendarInstance == null ? null : calendarInstance.getCalendar();
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = loan.getExpectedFirstRepaymentOnDate();
|
|
||||||
if (calendar != null) {// sync repayments
|
|
||||||
|
|
||||||
// TODO: AA - user provided first repayment date takes precedence
|
|
||||||
// over recalculated meeting date
|
|
||||||
if (calculatedRepaymentsStartingFromDate == null) {
|
|
||||||
// FIXME: AA - Possibility of having next meeting date
|
|
||||||
// immediately after disbursement date,
|
|
||||||
// need to have minimum number of days gap between disbursement
|
|
||||||
// and first repayment date.
|
|
||||||
final LoanProductRelatedDetail repaymentScheduleDetails = loan.repaymentScheduleDetail();
|
|
||||||
if (repaymentScheduleDetails != null) {// Not expecting to be
|
|
||||||
// null
|
|
||||||
final Integer repayEvery = repaymentScheduleDetails.getRepayEvery();
|
|
||||||
final String frequency = CalendarUtils.getMeetingFrequencyFromPeriodFrequencyType(repaymentScheduleDetails
|
|
||||||
.getRepaymentPeriodFrequencyType());
|
|
||||||
calculatedRepaymentsStartingFromDate = CalendarUtils.getFirstRepaymentMeetingDate(calendar, actualDisbursementDate,
|
|
||||||
repayEvery, frequency);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return calculatedRepaymentsStartingFromDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
@@ -594,39 +488,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ScheduleGeneratorDTO buildScheduleGeneratorDTO(final Loan loan) {
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = this.getCalculatedRepaymentsStartingFromDate(loan.getDisbursementDate(), loan,
|
|
||||||
calendarInstance);
|
|
||||||
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan
|
|
||||||
.getExpectedDisbursedOnLocalDate().toDate(), HolidayStatusType.ACTIVE.getValue());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
|
||||||
final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled();
|
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday,
|
|
||||||
allowTransactionsOnNonWorkingDay);
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
}
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, floatingRateDTO);
|
|
||||||
|
|
||||||
return scheduleGeneratorDTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AppUser getAppUserIfPresent() {
|
private AppUser getAppUserIfPresent() {
|
||||||
AppUser user = null;
|
AppUser user = null;
|
||||||
if (this.context != null) {
|
if (this.context != null) {
|
||||||
|
|||||||
+21
-25
@@ -1520,7 +1520,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
|| loanApplicationTerms.getInterestChargedFromLocalDate().isAfter(periodStartDate)) {
|
|| loanApplicationTerms.getInterestChargedFromLocalDate().isAfter(periodStartDate)) {
|
||||||
periodStartDateApplicableForInterest = loanApplicationTerms.getInterestChargedFromLocalDate();
|
periodStartDateApplicableForInterest = loanApplicationTerms.getInterestChargedFromLocalDate();
|
||||||
}
|
}
|
||||||
} else if(periodStartDate.isEqual(loanApplicationTerms.getExpectedDisbursementDate())){
|
} else if (periodStartDate.isEqual(loanApplicationTerms.getExpectedDisbursementDate())) {
|
||||||
periodStartDateApplicableForInterest = idealDisbursementDate;
|
periodStartDateApplicableForInterest = idealDisbursementDate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2023,6 +2023,18 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor,
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor,
|
||||||
final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final LocalDate rescheduleFrom) {
|
final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final LocalDate rescheduleFrom) {
|
||||||
|
|
||||||
|
// Fixed schedule End Date for generating schedule
|
||||||
|
final LocalDate scheduleTillDate = null;
|
||||||
|
return rescheduleNextInstallments(mc, loanApplicationTerms, loanCharges, holidayDetailDTO, transactions,
|
||||||
|
loanRepaymentScheduleTransactionProcessor, repaymentScheduleInstallments, rescheduleFrom, scheduleTillDate);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoanScheduleDTO rescheduleNextInstallments(final MathContext mc, final LoanApplicationTerms loanApplicationTerms,
|
||||||
|
final Set<LoanCharge> loanCharges, final HolidayDetailDTO holidayDetailDTO, final List<LoanTransaction> transactions,
|
||||||
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor,
|
||||||
|
final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final LocalDate rescheduleFrom,
|
||||||
|
final LocalDate scheduleTillDate) {
|
||||||
// Loan transactions to process and find the variation on payments
|
// Loan transactions to process and find the variation on payments
|
||||||
Collection<RecalculationDetail> recalculationDetails = new ArrayList<>();
|
Collection<RecalculationDetail> recalculationDetails = new ArrayList<>();
|
||||||
for (LoanTransaction loanTransaction : transactions) {
|
for (LoanTransaction loanTransaction : transactions) {
|
||||||
@@ -2031,8 +2043,6 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
}
|
}
|
||||||
final boolean applyInterestRecalculation = loanApplicationTerms.isInterestRecalculationEnabled();
|
final boolean applyInterestRecalculation = loanApplicationTerms.isInterestRecalculationEnabled();
|
||||||
|
|
||||||
// Fixed schedule End Date for generating schedule
|
|
||||||
final LocalDate scheduleTillDate = null;
|
|
||||||
LoanScheduleParams loanScheduleParams = null;
|
LoanScheduleParams loanScheduleParams = null;
|
||||||
Collection<LoanScheduleModelPeriod> periods = new ArrayList<>();
|
Collection<LoanScheduleModelPeriod> periods = new ArrayList<>();
|
||||||
final List<LoanRepaymentScheduleInstallment> retainedInstallments = new ArrayList<>();
|
final List<LoanRepaymentScheduleInstallment> retainedInstallments = new ArrayList<>();
|
||||||
@@ -2259,7 +2269,6 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
periods.addAll(loanScheduleModel.getPeriods());
|
periods.addAll(loanScheduleModel.getPeriods());
|
||||||
LoanScheduleModel loanScheduleModelwithPeriodChanges = LoanScheduleModel.withLoanScheduleModelPeriods(periods, loanScheduleModel);
|
LoanScheduleModel loanScheduleModelwithPeriodChanges = LoanScheduleModel.withLoanScheduleModelPeriods(periods, loanScheduleModel);
|
||||||
return LoanScheduleDTO.from(retainedInstallments, loanScheduleModelwithPeriodChanges);
|
return LoanScheduleDTO.from(retainedInstallments, loanScheduleModelwithPeriodChanges);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2368,14 +2377,6 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
return principalPortionCalculated;
|
return principalPortionCalculated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<LoanRepaymentScheduleInstallment> fetchInstallmentsFromScheduleModel(final LoanScheduleModel loanScheduleModel) {
|
|
||||||
final List<LoanRepaymentScheduleInstallment> installments = new ArrayList<>();
|
|
||||||
for (LoanScheduleModelPeriod loanScheduleModelPeriod : loanScheduleModel.getPeriods()) {
|
|
||||||
addLoanRepaymentScheduleInstallment(installments, loanScheduleModelPeriod);
|
|
||||||
}
|
|
||||||
return installments;
|
|
||||||
}
|
|
||||||
|
|
||||||
private LoanRepaymentScheduleInstallment addLoanRepaymentScheduleInstallment(final List<LoanRepaymentScheduleInstallment> installments,
|
private LoanRepaymentScheduleInstallment addLoanRepaymentScheduleInstallment(final List<LoanRepaymentScheduleInstallment> installments,
|
||||||
final LoanScheduleModelPeriod scheduledLoanInstallment) {
|
final LoanScheduleModelPeriod scheduledLoanInstallment) {
|
||||||
LoanRepaymentScheduleInstallment installment = null;
|
LoanRepaymentScheduleInstallment installment = null;
|
||||||
@@ -2437,29 +2438,24 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
public LoanRepaymentScheduleInstallment calculatePrepaymentAmount(final MonetaryCurrency currency, final LocalDate onDate,
|
public LoanRepaymentScheduleInstallment calculatePrepaymentAmount(final MonetaryCurrency currency, final LocalDate onDate,
|
||||||
final LoanApplicationTerms loanApplicationTerms, final MathContext mc, final Set<LoanCharge> charges,
|
final LoanApplicationTerms loanApplicationTerms, final MathContext mc, final Set<LoanCharge> charges,
|
||||||
final HolidayDetailDTO holidayDetailDTO, final List<LoanTransaction> loanTransactions,
|
final HolidayDetailDTO holidayDetailDTO, final List<LoanTransaction> loanTransactions,
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor) {
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor,
|
||||||
|
final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments) {
|
||||||
|
|
||||||
LocalDate calculateTill = onDate;
|
LocalDate calculateTill = onDate;
|
||||||
if (loanApplicationTerms.getPreClosureInterestCalculationStrategy().calculateTillRestFrequencyEnabled()) {
|
if (loanApplicationTerms.getPreClosureInterestCalculationStrategy().calculateTillRestFrequencyEnabled()) {
|
||||||
calculateTill = getNextRestScheduleDate(onDate.minusDays(1), loanApplicationTerms, holidayDetailDTO);
|
calculateTill = getNextRestScheduleDate(onDate.minusDays(1), loanApplicationTerms, holidayDetailDTO);
|
||||||
}
|
}
|
||||||
Collection<RecalculationDetail> recalculationDetails = new ArrayList<>();
|
|
||||||
for (LoanTransaction loanTransaction : loanTransactions) {
|
LoanScheduleDTO loanScheduleDTO = rescheduleNextInstallments(mc, loanApplicationTerms, charges, holidayDetailDTO, loanTransactions,
|
||||||
recalculationDetails.add(new RecalculationDetail(loanTransaction.getTransactionDate(), LoanTransaction
|
loanRepaymentScheduleTransactionProcessor, repaymentScheduleInstallments, onDate, calculateTill);
|
||||||
.copyTransactionProperties(loanTransaction)));
|
|
||||||
}
|
|
||||||
final boolean applyInterestRecalculation = loanApplicationTerms.isInterestRecalculationEnabled();
|
|
||||||
LoanScheduleParams loanScheduleRecalculationDTO = LoanScheduleParams.createLoanScheduleParamsForCompleteUpdate(
|
|
||||||
recalculationDetails, loanRepaymentScheduleTransactionProcessor, calculateTill, applyInterestRecalculation);
|
|
||||||
LoanScheduleModel loanScheduleModel = generate(mc, loanApplicationTerms, charges, holidayDetailDTO, loanScheduleRecalculationDTO);
|
|
||||||
List<LoanRepaymentScheduleInstallment> installments = fetchInstallmentsFromScheduleModel(loanScheduleModel);
|
|
||||||
loanRepaymentScheduleTransactionProcessor.handleTransaction(loanApplicationTerms.getExpectedDisbursementDate(), loanTransactions,
|
loanRepaymentScheduleTransactionProcessor.handleTransaction(loanApplicationTerms.getExpectedDisbursementDate(), loanTransactions,
|
||||||
currency, installments, charges);
|
currency, loanScheduleDTO.getInstallments(), charges);
|
||||||
Money feeCharges = Money.zero(currency);
|
Money feeCharges = Money.zero(currency);
|
||||||
Money penaltyCharges = Money.zero(currency);
|
Money penaltyCharges = Money.zero(currency);
|
||||||
Money totalPrincipal = Money.zero(currency);
|
Money totalPrincipal = Money.zero(currency);
|
||||||
Money totalInterest = Money.zero(currency);
|
Money totalInterest = Money.zero(currency);
|
||||||
for (final LoanRepaymentScheduleInstallment currentInstallment : installments) {
|
for (final LoanRepaymentScheduleInstallment currentInstallment : loanScheduleDTO.getInstallments()) {
|
||||||
if (currentInstallment.isNotFullyPaidOff()) {
|
if (currentInstallment.isNotFullyPaidOff()) {
|
||||||
totalPrincipal = totalPrincipal.plus(currentInstallment.getPrincipalOutstanding(currency));
|
totalPrincipal = totalPrincipal.plus(currentInstallment.getPrincipalOutstanding(currency));
|
||||||
totalInterest = totalInterest.plus(currentInstallment.getInterestOutstanding(currency));
|
totalInterest = totalInterest.plus(currentInstallment.getInterestOutstanding(currency));
|
||||||
|
|||||||
+6
-4
@@ -31,11 +31,13 @@ public interface LoanScheduleGenerator {
|
|||||||
|
|
||||||
LoanScheduleDTO rescheduleNextInstallments(MathContext mc, LoanApplicationTerms loanApplicationTerms, Set<LoanCharge> loanCharges,
|
LoanScheduleDTO rescheduleNextInstallments(MathContext mc, LoanApplicationTerms loanApplicationTerms, Set<LoanCharge> loanCharges,
|
||||||
final HolidayDetailDTO holidayDetailDTO, List<LoanTransaction> transactions,
|
final HolidayDetailDTO holidayDetailDTO, List<LoanTransaction> transactions,
|
||||||
LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, LocalDate rescheduleFrom);
|
LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor,
|
||||||
|
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, LocalDate rescheduleFrom);
|
||||||
|
|
||||||
LoanRepaymentScheduleInstallment calculatePrepaymentAmount(MonetaryCurrency currency,
|
LoanRepaymentScheduleInstallment calculatePrepaymentAmount(MonetaryCurrency currency, LocalDate onDate,
|
||||||
LocalDate onDate, LoanApplicationTerms loanApplicationTerms, MathContext mc, Set<LoanCharge> charges,
|
LoanApplicationTerms loanApplicationTerms, MathContext mc, Set<LoanCharge> charges, HolidayDetailDTO holidayDetailDTO,
|
||||||
HolidayDetailDTO holidayDetailDTO, List<LoanTransaction> loanTransactions, LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor);
|
List<LoanTransaction> loanTransactions, LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor,
|
||||||
|
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments);
|
||||||
|
|
||||||
LoanRescheduleModel reschedule(final MathContext mathContext, final LoanRescheduleRequest loanRescheduleRequest,
|
LoanRescheduleModel reschedule(final MathContext mathContext, final LoanRescheduleRequest loanRescheduleRequest,
|
||||||
final ApplicationCurrency applicationCurrency, final HolidayDetailDTO holidayDetailDTO, CalendarInstance restCalendarInstance,
|
final ApplicationCurrency applicationCurrency, final HolidayDetailDTO holidayDetailDTO, CalendarInstance restCalendarInstance,
|
||||||
|
|||||||
+27
-6
@@ -307,7 +307,10 @@ public class LoanScheduleAssembler {
|
|||||||
LoanProductInterestRecalculationDetails loanProductInterestRecalculationDetails = loanProduct
|
LoanProductInterestRecalculationDetails loanProductInterestRecalculationDetails = loanProduct
|
||||||
.getProductInterestRecalculationDetails();
|
.getProductInterestRecalculationDetails();
|
||||||
recalculationFrequencyType = loanProductInterestRecalculationDetails.getRestFrequencyType();
|
recalculationFrequencyType = loanProductInterestRecalculationDetails.getRestFrequencyType();
|
||||||
if (!recalculationFrequencyType.isSameAsRepayment()) {
|
if (recalculationFrequencyType.isSameAsRepayment()) {
|
||||||
|
restCalendarInstance = createCalendarForSameAsRepayment(repaymentEvery, repaymentPeriodFrequencyType,
|
||||||
|
expectedDisbursementDate);
|
||||||
|
} else {
|
||||||
LocalDate calendarStartDate = this.fromApiJsonHelper.extractLocalDateNamed(
|
LocalDate calendarStartDate = this.fromApiJsonHelper.extractLocalDateNamed(
|
||||||
LoanProductConstants.recalculationRestFrequencyDateParamName, element);
|
LoanProductConstants.recalculationRestFrequencyDateParamName, element);
|
||||||
if (calendarStartDate == null) {
|
if (calendarStartDate == null) {
|
||||||
@@ -320,7 +323,10 @@ public class LoanScheduleAssembler {
|
|||||||
.fromInt(loanProductInterestRecalculationDetails.getInterestRecalculationCompoundingMethod());
|
.fromInt(loanProductInterestRecalculationDetails.getInterestRecalculationCompoundingMethod());
|
||||||
if (compoundingMethod.isCompoundingEnabled()) {
|
if (compoundingMethod.isCompoundingEnabled()) {
|
||||||
compoundingFrequencyType = loanProductInterestRecalculationDetails.getCompoundingFrequencyType();
|
compoundingFrequencyType = loanProductInterestRecalculationDetails.getCompoundingFrequencyType();
|
||||||
if (!compoundingFrequencyType.isSameAsRepayment()) {
|
if (compoundingFrequencyType.isSameAsRepayment()) {
|
||||||
|
compoundingCalendarInstance = createCalendarForSameAsRepayment(repaymentEvery, repaymentPeriodFrequencyType,
|
||||||
|
expectedDisbursementDate);
|
||||||
|
} else {
|
||||||
LocalDate calendarStartDate = this.fromApiJsonHelper.extractLocalDateNamed(
|
LocalDate calendarStartDate = this.fromApiJsonHelper.extractLocalDateNamed(
|
||||||
LoanProductConstants.recalculationCompoundingFrequencyDateParamName, element);
|
LoanProductConstants.recalculationCompoundingFrequencyDateParamName, element);
|
||||||
if (calendarStartDate == null) {
|
if (calendarStartDate == null) {
|
||||||
@@ -380,9 +386,16 @@ public class LoanScheduleAssembler {
|
|||||||
calendar, BigDecimal.ZERO, loanTermVariations);
|
calendar, BigDecimal.ZERO, loanTermVariations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CalendarInstance createCalendarForSameAsRepayment(final Integer repaymentEvery,
|
||||||
|
final PeriodFrequencyType repaymentPeriodFrequencyType, final LocalDate expectedDisbursementDate) {
|
||||||
|
|
||||||
|
CalendarInstance restCalendarInstance = createInterestRecalculationCalendarInstance(expectedDisbursementDate, repaymentEvery,
|
||||||
|
CalendarFrequencyType.from(repaymentPeriodFrequencyType));
|
||||||
|
return restCalendarInstance;
|
||||||
|
}
|
||||||
|
|
||||||
private CalendarInstance createInterestRecalculationCalendarInstance(final LocalDate calendarStartDate,
|
private CalendarInstance createInterestRecalculationCalendarInstance(final LocalDate calendarStartDate,
|
||||||
final RecalculationFrequencyType recalculationFrequencyType, final Integer frequency) {
|
final RecalculationFrequencyType recalculationFrequencyType, final Integer frequency) {
|
||||||
final Integer repeatsOnDay = calendarStartDate.getDayOfWeek();
|
|
||||||
|
|
||||||
CalendarFrequencyType calendarFrequencyType = CalendarFrequencyType.INVALID;
|
CalendarFrequencyType calendarFrequencyType = CalendarFrequencyType.INVALID;
|
||||||
switch (recalculationFrequencyType) {
|
switch (recalculationFrequencyType) {
|
||||||
@@ -399,6 +412,12 @@ public class LoanScheduleAssembler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return createInterestRecalculationCalendarInstance(calendarStartDate, frequency, calendarFrequencyType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CalendarInstance createInterestRecalculationCalendarInstance(final LocalDate calendarStartDate, final Integer frequency,
|
||||||
|
CalendarFrequencyType calendarFrequencyType) {
|
||||||
|
final Integer repeatsOnDay = calendarStartDate.getDayOfWeek();
|
||||||
final String title = "loan_recalculation_detail";
|
final String title = "loan_recalculation_detail";
|
||||||
final Calendar calendar = Calendar.createRepeatingCalendar(title, calendarStartDate, CalendarType.COLLECTION.getValue(),
|
final Calendar calendar = Calendar.createRepeatingCalendar(title, calendarStartDate, CalendarType.COLLECTION.getValue(),
|
||||||
calendarFrequencyType, frequency, repeatsOnDay);
|
calendarFrequencyType, frequency, repeatsOnDay);
|
||||||
@@ -549,7 +568,8 @@ public class LoanScheduleAssembler {
|
|||||||
public LoanRepaymentScheduleInstallment calculatePrepaymentAmount(MonetaryCurrency currency, LocalDate onDate,
|
public LoanRepaymentScheduleInstallment calculatePrepaymentAmount(MonetaryCurrency currency, LocalDate onDate,
|
||||||
LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final Long officeId,
|
LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final Long officeId,
|
||||||
List<LoanTransaction> loanTransactions,
|
List<LoanTransaction> loanTransactions,
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor) {
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor,
|
||||||
|
final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments) {
|
||||||
final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(loanApplicationTerms.getInterestMethod());
|
final LoanScheduleGenerator loanScheduleGenerator = this.loanScheduleFactory.create(loanApplicationTerms.getInterestMethod());
|
||||||
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
|
final RoundingMode roundingMode = MoneyHelper.getRoundingMode();
|
||||||
final MathContext mc = new MathContext(8, roundingMode);
|
final MathContext mc = new MathContext(8, roundingMode);
|
||||||
@@ -561,7 +581,7 @@ public class LoanScheduleAssembler {
|
|||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
||||||
|
|
||||||
return loanScheduleGenerator.calculatePrepaymentAmount(currency, onDate, loanApplicationTerms, mc, loanCharges, holidayDetailDTO,
|
return loanScheduleGenerator.calculatePrepaymentAmount(currency, onDate, loanApplicationTerms, mc, loanCharges, holidayDetailDTO,
|
||||||
loanTransactions, loanRepaymentScheduleTransactionProcessor);
|
loanTransactions, loanRepaymentScheduleTransactionProcessor, repaymentScheduleInstallments);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,7 +756,8 @@ public class LoanScheduleAssembler {
|
|||||||
if (loan.getExpectedFirstRepaymentOnDate() == null) {
|
if (loan.getExpectedFirstRepaymentOnDate() == null) {
|
||||||
loan.setExpectedFirstRepaymentOnDate(loan.fetchRepaymentScheduleInstallment(1).getDueDate().toDate());
|
loan.setExpectedFirstRepaymentOnDate(loan.fetchRepaymentScheduleInstallment(1).getDueDate().toDate());
|
||||||
}
|
}
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan);
|
final LocalDate recalculateFrom = null;
|
||||||
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
AppUser currentUser = this.context.getAuthenticatedUserIfPresent();
|
AppUser currentUser = this.context.getAuthenticatedUserIfPresent();
|
||||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-54
@@ -22,21 +22,12 @@ import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidation
|
|||||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
|
||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
|
import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
|
import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
|
||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
|
||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstanceRepository;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.data.FloatingRateDTO;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.data.FloatingRatePeriodData;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.exception.FloatingRateNotFoundException;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.service.FloatingRatesReadPlatformService;
|
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanAccountDomainService;
|
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanDisbursementDetails;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanDisbursementDetails;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
||||||
@@ -50,6 +41,7 @@ import org.mifosplatform.portfolio.loanaccount.serialization.CalculateLoanSchedu
|
|||||||
import org.mifosplatform.portfolio.loanaccount.serialization.LoanApplicationCommandFromApiJsonHelper;
|
import org.mifosplatform.portfolio.loanaccount.serialization.LoanApplicationCommandFromApiJsonHelper;
|
||||||
import org.mifosplatform.portfolio.loanaccount.service.LoanAssembler;
|
import org.mifosplatform.portfolio.loanaccount.service.LoanAssembler;
|
||||||
import org.mifosplatform.portfolio.loanaccount.service.LoanReadPlatformService;
|
import org.mifosplatform.portfolio.loanaccount.service.LoanReadPlatformService;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.service.LoanUtilService;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository;
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository;
|
||||||
import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
||||||
@@ -68,25 +60,20 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
|||||||
private final LoanReadPlatformService loanReadPlatformService;
|
private final LoanReadPlatformService loanReadPlatformService;
|
||||||
private final LoanApplicationCommandFromApiJsonHelper loanApiJsonDeserializer;
|
private final LoanApplicationCommandFromApiJsonHelper loanApiJsonDeserializer;
|
||||||
private final LoanAssembler loanAssembler;
|
private final LoanAssembler loanAssembler;
|
||||||
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
|
|
||||||
private final LoanAccountDomainService accountDomainService;
|
|
||||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
|
||||||
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
||||||
private final ConfigurationDomainService configurationDomainService;
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
|
|
||||||
private final CurrencyReadPlatformService currencyReadPlatformService;
|
private final CurrencyReadPlatformService currencyReadPlatformService;
|
||||||
|
private final LoanUtilService loanUtilService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanScheduleCalculationPlatformServiceImpl(final CalculateLoanScheduleQueryFromApiJsonHelper fromApiJsonDeserializer,
|
public LoanScheduleCalculationPlatformServiceImpl(final CalculateLoanScheduleQueryFromApiJsonHelper fromApiJsonDeserializer,
|
||||||
final LoanScheduleAssembler loanScheduleAssembler, final FromJsonHelper fromJsonHelper,
|
final LoanScheduleAssembler loanScheduleAssembler, final FromJsonHelper fromJsonHelper,
|
||||||
final LoanProductRepository loanProductRepository, final LoanProductDataValidator loanProductCommandFromApiJsonDeserializer,
|
final LoanProductRepository loanProductRepository, final LoanProductDataValidator loanProductCommandFromApiJsonDeserializer,
|
||||||
final LoanReadPlatformService loanReadPlatformService, final LoanApplicationCommandFromApiJsonHelper loanApiJsonDeserializer,
|
final LoanReadPlatformService loanReadPlatformService, final LoanApplicationCommandFromApiJsonHelper loanApiJsonDeserializer,
|
||||||
final LoanAssembler loanAssembler, final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
final LoanAssembler loanAssembler,
|
||||||
final LoanAccountDomainService accountDomainService, final CalendarInstanceRepository calendarInstanceRepository,
|
|
||||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||||
final ConfigurationDomainService configurationDomainService,
|
final ConfigurationDomainService configurationDomainService, final CurrencyReadPlatformService currencyReadPlatformService,
|
||||||
final FloatingRatesReadPlatformService floatingRatesReadPlatformService,
|
final LoanUtilService loanUtilService) {
|
||||||
final CurrencyReadPlatformService currencyReadPlatformService) {
|
|
||||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||||
this.loanScheduleAssembler = loanScheduleAssembler;
|
this.loanScheduleAssembler = loanScheduleAssembler;
|
||||||
this.fromJsonHelper = fromJsonHelper;
|
this.fromJsonHelper = fromJsonHelper;
|
||||||
@@ -95,13 +82,10 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
|||||||
this.loanReadPlatformService = loanReadPlatformService;
|
this.loanReadPlatformService = loanReadPlatformService;
|
||||||
this.loanApiJsonDeserializer = loanApiJsonDeserializer;
|
this.loanApiJsonDeserializer = loanApiJsonDeserializer;
|
||||||
this.loanAssembler = loanAssembler;
|
this.loanAssembler = loanAssembler;
|
||||||
this.applicationCurrencyRepository = applicationCurrencyRepository;
|
|
||||||
this.accountDomainService = accountDomainService;
|
|
||||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
|
||||||
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
|
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
|
||||||
this.configurationDomainService = configurationDomainService;
|
this.configurationDomainService = configurationDomainService;
|
||||||
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
|
|
||||||
this.currencyReadPlatformService = currencyReadPlatformService;
|
this.currencyReadPlatformService = currencyReadPlatformService;
|
||||||
|
this.loanUtilService = loanUtilService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -174,7 +158,8 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
|||||||
LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(loan);
|
LoanApplicationTerms loanApplicationTerms = constructLoanApplicationTerms(loan);
|
||||||
LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = this.loanScheduleAssembler.calculatePrepaymentAmount(currency,
|
LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = this.loanScheduleAssembler.calculatePrepaymentAmount(currency,
|
||||||
today, loanApplicationTerms, loan.charges(), loan.getOfficeId(),
|
today, loanApplicationTerms, loan.charges(), loan.getOfficeId(),
|
||||||
loan.retreiveListOfTransactionsPostDisbursementExcludeAccruals(), loanRepaymentScheduleTransactionProcessor);
|
loan.retreiveListOfTransactionsPostDisbursementExcludeAccruals(), loanRepaymentScheduleTransactionProcessor,
|
||||||
|
loan.fetchRepaymentScheduleInstallments());
|
||||||
Money totalAmount = totalPrincipal.plus(loanRepaymentScheduleInstallment.getFeeChargesOutstanding(currency)).plus(
|
Money totalAmount = totalPrincipal.plus(loanRepaymentScheduleInstallment.getFeeChargesOutstanding(currency)).plus(
|
||||||
loanRepaymentScheduleInstallment.getPenaltyChargesOutstanding(currency));
|
loanRepaymentScheduleInstallment.getPenaltyChargesOutstanding(currency));
|
||||||
Money interestDue = Money.zero(currency);
|
Money interestDue = Money.zero(currency);
|
||||||
@@ -278,37 +263,10 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
|
|||||||
}
|
}
|
||||||
|
|
||||||
private LoanApplicationTerms constructLoanApplicationTerms(final Loan loan) {
|
private LoanApplicationTerms constructLoanApplicationTerms(final Loan loan) {
|
||||||
MonetaryCurrency currency = loan.getCurrency();
|
final LocalDate recalculateFrom = null;
|
||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
LoanApplicationTerms loanApplicationTerms = loan.constructLoanApplicationTerms(scheduleGeneratorDTO);
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
final CalendarInstance restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
final CalendarInstance compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = accountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
LoanApplicationTerms loanApplicationTerms = loan.constructLoanApplicationTerms(applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, restCalendarInstance, compoundingCalendarInstance, floatingRateDTO);
|
|
||||||
return loanApplicationTerms;
|
return loanApplicationTerms;
|
||||||
}
|
}
|
||||||
|
|
||||||
private FloatingRateDTO constructFloatingRateDTO(final Loan loan) {
|
|
||||||
FloatingRateDTO floatingRateDTO = null;
|
|
||||||
if (loan.loanProduct().isLinkedToFloatingInterestRate()) {
|
|
||||||
boolean isFloatingInterestRate = loan.getIsFloatingInterestRate();
|
|
||||||
BigDecimal interestRateDiff = loan.getInterestRateDifferential();
|
|
||||||
List<FloatingRatePeriodData> baseLendingRatePeriods = null;
|
|
||||||
try {
|
|
||||||
baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate().getRatePeriods();
|
|
||||||
} catch (final FloatingRateNotFoundException ex) {
|
|
||||||
// Do not do anything
|
|
||||||
}
|
|
||||||
floatingRateDTO = new FloatingRateDTO(isFloatingInterestRate, loan.getDisbursementDate(), interestRateDiff,
|
|
||||||
baseLendingRatePeriods);
|
|
||||||
}
|
|
||||||
return floatingRateDTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+3
-1
@@ -10,6 +10,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||||
@@ -87,7 +88,8 @@ public class LoanScheduleWritePlatformServiceImpl implements LoanScheduleWritePl
|
|||||||
final Map<String, Object> changes = new HashMap<>();
|
final Map<String, Object> changes = new HashMap<>();
|
||||||
changes.put("removedEntityIds", deletedVariations);
|
changes.put("removedEntityIds", deletedVariations);
|
||||||
loan.getLoanTermVariations().clear();
|
loan.getLoanTermVariations().clear();
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan);
|
final LocalDate recalculateFrom = null;
|
||||||
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
AppUser currentUser = this.context.getAuthenticatedUserIfPresent();
|
AppUser currentUser = this.context.getAuthenticatedUserIfPresent();
|
||||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
||||||
this.loanAccountDomainService.saveLoanWithDataIntegrityViolationChecks(loan);
|
this.loanAccountDomainService.saveLoanWithDataIntegrityViolationChecks(loan);
|
||||||
|
|||||||
+39
-47
@@ -8,7 +8,13 @@ package org.mifosplatform.portfolio.loanaccount.rescheduleloan.service;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.joda.time.format.DateTimeFormat;
|
import org.joda.time.format.DateTimeFormat;
|
||||||
@@ -43,17 +49,34 @@ import org.mifosplatform.portfolio.floatingrates.service.FloatingRatesReadPlatfo
|
|||||||
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.LoanChargePaidByData;
|
import org.mifosplatform.portfolio.loanaccount.data.LoanChargePaidByData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.*;
|
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanInstallmentCharge;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepositoryWrapper;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanSummary;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanSummaryWrapper;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanRepaymentScheduleHistory;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanRepaymentScheduleHistory;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanRepaymentScheduleHistoryRepository;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanRepaymentScheduleHistoryRepository;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanScheduleHistoryWritePlatformService;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.service.LoanScheduleHistoryWritePlatformService;
|
||||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.RescheduleLoansApiConstants;
|
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.RescheduleLoansApiConstants;
|
||||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.data.LoanRescheduleRequestDataValidator;
|
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.data.LoanRescheduleRequestDataValidator;
|
||||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.*;
|
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.DefaultLoanReschedulerFactory;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleModel;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleModelRepaymentPeriod;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequestRepository;
|
||||||
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.exception.LoanRescheduleRequestNotFoundException;
|
import org.mifosplatform.portfolio.loanaccount.rescheduleloan.exception.LoanRescheduleRequestNotFoundException;
|
||||||
import org.mifosplatform.portfolio.loanaccount.service.LoanAssembler;
|
import org.mifosplatform.portfolio.loanaccount.service.LoanAssembler;
|
||||||
import org.mifosplatform.portfolio.loanaccount.service.LoanChargeReadPlatformService;
|
import org.mifosplatform.portfolio.loanaccount.service.LoanChargeReadPlatformService;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.service.LoanUtilService;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductMinimumRepaymentScheduleRelatedDetail;
|
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductMinimumRepaymentScheduleRelatedDetail;
|
||||||
import org.mifosplatform.useradministration.domain.AppUser;
|
import org.mifosplatform.useradministration.domain.AppUser;
|
||||||
@@ -81,14 +104,13 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
|||||||
private final LoanRepaymentScheduleHistoryRepository loanRepaymentScheduleHistoryRepository;
|
private final LoanRepaymentScheduleHistoryRepository loanRepaymentScheduleHistoryRepository;
|
||||||
private final LoanScheduleHistoryWritePlatformService loanScheduleHistoryWritePlatformService;
|
private final LoanScheduleHistoryWritePlatformService loanScheduleHistoryWritePlatformService;
|
||||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||||
private final LoanAccountDomainService loanAccountDomainService;
|
|
||||||
private final LoanChargeReadPlatformService loanChargeReadPlatformService;
|
private final LoanChargeReadPlatformService loanChargeReadPlatformService;
|
||||||
private final LoanScheduleGeneratorFactory loanScheduleFactory;
|
|
||||||
private final LoanTransactionRepository loanTransactionRepository;
|
private final LoanTransactionRepository loanTransactionRepository;
|
||||||
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||||
private final LoanRepository loanRepository;
|
private final LoanRepository loanRepository;
|
||||||
private final LoanAssembler loanAssembler;
|
private final LoanAssembler loanAssembler;
|
||||||
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
|
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
|
||||||
|
private final LoanUtilService loanUtilService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LoanRescheduleRequestWritePlatformServiceImpl constructor
|
* LoanRescheduleRequestWritePlatformServiceImpl constructor
|
||||||
@@ -104,11 +126,11 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
|||||||
HolidayRepositoryWrapper holidayRepository, WorkingDaysRepositoryWrapper workingDaysRepository,
|
HolidayRepositoryWrapper holidayRepository, WorkingDaysRepositoryWrapper workingDaysRepository,
|
||||||
LoanRepaymentScheduleHistoryRepository loanRepaymentScheduleHistoryRepository,
|
LoanRepaymentScheduleHistoryRepository loanRepaymentScheduleHistoryRepository,
|
||||||
final LoanScheduleHistoryWritePlatformService loanScheduleHistoryWritePlatformService,
|
final LoanScheduleHistoryWritePlatformService loanScheduleHistoryWritePlatformService,
|
||||||
final CalendarInstanceRepository calendarInstanceRepository, final LoanAccountDomainService loanAccountDomainService,
|
final CalendarInstanceRepository calendarInstanceRepository, final LoanChargeReadPlatformService loanChargeReadPlatformService,
|
||||||
final LoanChargeReadPlatformService loanChargeReadPlatformService, final LoanScheduleGeneratorFactory loanScheduleFactory,
|
|
||||||
final LoanTransactionRepository loanTransactionRepository,
|
final LoanTransactionRepository loanTransactionRepository,
|
||||||
final JournalEntryWritePlatformService journalEntryWritePlatformService, final LoanRepository loanRepository,
|
final JournalEntryWritePlatformService journalEntryWritePlatformService, final LoanRepository loanRepository,
|
||||||
final LoanAssembler loanAssembler, final FloatingRatesReadPlatformService floatingRatesReadPlatformService) {
|
final LoanAssembler loanAssembler, final FloatingRatesReadPlatformService floatingRatesReadPlatformService,
|
||||||
|
final LoanUtilService loanUtilService) {
|
||||||
this.loanRepositoryWrapper = loanRepositoryWrapper;
|
this.loanRepositoryWrapper = loanRepositoryWrapper;
|
||||||
this.codeValueRepositoryWrapper = codeValueRepositoryWrapper;
|
this.codeValueRepositoryWrapper = codeValueRepositoryWrapper;
|
||||||
this.platformSecurityContext = platformSecurityContext;
|
this.platformSecurityContext = platformSecurityContext;
|
||||||
@@ -121,14 +143,13 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
|||||||
this.loanRepaymentScheduleHistoryRepository = loanRepaymentScheduleHistoryRepository;
|
this.loanRepaymentScheduleHistoryRepository = loanRepaymentScheduleHistoryRepository;
|
||||||
this.loanScheduleHistoryWritePlatformService = loanScheduleHistoryWritePlatformService;
|
this.loanScheduleHistoryWritePlatformService = loanScheduleHistoryWritePlatformService;
|
||||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||||
this.loanAccountDomainService = loanAccountDomainService;
|
|
||||||
this.loanChargeReadPlatformService = loanChargeReadPlatformService;
|
this.loanChargeReadPlatformService = loanChargeReadPlatformService;
|
||||||
this.loanScheduleFactory = loanScheduleFactory;
|
|
||||||
this.loanTransactionRepository = loanTransactionRepository;
|
this.loanTransactionRepository = loanTransactionRepository;
|
||||||
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
||||||
this.loanRepository = loanRepository;
|
this.loanRepository = loanRepository;
|
||||||
this.loanAssembler = loanAssembler;
|
this.loanAssembler = loanAssembler;
|
||||||
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
|
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
|
||||||
|
this.loanUtilService = loanUtilService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -398,8 +419,8 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
|||||||
for (final LoanRepaymentScheduleInstallment repaymentScheduleInstallment : repaymentScheduleInstallments) {
|
for (final LoanRepaymentScheduleInstallment repaymentScheduleInstallment : repaymentScheduleInstallments) {
|
||||||
repaymentScheduleInstallment.updateDerivedFields(currency, new LocalDate());
|
repaymentScheduleInstallment.updateDerivedFields(currency, new LocalDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
//updates maturity date
|
// updates maturity date
|
||||||
loan.updateLoanScheduleDependentDerivedFields();
|
loan.updateLoanScheduleDependentDerivedFields();
|
||||||
// update the loan object
|
// update the loan object
|
||||||
this.loanRepository.save(loan);
|
this.loanRepository.save(loan);
|
||||||
@@ -448,40 +469,12 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
|||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
ApplicationCurrency applicationCurrency = null;
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = null;
|
|
||||||
List<Holiday> holidays = null;
|
|
||||||
boolean isHolidayEnabled = false;
|
|
||||||
WorkingDays workingDays = null;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
|
|
||||||
isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate()
|
|
||||||
.toDate());
|
|
||||||
workingDays = this.workingDaysRepository.findOne();
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
recalculateFrom = DateUtils.getLocalDateOfTenant();
|
recalculateFrom = DateUtils.getLocalDateOfTenant();
|
||||||
}
|
}
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance,
|
|
||||||
recalculateFrom, overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
|
|
||||||
Money accruedCharge = Money.zero(loan.getCurrency());
|
Money accruedCharge = Money.zero(loan.getCurrency());
|
||||||
if (loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
if (loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
||||||
@@ -583,11 +576,10 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
|||||||
boolean isFloatingInterestRate = loan.getIsFloatingInterestRate();
|
boolean isFloatingInterestRate = loan.getIsFloatingInterestRate();
|
||||||
BigDecimal interestRateDiff = loan.getInterestRateDifferential();
|
BigDecimal interestRateDiff = loan.getInterestRateDifferential();
|
||||||
List<FloatingRatePeriodData> baseLendingRatePeriods = null;
|
List<FloatingRatePeriodData> baseLendingRatePeriods = null;
|
||||||
try{
|
try {
|
||||||
baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate()
|
baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate().getRatePeriods();
|
||||||
.getRatePeriods();
|
} catch (final FloatingRateNotFoundException ex) {
|
||||||
}catch(final FloatingRateNotFoundException ex){
|
// Do not do anything
|
||||||
// Do not do anything
|
|
||||||
}
|
}
|
||||||
floatingRateDTO = new FloatingRateDTO(isFloatingInterestRate, loan.getDisbursementDate(), interestRateDiff,
|
floatingRateDTO = new FloatingRateDTO(isFloatingInterestRate, loan.getDisbursementDate(), interestRateDiff,
|
||||||
baseLendingRatePeriods);
|
baseLendingRatePeriods);
|
||||||
|
|||||||
+18
-16
@@ -5,8 +5,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.mifosplatform.portfolio.loanaccount.service;
|
package org.mifosplatform.portfolio.loanaccount.service;
|
||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import java.math.BigDecimal;
|
||||||
import com.google.gson.JsonElement;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
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;
|
||||||
import org.mifosplatform.infrastructure.accountnumberformat.domain.AccountNumberFormat;
|
import org.mifosplatform.infrastructure.accountnumberformat.domain.AccountNumberFormat;
|
||||||
@@ -56,7 +62,6 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
|||||||
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanAccountDomainService;
|
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanDisbursementDetails;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanDisbursementDetails;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
||||||
@@ -97,13 +102,8 @@ import org.springframework.dao.DataIntegrityViolationException;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import com.google.gson.JsonArray;
|
||||||
import java.util.ArrayList;
|
import com.google.gson.JsonElement;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements LoanApplicationWritePlatformService {
|
public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements LoanApplicationWritePlatformService {
|
||||||
@@ -134,11 +134,11 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
private final AccountAssociationsRepository accountAssociationsRepository;
|
private final AccountAssociationsRepository accountAssociationsRepository;
|
||||||
private final LoanReadPlatformService loanReadPlatformService;
|
private final LoanReadPlatformService loanReadPlatformService;
|
||||||
private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository;
|
private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository;
|
||||||
private final LoanAccountDomainService loanAccountDomainService;
|
|
||||||
private final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository;
|
private final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository;
|
||||||
private final BusinessEventNotifierService businessEventNotifierService;
|
private final BusinessEventNotifierService businessEventNotifierService;
|
||||||
private final ConfigurationDomainService configurationDomainService;
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
private final LoanScheduleAssembler loanScheduleAssembler;
|
private final LoanScheduleAssembler loanScheduleAssembler;
|
||||||
|
private final LoanUtilService loanUtilService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
|
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
|
||||||
@@ -154,10 +154,10 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository,
|
final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository,
|
||||||
final SavingsAccountAssembler savingsAccountAssembler, final AccountAssociationsRepository accountAssociationsRepository,
|
final SavingsAccountAssembler savingsAccountAssembler, final AccountAssociationsRepository accountAssociationsRepository,
|
||||||
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository,
|
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository,
|
||||||
final LoanReadPlatformService loanReadPlatformService, final LoanAccountDomainService loanAccountDomainService,
|
final LoanReadPlatformService loanReadPlatformService,
|
||||||
final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository,
|
final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository,
|
||||||
final BusinessEventNotifierService businessEventNotifierService, final ConfigurationDomainService configurationDomainService,
|
final BusinessEventNotifierService businessEventNotifierService, final ConfigurationDomainService configurationDomainService,
|
||||||
final LoanScheduleAssembler loanScheduleAssembler) {
|
final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.fromJsonHelper = fromJsonHelper;
|
this.fromJsonHelper = fromJsonHelper;
|
||||||
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
|
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
|
||||||
@@ -182,11 +182,11 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
this.accountAssociationsRepository = accountAssociationsRepository;
|
this.accountAssociationsRepository = accountAssociationsRepository;
|
||||||
this.repaymentScheduleInstallmentRepository = repaymentScheduleInstallmentRepository;
|
this.repaymentScheduleInstallmentRepository = repaymentScheduleInstallmentRepository;
|
||||||
this.loanReadPlatformService = loanReadPlatformService;
|
this.loanReadPlatformService = loanReadPlatformService;
|
||||||
this.loanAccountDomainService = loanAccountDomainService;
|
|
||||||
this.accountNumberFormatRepository = accountNumberFormatRepository;
|
this.accountNumberFormatRepository = accountNumberFormatRepository;
|
||||||
this.businessEventNotifierService = businessEventNotifierService;
|
this.businessEventNotifierService = businessEventNotifierService;
|
||||||
this.configurationDomainService = configurationDomainService;
|
this.configurationDomainService = configurationDomainService;
|
||||||
this.loanScheduleAssembler = loanScheduleAssembler;
|
this.loanScheduleAssembler = loanScheduleAssembler;
|
||||||
|
this.loanUtilService = loanUtilService;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||||
@@ -894,7 +894,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
// to recompute the schedule
|
// to recompute the schedule
|
||||||
if (changes.containsKey(LoanApiConstants.approvedLoanAmountParameterName) || changes.containsKey("recalculateLoanSchedule")
|
if (changes.containsKey(LoanApiConstants.approvedLoanAmountParameterName) || changes.containsKey("recalculateLoanSchedule")
|
||||||
|| changes.containsKey("expectedDisbursementDate")) {
|
|| changes.containsKey("expectedDisbursementDate")) {
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = loanAccountDomainService.buildScheduleGeneratorDTO(loan);
|
LocalDate recalculateFrom = null;
|
||||||
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,7 +942,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
|
|
||||||
if (changes.containsKey(LoanApiConstants.approvedLoanAmountParameterName)
|
if (changes.containsKey(LoanApiConstants.approvedLoanAmountParameterName)
|
||||||
|| changes.containsKey(LoanApiConstants.disbursementPrincipalParameterName)) {
|
|| changes.containsKey(LoanApiConstants.disbursementPrincipalParameterName)) {
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = loanAccountDomainService.buildScheduleGeneratorDTO(loan);
|
LocalDate recalculateFrom = null;
|
||||||
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-63
@@ -26,7 +26,6 @@ import org.joda.time.format.DateTimeFormatter;
|
|||||||
import org.mifosplatform.accounting.common.AccountingRuleType;
|
import org.mifosplatform.accounting.common.AccountingRuleType;
|
||||||
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
import org.mifosplatform.infrastructure.codes.data.CodeValueData;
|
||||||
import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService;
|
import org.mifosplatform.infrastructure.codes.service.CodeValueReadPlatformService;
|
||||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
|
||||||
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||||
@@ -35,9 +34,6 @@ import org.mifosplatform.infrastructure.core.service.PaginationHelper;
|
|||||||
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
|
||||||
import org.mifosplatform.infrastructure.core.service.SearchParameters;
|
import org.mifosplatform.infrastructure.core.service.SearchParameters;
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
import org.mifosplatform.organisation.holiday.domain.Holiday;
|
|
||||||
import org.mifosplatform.organisation.holiday.domain.HolidayRepository;
|
|
||||||
import org.mifosplatform.organisation.holiday.domain.HolidayStatusType;
|
|
||||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
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;
|
||||||
@@ -45,15 +41,11 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
|||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.organisation.staff.data.StaffData;
|
import org.mifosplatform.organisation.staff.data.StaffData;
|
||||||
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
|
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
|
||||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDays;
|
|
||||||
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
|
||||||
import org.mifosplatform.portfolio.account.data.AccountTransferData;
|
import org.mifosplatform.portfolio.account.data.AccountTransferData;
|
||||||
import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
|
import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
|
||||||
import org.mifosplatform.portfolio.accountdetails.service.AccountEnumerations;
|
import org.mifosplatform.portfolio.accountdetails.service.AccountEnumerations;
|
||||||
import org.mifosplatform.portfolio.calendar.data.CalendarData;
|
import org.mifosplatform.portfolio.calendar.data.CalendarData;
|
||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
|
||||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstanceRepository;
|
|
||||||
import org.mifosplatform.portfolio.calendar.service.CalendarReadPlatformService;
|
import org.mifosplatform.portfolio.calendar.service.CalendarReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
import org.mifosplatform.portfolio.charge.data.ChargeData;
|
||||||
import org.mifosplatform.portfolio.charge.domain.ChargeTimeType;
|
import org.mifosplatform.portfolio.charge.domain.ChargeTimeType;
|
||||||
@@ -63,10 +55,7 @@ import org.mifosplatform.portfolio.client.domain.ClientEnumerations;
|
|||||||
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
|
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
|
||||||
import org.mifosplatform.portfolio.common.service.CommonEnumerations;
|
import org.mifosplatform.portfolio.common.service.CommonEnumerations;
|
||||||
import org.mifosplatform.portfolio.floatingrates.data.FloatingRateDTO;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.data.FloatingRatePeriodData;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.data.InterestRatePeriodData;
|
import org.mifosplatform.portfolio.floatingrates.data.InterestRatePeriodData;
|
||||||
import org.mifosplatform.portfolio.floatingrates.exception.FloatingRateNotFoundException;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.service.FloatingRatesReadPlatformService;
|
import org.mifosplatform.portfolio.floatingrates.service.FloatingRatesReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.fund.data.FundData;
|
import org.mifosplatform.portfolio.fund.data.FundData;
|
||||||
import org.mifosplatform.portfolio.fund.service.FundReadPlatformService;
|
import org.mifosplatform.portfolio.fund.service.FundReadPlatformService;
|
||||||
@@ -74,7 +63,6 @@ import org.mifosplatform.portfolio.group.data.GroupGeneralData;
|
|||||||
import org.mifosplatform.portfolio.group.data.GroupRoleData;
|
import org.mifosplatform.portfolio.group.data.GroupRoleData;
|
||||||
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
|
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.DisbursementData;
|
import org.mifosplatform.portfolio.loanaccount.data.DisbursementData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.HolidayDetailDTO;
|
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData;
|
import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.LoanApplicationTimelineData;
|
import org.mifosplatform.portfolio.loanaccount.data.LoanApplicationTimelineData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.LoanApprovalData;
|
import org.mifosplatform.portfolio.loanaccount.data.LoanApprovalData;
|
||||||
@@ -87,6 +75,7 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData;
|
|||||||
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
|
import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionEnumData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.PaidInAdvanceData;
|
import org.mifosplatform.portfolio.loanaccount.data.PaidInAdvanceData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
|
import org.mifosplatform.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.data.ScheduleGeneratorDTO;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
||||||
@@ -101,7 +90,6 @@ import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFound
|
|||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanSchedulePeriodData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
|
||||||
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
|
||||||
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
|
import org.mifosplatform.portfolio.loanproduct.data.TransactionProcessingStrategyData;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
import org.mifosplatform.portfolio.loanproduct.domain.InterestMethod;
|
||||||
@@ -143,14 +131,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
private final LoanMapper loaanLoanMapper = new LoanMapper();
|
private final LoanMapper loaanLoanMapper = new LoanMapper();
|
||||||
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||||
private final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
|
private final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
|
||||||
private final LoanScheduleGeneratorFactory loanScheduleFactory;
|
|
||||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
|
||||||
private final HolidayRepository holidayRepository;
|
|
||||||
private final ConfigurationDomainService configurationDomainService;
|
|
||||||
private final WorkingDaysRepositoryWrapper workingDaysRepository;
|
|
||||||
private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
|
private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
|
||||||
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
private final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory;
|
||||||
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
|
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
|
||||||
|
private final LoanUtilService loanUtilService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanReadPlatformServiceImpl(final PlatformSecurityContext context, final LoanRepository loanRepository,
|
public LoanReadPlatformServiceImpl(final PlatformSecurityContext context, final LoanRepository loanRepository,
|
||||||
@@ -161,11 +145,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final FundReadPlatformService fundReadPlatformService, final ChargeReadPlatformService chargeReadPlatformService,
|
final FundReadPlatformService fundReadPlatformService, final ChargeReadPlatformService chargeReadPlatformService,
|
||||||
final CodeValueReadPlatformService codeValueReadPlatformService, final RoutingDataSource dataSource,
|
final CodeValueReadPlatformService codeValueReadPlatformService, final RoutingDataSource dataSource,
|
||||||
final CalendarReadPlatformService calendarReadPlatformService, final StaffReadPlatformService staffReadPlatformService,
|
final CalendarReadPlatformService calendarReadPlatformService, final StaffReadPlatformService staffReadPlatformService,
|
||||||
final LoanScheduleGeneratorFactory loanScheduleFactory, final CalendarInstanceRepository calendarInstanceRepository,
|
final PaymentTypeReadPlatformService paymentTypeReadPlatformService,
|
||||||
final HolidayRepository holidayRepository, final ConfigurationDomainService configurationDomainService,
|
|
||||||
final WorkingDaysRepositoryWrapper workingDaysRepository, PaymentTypeReadPlatformService paymentTypeReadPlatformService,
|
|
||||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||||
final FloatingRatesReadPlatformService floatingRatesReadPlatformService) {
|
final FloatingRatesReadPlatformService floatingRatesReadPlatformService, final LoanUtilService loanUtilService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.loanRepository = loanRepository;
|
this.loanRepository = loanRepository;
|
||||||
this.loanTransactionRepository = loanTransactionRepository;
|
this.loanTransactionRepository = loanTransactionRepository;
|
||||||
@@ -181,14 +163,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
this.staffReadPlatformService = staffReadPlatformService;
|
this.staffReadPlatformService = staffReadPlatformService;
|
||||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
|
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
|
||||||
this.loanScheduleFactory = loanScheduleFactory;
|
|
||||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
|
||||||
this.holidayRepository = holidayRepository;
|
|
||||||
this.configurationDomainService = configurationDomainService;
|
|
||||||
this.workingDaysRepository = workingDaysRepository;
|
|
||||||
this.paymentTypeReadPlatformService = paymentTypeReadPlatformService;
|
this.paymentTypeReadPlatformService = paymentTypeReadPlatformService;
|
||||||
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
|
this.loanRepaymentScheduleTransactionProcessorFactory = loanRepaymentScheduleTransactionProcessorFactory;
|
||||||
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
|
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
|
||||||
|
this.loanUtilService = loanUtilService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -429,25 +407,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final CurrencyData currencyData = applicationCurrency.toData();
|
final CurrencyData currencyData = applicationCurrency.toData();
|
||||||
|
|
||||||
final LocalDate earliestUnpaidInstallmentDate = LocalDate.now();
|
final LocalDate earliestUnpaidInstallmentDate = LocalDate.now();
|
||||||
|
final LocalDate recalculateFrom = null;
|
||||||
CalendarInstance restCalendarInstance = null;
|
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = loan.fetchPrepaymentDetail(scheduleGeneratorDTO, onDate);
|
||||||
HolidayDetailDTO holidayDetailDTO = null;
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan
|
|
||||||
.getDisbursementDate().toDate(), HolidayStatusType.ACTIVE.getValue());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
|
||||||
}
|
|
||||||
|
|
||||||
final FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = loan.fetchPrepaymentDetail(this.loanScheduleFactory,
|
|
||||||
restCalendarInstance, compoundingCalendarInstance, holidayDetailDTO, onDate, floatingRateDTO);
|
|
||||||
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.REPAYMENT);
|
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.REPAYMENT);
|
||||||
final Collection<PaymentTypeData> paymentOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
|
final Collection<PaymentTypeData> paymentOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
|
||||||
final BigDecimal outstandingLoanBalance = loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount();
|
final BigDecimal outstandingLoanBalance = loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount();
|
||||||
@@ -1993,23 +1955,6 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
null, null, null, false);
|
null, null, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FloatingRateDTO constructFloatingRateDTO(final Loan loan) {
|
|
||||||
FloatingRateDTO floatingRateDTO = null;
|
|
||||||
if (loan.loanProduct().isLinkedToFloatingInterestRate()) {
|
|
||||||
boolean isFloatingInterestRate = loan.getIsFloatingInterestRate();
|
|
||||||
BigDecimal interestRateDiff = loan.getInterestRateDifferential();
|
|
||||||
List<FloatingRatePeriodData> baseLendingRatePeriods = null;
|
|
||||||
try {
|
|
||||||
baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate().getRatePeriods();
|
|
||||||
} catch (final FloatingRateNotFoundException ex) {
|
|
||||||
// Do not do anything
|
|
||||||
}
|
|
||||||
floatingRateDTO = new FloatingRateDTO(isFloatingInterestRate, loan.getDisbursementDate(), interestRateDiff,
|
|
||||||
baseLendingRatePeriods);
|
|
||||||
}
|
|
||||||
return floatingRateDTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<InterestRatePeriodData> retrieveLoanInterestRatePeriodData(Long loanId) {
|
public Collection<InterestRatePeriodData> retrieveLoanInterestRatePeriodData(Long loanId) {
|
||||||
this.context.authenticatedUser();
|
this.context.authenticatedUser();
|
||||||
|
|||||||
+84
-51
@@ -60,9 +60,92 @@ public class LoanUtilService {
|
|||||||
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
|
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getCalculatedRepaymentsStartingFromDate(final LocalDate actualDisbursementDate, final Loan loan,
|
public ScheduleGeneratorDTO buildScheduleGeneratorDTO(final Loan loan, final LocalDate recalculateFrom) {
|
||||||
|
final HolidayDetailDTO holidayDetailDTO = null;
|
||||||
|
return buildScheduleGeneratorDTO(loan, recalculateFrom, holidayDetailDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScheduleGeneratorDTO buildScheduleGeneratorDTO(final Loan loan, final LocalDate recalculateFrom,
|
||||||
|
final HolidayDetailDTO holidayDetailDTO) {
|
||||||
|
HolidayDetailDTO holidayDetails = holidayDetailDTO;
|
||||||
|
if (holidayDetailDTO == null) {
|
||||||
|
holidayDetails = constructHolidayDTO(loan);
|
||||||
|
}
|
||||||
|
final MonetaryCurrency currency = loan.getCurrency();
|
||||||
|
ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
||||||
|
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
||||||
|
CalendarEntityType.LOANS.getValue());
|
||||||
|
LocalDate calculatedRepaymentsStartingFromDate = this.getCalculatedRepaymentsStartingFromDate(loan.getDisbursementDate(), loan,
|
||||||
|
calendarInstance);
|
||||||
|
CalendarInstance restCalendarInstance = null;
|
||||||
|
CalendarInstance compoundingCalendarInstance = null;
|
||||||
|
Long overdurPenaltyWaitPeriod = null;
|
||||||
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
|
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
||||||
|
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
||||||
|
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
||||||
|
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
||||||
|
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
||||||
|
}
|
||||||
|
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
||||||
|
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
||||||
|
calculatedRepaymentsStartingFromDate, holidayDetails, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
||||||
|
overdurPenaltyWaitPeriod, floatingRateDTO);
|
||||||
|
|
||||||
|
return scheduleGeneratorDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getCalculatedRepaymentsStartingFromDate(final Loan loan) {
|
||||||
|
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
||||||
|
CalendarEntityType.LOANS.getValue());
|
||||||
|
return this.getCalculatedRepaymentsStartingFromDate(loan.getDisbursementDate(), loan, calendarInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HolidayDetailDTO constructHolidayDTO(final Loan loan) {
|
||||||
|
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
||||||
|
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan
|
||||||
|
.getDisbursementDate().toDate(), HolidayStatusType.ACTIVE.getValue());
|
||||||
|
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
||||||
|
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
||||||
|
final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled();
|
||||||
|
|
||||||
|
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday,
|
||||||
|
allowTransactionsOnNonWorkingDay);
|
||||||
|
return holidayDetailDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FloatingRateDTO constructFloatingRateDTO(final Loan loan) {
|
||||||
|
FloatingRateDTO floatingRateDTO = null;
|
||||||
|
if (loan.loanProduct().isLinkedToFloatingInterestRate()) {
|
||||||
|
boolean isFloatingInterestRate = loan.getIsFloatingInterestRate();
|
||||||
|
BigDecimal interestRateDiff = loan.getInterestRateDifferential();
|
||||||
|
List<FloatingRatePeriodData> baseLendingRatePeriods = null;
|
||||||
|
try {
|
||||||
|
baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate().getRatePeriods();
|
||||||
|
} catch (final FloatingRateNotFoundException ex) {
|
||||||
|
// Do not do anything
|
||||||
|
}
|
||||||
|
|
||||||
|
floatingRateDTO = new FloatingRateDTO(isFloatingInterestRate, loan.getDisbursementDate(), interestRateDiff,
|
||||||
|
baseLendingRatePeriods);
|
||||||
|
}
|
||||||
|
return floatingRateDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LocalDate getCalculatedRepaymentsStartingFromDate(final LocalDate actualDisbursementDate, final Loan loan,
|
||||||
final CalendarInstance calendarInstance) {
|
final CalendarInstance calendarInstance) {
|
||||||
final Calendar calendar = calendarInstance == null ? null : calendarInstance.getCalendar();
|
final Calendar calendar = calendarInstance == null ? null : calendarInstance.getCalendar();
|
||||||
|
return calculateRepaymentStartingFromDate(actualDisbursementDate, loan, calendar);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getCalculatedRepaymentsStartingFromDate(final LocalDate actualDisbursementDate, final Loan loan,
|
||||||
|
final Calendar calendar) {
|
||||||
|
if (calendar == null) { return getCalculatedRepaymentsStartingFromDate(loan); }
|
||||||
|
return calculateRepaymentStartingFromDate(actualDisbursementDate, loan, calendar);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private LocalDate calculateRepaymentStartingFromDate(final LocalDate actualDisbursementDate, final Loan loan, final Calendar calendar) {
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = loan.getExpectedFirstRepaymentOnDate();
|
LocalDate calculatedRepaymentsStartingFromDate = loan.getExpectedFirstRepaymentOnDate();
|
||||||
if (calendar != null) {// sync repayments
|
if (calendar != null) {// sync repayments
|
||||||
|
|
||||||
@@ -87,54 +170,4 @@ public class LoanUtilService {
|
|||||||
return calculatedRepaymentsStartingFromDate;
|
return calculatedRepaymentsStartingFromDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduleGeneratorDTO buildScheduleGeneratorDTO(final Loan loan) {
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = this.getCalculatedRepaymentsStartingFromDate(loan.getDisbursementDate(), loan,
|
|
||||||
calendarInstance);
|
|
||||||
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan
|
|
||||||
.getExpectedDisbursedOnLocalDate().toDate(), HolidayStatusType.ACTIVE.getValue());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
|
||||||
final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled();
|
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday,
|
|
||||||
allowTransactionsOnNonWorkingDay);
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
}
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, floatingRateDTO);
|
|
||||||
|
|
||||||
return scheduleGeneratorDTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
private FloatingRateDTO constructFloatingRateDTO(final Loan loan) {
|
|
||||||
FloatingRateDTO floatingRateDTO = null;
|
|
||||||
if (loan.loanProduct().isLinkedToFloatingInterestRate()) {
|
|
||||||
boolean isFloatingInterestRate = loan.getIsFloatingInterestRate();
|
|
||||||
BigDecimal interestRateDiff = loan.getInterestRateDifferential();
|
|
||||||
List<FloatingRatePeriodData> baseLendingRatePeriods = null;
|
|
||||||
try {
|
|
||||||
baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate().getRatePeriods();
|
|
||||||
} catch (final FloatingRateNotFoundException ex) {
|
|
||||||
// Do not do anything
|
|
||||||
}
|
|
||||||
|
|
||||||
floatingRateDTO = new FloatingRateDTO(isFloatingInterestRate, loan.getDisbursementDate(), interestRateDiff,
|
|
||||||
baseLendingRatePeriods);
|
|
||||||
}
|
|
||||||
return floatingRateDTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+87
-491
@@ -97,10 +97,6 @@ import org.mifosplatform.portfolio.common.BusinessEventNotificationConstants.BUS
|
|||||||
import org.mifosplatform.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
|
import org.mifosplatform.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
|
||||||
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
|
import org.mifosplatform.portfolio.common.domain.PeriodFrequencyType;
|
||||||
import org.mifosplatform.portfolio.common.service.BusinessEventNotifierService;
|
import org.mifosplatform.portfolio.common.service.BusinessEventNotifierService;
|
||||||
import org.mifosplatform.portfolio.floatingrates.data.FloatingRateDTO;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.data.FloatingRatePeriodData;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.exception.FloatingRateNotFoundException;
|
|
||||||
import org.mifosplatform.portfolio.floatingrates.service.FloatingRatesReadPlatformService;
|
|
||||||
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.api.LoanApiConstants;
|
import org.mifosplatform.portfolio.loanaccount.api.LoanApiConstants;
|
||||||
@@ -140,7 +136,6 @@ import org.mifosplatform.portfolio.loanaccount.exception.MultiDisbursementDataRe
|
|||||||
import org.mifosplatform.portfolio.loanaccount.guarantor.service.GuarantorDomainService;
|
import org.mifosplatform.portfolio.loanaccount.guarantor.service.GuarantorDomainService;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.data.OverdueLoanScheduleData;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.DefaultScheduledDateGenerator;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.DefaultScheduledDateGenerator;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
|
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
||||||
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.ScheduledDateGenerator;
|
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.ScheduledDateGenerator;
|
||||||
@@ -188,7 +183,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
private final LoanChargeRepository loanChargeRepository;
|
private final LoanChargeRepository loanChargeRepository;
|
||||||
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
|
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
|
||||||
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||||
private final LoanScheduleGeneratorFactory loanScheduleFactory;
|
|
||||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||||
private final PaymentDetailWritePlatformService paymentDetailWritePlatformService;
|
private final PaymentDetailWritePlatformService paymentDetailWritePlatformService;
|
||||||
private final HolidayRepositoryWrapper holidayRepository;
|
private final HolidayRepositoryWrapper holidayRepository;
|
||||||
@@ -210,7 +204,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
private final AccountTransferDetailRepository accountTransferDetailRepository;
|
private final AccountTransferDetailRepository accountTransferDetailRepository;
|
||||||
private final BusinessEventNotifierService businessEventNotifierService;
|
private final BusinessEventNotifierService businessEventNotifierService;
|
||||||
private final GuarantorDomainService guarantorDomainService;
|
private final GuarantorDomainService guarantorDomainService;
|
||||||
private final FloatingRatesReadPlatformService floatingRatesReadPlatformService;
|
private final LoanUtilService loanUtilService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
@@ -221,7 +215,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final ChargeRepositoryWrapper chargeRepository, final LoanChargeRepository loanChargeRepository,
|
final ChargeRepositoryWrapper chargeRepository, final LoanChargeRepository loanChargeRepository,
|
||||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
||||||
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
||||||
final LoanScheduleGeneratorFactory loanScheduleFactory, final CalendarInstanceRepository calendarInstanceRepository,
|
final CalendarInstanceRepository calendarInstanceRepository,
|
||||||
final PaymentDetailWritePlatformService paymentDetailWritePlatformService, final HolidayRepositoryWrapper holidayRepository,
|
final PaymentDetailWritePlatformService paymentDetailWritePlatformService, final HolidayRepositoryWrapper holidayRepository,
|
||||||
final ConfigurationDomainService configurationDomainService, final WorkingDaysRepositoryWrapper workingDaysRepository,
|
final ConfigurationDomainService configurationDomainService, final WorkingDaysRepositoryWrapper workingDaysRepository,
|
||||||
final LoanProductReadPlatformService loanProductReadPlatformService,
|
final LoanProductReadPlatformService loanProductReadPlatformService,
|
||||||
@@ -237,7 +231,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final AccountAssociationsRepository accountAssociationRepository,
|
final AccountAssociationsRepository accountAssociationRepository,
|
||||||
final AccountTransferDetailRepository accountTransferDetailRepository,
|
final AccountTransferDetailRepository accountTransferDetailRepository,
|
||||||
final BusinessEventNotifierService businessEventNotifierService, final GuarantorDomainService guarantorDomainService,
|
final BusinessEventNotifierService businessEventNotifierService, final GuarantorDomainService guarantorDomainService,
|
||||||
final FloatingRatesReadPlatformService floatingRatesReadPlatformService) {
|
final LoanUtilService loanUtilService) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
|
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
|
||||||
this.loanAssembler = loanAssembler;
|
this.loanAssembler = loanAssembler;
|
||||||
@@ -250,7 +244,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
this.applicationCurrencyRepository = applicationCurrencyRepository;
|
this.applicationCurrencyRepository = applicationCurrencyRepository;
|
||||||
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
||||||
this.loanUpdateCommandFromApiJsonDeserializer = loanUpdateCommandFromApiJsonDeserializer;
|
this.loanUpdateCommandFromApiJsonDeserializer = loanUpdateCommandFromApiJsonDeserializer;
|
||||||
this.loanScheduleFactory = loanScheduleFactory;
|
|
||||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||||
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
this.paymentDetailWritePlatformService = paymentDetailWritePlatformService;
|
||||||
this.holidayRepository = holidayRepository;
|
this.holidayRepository = holidayRepository;
|
||||||
@@ -272,7 +265,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
this.accountTransferDetailRepository = accountTransferDetailRepository;
|
this.accountTransferDetailRepository = accountTransferDetailRepository;
|
||||||
this.businessEventNotifierService = businessEventNotifierService;
|
this.businessEventNotifierService = businessEventNotifierService;
|
||||||
this.guarantorDomainService = guarantorDomainService;
|
this.guarantorDomainService = guarantorDomainService;
|
||||||
this.floatingRatesReadPlatformService = floatingRatesReadPlatformService;
|
this.loanUtilService = loanUtilService;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||||
@@ -306,9 +299,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_DISBURSAL,
|
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_DISBURSAL,
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
|
|
||||||
@@ -318,14 +308,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
// Recalculate first repayment date based in actual disbursement date.
|
// Recalculate first repayment date based in actual disbursement date.
|
||||||
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
actualDisbursementDate, loan, calendarInstance);
|
|
||||||
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
|
|
||||||
actualDisbursementDate.toDate());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
|
||||||
final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled();
|
|
||||||
updateLoanCounters(loan, actualDisbursementDate);
|
updateLoanCounters(loan, actualDisbursementDate);
|
||||||
Money amountBeforeAdjust = loan.getPrincpal();
|
Money amountBeforeAdjust = loan.getPrincpal();
|
||||||
loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED);
|
loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED);
|
||||||
@@ -348,24 +330,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
loan.getLoanTransactions().add(disbursementTransaction);
|
loan.getLoanTransactions().add(disbursementTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
}
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday,
|
|
||||||
allowTransactionsOnNonWorkingDay);
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance,
|
|
||||||
recalculateFrom, overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
|
|
||||||
regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO);
|
regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO);
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
@@ -483,7 +449,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
private void updateRecurringCalendarDatesForInterestRecalculation(final Loan loan) {
|
private void updateRecurringCalendarDatesForInterestRecalculation(final Loan loan) {
|
||||||
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()
|
||||||
&& loan.loanInterestRecalculationDetails().getRestFrequencyType().isSameAsRepayment() && !loan.isDisbursed()) {
|
&& loan.loanInterestRecalculationDetails().getRestFrequencyType().isSameAsRepayment()) {
|
||||||
final CalendarInstance calendarInstanceForInterestRecalculation = this.calendarInstanceRepository
|
final CalendarInstance calendarInstanceForInterestRecalculation = this.calendarInstanceRepository
|
||||||
.findByEntityIdAndEntityTypeIdAndCalendarTypeId(loan.loanInterestRecalculationDetailId(),
|
.findByEntityIdAndEntityTypeIdAndCalendarTypeId(loan.loanInterestRecalculationDetailId(),
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue(), CalendarType.COLLECTION.getValue());
|
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue(), CalendarType.COLLECTION.getValue());
|
||||||
@@ -560,8 +526,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
checkClientOrGroupActive(loan);
|
checkClientOrGroupActive(loan);
|
||||||
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_DISBURSAL,
|
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_DISBURSAL,
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
@@ -574,14 +538,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
// disbursement date and next available meeting dates
|
// disbursement date and next available meeting dates
|
||||||
// assuming repayment schedule won't regenerate because expected
|
// assuming repayment schedule won't regenerate because expected
|
||||||
// disbursement and actual disbursement happens on same date
|
// disbursement and actual disbursement happens on same date
|
||||||
final LocalDate firstRepaymentOnDate = null;
|
|
||||||
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
||||||
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
|
|
||||||
actualDisbursementDate.toDate());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
|
||||||
final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled();
|
|
||||||
loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED);
|
loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED);
|
||||||
updateLoanCounters(loan, actualDisbursementDate);
|
updateLoanCounters(loan, actualDisbursementDate);
|
||||||
boolean canDisburse = loan.canDisburse(actualDisbursementDate);
|
boolean canDisburse = loan.canDisburse(actualDisbursementDate);
|
||||||
@@ -604,24 +561,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
disbursementTransaction.updateLoan(loan);
|
disbursementTransaction.updateLoan(loan);
|
||||||
loan.getLoanTransactions().add(disbursementTransaction);
|
loan.getLoanTransactions().add(disbursementTransaction);
|
||||||
}
|
}
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
}
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays,
|
|
||||||
allowTransactionsOnHoliday, allowTransactionsOnNonWorkingDay);
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
final ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
firstRepaymentOnDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
|
||||||
overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO);
|
regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO);
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive(
|
this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive(
|
||||||
@@ -691,37 +632,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
||||||
removeLoanCycle(loan);
|
removeLoanCycle(loan);
|
||||||
|
|
||||||
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
//
|
//
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
final MonetaryCurrency currency = loan.getCurrency();
|
||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
||||||
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
final LocalDate recalculateFrom = null;
|
||||||
CalendarEntityType.LOANS.getValue());
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
final LocalDate actualDisbursementDate = loan.getDisbursementDate();
|
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
actualDisbursementDate, loan, calendarInstance);
|
|
||||||
|
|
||||||
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
|
|
||||||
actualDisbursementDate.toDate());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
}
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(this.loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, floatingRateDTO);
|
|
||||||
|
|
||||||
final Map<String, Object> changes = loan.undoDisbursal(scheduleGeneratorDTO, existingTransactionIds,
|
final Map<String, Object> changes = loan.undoDisbursal(scheduleGeneratorDTO, existingTransactionIds,
|
||||||
existingReversedTransactionIds, currentUser);
|
existingReversedTransactionIds, currentUser);
|
||||||
@@ -806,25 +724,25 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
HolidayDetailDTO holidayDetailDTO = null;
|
HolidayDetailDTO holidayDetailDTO = null;
|
||||||
Boolean isHolidayValidationDone = false;
|
Boolean isHolidayValidationDone = false;
|
||||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
||||||
for(final SingleRepaymentCommand singleLoanRepaymentCommand : repaymentCommand){
|
for (final SingleRepaymentCommand singleLoanRepaymentCommand : repaymentCommand) {
|
||||||
if(singleLoanRepaymentCommand != null){
|
if (singleLoanRepaymentCommand != null) {
|
||||||
Loan loans = this.loanRepository.findOne(singleLoanRepaymentCommand.getLoanId());
|
Loan loans = this.loanRepository.findOne(singleLoanRepaymentCommand.getLoanId());
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loans.getOfficeId(),
|
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loans.getOfficeId(),
|
||||||
singleLoanRepaymentCommand.getTransactionDate().toDate());
|
singleLoanRepaymentCommand.getTransactionDate().toDate());
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
||||||
final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled();
|
final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled();
|
||||||
boolean isHolidayEnabled = false;
|
boolean isHolidayEnabled = false;
|
||||||
isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
||||||
holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday,
|
holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday,
|
||||||
allowTransactionsOnNonWorkingDay);
|
allowTransactionsOnNonWorkingDay);
|
||||||
loans.validateRepaymentDateIsOnHoliday(singleLoanRepaymentCommand.getTransactionDate(), holidayDetailDTO.isAllowTransactionsOnHoliday(),
|
loans.validateRepaymentDateIsOnHoliday(singleLoanRepaymentCommand.getTransactionDate(),
|
||||||
holidayDetailDTO.getHolidays());
|
holidayDetailDTO.isAllowTransactionsOnHoliday(), holidayDetailDTO.getHolidays());
|
||||||
loans.validateRepaymentDateIsOnNonWorkingDay(singleLoanRepaymentCommand.getTransactionDate(), holidayDetailDTO.getWorkingDays(),
|
loans.validateRepaymentDateIsOnNonWorkingDay(singleLoanRepaymentCommand.getTransactionDate(),
|
||||||
holidayDetailDTO.isAllowTransactionsOnNonWorkingDay());
|
holidayDetailDTO.getWorkingDays(), holidayDetailDTO.isAllowTransactionsOnNonWorkingDay());
|
||||||
isHolidayValidationDone = true;
|
isHolidayValidationDone = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
for (final SingleRepaymentCommand singleLoanRepaymentCommand : repaymentCommand) {
|
for (final SingleRepaymentCommand singleLoanRepaymentCommand : repaymentCommand) {
|
||||||
if (singleLoanRepaymentCommand != null) {
|
if (singleLoanRepaymentCommand != null) {
|
||||||
@@ -836,7 +754,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder();
|
final CommandProcessingResultBuilder commandProcessingResultBuilder = new CommandProcessingResultBuilder();
|
||||||
LoanTransaction loanTransaction = this.loanAccountDomainService.makeRepayment(loan, commandProcessingResultBuilder,
|
LoanTransaction loanTransaction = this.loanAccountDomainService.makeRepayment(loan, commandProcessingResultBuilder,
|
||||||
bulkRepaymentCommand.getTransactionDate(), singleLoanRepaymentCommand.getTransactionAmount(), paymentDetail,
|
bulkRepaymentCommand.getTransactionDate(), singleLoanRepaymentCommand.getTransactionAmount(), paymentDetail,
|
||||||
bulkRepaymentCommand.getNote(), null, isRecoveryRepayment, isAccountTransfer, holidayDetailDTO, isHolidayValidationDone);
|
bulkRepaymentCommand.getNote(), null, isRecoveryRepayment, isAccountTransfer, holidayDetailDTO,
|
||||||
|
isHolidayValidationDone);
|
||||||
transactionIds.add(loanTransaction.getId());
|
transactionIds.add(loanTransaction.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -896,46 +815,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
interestComponent, unrecognizedIncome, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
interestComponent, unrecognizedIncome, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository
|
|
||||||
.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), transactionDate.toDate());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
final boolean allowTransactionsOnNonWorkingDay = this.configurationDomainService.allowTransactionsOnNonWorkingDayEnabled();
|
|
||||||
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
ApplicationCurrency applicationCurrency = null;
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = null;
|
|
||||||
boolean isHolidayEnabled = false;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
|
||||||
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
|
|
||||||
isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
recalculateFrom = transactionToAdjust.getTransactionDate().isAfter(transactionDate) ? transactionDate : transactionToAdjust
|
recalculateFrom = transactionToAdjust.getTransactionDate().isAfter(transactionDate) ? transactionDate : transactionToAdjust
|
||||||
.getTransactionDate();
|
.getTransactionDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday,
|
|
||||||
allowTransactionsOnNonWorkingDay);
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
|
||||||
overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
|
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loan.adjustExistingTransaction(newTransactionDetail,
|
final ChangedTransactionDetail changedTransactionDetail = loan.adjustExistingTransaction(newTransactionDetail,
|
||||||
defaultLoanLifecycleStateMachine(), transactionToAdjust, existingTransactionIds, existingReversedTransactionIds,
|
defaultLoanLifecycleStateMachine(), transactionToAdjust, existingTransactionIds, existingReversedTransactionIds,
|
||||||
@@ -1050,41 +937,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
transactionDate, interestComponent, unrecognizedIncome, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
transactionDate, interestComponent, unrecognizedIncome, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
||||||
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_WAIVE_INTEREST,
|
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_WAIVE_INTEREST,
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN_TRANSACTION, waiveInterestTransaction));
|
constructEntityMap(BUSINESS_ENTITY.LOAN_TRANSACTION, waiveInterestTransaction));
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
ApplicationCurrency applicationCurrency = null;
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = null;
|
|
||||||
List<Holiday> holidays = null;
|
|
||||||
boolean isHolidayEnabled = false;
|
|
||||||
WorkingDays workingDays = null;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
|
|
||||||
isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate().toDate());
|
|
||||||
workingDays = this.workingDaysRepository.findOne();
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
recalculateFrom = transactionDate;
|
recalculateFrom = transactionDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
|
||||||
overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loan.waiveInterest(waiveInterestTransaction,
|
final ChangedTransactionDetail changedTransactionDetail = loan.waiveInterest(waiveInterestTransaction,
|
||||||
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO,
|
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO,
|
||||||
currentUser);
|
currentUser);
|
||||||
@@ -1151,37 +1009,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan
|
|
||||||
.getDisbursementDate().toDate());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
updateLoanCounters(loan, loan.getDisbursementDate());
|
updateLoanCounters(loan, loan.getDisbursementDate());
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
recalculateFrom = command.localDateValueOfParameterNamed("transactionDate");
|
recalculateFrom = command.localDateValueOfParameterNamed("transactionDate");
|
||||||
}
|
}
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
|
||||||
overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
|
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loan.closeAsWrittenOff(command, defaultLoanLifecycleStateMachine(),
|
final ChangedTransactionDetail changedTransactionDetail = loan.closeAsWrittenOff(command, defaultLoanLifecycleStateMachine(),
|
||||||
changes, existingTransactionIds, existingReversedTransactionIds, currentUser, scheduleGeneratorDTO);
|
changes, existingTransactionIds, existingReversedTransactionIds, currentUser, scheduleGeneratorDTO);
|
||||||
@@ -1235,39 +1070,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan
|
|
||||||
.getDisbursementDate().toDate());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
updateLoanCounters(loan, loan.getDisbursementDate());
|
updateLoanCounters(loan, loan.getDisbursementDate());
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
|
||||||
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
recalculateFrom = command.localDateValueOfParameterNamed("transactionDate");
|
recalculateFrom = command.localDateValueOfParameterNamed("transactionDate");
|
||||||
}
|
}
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(this.loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
|
||||||
overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
ChangedTransactionDetail changedTransactionDetail = loan.close(command, defaultLoanLifecycleStateMachine(), changes,
|
ChangedTransactionDetail changedTransactionDetail = loan.close(command, defaultLoanLifecycleStateMachine(), changes,
|
||||||
existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO, currentUser);
|
existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO, currentUser);
|
||||||
final LoanTransaction possibleClosingTransaction = changedTransactionDetail.getNewTransactionMappings().remove(0L);
|
final LoanTransaction possibleClosingTransaction = changedTransactionDetail.getNewTransactionMappings().remove(0L);
|
||||||
@@ -1503,30 +1313,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
public void runScheduleRecalculation(final Loan loan, final LocalDate recalculateFrom) {
|
public void runScheduleRecalculation(final Loan loan, final LocalDate recalculateFrom) {
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
AppUser currentUser = getAppUserIfPresent();
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
CalendarInstance restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
ScheduleGeneratorDTO generatorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
CalendarInstance compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
|
|
||||||
boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate()
|
|
||||||
.toDate());
|
|
||||||
WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
final Long overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO generatorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance,
|
|
||||||
recalculateFrom, overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
ChangedTransactionDetail changedTransactionDetail = loan.handleRegenerateRepaymentScheduleWithInterestRecalculation(
|
ChangedTransactionDetail changedTransactionDetail = loan.handleRegenerateRepaymentScheduleWithInterestRecalculation(
|
||||||
generatorDTO, currentUser);
|
generatorDTO, currentUser);
|
||||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||||
@@ -1545,33 +1332,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
public void updateOriginalSchedule(Loan loan) {
|
public void updateOriginalSchedule(Loan loan) {
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
|
final LocalDate recalculateFrom = null;
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
|
|
||||||
boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate()
|
|
||||||
.toDate());
|
|
||||||
WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
}
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance,
|
|
||||||
floatingRateDTO);
|
|
||||||
createLoanScheduleArchive(loan, scheduleGeneratorDTO);
|
createLoanScheduleArchive(loan, scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1697,40 +1459,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
ApplicationCurrency applicationCurrency = null;
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = null;
|
|
||||||
List<Holiday> holidays = null;
|
|
||||||
boolean isHolidayEnabled = false;
|
|
||||||
WorkingDays workingDays = null;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
|
|
||||||
isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate().toDate());
|
|
||||||
workingDays = this.workingDaysRepository.findOne();
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
}
|
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
|
||||||
overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
|
|
||||||
Money accruedCharge = Money.zero(loan.getCurrency());
|
Money accruedCharge = Money.zero(loan.getCurrency());
|
||||||
if (loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
if (loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
||||||
@@ -2641,43 +2371,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
if (!loan.isClosedWrittenOff()) { throw new PlatformServiceUnavailableException(
|
if (!loan.isClosedWrittenOff()) { throw new PlatformServiceUnavailableException(
|
||||||
"error.msg.loan.status.not.written.off.update.not.allowed", "Loan :" + loanId
|
"error.msg.loan.status.not.written.off.update.not.allowed", "Loan :" + loanId
|
||||||
+ " update not allowed as loan status is not written off", loanId); }
|
+ " update not allowed as loan status is not written off", loanId); }
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
ApplicationCurrency applicationCurrency = null;
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = null;
|
|
||||||
List<Holiday> holidays = null;
|
|
||||||
boolean isHolidayEnabled = false;
|
|
||||||
WorkingDays workingDays = null;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
|
||||||
LoanTransaction writeOffTransaction = loan.findWriteOffTransaction();
|
LoanTransaction writeOffTransaction = loan.findWriteOffTransaction();
|
||||||
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_UNDO_WRITTEN_OFF,
|
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_UNDO_WRITTEN_OFF,
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN_TRANSACTION, writeOffTransaction));
|
constructEntityMap(BUSINESS_ENTITY.LOAN_TRANSACTION, writeOffTransaction));
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
|
|
||||||
isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate().toDate());
|
|
||||||
workingDays = this.workingDaysRepository.findOne();
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
}
|
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
|
||||||
overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
|
|
||||||
ChangedTransactionDetail changedTransactionDetail = loan.undoWrittenOff(existingTransactionIds, existingReversedTransactionIds,
|
ChangedTransactionDetail changedTransactionDetail = loan.undoWrittenOff(existingTransactionIds, existingReversedTransactionIds,
|
||||||
scheduleGeneratorDTO, currentUser);
|
scheduleGeneratorDTO, currentUser);
|
||||||
@@ -2776,38 +2475,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
private CommandProcessingResult processLoanDisbursementDetail(final Loan loan, Long loanId, JsonCommand command,
|
private CommandProcessingResult processLoanDisbursementDetail(final Loan loan, Long loanId, JsonCommand command,
|
||||||
LoanDisbursementDetails loanDisbursementDetails) {
|
LoanDisbursementDetails loanDisbursementDetails) {
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan
|
|
||||||
.getDisbursementDate().toDate());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
final Map<String, Object> changes = new LinkedHashMap<>();
|
final Map<String, Object> changes = new LinkedHashMap<>();
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
Long overdurPenaltyWaitPeriod = null;
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
}
|
|
||||||
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(this.loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
|
||||||
overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
|
|
||||||
ChangedTransactionDetail changedTransactionDetail = null;
|
ChangedTransactionDetail changedTransactionDetail = null;
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
AppUser currentUser = getAppUserIfPresent();
|
||||||
@@ -2949,35 +2621,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
AppUser currentUser = getAppUserIfPresent();
|
AppUser currentUser = getAppUserIfPresent();
|
||||||
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_INTEREST_RECALCULATION,
|
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_INTEREST_RECALCULATION,
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
ScheduleGeneratorDTO generatorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
LocalDate calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
loan.getDisbursementDate(), loan, calendarInstance);
|
|
||||||
|
|
||||||
boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate()
|
|
||||||
.toDate());
|
|
||||||
WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
Long overdurPenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO generatorDTO = new ScheduleGeneratorDTO(loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance, recalculateFrom,
|
|
||||||
overdurPenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
|
|
||||||
ChangedTransactionDetail changedTransactionDetail = loan.recalculateScheduleFromLastTransaction(generatorDTO,
|
ChangedTransactionDetail changedTransactionDetail = loan.recalculateScheduleFromLastTransaction(generatorDTO,
|
||||||
existingTransactionIds, existingReversedTransactionIds, currentUser);
|
existingTransactionIds, existingReversedTransactionIds, currentUser);
|
||||||
@@ -3105,47 +2752,47 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
map.put(entityEvent, entity);
|
map.put(entityEvent, entity);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public CommandProcessingResult undoLastLoanDisbursal(Long loanId, JsonCommand command) {
|
public CommandProcessingResult undoLastLoanDisbursal(Long loanId, JsonCommand command) {
|
||||||
final AppUser currentUser = getAppUserIfPresent();
|
final AppUser currentUser = getAppUserIfPresent();
|
||||||
|
|
||||||
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||||
final LocalDate recalculateFromDate = loan.getLastRepaymentDate();
|
final LocalDate recalculateFromDate = loan.getLastRepaymentDate();
|
||||||
validateIsMultiDisbursalLoanAndDisbursedMoreThanOneTranche(loan);
|
validateIsMultiDisbursalLoanAndDisbursedMoreThanOneTranche(loan);
|
||||||
checkClientOrGroupActive(loan);
|
checkClientOrGroupActive(loan);
|
||||||
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_UNDO_LASTDISBURSAL,
|
this.businessEventNotifierService.notifyBusinessEventToBeExecuted(BUSINESS_EVENTS.LOAN_UNDO_LASTDISBURSAL,
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
||||||
|
|
||||||
final MonetaryCurrency currency = loan.getCurrency();
|
|
||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = getScheduleGeneratorDTO(loan, recalculateFromDate, applicationCurrency);
|
final MonetaryCurrency currency = loan.getCurrency();
|
||||||
|
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
||||||
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
|
|
||||||
final Map<String, Object> changes = loan.undoLastDisbursal(scheduleGeneratorDTO, existingTransactionIds,
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFromDate);
|
||||||
existingReversedTransactionIds, currentUser, loan);
|
|
||||||
if (!changes.isEmpty()) {
|
|
||||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
|
||||||
String noteText = null;
|
|
||||||
if (command.hasParameter("note")) {
|
|
||||||
noteText = command.stringValueOfParameterNamed("note");
|
|
||||||
if (StringUtils.isNotBlank(noteText)) {
|
|
||||||
final Note note = Note.loanNote(loan, noteText);
|
|
||||||
this.noteRepository.save(note);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
boolean isAccountTransfer = false;
|
|
||||||
final Map<String, Object> accountingBridgeData = loan.deriveAccountingBridgeData(applicationCurrency.toData(),
|
|
||||||
existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
|
||||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
|
||||||
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_UNDO_LASTDISBURSAL,
|
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
final Map<String, Object> changes = loan.undoLastDisbursal(scheduleGeneratorDTO, existingTransactionIds,
|
||||||
|
existingReversedTransactionIds, currentUser, loan);
|
||||||
|
if (!changes.isEmpty()) {
|
||||||
|
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||||
|
String noteText = null;
|
||||||
|
if (command.hasParameter("note")) {
|
||||||
|
noteText = command.stringValueOfParameterNamed("note");
|
||||||
|
if (StringUtils.isNotBlank(noteText)) {
|
||||||
|
final Note note = Note.loanNote(loan, noteText);
|
||||||
|
this.noteRepository.save(note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean isAccountTransfer = false;
|
||||||
|
final Map<String, Object> accountingBridgeData = loan.deriveAccountingBridgeData(applicationCurrency.toData(),
|
||||||
|
existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
|
||||||
|
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||||
|
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_UNDO_LASTDISBURSAL,
|
||||||
|
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loan.getId()) //
|
.withEntityId(loan.getId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
@@ -3154,74 +2801,23 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
.withLoanId(loanId) //
|
.withLoanId(loanId) //
|
||||||
.with(changes) //
|
.with(changes) //
|
||||||
.build();
|
.build();
|
||||||
}
|
|
||||||
|
|
||||||
private ScheduleGeneratorDTO getScheduleGeneratorDTO(final Loan loan, final LocalDate recalculateFromDate,
|
|
||||||
final ApplicationCurrency applicationCurrency) {
|
|
||||||
|
|
||||||
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByEntityId(loan.getId(),
|
|
||||||
CalendarEntityType.LOANS.getValue());
|
|
||||||
final LocalDate actualDisbursementDate = loan.getDisbursementDate();
|
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate = this.loanAccountDomainService.getCalculatedRepaymentsStartingFromDate(
|
|
||||||
actualDisbursementDate, loan, calendarInstance);
|
|
||||||
|
|
||||||
final boolean isHolidayEnabled = this.configurationDomainService.isRescheduleRepaymentsOnHolidaysEnabled();
|
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
|
|
||||||
actualDisbursementDate.toDate());
|
|
||||||
final WorkingDays workingDays = this.workingDaysRepository.findOne();
|
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = new HolidayDetailDTO(isHolidayEnabled, holidays, workingDays);
|
|
||||||
CalendarInstance restCalendarInstance = null;
|
|
||||||
CalendarInstance compoundingCalendarInstance = null;
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
|
||||||
restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(),
|
|
||||||
CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue());
|
|
||||||
compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(
|
|
||||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_COMPOUNDING_DETAIL.getValue());
|
|
||||||
}
|
|
||||||
FloatingRateDTO floatingRateDTO = constructFloatingRateDTO(loan);
|
|
||||||
Long overduePenaltyWaitPeriod = this.configurationDomainService.retrievePenaltyWaitPeriod();
|
|
||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = new ScheduleGeneratorDTO(this.loanScheduleFactory, applicationCurrency,
|
|
||||||
calculatedRepaymentsStartingFromDate, holidayDetailDTO, restCalendarInstance, compoundingCalendarInstance,
|
|
||||||
recalculateFromDate, overduePenaltyWaitPeriod, floatingRateDTO);
|
|
||||||
|
|
||||||
return scheduleGeneratorDTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateIsMultiDisbursalLoanAndDisbursedMoreThanOneTranche(Loan loan) {
|
|
||||||
if(!loan.isMultiDisburmentLoan()){
|
|
||||||
final String errorMessage = "loan.product.does.not.support.multiple.disbursals.cannot.undo.last.disbursal";
|
|
||||||
throw new LoanMultiDisbursementException(errorMessage);
|
|
||||||
}
|
|
||||||
Integer trancheDisbursedCount = 0;
|
|
||||||
for(LoanDisbursementDetails disbursementDetails : loan.getDisbursementDetails()){
|
|
||||||
if(disbursementDetails.actualDisbursementDate() != null){
|
|
||||||
trancheDisbursedCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(trancheDisbursedCount <=1){
|
|
||||||
final String errorMessage = "tranches.should.be.disbursed.more.than.one.to.undo.last.disbursal";
|
|
||||||
throw new LoanMultiDisbursementException(errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private FloatingRateDTO constructFloatingRateDTO(final Loan loan) {
|
|
||||||
FloatingRateDTO floatingRateDTO = null;
|
|
||||||
if (loan.loanProduct().isLinkedToFloatingInterestRate()) {
|
|
||||||
boolean isFloatingInterestRate = loan.getIsFloatingInterestRate();
|
|
||||||
BigDecimal interestRateDiff = loan.getInterestRateDifferential();
|
|
||||||
List<FloatingRatePeriodData> baseLendingRatePeriods = null;
|
|
||||||
try {
|
|
||||||
baseLendingRatePeriods = this.floatingRatesReadPlatformService.retrieveBaseLendingRate().getRatePeriods();
|
|
||||||
} catch (final FloatingRateNotFoundException ex) {
|
|
||||||
// Do not do anything
|
|
||||||
}
|
|
||||||
floatingRateDTO = new FloatingRateDTO(isFloatingInterestRate, loan.getDisbursementDate(), interestRateDiff,
|
|
||||||
baseLendingRatePeriods);
|
|
||||||
}
|
|
||||||
return floatingRateDTO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateIsMultiDisbursalLoanAndDisbursedMoreThanOneTranche(Loan loan) {
|
||||||
|
if (!loan.isMultiDisburmentLoan()) {
|
||||||
|
final String errorMessage = "loan.product.does.not.support.multiple.disbursals.cannot.undo.last.disbursal";
|
||||||
|
throw new LoanMultiDisbursementException(errorMessage);
|
||||||
|
}
|
||||||
|
Integer trancheDisbursedCount = 0;
|
||||||
|
for (LoanDisbursementDetails disbursementDetails : loan.getDisbursementDetails()) {
|
||||||
|
if (disbursementDetails.actualDisbursementDate() != null) {
|
||||||
|
trancheDisbursedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (trancheDisbursedCount <= 1) {
|
||||||
|
final String errorMessage = "tranches.should.be.disbursed.more.than.one.to.undo.last.disbursal";
|
||||||
|
throw new LoanMultiDisbursementException(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user