Merge pull request #1606 from pramodn02/MIFOSX-2441

MIFOSX-2441: fix for prepay loan on the same day
This commit is contained in:
Adi Narayana Raju
2016-01-20 09:59:56 +05:30
7 changed files with 21 additions and 33 deletions
@@ -4954,7 +4954,7 @@ public class Loan extends AbstractPersistable<Long> {
for (LoanTransaction loanTransaction : allNonContraTransactionsPostDisbursement) {
copyTransactions.add(LoanTransaction.copyTransactionProperties(loanTransaction));
}
loanRepaymentScheduleTransactionProcessor.populateDerivedFeildsWithoutReprocess(getDisbursementDate(), copyTransactions,
loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(), copyTransactions,
getCurrency(), this.repaymentScheduleInstallments, charges());
updateLoanSummaryDerivedFields();
@@ -615,6 +615,10 @@ public class LoanCharge extends AbstractPersistable<Long> {
public BigDecimal amountOutstanding() {
return this.amountOutstanding;
}
public Money getAmountOutstanding(final MonetaryCurrency currency) {
return Money.of(currency, this.amountOutstanding);
}
public boolean hasNotLoanIdentifiedBy(final Long loanId) {
return !hasLoanIdentifiedBy(loanId);
@@ -645,6 +649,10 @@ public class LoanCharge extends AbstractPersistable<Long> {
public boolean isNotFullyPaid() {
return !isPaid();
}
public boolean isChargePending(){
return isNotFullyPaid() && !isWaived();
}
public boolean isPaid() {
return this.paid;
@@ -881,7 +889,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
final Money amountWaived = chargePerInstallment.updateWaivedAndAmountPaidThroughChargePaymentAmount(currency);
this.amountWaived = this.amountWaived.add(amountWaived.getAmount());
this.amountOutstanding = this.amountOutstanding.subtract(amountWaived.getAmount());
if (determineIfFullyPaid()) {
if (determineIfFullyPaid() && Money.of(currency, this.amountWaived).isGreaterThanZero()) {
this.paid = false;
this.waived = true;
}
@@ -48,17 +48,11 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
* falls before existing transactions or and adjustment is made to an
* existing in which case the entire loan schedule needs to be re-processed.
*/
@Override
public ChangedTransactionDetail handleTransaction(final LocalDate disbursementDate,
final List<LoanTransaction> transactionsPostDisbursement, final MonetaryCurrency currency,
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) {
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
// loan charges)
if (reprocessCharges) {
final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper();
wrapper.reprocess(currency, disbursementDate, installments, charges);
}
final LoanRepaymentScheduleProcessingWrapper wrapper = new LoanRepaymentScheduleProcessingWrapper();
wrapper.reprocess(currency, disbursementDate, installments, charges);
final ChangedTransactionDetail changedTransactionDetail = new ChangedTransactionDetail();
final List<LoanTransaction> transactionstoBeProcessed = new ArrayList<>();
@@ -328,7 +320,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
Money amountRemaining = feeCharges;
while (amountRemaining.isGreaterThanZero()) {
final LoanCharge unpaidCharge = findEarliestUnpaidChargeFromUnOrderedSet(charges);
final LoanCharge unpaidCharge = findEarliestUnpaidChargeFromUnOrderedSet(charges, feeCharges.getCurrency());
Money feeAmount = feeCharges.zero();
if (loanTransaction.isChargePayment()) {
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 installemntCharge = null;
LoanInstallmentCharge chargePerInstallment = null;
for (final LoanCharge loanCharge : charges) {
if (loanCharge.isNotFullyPaid() && !loanCharge.isDueAtDisbursement()) {
if (loanCharge.getAmountOutstanding(currency).isGreaterThanZero() && !loanCharge.isDueAtDisbursement()) {
if (loanCharge.isInstalmentFee()) {
LoanInstallmentCharge unpaidLoanChargePerInstallment = loanCharge.getUnpaidInstallmentLoanCharge();
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) {
LoanCharge latestPaidCharge = null;
LoanCharge installemntCharge = null;
@@ -36,10 +36,6 @@ public interface LoanRepaymentScheduleTransactionProcessor {
*/
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,
final Set<LoanCharge> charges);
@@ -488,7 +488,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
final ScheduleCurrentPeriodParams currentPeriodParams, final Money lastTotalOutstandingInterestPaymentDueToGrace,
final LocalDate transactionDate, final LoanScheduleModelPeriod installment) {
LoanScheduleModelPeriod modifiedInstallment = installment;
if (scheduleParams.getOutstandingBalance().isLessThan(currentPeriodParams.getInterestForThisPeriod())
if (!scheduleParams.getOutstandingBalance().isGreaterThan(currentPeriodParams.getInterestForThisPeriod())
&& !scheduledDueDate.equals(transactionDate)) {
final Collection<LoanTermVariationsData> interestRates = loanApplicationTerms.getLoanTermVariations().getInterestRateChanges();
LocalDate calculateTill = transactionDate;
@@ -602,7 +602,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
&& scheduleParams.getLoanRepaymentScheduleTransactionProcessor()
.isInterestFirstRepaymentScheduleTransactionProcessor()) {
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();
// calculates period start date for interest
@@ -454,7 +454,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
for (LoanCharge loanCharge : loanCharges) {
if (loanCharge.isNotFullyPaid() && !loanCharge.isWaived()) {
if (loanCharge.isChargePending()) {
Integer loanInstallmentNumber = null;
if (loanCharge.isInstalmentFee()) {
@@ -372,7 +372,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<>();
for (final LoanCharge loanCharge : loanCharges) {
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()
&& loanCharge.isNotFullyPaid() && !loanCharge.isWaived()) {
&& loanCharge.isChargePending()) {
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amountOutstanding());
}
}
@@ -599,7 +599,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final Map<Long, BigDecimal> disBuLoanCharges = new HashMap<>();
for (final LoanCharge loanCharge : loanCharges) {
if (loanCharge.isDueAtDisbursement() && loanCharge.getChargePaymentMode().isPaymentModeAccountTransfer()
&& loanCharge.isNotFullyPaid() && !loanCharge.isWaived()) {
&& loanCharge.isChargePending()) {
disBuLoanCharges.put(loanCharge.getId(), loanCharge.amountOutstanding());
}
}