MIFOSX-2227 : added mapping between Loan transaction and repayment schedule
This commit is contained in:
+44
-2
@@ -7,6 +7,7 @@ package org.mifosplatform.portfolio.loanaccount.domain;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -119,6 +120,11 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
|||||||
@Column(name = "manually_adjusted_or_reversed", nullable = false)
|
@Column(name = "manually_adjusted_or_reversed", nullable = false)
|
||||||
private boolean manuallyAdjustedOrReversed;
|
private boolean manuallyAdjustedOrReversed;
|
||||||
|
|
||||||
|
@LazyCollection(LazyCollectionOption.FALSE)
|
||||||
|
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
|
@JoinColumn(name = "loan_transaction_id", referencedColumnName= "id" , nullable = false)
|
||||||
|
private Set<LoanTransactionToRepaymentScheduleMapping> loanTransactionToRepaymentScheduleMappings = new HashSet<>();
|
||||||
|
|
||||||
protected LoanTransaction() {
|
protected LoanTransaction() {
|
||||||
this.loan = null;
|
this.loan = null;
|
||||||
this.dateOf = null;
|
this.dateOf = null;
|
||||||
@@ -640,9 +646,9 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
|||||||
private LocalDate getCreatedDate() {
|
private LocalDate getCreatedDate() {
|
||||||
return new LocalDate(this.createdDate);
|
return new LocalDate(this.createdDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDateTime getCreatedDateTime() {
|
public LocalDateTime getCreatedDateTime() {
|
||||||
return new LocalDateTime(this.createdDate);
|
return new LocalDateTime(this.createdDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLastTransaction(final LoanTransaction loanTransaction) {
|
public boolean isLastTransaction(final LoanTransaction loanTransaction) {
|
||||||
@@ -662,4 +668,40 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
return isLatest;
|
return isLatest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateLoanTransactionToRepaymentScheduleMappings(final Collection<LoanTransactionToRepaymentScheduleMapping> mappings) {
|
||||||
|
Collection<LoanTransactionToRepaymentScheduleMapping> retainMappings = new ArrayList<>();
|
||||||
|
for (LoanTransactionToRepaymentScheduleMapping updatedrepaymentScheduleMapping : mappings) {
|
||||||
|
updateMapingDetail(retainMappings, updatedrepaymentScheduleMapping);
|
||||||
|
}
|
||||||
|
this.loanTransactionToRepaymentScheduleMappings.retainAll(retainMappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateMapingDetail(final Collection<LoanTransactionToRepaymentScheduleMapping> retainMappings,
|
||||||
|
final LoanTransactionToRepaymentScheduleMapping updatedrepaymentScheduleMapping) {
|
||||||
|
boolean isMappingUpdated = false;
|
||||||
|
for (LoanTransactionToRepaymentScheduleMapping repaymentScheduleMapping : this.loanTransactionToRepaymentScheduleMappings) {
|
||||||
|
if (updatedrepaymentScheduleMapping.getLoanRepaymentScheduleInstallment().getId() != null
|
||||||
|
&& repaymentScheduleMapping.getLoanRepaymentScheduleInstallment().getDueDate()
|
||||||
|
.equals(updatedrepaymentScheduleMapping.getLoanRepaymentScheduleInstallment().getDueDate())) {
|
||||||
|
repaymentScheduleMapping.setComponents(updatedrepaymentScheduleMapping.getPrincipalPortion(),
|
||||||
|
updatedrepaymentScheduleMapping.getInterestPortion(), updatedrepaymentScheduleMapping.getFeeChargesPortion(),
|
||||||
|
updatedrepaymentScheduleMapping.getPenaltyChargesPortion());
|
||||||
|
isMappingUpdated = true;
|
||||||
|
retainMappings.add(repaymentScheduleMapping);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isMappingUpdated) {
|
||||||
|
this.loanTransactionToRepaymentScheduleMappings.add(updatedrepaymentScheduleMapping);
|
||||||
|
retainMappings.add(updatedrepaymentScheduleMapping);
|
||||||
|
}
|
||||||
|
return isMappingUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Set<LoanTransactionToRepaymentScheduleMapping> getLoanTransactionToRepaymentScheduleMappings() {
|
||||||
|
return this.loanTransactionToRepaymentScheduleMappings;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+145
@@ -0,0 +1,145 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.portfolio.loanaccount.domain;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
|
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "m_loan_transaction_repayment_schedule_mapping")
|
||||||
|
public class LoanTransactionToRepaymentScheduleMapping extends AbstractPersistable<Long> {
|
||||||
|
|
||||||
|
@ManyToOne(optional = false, cascade = CascadeType.PERSIST)
|
||||||
|
@JoinColumn(name = "loan_repayment_schedule_id", nullable = false)
|
||||||
|
private LoanRepaymentScheduleInstallment installment;
|
||||||
|
|
||||||
|
@Column(name = "principal_portion_derived", scale = 6, precision = 19, nullable = true)
|
||||||
|
private BigDecimal principalPortion;
|
||||||
|
|
||||||
|
@Column(name = "interest_portion_derived", scale = 6, precision = 19, nullable = true)
|
||||||
|
private BigDecimal interestPortion;
|
||||||
|
|
||||||
|
@Column(name = "fee_charges_portion_derived", scale = 6, precision = 19, nullable = true)
|
||||||
|
private BigDecimal feeChargesPortion;
|
||||||
|
|
||||||
|
@Column(name = "penalty_charges_portion_derived", scale = 6, precision = 19, nullable = true)
|
||||||
|
private BigDecimal penaltyChargesPortion;
|
||||||
|
|
||||||
|
@Column(name = "amount", scale = 6, precision = 19)
|
||||||
|
private BigDecimal amount;
|
||||||
|
|
||||||
|
protected LoanTransactionToRepaymentScheduleMapping() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoanTransactionToRepaymentScheduleMapping(final LoanRepaymentScheduleInstallment installment,
|
||||||
|
final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion,
|
||||||
|
final BigDecimal penaltyChargesPortion, final BigDecimal amount) {
|
||||||
|
this.installment = installment;
|
||||||
|
this.principalPortion = principalPortion;
|
||||||
|
this.interestPortion = interestPortion;
|
||||||
|
this.feeChargesPortion = feeChargesPortion;
|
||||||
|
this.penaltyChargesPortion = penaltyChargesPortion;
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LoanTransactionToRepaymentScheduleMapping createFrom(final LoanRepaymentScheduleInstallment installment,
|
||||||
|
final Money principalPortion, final Money interestPortion, final Money feeChargesPortion, final Money penaltyChargesPortion) {
|
||||||
|
return new LoanTransactionToRepaymentScheduleMapping(installment, defaultToNullIfZero(principalPortion),
|
||||||
|
defaultToNullIfZero(interestPortion), defaultToNullIfZero(feeChargesPortion), defaultToNullIfZero(penaltyChargesPortion),
|
||||||
|
defaultToNullIfZero(principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BigDecimal defaultToNullIfZero(final Money value) {
|
||||||
|
BigDecimal result = value.getAmount();
|
||||||
|
if (value.isZero()) {
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal defaultToZeroIfNull(final BigDecimal value) {
|
||||||
|
BigDecimal result = value;
|
||||||
|
if (value == null) {
|
||||||
|
result = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoanRepaymentScheduleInstallment getLoanRepaymentScheduleInstallment() {
|
||||||
|
return this.installment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateComponents(final Money principal, final Money interest, final Money feeCharges, final Money penaltyCharges) {
|
||||||
|
final MonetaryCurrency currency = principal.getCurrency();
|
||||||
|
this.principalPortion = defaultToNullIfZero(getPrincipalPortion(currency).plus(principal));
|
||||||
|
this.interestPortion = defaultToNullIfZero(getInterestPortion(currency).plus(interest));
|
||||||
|
updateChargesComponents(feeCharges, penaltyCharges);
|
||||||
|
updateAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAmount() {
|
||||||
|
this.amount = defaultToZeroIfNull(getPrincipalPortion()).add(defaultToZeroIfNull(getInterestPortion()))
|
||||||
|
.add(defaultToZeroIfNull(getFeeChargesPortion())).add(defaultToZeroIfNull(getPenaltyChargesPortion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComponents(final BigDecimal principal, final BigDecimal interest, final BigDecimal feeCharges,
|
||||||
|
final BigDecimal penaltyCharges) {
|
||||||
|
this.principalPortion = principal;
|
||||||
|
this.interestPortion = interest;
|
||||||
|
this.feeChargesPortion = feeCharges;
|
||||||
|
this.penaltyChargesPortion = penaltyCharges;
|
||||||
|
updateAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateChargesComponents(final Money feeCharges, final Money penaltyCharges) {
|
||||||
|
final MonetaryCurrency currency = feeCharges.getCurrency();
|
||||||
|
this.feeChargesPortion = defaultToNullIfZero(getFeeChargesPortion(currency).plus(feeCharges));
|
||||||
|
this.penaltyChargesPortion = defaultToNullIfZero(getPenaltyChargesPortion(currency).plus(penaltyCharges));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Money getPrincipalPortion(final MonetaryCurrency currency) {
|
||||||
|
return Money.of(currency, this.principalPortion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Money getInterestPortion(final MonetaryCurrency currency) {
|
||||||
|
return Money.of(currency, this.interestPortion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Money getFeeChargesPortion(final MonetaryCurrency currency) {
|
||||||
|
return Money.of(currency, this.feeChargesPortion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Money getPenaltyChargesPortion(final MonetaryCurrency currency) {
|
||||||
|
return Money.of(currency, this.penaltyChargesPortion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getPrincipalPortion() {
|
||||||
|
return this.principalPortion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getInterestPortion() {
|
||||||
|
return this.interestPortion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getFeeChargesPortion() {
|
||||||
|
return this.feeChargesPortion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getPenaltyChargesPortion() {
|
||||||
|
return this.penaltyChargesPortion;
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
-12
@@ -24,6 +24,7 @@ import org.mifosplatform.portfolio.loanaccount.domain.LoanInstallmentCharge;
|
|||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleProcessingWrapper;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleProcessingWrapper;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionToRepaymentScheduleMapping;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionType;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.impl.CreocoreLoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.impl.CreocoreLoanRepaymentScheduleTransactionProcessor;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.impl.HeavensFamilyLoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.impl.HeavensFamilyLoanRepaymentScheduleTransactionProcessor;
|
||||||
@@ -170,7 +171,9 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
* reverse the original transaction and update
|
* reverse the original transaction and update
|
||||||
* changedTransactionDetail accordingly
|
* changedTransactionDetail accordingly
|
||||||
**/
|
**/
|
||||||
if (!LoanTransaction.transactionAmountsMatch(currency, loanTransaction, newLoanTransaction)) {
|
if (LoanTransaction.transactionAmountsMatch(currency, loanTransaction, newLoanTransaction)) {
|
||||||
|
loanTransaction.updateLoanTransactionToRepaymentScheduleMappings(newLoanTransaction.getLoanTransactionToRepaymentScheduleMappings());
|
||||||
|
} else{
|
||||||
loanTransaction.reverse();
|
loanTransaction.reverse();
|
||||||
loanTransaction.updateExternalId(null);
|
loanTransaction.updateExternalId(null);
|
||||||
changedTransactionDetail.getNewTransactionMappings().put(loanTransaction.getId(), newLoanTransaction);
|
changedTransactionDetail.getNewTransactionMappings().put(loanTransaction.getId(), newLoanTransaction);
|
||||||
@@ -267,6 +270,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
if (amountToProcess != null) {
|
if (amountToProcess != null) {
|
||||||
transactionAmountUnprocessed = amountToProcess;
|
transactionAmountUnprocessed = amountToProcess;
|
||||||
}
|
}
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings = new ArrayList<>();
|
||||||
|
|
||||||
for (final LoanRepaymentScheduleInstallment currentInstallment : installments) {
|
for (final LoanRepaymentScheduleInstallment currentInstallment : installments) {
|
||||||
if (transactionAmountUnprocessed.isGreaterThanZero()) {
|
if (transactionAmountUnprocessed.isGreaterThanZero()) {
|
||||||
@@ -277,23 +281,24 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
// current installment?
|
// current installment?
|
||||||
if (isTransactionInAdvanceOfInstallment(installmentIndex, installments, transactionDate, transactionAmountUnprocessed)) {
|
if (isTransactionInAdvanceOfInstallment(installmentIndex, installments, transactionDate, transactionAmountUnprocessed)) {
|
||||||
transactionAmountUnprocessed = handleTransactionThatIsPaymentInAdvanceOfInstallment(currentInstallment,
|
transactionAmountUnprocessed = handleTransactionThatIsPaymentInAdvanceOfInstallment(currentInstallment,
|
||||||
installments, loanTransaction, transactionDate, transactionAmountUnprocessed);
|
installments, loanTransaction, transactionDate, transactionAmountUnprocessed, transactionMappings);
|
||||||
} else if (isTransactionALateRepaymentOnInstallment(installmentIndex, installments,
|
} else if (isTransactionALateRepaymentOnInstallment(installmentIndex, installments,
|
||||||
loanTransaction.getTransactionDate())) {
|
loanTransaction.getTransactionDate())) {
|
||||||
// does this result in a late payment of existing
|
// does this result in a late payment of existing
|
||||||
// installment?
|
// installment?
|
||||||
transactionAmountUnprocessed = handleTransactionThatIsALateRepaymentOfInstallment(currentInstallment, installments,
|
transactionAmountUnprocessed = handleTransactionThatIsALateRepaymentOfInstallment(currentInstallment, installments,
|
||||||
loanTransaction, transactionAmountUnprocessed);
|
loanTransaction, transactionAmountUnprocessed, transactionMappings);
|
||||||
} else {
|
} else {
|
||||||
// standard transaction
|
// standard transaction
|
||||||
transactionAmountUnprocessed = handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment,
|
transactionAmountUnprocessed = handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment,
|
||||||
loanTransaction, transactionAmountUnprocessed);
|
loanTransaction, transactionAmountUnprocessed, transactionMappings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
installmentIndex++;
|
installmentIndex++;
|
||||||
}
|
}
|
||||||
|
loanTransaction.updateLoanTransactionToRepaymentScheduleMappings(transactionMappings);
|
||||||
return transactionAmountUnprocessed;
|
return transactionAmountUnprocessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +332,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
if (loanTransaction.isChargePayment()) {
|
if (loanTransaction.isChargePayment()) {
|
||||||
feeAmount = feeCharges;
|
feeAmount = feeCharges;
|
||||||
}
|
}
|
||||||
if(unpaidCharge == null) break ; //All are trache charges
|
if (unpaidCharge == null) break; // All are trache charges
|
||||||
final Money amountPaidTowardsCharge = unpaidCharge.updatePaidAmountBy(amountRemaining, installmentNumber, feeAmount);
|
final Money amountPaidTowardsCharge = unpaidCharge.updatePaidAmountBy(amountRemaining, installmentNumber, feeAmount);
|
||||||
if (!amountPaidTowardsCharge.isZero()) {
|
if (!amountPaidTowardsCharge.isZero()) {
|
||||||
Set<LoanChargePaidBy> chargesPaidBies = loanTransaction.getLoanChargesPaid();
|
Set<LoanChargePaidBy> chargesPaidBies = loanTransaction.getLoanChargesPaid();
|
||||||
@@ -421,10 +426,13 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* For late repayments, how should components of installment be paid off
|
* For late repayments, how should components of installment be paid off
|
||||||
|
*
|
||||||
|
* @param transactionMappings
|
||||||
|
* TODO
|
||||||
*/
|
*/
|
||||||
protected abstract Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected abstract Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final Money transactionAmountUnprocessed);
|
final Money transactionAmountUnprocessed, final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is responsible for checking if the current transaction is 'an
|
* This method is responsible for checking if the current transaction is 'an
|
||||||
@@ -444,16 +452,24 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* For early/'in advance' repayments.
|
* For early/'in advance' repayments.
|
||||||
|
*
|
||||||
|
* @param transactionMappings
|
||||||
|
* TODO
|
||||||
*/
|
*/
|
||||||
protected abstract Money handleTransactionThatIsPaymentInAdvanceOfInstallment(
|
protected abstract Money handleTransactionThatIsPaymentInAdvanceOfInstallment(
|
||||||
final LoanRepaymentScheduleInstallment currentInstallment, final List<LoanRepaymentScheduleInstallment> installments,
|
final LoanRepaymentScheduleInstallment currentInstallment, final List<LoanRepaymentScheduleInstallment> installments,
|
||||||
final LoanTransaction loanTransaction, final LocalDate transactionDate, final Money paymentInAdvance);
|
final LoanTransaction loanTransaction, final LocalDate transactionDate, final Money paymentInAdvance,
|
||||||
|
final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For normal on-time repayments.
|
* For normal on-time repayments.
|
||||||
|
*
|
||||||
|
* @param transactionMappings
|
||||||
|
* TODO
|
||||||
*/
|
*/
|
||||||
protected abstract Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected abstract Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed);
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when a transaction results in an over-payment of the full loan.
|
* Invoked when a transaction results in an over-payment of the full loan.
|
||||||
@@ -489,7 +505,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
public void handleRefund(LoanTransaction loanTransaction, MonetaryCurrency currency,
|
public void handleRefund(LoanTransaction loanTransaction, MonetaryCurrency currency,
|
||||||
List<LoanRepaymentScheduleInstallment> installments, final Set<LoanCharge> charges) {
|
List<LoanRepaymentScheduleInstallment> installments, final Set<LoanCharge> charges) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings = new ArrayList<>();
|
||||||
final Comparator<LoanRepaymentScheduleInstallment> byDate = new Comparator<LoanRepaymentScheduleInstallment>() {
|
final Comparator<LoanRepaymentScheduleInstallment> byDate = new Comparator<LoanRepaymentScheduleInstallment>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -506,7 +522,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
|
|
||||||
if (outstanding.isLessThan(due)) {
|
if (outstanding.isLessThan(due)) {
|
||||||
transactionAmountUnprocessed = handleRefundTransactionPaymentOfInstallment(currentInstallment, loanTransaction,
|
transactionAmountUnprocessed = handleRefundTransactionPaymentOfInstallment(currentInstallment, loanTransaction,
|
||||||
transactionAmountUnprocessed);
|
transactionAmountUnprocessed, transactionMappings);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,7 +543,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
if (penaltyCharges.isGreaterThanZero()) {
|
if (penaltyCharges.isGreaterThanZero()) {
|
||||||
undoChargesPaidAmountBy(loanTransaction, penaltyCharges, loanPenalties, installmentNumber);
|
undoChargesPaidAmountBy(loanTransaction, penaltyCharges, loanPenalties, installmentNumber);
|
||||||
}
|
}
|
||||||
|
loanTransaction.updateLoanTransactionToRepaymentScheduleMappings(transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -537,9 +553,13 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
|||||||
* Undoes principal, interest, fees and charges of this transaction based on
|
* Undoes principal, interest, fees and charges of this transaction based on
|
||||||
* the repayment strategy
|
* the repayment strategy
|
||||||
*
|
*
|
||||||
|
* @param transactionMappings
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
protected abstract Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected abstract Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed);
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings);
|
||||||
|
|
||||||
private void undoChargesPaidAmountBy(final LoanTransaction loanTransaction, final Money feeCharges, final Set<LoanCharge> charges,
|
private void undoChargesPaidAmountBy(final LoanTransaction loanTransaction, final Money feeCharges, final Set<LoanCharge> charges,
|
||||||
final Integer installmentNumber) {
|
final Integer installmentNumber) {
|
||||||
|
|||||||
+32
-21
@@ -12,6 +12,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
|||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionToRepaymentScheduleMapping;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||||
|
|
||||||
@@ -52,9 +53,10 @@ public class CreocoreLoanRepaymentScheduleTransactionProcessor extends AbstractL
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final LocalDate transactionDate, final Money paymentInAdvance) {
|
final LocalDate transactionDate, final Money paymentInAdvance,
|
||||||
|
final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance, transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,9 +67,10 @@ public class CreocoreLoanRepaymentScheduleTransactionProcessor extends AbstractL
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final Money transactionAmountUnprocessed) {
|
final Money transactionAmountUnprocessed, final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed,
|
||||||
|
transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,7 +78,8 @@ public class CreocoreLoanRepaymentScheduleTransactionProcessor extends AbstractL
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||||
@@ -119,7 +123,10 @@ public class CreocoreLoanRepaymentScheduleTransactionProcessor extends AbstractL
|
|||||||
principalPortion = currentInstallment.payPrincipalComponent(transactionDate, transactionAmountRemaining);
|
principalPortion = currentInstallment.payPrincipalComponent(transactionDate, transactionAmountRemaining);
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
||||||
}
|
}
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
@@ -129,10 +136,11 @@ public class CreocoreLoanRepaymentScheduleTransactionProcessor extends AbstractL
|
|||||||
protected void onLoanOverpayment(final LoanTransaction loanTransaction, final Money loanOverPaymentAmount) {
|
protected void onLoanOverpayment(final LoanTransaction loanTransaction, final Money loanOverPaymentAmount) {
|
||||||
// dont do anything for with loan over-payment
|
// dont do anything for with loan over-payment
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
Money transactionAmountRemaining = transactionAmountUnprocessed;
|
Money transactionAmountRemaining = transactionAmountUnprocessed;
|
||||||
@@ -140,26 +148,29 @@ public class CreocoreLoanRepaymentScheduleTransactionProcessor extends AbstractL
|
|||||||
Money interestPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
Money interestPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||||
Money feeChargesPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
Money feeChargesPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||||
Money penaltyChargesPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
Money penaltyChargesPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||||
|
|
||||||
principalPortion = currentInstallment.unpayPrincipalComponent(transactionDate, transactionAmountRemaining);
|
principalPortion = currentInstallment.unpayPrincipalComponent(transactionDate, transactionAmountRemaining);
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
transactionAmountRemaining = transactionAmountRemaining.minus(principalPortion);
|
||||||
|
|
||||||
if(transactionAmountRemaining.isGreaterThanZero()) {
|
if (transactionAmountRemaining.isGreaterThanZero()) {
|
||||||
interestPortion = currentInstallment.unpayInterestComponent(transactionDate, transactionAmountRemaining);
|
interestPortion = currentInstallment.unpayInterestComponent(transactionDate, transactionAmountRemaining);
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(transactionAmountRemaining.isGreaterThanZero()) {
|
if (transactionAmountRemaining.isGreaterThanZero()) {
|
||||||
feeChargesPortion = currentInstallment.unpayFeeChargesComponent(transactionDate, transactionAmountRemaining);
|
feeChargesPortion = currentInstallment.unpayFeeChargesComponent(transactionDate, transactionAmountRemaining);
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(transactionAmountRemaining.isGreaterThanZero()) {
|
if (transactionAmountRemaining.isGreaterThanZero()) {
|
||||||
penaltyChargesPortion = currentInstallment.unpayPenaltyChargesComponent(transactionDate, transactionAmountRemaining);
|
penaltyChargesPortion = currentInstallment.unpayPenaltyChargesComponent(transactionDate, transactionAmountRemaining);
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||||
}
|
}
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+22
-8
@@ -12,6 +12,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
|||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionToRepaymentScheduleMapping;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||||
|
|
||||||
@@ -29,7 +30,8 @@ public class EarlyPaymentLoanRepaymentScheduleTransactionProcessor extends Abstr
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final LocalDate transactionDate, final Money paymentInAdvance) {
|
final LocalDate transactionDate, final Money paymentInAdvance,
|
||||||
|
final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = paymentInAdvance.getCurrency();
|
final MonetaryCurrency currency = paymentInAdvance.getCurrency();
|
||||||
Money transactionAmountRemaining = paymentInAdvance;
|
Money transactionAmountRemaining = paymentInAdvance;
|
||||||
@@ -69,7 +71,10 @@ public class EarlyPaymentLoanRepaymentScheduleTransactionProcessor extends Abstr
|
|||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
}
|
}
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -82,9 +87,10 @@ public class EarlyPaymentLoanRepaymentScheduleTransactionProcessor extends Abstr
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final Money transactionAmountUnprocessed) {
|
final Money transactionAmountUnprocessed, List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed,
|
||||||
|
transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -92,7 +98,8 @@ public class EarlyPaymentLoanRepaymentScheduleTransactionProcessor extends Abstr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||||
@@ -134,13 +141,17 @@ public class EarlyPaymentLoanRepaymentScheduleTransactionProcessor extends Abstr
|
|||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
}
|
}
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
// final MonetaryCurrency currency =
|
// final MonetaryCurrency currency =
|
||||||
@@ -172,7 +183,10 @@ public class EarlyPaymentLoanRepaymentScheduleTransactionProcessor extends Abstr
|
|||||||
}
|
}
|
||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-7
@@ -12,6 +12,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
|||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionToRepaymentScheduleMapping;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||||
|
|
||||||
@@ -38,9 +39,10 @@ public class HeavensFamilyLoanRepaymentScheduleTransactionProcessor extends Abst
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final Money transactionAmountUnprocessed) {
|
final Money transactionAmountUnprocessed, List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed,
|
||||||
|
transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -69,7 +71,8 @@ public class HeavensFamilyLoanRepaymentScheduleTransactionProcessor extends Abst
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final LocalDate transactionDate, final Money paymentInAdvance) {
|
final LocalDate transactionDate, final Money paymentInAdvance,
|
||||||
|
final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = paymentInAdvance.getCurrency();
|
final MonetaryCurrency currency = paymentInAdvance.getCurrency();
|
||||||
Money transactionAmountRemaining = paymentInAdvance;
|
Money transactionAmountRemaining = paymentInAdvance;
|
||||||
@@ -120,6 +123,10 @@ public class HeavensFamilyLoanRepaymentScheduleTransactionProcessor extends Abst
|
|||||||
}
|
}
|
||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +135,8 @@ public class HeavensFamilyLoanRepaymentScheduleTransactionProcessor extends Abst
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||||
@@ -176,15 +184,20 @@ public class HeavensFamilyLoanRepaymentScheduleTransactionProcessor extends Abst
|
|||||||
}
|
}
|
||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onLoanOverpayment(final LoanTransaction loanTransaction, final Money loanOverPaymentAmount) {}
|
protected void onLoanOverpayment(final LoanTransaction loanTransaction, final Money loanOverPaymentAmount) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||||
@@ -215,7 +228,10 @@ public class HeavensFamilyLoanRepaymentScheduleTransactionProcessor extends Abst
|
|||||||
}
|
}
|
||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+20
-9
@@ -12,6 +12,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
|||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionToRepaymentScheduleMapping;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||||
|
|
||||||
@@ -30,9 +31,10 @@ public class InterestPrincipalPenaltyFeesOrderLoanRepaymentScheduleTransactionPr
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final LocalDate transactionDate, final Money paymentInAdvance) {
|
final LocalDate transactionDate, final Money paymentInAdvance,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance, transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,9 +45,10 @@ public class InterestPrincipalPenaltyFeesOrderLoanRepaymentScheduleTransactionPr
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final Money transactionAmountUnprocessed) {
|
final Money transactionAmountUnprocessed, List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed,
|
||||||
|
transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,7 +56,8 @@ public class InterestPrincipalPenaltyFeesOrderLoanRepaymentScheduleTransactionPr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||||
@@ -101,13 +105,17 @@ public class InterestPrincipalPenaltyFeesOrderLoanRepaymentScheduleTransactionPr
|
|||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
}
|
}
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
Money transactionAmountRemaining = transactionAmountUnprocessed;
|
Money transactionAmountRemaining = transactionAmountUnprocessed;
|
||||||
@@ -137,7 +145,10 @@ public class InterestPrincipalPenaltyFeesOrderLoanRepaymentScheduleTransactionPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+20
-9
@@ -12,6 +12,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
|||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionToRepaymentScheduleMapping;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||||
|
|
||||||
@@ -45,9 +46,10 @@ public class MifosStyleLoanRepaymentScheduleTransactionProcessor extends Abstrac
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final LocalDate transactionDate, final Money paymentInAdvance) {
|
final LocalDate transactionDate, final Money paymentInAdvance,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance, transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,9 +59,10 @@ public class MifosStyleLoanRepaymentScheduleTransactionProcessor extends Abstrac
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final Money transactionAmountUnprocessed) {
|
final Money transactionAmountUnprocessed, List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed,
|
||||||
|
transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -67,7 +70,8 @@ public class MifosStyleLoanRepaymentScheduleTransactionProcessor extends Abstrac
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||||
@@ -115,7 +119,10 @@ public class MifosStyleLoanRepaymentScheduleTransactionProcessor extends Abstrac
|
|||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
}
|
}
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,10 +130,11 @@ public class MifosStyleLoanRepaymentScheduleTransactionProcessor extends Abstrac
|
|||||||
protected void onLoanOverpayment(final LoanTransaction loanTransaction, final Money loanOverPaymentAmount) {
|
protected void onLoanOverpayment(final LoanTransaction loanTransaction, final Money loanOverPaymentAmount) {
|
||||||
// TODO - KW - dont do anything with loan over-payment for now
|
// TODO - KW - dont do anything with loan over-payment for now
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||||
@@ -154,7 +162,10 @@ public class MifosStyleLoanRepaymentScheduleTransactionProcessor extends Abstrac
|
|||||||
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||||
}
|
}
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+22
-9
@@ -12,6 +12,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
|||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionToRepaymentScheduleMapping;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||||
|
|
||||||
@@ -30,9 +31,10 @@ public class PrincipalInterestPenaltyFeesOrderLoanRepaymentScheduleTransactionPr
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final LocalDate transactionDate, final Money paymentInAdvance) {
|
final LocalDate transactionDate, final Money paymentInAdvance,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance, transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,9 +45,10 @@ public class PrincipalInterestPenaltyFeesOrderLoanRepaymentScheduleTransactionPr
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final Money transactionAmountUnprocessed) {
|
final Money transactionAmountUnprocessed, List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed,
|
||||||
|
transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,7 +56,8 @@ public class PrincipalInterestPenaltyFeesOrderLoanRepaymentScheduleTransactionPr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||||
@@ -101,16 +105,22 @@ public class PrincipalInterestPenaltyFeesOrderLoanRepaymentScheduleTransactionPr
|
|||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
}
|
}
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
|
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
//final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
// final MonetaryCurrency currency =
|
||||||
|
// transactionAmountUnprocessed.getCurrency();
|
||||||
Money transactionAmountRemaining = transactionAmountUnprocessed;
|
Money transactionAmountRemaining = transactionAmountUnprocessed;
|
||||||
Money principalPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
Money principalPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||||
Money interestPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
Money interestPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||||
@@ -138,7 +148,10 @@ public class PrincipalInterestPenaltyFeesOrderLoanRepaymentScheduleTransactionPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+44
-6
@@ -12,6 +12,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
|||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||||
|
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionToRepaymentScheduleMapping;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.AbstractLoanRepaymentScheduleTransactionProcessor;
|
||||||
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
import org.mifosplatform.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor;
|
||||||
|
|
||||||
@@ -52,9 +53,10 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final LocalDate transactionDate, final Money paymentInAdvance) {
|
final LocalDate transactionDate, final Money paymentInAdvance,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance);
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance, transactionMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,7 +66,7 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
|||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
||||||
final Money transactionAmountUnprocessed) {
|
final Money transactionAmountUnprocessed, List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
// pay of overdue and current interest due given transaction date
|
// pay of overdue and current interest due given transaction date
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
@@ -80,6 +82,10 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
|||||||
|
|
||||||
final Money principalPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
final Money principalPortion = Money.zero(transactionAmountRemaining.getCurrency());
|
||||||
loanTransaction.updateComponents(principalPortion, interestWaivedPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestWaivedPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (interestWaivedPortion.isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestWaivedPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
} else if (loanTransaction.isChargePayment()) {
|
} else if (loanTransaction.isChargePayment()) {
|
||||||
final Money principalPortion = Money.zero(currency);
|
final Money principalPortion = Money.zero(currency);
|
||||||
final Money interestPortion = Money.zero(currency);
|
final Money interestPortion = Money.zero(currency);
|
||||||
@@ -91,6 +97,10 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
|||||||
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||||
}
|
}
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
final LoanRepaymentScheduleInstallment currentInstallmentBasedOnTransactionDate = nearestInstallment(
|
final LoanRepaymentScheduleInstallment currentInstallmentBasedOnTransactionDate = nearestInstallment(
|
||||||
@@ -112,6 +122,10 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
|||||||
|
|
||||||
final Money principalPortion = Money.zero(currency);
|
final Money principalPortion = Money.zero(currency);
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(installment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +138,21 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
|||||||
|
|
||||||
final Money interestPortion = Money.zero(currency);
|
final Money interestPortion = Money.zero(currency);
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, Money.zero(currency), Money.zero(currency));
|
loanTransaction.updateComponents(principalPortion, interestPortion, Money.zero(currency), Money.zero(currency));
|
||||||
|
boolean isMappingUpdated = false;
|
||||||
|
for (LoanTransactionToRepaymentScheduleMapping repaymentScheduleMapping : transactionMappings) {
|
||||||
|
if (repaymentScheduleMapping.getLoanRepaymentScheduleInstallment().getDueDate().equals(installment.getDueDate())) {
|
||||||
|
repaymentScheduleMapping.updateComponents(principalPortion, principalPortion.zero(), principalPortion.zero(),
|
||||||
|
principalPortion.zero());
|
||||||
|
isMappingUpdated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isMappingUpdated
|
||||||
|
&& principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion)
|
||||||
|
.isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(installment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,7 +179,8 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
||||||
@@ -197,6 +227,10 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +247,8 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleRefundTransactionPaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed) {
|
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
||||||
|
final List<LoanTransactionToRepaymentScheduleMapping> transactionMappings) {
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
// final MonetaryCurrency currency =
|
// final MonetaryCurrency currency =
|
||||||
@@ -245,7 +280,10 @@ public class RBILoanRepaymentScheduleTransactionProcessor extends AbstractLoanRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(currentInstallment, principalPortion,
|
||||||
|
interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+52
-46
@@ -54,23 +54,23 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, final LocalDate scheduleTillDate) {
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, final LocalDate scheduleTillDate) {
|
||||||
|
|
||||||
final ApplicationCurrency applicationCurrency = loanApplicationTerms.getApplicationCurrency();
|
final ApplicationCurrency applicationCurrency = loanApplicationTerms.getApplicationCurrency();
|
||||||
// 1. generate list of proposed schedule due dates
|
// generate list of proposed schedule due dates
|
||||||
final LocalDate loanEndDate = this.scheduledDateGenerator.getLastRepaymentDate(loanApplicationTerms, holidayDetailDTO);
|
final LocalDate loanEndDate = this.scheduledDateGenerator.getLastRepaymentDate(loanApplicationTerms, holidayDetailDTO);
|
||||||
loanApplicationTerms.updateLoanEndDate(loanEndDate);
|
loanApplicationTerms.updateLoanEndDate(loanEndDate);
|
||||||
|
|
||||||
// 2. determine the total charges due at time of disbursement
|
// determine the total charges due at time of disbursement
|
||||||
final BigDecimal chargesDueAtTimeOfDisbursement = deriveTotalChargesDueAtTimeOfDisbursement(loanCharges);
|
final BigDecimal chargesDueAtTimeOfDisbursement = deriveTotalChargesDueAtTimeOfDisbursement(loanCharges);
|
||||||
|
|
||||||
// 3. setup variables for tracking important facts required for loan
|
// setup variables for tracking important facts required for loan
|
||||||
// schedule generation.
|
// schedule generation.
|
||||||
Money principalDisbursed ;
|
Money principalToBeScheduled;
|
||||||
|
|
||||||
if(loanApplicationTerms.isMultiDisburseLoan() && loanApplicationTerms.getApprovedPrincipal().isGreaterThanZero()) {
|
if (loanApplicationTerms.isMultiDisburseLoan() && loanApplicationTerms.getApprovedPrincipal().isGreaterThanZero()) {
|
||||||
principalDisbursed = loanApplicationTerms.getApprovedPrincipal();
|
principalToBeScheduled = loanApplicationTerms.getApprovedPrincipal();
|
||||||
}else {
|
} else {
|
||||||
principalDisbursed = loanApplicationTerms.getPrincipal();
|
principalToBeScheduled = loanApplicationTerms.getPrincipal();
|
||||||
}
|
}
|
||||||
final MonetaryCurrency currency = principalDisbursed.getCurrency();
|
final MonetaryCurrency currency = principalToBeScheduled.getCurrency();
|
||||||
final int numberOfRepayments = loanApplicationTerms.getNumberOfRepayments();
|
final int numberOfRepayments = loanApplicationTerms.getNumberOfRepayments();
|
||||||
|
|
||||||
// variables for cumulative totals
|
// variables for cumulative totals
|
||||||
@@ -80,14 +80,14 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
BigDecimal totalPenaltyChargesCharged = BigDecimal.ZERO;
|
BigDecimal totalPenaltyChargesCharged = BigDecimal.ZERO;
|
||||||
BigDecimal totalRepaymentExpected = chargesDueAtTimeOfDisbursement;
|
BigDecimal totalRepaymentExpected = chargesDueAtTimeOfDisbursement;
|
||||||
final BigDecimal totalOutstanding = BigDecimal.ZERO;
|
final BigDecimal totalOutstanding = BigDecimal.ZERO;
|
||||||
Money totalCumulativePrincipal = principalDisbursed.zero();
|
Money totalCumulativePrincipal = principalToBeScheduled.zero();
|
||||||
Money totalCumulativeInterest = principalDisbursed.zero();
|
Money totalCumulativeInterest = principalToBeScheduled.zero();
|
||||||
Money totalOutstandingInterestPaymentDueToGrace = principalDisbursed.zero();
|
Money totalOutstandingInterestPaymentDueToGrace = principalToBeScheduled.zero();
|
||||||
|
|
||||||
final Collection<LoanScheduleModelPeriod> periods = createNewLoanScheduleListWithDisbursementDetails(numberOfRepayments,
|
final Collection<LoanScheduleModelPeriod> periods = createNewLoanScheduleListWithDisbursementDetails(numberOfRepayments,
|
||||||
loanApplicationTerms, chargesDueAtTimeOfDisbursement);
|
loanApplicationTerms, chargesDueAtTimeOfDisbursement);
|
||||||
|
|
||||||
// 4. Determine the total interest owed over the full loan for FLAT
|
// Determine the total interest owed over the full loan for FLAT
|
||||||
// interest method .
|
// interest method .
|
||||||
Money totalInterestChargedForFullLoanTerm = loanApplicationTerms.calculateTotalInterestCharged(
|
Money totalInterestChargedForFullLoanTerm = loanApplicationTerms.calculateTotalInterestCharged(
|
||||||
this.paymentPeriodsInOneYearCalculator, mc);
|
this.paymentPeriodsInOneYearCalculator, mc);
|
||||||
@@ -104,10 +104,10 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
|
|
||||||
// Actual period Number as per the schedule
|
// Actual period Number as per the schedule
|
||||||
int periodNumber = 1;
|
int periodNumber = 1;
|
||||||
// Actual period Number and interest only repayments
|
// Actual period Number plus interest only repayments
|
||||||
int instalmentNumber = 1;
|
int instalmentNumber = 1;
|
||||||
|
|
||||||
Money outstandingBalance = principalDisbursed;
|
Money outstandingBalance = principalToBeScheduled;
|
||||||
|
|
||||||
// Set fixed EMI Amount
|
// Set fixed EMI Amount
|
||||||
updateFixedInstallmentAmount(mc, loanApplicationTerms, actualRepaymentDate, periodNumber, outstandingBalance, holidayDetailDTO);
|
updateFixedInstallmentAmount(mc, loanApplicationTerms, actualRepaymentDate, periodNumber, outstandingBalance, holidayDetailDTO);
|
||||||
@@ -120,7 +120,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
// details to map
|
// details to map
|
||||||
BigDecimal disburseAmt = getDisbursementAmount(loanApplicationTerms, periodStartDate, periods, chargesDueAtTimeOfDisbursement,
|
BigDecimal disburseAmt = getDisbursementAmount(loanApplicationTerms, periodStartDate, periods, chargesDueAtTimeOfDisbursement,
|
||||||
disburseDetailMap, isInterestRecalculationRequired(loanApplicationTerms, transactions));
|
disburseDetailMap, isInterestRecalculationRequired(loanApplicationTerms, transactions));
|
||||||
principalDisbursed = principalDisbursed.zero().plus(disburseAmt);
|
principalToBeScheduled = principalToBeScheduled.zero().plus(disburseAmt);
|
||||||
loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().zero().plus(disburseAmt));
|
loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().zero().plus(disburseAmt));
|
||||||
outstandingBalance = outstandingBalance.zero().plus(disburseAmt);
|
outstandingBalance = outstandingBalance.zero().plus(disburseAmt);
|
||||||
}
|
}
|
||||||
@@ -228,16 +228,17 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
// updates actual outstanding balance with new
|
// updates actual outstanding balance with new
|
||||||
// disbursement detail
|
// disbursement detail
|
||||||
outstandingBalance = outstandingBalance.plus(disburseDetail.getValue());
|
outstandingBalance = outstandingBalance.plus(disburseDetail.getValue());
|
||||||
principalDisbursed = principalDisbursed.plus(disburseDetail.getValue());
|
principalToBeScheduled = principalToBeScheduled.plus(disburseDetail.getValue());
|
||||||
loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().plus(disburseDetail.getValue()));
|
loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().plus(disburseDetail.getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds new interest repayment to the schedule as per the repayment
|
// process repayments to the schedule as per the repayment
|
||||||
// transaction processor configuration
|
// transaction processor configuration
|
||||||
// will be added only if there is a loan repayment between the
|
// will add a new schedule with interest till the transaction date
|
||||||
// period for interest first repayment strategies
|
// for a loan repayment which falls between the
|
||||||
|
// two periods for interest first repayment strategies
|
||||||
Money earlyPaidAmount = Money.zero(currency);
|
Money earlyPaidAmount = Money.zero(currency);
|
||||||
LoanScheduleModelPeriod lastInstallment = null;
|
LoanScheduleModelPeriod lastInstallment = null;
|
||||||
if (isInterestRecalculationRequired(loanApplicationTerms, transactions)) {
|
if (isInterestRecalculationRequired(loanApplicationTerms, transactions)) {
|
||||||
@@ -282,7 +283,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
totalOutstandingInterestPaymentDueToGrace = principalInterestForThisPeriod.interestPaymentDueToGrace();
|
totalOutstandingInterestPaymentDueToGrace = principalInterestForThisPeriod.interestPaymentDueToGrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
Money principalForThisPeriod = principalDisbursed.zero();
|
Money principalForThisPeriod = principalToBeScheduled.zero();
|
||||||
|
|
||||||
// applies all the applicable charges to the
|
// applies all the applicable charges to the
|
||||||
// newly
|
// newly
|
||||||
@@ -290,17 +291,17 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
PrincipalInterest principalInterest = new PrincipalInterest(principalForThisPeriod,
|
PrincipalInterest principalInterest = new PrincipalInterest(principalForThisPeriod,
|
||||||
interestForThisinstallment, null);
|
interestForThisinstallment, null);
|
||||||
Money feeChargesForInstallment = cumulativeFeeChargesDueWithin(periodStartDate,
|
Money feeChargesForInstallment = cumulativeFeeChargesDueWithin(periodStartDate,
|
||||||
detail.getTransactionDate(), loanCharges, currency, principalInterest, principalDisbursed,
|
detail.getTransactionDate(), loanCharges, currency, principalInterest, principalToBeScheduled,
|
||||||
totalCumulativeInterest, numberOfRepayments, true);
|
totalCumulativeInterest, numberOfRepayments, true);
|
||||||
Money penaltyChargesForInstallment = cumulativePenaltyChargesDueWithin(periodStartDate,
|
Money penaltyChargesForInstallment = cumulativePenaltyChargesDueWithin(periodStartDate,
|
||||||
detail.getTransactionDate(), loanCharges, currency, principalInterest, principalDisbursed,
|
detail.getTransactionDate(), loanCharges, currency, principalInterest, principalToBeScheduled,
|
||||||
totalCumulativeInterest, numberOfRepayments, true);
|
totalCumulativeInterest, numberOfRepayments, true);
|
||||||
|
|
||||||
// 8. sum up real totalInstallmentDue from
|
// sum up real totalInstallmentDue from
|
||||||
// components
|
// components
|
||||||
final Money totalInstallmentDue = principalForThisPeriod.plus(interestForThisinstallment)
|
final Money totalInstallmentDue = principalForThisPeriod.plus(interestForThisinstallment)
|
||||||
.plus(feeChargesForInstallment).plus(penaltyChargesForInstallment);
|
.plus(feeChargesForInstallment).plus(penaltyChargesForInstallment);
|
||||||
// 9. create repayment period from parts
|
// create repayment period from parts
|
||||||
installment = LoanScheduleModelRepaymentPeriod.repayment(instalmentNumber, periodStartDate,
|
installment = LoanScheduleModelRepaymentPeriod.repayment(instalmentNumber, periodStartDate,
|
||||||
detail.getTransactionDate(), principalForThisPeriod, outstandingBalance,
|
detail.getTransactionDate(), principalForThisPeriod, outstandingBalance,
|
||||||
interestForThisinstallment, feeChargesForInstallment, penaltyChargesForInstallment,
|
interestForThisinstallment, feeChargesForInstallment, penaltyChargesForInstallment,
|
||||||
@@ -488,7 +489,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
mergeVariationsToMap(principalPortionMap, latePaymentMap, disburseDetailMap, compoundingMap), compoundingMap,
|
mergeVariationsToMap(principalPortionMap, latePaymentMap, disburseDetailMap, compoundingMap), compoundingMap,
|
||||||
periodStartDateApplicableForInterest, scheduledDueDate, daysInPeriodApplicableForInterest);
|
periodStartDateApplicableForInterest, scheduledDueDate, daysInPeriodApplicableForInterest);
|
||||||
|
|
||||||
if (loanApplicationTerms.getFixedEmiAmount() != null
|
if (loanApplicationTerms.getFixedEmiAmount() != null
|
||||||
&& loanApplicationTerms.getFixedEmiAmount().compareTo(principalInterestForThisPeriod.interest().getAmount()) != 1) {
|
&& loanApplicationTerms.getFixedEmiAmount().compareTo(principalInterestForThisPeriod.interest().getAmount()) != 1) {
|
||||||
String errorMsg = "EMI amount must be greater than : " + principalInterestForThisPeriod.interest().getAmount();
|
String errorMsg = "EMI amount must be greater than : " + principalInterestForThisPeriod.interest().getAmount();
|
||||||
throw new MultiDisbursementEmiAmountException(errorMsg, principalInterestForThisPeriod.interest().getAmount(),
|
throw new MultiDisbursementEmiAmountException(errorMsg, principalInterestForThisPeriod.interest().getAmount(),
|
||||||
@@ -520,13 +521,14 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
BigDecimal fixedEmiAmount = loanApplicationTerms.getFixedEmiAmount();
|
BigDecimal fixedEmiAmount = loanApplicationTerms.getFixedEmiAmount();
|
||||||
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal, totalCumulativePrincipal,
|
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal, totalCumulativePrincipal,
|
||||||
periodNumber + 1, mc, holidayDetailDTO);
|
periodNumber + 1, mc, holidayDetailDTO);
|
||||||
if (loanApplicationTerms.getAmortizationMethod().isEqualInstallment() && fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
|
if (loanApplicationTerms.getAmortizationMethod().isEqualInstallment()
|
||||||
|
&& fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
|
||||||
isEmiAmountChanged = true;
|
isEmiAmountChanged = true;
|
||||||
}
|
}
|
||||||
principalForThisPeriod = principalForThisPeriod.plus(earlyPaidAmount);
|
principalForThisPeriod = principalForThisPeriod.plus(earlyPaidAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. update outstandingLoanBlance using current period
|
// update outstandingLoanBlance using current period
|
||||||
// 'principalDue'
|
// 'principalDue'
|
||||||
outstandingBalance = outstandingBalance.minus(principalForThisPeriod.minus(reducedBalance));
|
outstandingBalance = outstandingBalance.minus(principalForThisPeriod.minus(reducedBalance));
|
||||||
|
|
||||||
@@ -534,21 +536,21 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
principalForThisPeriod = principalForThisPeriod.plus(outstandingBalance);
|
principalForThisPeriod = principalForThisPeriod.plus(outstandingBalance);
|
||||||
outstandingBalance = outstandingBalance.zero();
|
outstandingBalance = outstandingBalance.zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isNextRepaymentAvailable){
|
if (!isNextRepaymentAvailable) {
|
||||||
disburseDetailMap.clear();
|
disburseDetailMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// applies charges for the period
|
// applies charges for the period
|
||||||
PrincipalInterest principalInterest = new PrincipalInterest(principalForThisPeriod, interestForThisinstallment, null);
|
PrincipalInterest principalInterest = new PrincipalInterest(principalForThisPeriod, interestForThisinstallment, null);
|
||||||
Money feeChargesForInstallment = cumulativeFeeChargesDueWithin(periodStartDate, scheduledDueDate, loanCharges, currency,
|
Money feeChargesForInstallment = cumulativeFeeChargesDueWithin(periodStartDate, scheduledDueDate, loanCharges, currency,
|
||||||
principalInterest, principalDisbursed, totalCumulativeInterest, numberOfRepayments, true);
|
principalInterest, principalToBeScheduled, totalCumulativeInterest, numberOfRepayments, true);
|
||||||
Money penaltyChargesForInstallment = cumulativePenaltyChargesDueWithin(periodStartDate, scheduledDueDate, loanCharges,
|
Money penaltyChargesForInstallment = cumulativePenaltyChargesDueWithin(periodStartDate, scheduledDueDate, loanCharges,
|
||||||
currency, principalInterest, principalDisbursed, totalCumulativeInterest, numberOfRepayments, true);
|
currency, principalInterest, principalToBeScheduled, totalCumulativeInterest, numberOfRepayments, true);
|
||||||
totalFeeChargesCharged = totalFeeChargesCharged.add(feeChargesForInstallment.getAmount());
|
totalFeeChargesCharged = totalFeeChargesCharged.add(feeChargesForInstallment.getAmount());
|
||||||
totalPenaltyChargesCharged = totalPenaltyChargesCharged.add(penaltyChargesForInstallment.getAmount());
|
totalPenaltyChargesCharged = totalPenaltyChargesCharged.add(penaltyChargesForInstallment.getAmount());
|
||||||
|
|
||||||
// 8. sum up real totalInstallmentDue from components
|
// sum up real totalInstallmentDue from components
|
||||||
final Money totalInstallmentDue = principalForThisPeriod.plus(interestForThisinstallment).plus(feeChargesForInstallment)
|
final Money totalInstallmentDue = principalForThisPeriod.plus(interestForThisinstallment).plus(feeChargesForInstallment)
|
||||||
.plus(penaltyChargesForInstallment);
|
.plus(penaltyChargesForInstallment);
|
||||||
|
|
||||||
@@ -559,7 +561,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. create repayment period from parts
|
// create repayment period from parts
|
||||||
LoanScheduleModelPeriod installment = LoanScheduleModelRepaymentPeriod.repayment(instalmentNumber, periodStartDate,
|
LoanScheduleModelPeriod installment = LoanScheduleModelRepaymentPeriod.repayment(instalmentNumber, periodStartDate,
|
||||||
scheduledDueDate, principalForThisPeriod, outstandingBalance, interestForThisinstallment, feeChargesForInstallment,
|
scheduledDueDate, principalForThisPeriod, outstandingBalance, interestForThisinstallment, feeChargesForInstallment,
|
||||||
penaltyChargesForInstallment, totalInstallmentDue, false);
|
penaltyChargesForInstallment, totalInstallmentDue, false);
|
||||||
@@ -614,7 +616,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
final Money totalDue = principalForThisPeriod//
|
final Money totalDue = principalForThisPeriod//
|
||||||
.plus(interestForThisinstallment);
|
.plus(interestForThisinstallment);
|
||||||
|
|
||||||
// 9. create and replaces repayment period
|
// create and replaces repayment period
|
||||||
// from parts
|
// from parts
|
||||||
installment = LoanScheduleModelRepaymentPeriod.repayment(instalmentNumber, periodStartDate,
|
installment = LoanScheduleModelRepaymentPeriod.repayment(instalmentNumber, periodStartDate,
|
||||||
detail.getTransactionDate(), principalForThisPeriod, outstandingBalance,
|
detail.getTransactionDate(), principalForThisPeriod, outstandingBalance,
|
||||||
@@ -643,7 +645,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal,
|
reducePrincipal = applyEarlyPaymentStrategy(loanApplicationTerms, reducePrincipal,
|
||||||
totalCumulativePrincipal.plus(principalForThisPeriod.minus(principalProcessed)), periodNumber + 1, mc,
|
totalCumulativePrincipal.plus(principalForThisPeriod.minus(principalProcessed)), periodNumber + 1, mc,
|
||||||
holidayDetailDTO);
|
holidayDetailDTO);
|
||||||
if (loanApplicationTerms.getAmortizationMethod().isEqualInstallment() && fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
|
if (loanApplicationTerms.getAmortizationMethod().isEqualInstallment()
|
||||||
|
&& fixedEmiAmount.compareTo(loanApplicationTerms.getFixedEmiAmount()) != 0) {
|
||||||
isEmiAmountChanged = true;
|
isEmiAmountChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -694,18 +697,20 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
totalOutstandingInterestPaymentDueToGrace = totalOutstandingInterestPaymentDueToGrace.zero();
|
totalOutstandingInterestPaymentDueToGrace = totalOutstandingInterestPaymentDueToGrace.zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. determine fees and penalties for charges which depends on total
|
// determine fees and penalties for charges which depends on total
|
||||||
// loan interest
|
// loan interest
|
||||||
for (LoanScheduleModelPeriod loanScheduleModelPeriod : periods) {
|
for (LoanScheduleModelPeriod loanScheduleModelPeriod : periods) {
|
||||||
if (loanScheduleModelPeriod.isRepaymentPeriod()) {
|
if (loanScheduleModelPeriod.isRepaymentPeriod()) {
|
||||||
PrincipalInterest principalInterest = new PrincipalInterest(Money.of(currency, loanScheduleModelPeriod.principalDue()),
|
PrincipalInterest principalInterest = new PrincipalInterest(Money.of(currency, loanScheduleModelPeriod.principalDue()),
|
||||||
Money.of(currency, loanScheduleModelPeriod.interestDue()), null);
|
Money.of(currency, loanScheduleModelPeriod.interestDue()), null);
|
||||||
Money feeChargesForInstallment = cumulativeFeeChargesDueWithin(loanScheduleModelPeriod.periodFromDate(),
|
Money feeChargesForInstallment = cumulativeFeeChargesDueWithin(loanScheduleModelPeriod.periodFromDate(),
|
||||||
loanScheduleModelPeriod.periodDueDate(), nonCompoundingCharges, currency, principalInterest, principalDisbursed,
|
loanScheduleModelPeriod.periodDueDate(), nonCompoundingCharges, currency, principalInterest,
|
||||||
totalCumulativeInterest, numberOfRepayments, !loanScheduleModelPeriod.isRecalculatedInterestComponent());
|
principalToBeScheduled, totalCumulativeInterest, numberOfRepayments,
|
||||||
|
!loanScheduleModelPeriod.isRecalculatedInterestComponent());
|
||||||
Money penaltyChargesForInstallment = cumulativePenaltyChargesDueWithin(loanScheduleModelPeriod.periodFromDate(),
|
Money penaltyChargesForInstallment = cumulativePenaltyChargesDueWithin(loanScheduleModelPeriod.periodFromDate(),
|
||||||
loanScheduleModelPeriod.periodDueDate(), nonCompoundingCharges, currency, principalInterest, principalDisbursed,
|
loanScheduleModelPeriod.periodDueDate(), nonCompoundingCharges, currency, principalInterest,
|
||||||
totalCumulativeInterest, numberOfRepayments, !loanScheduleModelPeriod.isRecalculatedInterestComponent());
|
principalToBeScheduled, totalCumulativeInterest, numberOfRepayments,
|
||||||
|
!loanScheduleModelPeriod.isRecalculatedInterestComponent());
|
||||||
totalFeeChargesCharged = totalFeeChargesCharged.add(feeChargesForInstallment.getAmount());
|
totalFeeChargesCharged = totalFeeChargesCharged.add(feeChargesForInstallment.getAmount());
|
||||||
totalPenaltyChargesCharged = totalPenaltyChargesCharged.add(penaltyChargesForInstallment.getAmount());
|
totalPenaltyChargesCharged = totalPenaltyChargesCharged.add(penaltyChargesForInstallment.getAmount());
|
||||||
totalRepaymentExpected = totalRepaymentExpected.add(feeChargesForInstallment.getAmount()).add(
|
totalRepaymentExpected = totalRepaymentExpected.add(feeChargesForInstallment.getAmount()).add(
|
||||||
@@ -730,7 +735,7 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
|
|
||||||
loanApplicationTerms.resetFixedEmiAmount();
|
loanApplicationTerms.resetFixedEmiAmount();
|
||||||
|
|
||||||
return LoanScheduleModel.from(periods, applicationCurrency, loanTermInDays, principalDisbursed,
|
return LoanScheduleModel.from(periods, applicationCurrency, loanTermInDays, principalToBeScheduled,
|
||||||
totalCumulativePrincipal.getAmount(), totalPrincipalPaid, totalCumulativeInterest.getAmount(), totalFeeChargesCharged,
|
totalCumulativePrincipal.getAmount(), totalPrincipalPaid, totalCumulativeInterest.getAmount(), totalFeeChargesCharged,
|
||||||
totalPenaltyChargesCharged, totalRepaymentExpected, totalOutstanding);
|
totalPenaltyChargesCharged, totalRepaymentExpected, totalOutstanding);
|
||||||
}
|
}
|
||||||
@@ -943,8 +948,9 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
updateFixedInstallmentAmount(mc, loanApplicationTerms, loanApplicationTerms.getExpectedDisbursementDate(),
|
updateFixedInstallmentAmount(mc, loanApplicationTerms, loanApplicationTerms.getExpectedDisbursementDate(),
|
||||||
periodNumber, loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal), holidayDetailDTO);
|
periodNumber, loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal), holidayDetailDTO);
|
||||||
}
|
}
|
||||||
if(loanApplicationTerms.getAmortizationMethod().isEqualPrincipal()){
|
if (loanApplicationTerms.getAmortizationMethod().isEqualPrincipal()) {
|
||||||
loanApplicationTerms.updateFixedPrincipalAmount(mc, periodNumber, loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal));
|
loanApplicationTerms.updateFixedPrincipalAmount(mc, periodNumber,
|
||||||
|
loanApplicationTerms.getPrincipal().minus(totalCumulativePrincipal));
|
||||||
}
|
}
|
||||||
reducePrincipal = reducePrincipal.zero();
|
reducePrincipal = reducePrincipal.zero();
|
||||||
break;
|
break;
|
||||||
|
|||||||
-1
@@ -6,7 +6,6 @@
|
|||||||
package org.mifosplatform.portfolio.loanaccount.service;
|
package org.mifosplatform.portfolio.loanaccount.service;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
CREATE TABLE `m_loan_transaction_repayment_schedule_mapping` (
|
||||||
|
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
|
||||||
|
`loan_transaction_id` BIGINT(20) NOT NULL,
|
||||||
|
`loan_repayment_schedule_id` BIGINT(20) NOT NULL,
|
||||||
|
`amount` DECIMAL(19,6) NOT NULL,
|
||||||
|
`principal_portion_derived` DECIMAL(19,6) NULL DEFAULT NULL,
|
||||||
|
`interest_portion_derived` DECIMAL(19,6) NULL DEFAULT NULL,
|
||||||
|
`fee_charges_portion_derived` DECIMAL(19,6) NULL DEFAULT NULL,
|
||||||
|
`penalty_charges_portion_derived` DECIMAL(19,6) NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
INDEX `FK_mappings_m_loan_transaction` (`loan_transaction_id`),
|
||||||
|
INDEX `FK_mappings_m_loan_repayment_schedule` (`loan_repayment_schedule_id`),
|
||||||
|
CONSTRAINT `FK_mappings_m_loan_repayment_schedule` FOREIGN KEY (`loan_repayment_schedule_id`) REFERENCES `m_loan_repayment_schedule` (`id`),
|
||||||
|
CONSTRAINT `FK_mappings_m_loan_transaction` FOREIGN KEY (`loan_transaction_id`) REFERENCES `m_loan_transaction` (`id`)
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user