Merge pull request #1606 from pramodn02/MIFOSX-2441
MIFOSX-2441: fix for prepay loan on the same day
This commit is contained in:
+1
-1
@@ -4954,7 +4954,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
for (LoanTransaction loanTransaction : allNonContraTransactionsPostDisbursement) {
|
for (LoanTransaction loanTransaction : allNonContraTransactionsPostDisbursement) {
|
||||||
copyTransactions.add(LoanTransaction.copyTransactionProperties(loanTransaction));
|
copyTransactions.add(LoanTransaction.copyTransactionProperties(loanTransaction));
|
||||||
}
|
}
|
||||||
loanRepaymentScheduleTransactionProcessor.populateDerivedFeildsWithoutReprocess(getDisbursementDate(), copyTransactions,
|
loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), copyTransactions,
|
||||||
getCurrency(), this.repaymentScheduleInstallments, charges());
|
getCurrency(), this.repaymentScheduleInstallments, charges());
|
||||||
|
|
||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
|
|||||||
+9
-1
@@ -615,6 +615,10 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
public BigDecimal amountOutstanding() {
|
public BigDecimal amountOutstanding() {
|
||||||
return this.amountOutstanding;
|
return this.amountOutstanding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Money getAmountOutstanding(final MonetaryCurrency currency) {
|
||||||
|
return Money.of(currency, this.amountOutstanding);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasNotLoanIdentifiedBy(final Long loanId) {
|
public boolean hasNotLoanIdentifiedBy(final Long loanId) {
|
||||||
return !hasLoanIdentifiedBy(loanId);
|
return !hasLoanIdentifiedBy(loanId);
|
||||||
@@ -645,6 +649,10 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
public boolean isNotFullyPaid() {
|
public boolean isNotFullyPaid() {
|
||||||
return !isPaid();
|
return !isPaid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isChargePending(){
|
||||||
|
return isNotFullyPaid() && !isWaived();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPaid() {
|
public boolean isPaid() {
|
||||||
return this.paid;
|
return this.paid;
|
||||||
@@ -881,7 +889,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
|||||||
final Money amountWaived = chargePerInstallment.updateWaivedAndAmountPaidThroughChargePaymentAmount(currency);
|
final Money amountWaived = chargePerInstallment.updateWaivedAndAmountPaidThroughChargePaymentAmount(currency);
|
||||||
this.amountWaived = this.amountWaived.add(amountWaived.getAmount());
|
this.amountWaived = this.amountWaived.add(amountWaived.getAmount());
|
||||||
this.amountOutstanding = this.amountOutstanding.subtract(amountWaived.getAmount());
|
this.amountOutstanding = this.amountOutstanding.subtract(amountWaived.getAmount());
|
||||||
if (determineIfFullyPaid()) {
|
if (determineIfFullyPaid() && Money.of(currency, this.amountWaived).isGreaterThanZero()) {
|
||||||
this.paid = false;
|
this.paid = false;
|
||||||
this.waived = true;
|
this.waived = true;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-22
@@ -48,17 +48,11 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
* falls before existing transactions or and adjustment is made to an
|
* falls before existing transactions or and adjustment is made to an
|
||||||
* existing in which case the entire loan schedule needs to be re-processed.
|
* existing in which case the entire loan schedule needs to be re-processed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChangedTransactionDetail handleTransaction(final LocalDate disbursementDate,
|
public ChangedTransactionDetail handleTransaction(final LocalDate disbursementDate,
|
||||||
final List<LoanTransaction> transactionsPostDisbursement, final MonetaryCurrency currency,
|
final List<LoanTransaction> transactionsPostDisbursement, final MonetaryCurrency currency,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final Set<LoanCharge> charges) {
|
final List<LoanRepaymentScheduleInstallment> installments, final Set<LoanCharge> charges) {
|
||||||
final boolean reprocessCharges = true;
|
|
||||||
return handleTransaction(disbursementDate, transactionsPostDisbursement, currency, installments, charges, reprocessCharges);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ChangedTransactionDetail handleTransaction(final LocalDate disbursementDate,
|
|
||||||
final List<LoanTransaction> transactionsPostDisbursement, final MonetaryCurrency currency,
|
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final Set<LoanCharge> charges, boolean reprocessCharges) {
|
|
||||||
|
|
||||||
if (charges != null) {
|
if (charges != null) {
|
||||||
for (final LoanCharge loanCharge : charges) {
|
for (final LoanCharge loanCharge : charges) {
|
||||||
@@ -75,10 +69,8 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
|
|
||||||
// re-process loan charges over repayment periods (picking up on waived
|
// re-process loan charges over repayment periods (picking up on waived
|
||||||
// loan charges)
|
// loan charges)
|
||||||
if (reprocessCharges) {
|
final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper();
|
||||||
final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper();
|
wrapper.reprocess(currency, disbursementDate, installments, charges);
|
||||||
wrapper.reprocess(currency, disbursementDate, installments, charges);
|
|
||||||
}
|
|
||||||
|
|
||||||
final ChangedTransactionDetail changedTransactionDetail = new ChangedTransactionDetail();
|
final ChangedTransactionDetail changedTransactionDetail = new ChangedTransactionDetail();
|
||||||
final List<LoanTransaction> transactionstoBeProcessed = new ArrayList<>();
|
final List<LoanTransaction> transactionstoBeProcessed = new ArrayList<>();
|
||||||
@@ -328,7 +320,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
|
|
||||||
Money amountRemaining = feeCharges;
|
Money amountRemaining = feeCharges;
|
||||||
while (amountRemaining.isGreaterThanZero()) {
|
while (amountRemaining.isGreaterThanZero()) {
|
||||||
final LoanCharge unpaidCharge = findEarliestUnpaidChargeFromUnOrderedSet(charges);
|
final LoanCharge unpaidCharge = findEarliestUnpaidChargeFromUnOrderedSet(charges, feeCharges.getCurrency());
|
||||||
Money feeAmount = feeCharges.zero();
|
Money feeAmount = feeCharges.zero();
|
||||||
if (loanTransaction.isChargePayment()) {
|
if (loanTransaction.isChargePayment()) {
|
||||||
feeAmount = feeCharges;
|
feeAmount = feeCharges;
|
||||||
@@ -355,12 +347,12 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanCharge findEarliestUnpaidChargeFromUnOrderedSet(final Set<LoanCharge> charges) {
|
private LoanCharge findEarliestUnpaidChargeFromUnOrderedSet(final Set<LoanCharge> charges, final MonetaryCurrency currency) {
|
||||||
LoanCharge earliestUnpaidCharge = null;
|
LoanCharge earliestUnpaidCharge = null;
|
||||||
LoanCharge installemntCharge = null;
|
LoanCharge installemntCharge = null;
|
||||||
LoanInstallmentCharge chargePerInstallment = null;
|
LoanInstallmentCharge chargePerInstallment = null;
|
||||||
for (final LoanCharge loanCharge : charges) {
|
for (final LoanCharge loanCharge : charges) {
|
||||||
if (loanCharge.isNotFullyPaid() && !loanCharge.isDueAtDisbursement()) {
|
if (loanCharge.getAmountOutstanding(currency).isGreaterThanZero() && !loanCharge.isDueAtDisbursement()) {
|
||||||
if (loanCharge.isInstalmentFee()) {
|
if (loanCharge.isInstalmentFee()) {
|
||||||
LoanInstallmentCharge unpaidLoanChargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge();
|
LoanInstallmentCharge unpaidLoanChargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge();
|
||||||
if (chargePerInstallment == null
|
if (chargePerInstallment == null
|
||||||
@@ -587,14 +579,6 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChangedTransactionDetail populateDerivedFeildsWithoutReprocess(final LocalDate disbursementDate,
|
|
||||||
final List<LoanTransaction> transactionsPostDisbursement, final MonetaryCurrency currency,
|
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final Set<LoanCharge> charges) {
|
|
||||||
final boolean reprocessCharges = false;
|
|
||||||
return handleTransaction(disbursementDate, transactionsPostDisbursement, currency, installments, charges, reprocessCharges);
|
|
||||||
}
|
|
||||||
|
|
||||||
private LoanCharge findLatestPaidChargeFromUnOrderedSet(final Set<LoanCharge> charges, MonetaryCurrency currency) {
|
private LoanCharge findLatestPaidChargeFromUnOrderedSet(final Set<LoanCharge> charges, MonetaryCurrency currency) {
|
||||||
LoanCharge latestPaidCharge = null;
|
LoanCharge latestPaidCharge = null;
|
||||||
LoanCharge installemntCharge = null;
|
LoanCharge installemntCharge = null;
|
||||||
|
|||||||
-4
@@ -36,10 +36,6 @@ public interface LoanRepaymentScheduleTransactionProcessor {
|
|||||||
*/
|
*/
|
||||||
boolean isInterestFirstRepaymentScheduleTransactionProcessor();
|
boolean isInterestFirstRepaymentScheduleTransactionProcessor();
|
||||||
|
|
||||||
ChangedTransactionDetail populateDerivedFeildsWithoutReprocess(LocalDate disbursementDate,
|
|
||||||
List<LoanTransaction> transactionsPostDisbursement, MonetaryCurrency currency,
|
|
||||||
List<LoanRepaymentScheduleInstallment> installments, Set<LoanCharge> charges);
|
|
||||||
|
|
||||||
void handleRefund(LoanTransaction loanTransaction, MonetaryCurrency currency, List<LoanRepaymentScheduleInstallment> installments,
|
void handleRefund(LoanTransaction loanTransaction, MonetaryCurrency currency, List<LoanRepaymentScheduleInstallment> installments,
|
||||||
final Set<LoanCharge> charges);
|
final Set<LoanCharge> charges);
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -488,7 +488,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
final ScheduleCurrentPeriodParams currentPeriodParams, final Money lastTotalOutstandingInterestPaymentDueToGrace,
|
final ScheduleCurrentPeriodParams currentPeriodParams, final Money lastTotalOutstandingInterestPaymentDueToGrace,
|
||||||
final LocalDate transactionDate, final LoanScheduleModelPeriod installment) {
|
final LocalDate transactionDate, final LoanScheduleModelPeriod installment) {
|
||||||
LoanScheduleModelPeriod modifiedInstallment = installment;
|
LoanScheduleModelPeriod modifiedInstallment = installment;
|
||||||
if (scheduleParams.getOutstandingBalance().isLessThan(currentPeriodParams.getInterestForThisPeriod())
|
if (!scheduleParams.getOutstandingBalance().isGreaterThan(currentPeriodParams.getInterestForThisPeriod())
|
||||||
&& !scheduledDueDate.equals(transactionDate)) {
|
&& !scheduledDueDate.equals(transactionDate)) {
|
||||||
final Collection<LoanTermVariationsData> interestRates = loanApplicationTerms.getLoanTermVariations().getInterestRateChanges();
|
final Collection<LoanTermVariationsData> interestRates = loanApplicationTerms.getLoanTermVariations().getInterestRateChanges();
|
||||||
LocalDate calculateTill = transactionDate;
|
LocalDate calculateTill = transactionDate;
|
||||||
@@ -602,7 +602,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
&& scheduleParams.getLoanRepaymentScheduleTransactionProcessor()
|
&& scheduleParams.getLoanRepaymentScheduleTransactionProcessor()
|
||||||
.isInterestFirstRepaymentScheduleTransactionProcessor()) {
|
.isInterestFirstRepaymentScheduleTransactionProcessor()) {
|
||||||
List<LoanTransaction> currentTransactions = createCurrentTransactionList(detail);
|
List<LoanTransaction> currentTransactions = createCurrentTransactionList(detail);
|
||||||
if (!transactionDate.isEqual(scheduleParams.getPeriodStartDate())) {
|
if (!transactionDate.isEqual(scheduleParams.getPeriodStartDate()) || scheduleParams.getInstalmentNumber() == 1) {
|
||||||
|
|
||||||
int periodDays = Days.daysBetween(scheduleParams.getPeriodStartDate(), transactionDate).getDays();
|
int periodDays = Days.daysBetween(scheduleParams.getPeriodStartDate(), transactionDate).getDays();
|
||||||
// calculates period start date for interest
|
// calculates period start date for interest
|
||||||
|
|||||||
+1
-1
@@ -454,7 +454,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
|||||||
|
|
||||||
for (LoanCharge loanCharge : loanCharges) {
|
for (LoanCharge loanCharge : loanCharges) {
|
||||||
|
|
||||||
if (loanCharge.isNotFullyPaid() && !loanCharge.isWaived()) {
|
if (loanCharge.isChargePending()) {
|
||||||
Integer loanInstallmentNumber = null;
|
Integer loanInstallmentNumber = null;
|
||||||
|
|
||||||
if (loanCharge.isInstalmentFee()) {
|
if (loanCharge.isInstalmentFee()) {
|
||||||
|
|||||||
+2
-2
@@ -372,7 +372,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<>();
|
final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<>();
|
||||||
for (final LoanCharge loanCharge : loanCharges) {
|
for (final LoanCharge loanCharge : loanCharges) {
|
||||||
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()
|
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()
|
||||||
&& loanCharge.isNotFullyPaid() && !loanCharge.isWaived()) {
|
&& loanCharge.isChargePending()) {
|
||||||
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amountOutstanding());
|
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amountOutstanding());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -599,7 +599,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<>();
|
final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<>();
|
||||||
for (final LoanCharge loanCharge : loanCharges) {
|
for (final LoanCharge loanCharge : loanCharges) {
|
||||||
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()
|
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()
|
||||||
&& loanCharge.isNotFullyPaid() && !loanCharge.isWaived()) {
|
&& loanCharge.isChargePending()) {
|
||||||
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amountOutstanding());
|
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amountOutstanding());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user