FINERACT-2273: Make sure the setters of Loan repayment installment entity balances maintain the scaling of 6 and set null in case the value is zero
This commit is contained in:
committed by
Adam Saghy
parent
6cb60f48fc
commit
88105c3cac
+206
-146
@@ -40,6 +40,7 @@ import org.apache.fineract.infrastructure.core.service.DateUtils;
|
|||||||
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.apache.fineract.organisation.monetary.domain.Money;
|
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||||
|
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||||
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.AllocationType;
|
import org.apache.fineract.portfolio.loanproduct.domain.AllocationType;
|
||||||
import org.apache.fineract.portfolio.repaymentwithpostdatedchecks.domain.PostDatedChecks;
|
import org.apache.fineract.portfolio.repaymentwithpostdatedchecks.domain.PostDatedChecks;
|
||||||
@@ -196,17 +197,17 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
this.installmentNumber = installmentNumber;
|
this.installmentNumber = installmentNumber;
|
||||||
this.fromDate = fromDate;
|
this.fromDate = fromDate;
|
||||||
this.dueDate = dueDate;
|
this.dueDate = dueDate;
|
||||||
this.principal = defaultToNullIfZero(principal);
|
setPrincipal(principal);
|
||||||
this.interestCharged = defaultToNullIfZero(interest);
|
setInterestCharged(interest);
|
||||||
this.feeChargesCharged = defaultToNullIfZero(feeCharges);
|
setFeeChargesCharged(feeCharges);
|
||||||
this.penaltyCharges = defaultToNullIfZero(penaltyCharges);
|
setPenaltyCharges(penaltyCharges);
|
||||||
this.obligationsMet = false;
|
this.obligationsMet = false;
|
||||||
this.recalculatedInterestComponent = recalculatedInterestComponent;
|
this.recalculatedInterestComponent = recalculatedInterestComponent;
|
||||||
if (compoundingDetails != null) {
|
if (compoundingDetails != null) {
|
||||||
compoundingDetails.forEach(cd -> cd.setLoanRepaymentScheduleInstallment(this));
|
compoundingDetails.forEach(cd -> cd.setLoanRepaymentScheduleInstallment(this));
|
||||||
}
|
}
|
||||||
this.loanCompoundingDetails = compoundingDetails;
|
this.loanCompoundingDetails = compoundingDetails;
|
||||||
this.rescheduleInterestPortion = rescheduleInterestPortion;
|
setRescheduleInterestPortion(rescheduleInterestPortion);
|
||||||
this.isDownPayment = isDownPayment;
|
this.isDownPayment = isDownPayment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,10 +219,10 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
this.installmentNumber = installmentNumber;
|
this.installmentNumber = installmentNumber;
|
||||||
this.fromDate = fromDate;
|
this.fromDate = fromDate;
|
||||||
this.dueDate = dueDate;
|
this.dueDate = dueDate;
|
||||||
this.principal = defaultToNullIfZero(principal);
|
setPrincipal(principal);
|
||||||
this.interestCharged = defaultToNullIfZero(interest);
|
setInterestCharged(interest);
|
||||||
this.feeChargesCharged = defaultToNullIfZero(feeCharges);
|
setFeeChargesCharged(feeCharges);
|
||||||
this.penaltyCharges = defaultToNullIfZero(penaltyCharges);
|
setPenaltyCharges(penaltyCharges);
|
||||||
this.obligationsMet = false;
|
this.obligationsMet = false;
|
||||||
this.recalculatedInterestComponent = recalculatedInterestComponent;
|
this.recalculatedInterestComponent = recalculatedInterestComponent;
|
||||||
if (compoundingDetails != null) {
|
if (compoundingDetails != null) {
|
||||||
@@ -246,14 +247,14 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
this.installmentNumber = installmentNumber;
|
this.installmentNumber = installmentNumber;
|
||||||
this.fromDate = fromDate;
|
this.fromDate = fromDate;
|
||||||
this.dueDate = dueDate;
|
this.dueDate = dueDate;
|
||||||
this.principal = principal;
|
setPrincipal(principal);
|
||||||
this.interestCharged = interestCharged;
|
setInterestCharged(interestCharged);
|
||||||
this.feeChargesCharged = feeChargesCharged;
|
setFeeChargesCharged(feeChargesCharged);
|
||||||
this.penaltyCharges = penaltyCharges;
|
setPenaltyCharges(penaltyCharges);
|
||||||
this.creditedPrincipal = creditedPrincipal;
|
setCreditedPrincipal(creditedPrincipal);
|
||||||
this.creditedInterest = creditedInterest;
|
setCreditedInterest(creditedInterest);
|
||||||
this.creditedFee = creditedFee;
|
setCreditedFee(creditedFee);
|
||||||
this.creditedPenalty = creditedPenalty;
|
setCreditedPenalty(creditedPenalty);
|
||||||
this.additional = additional;
|
this.additional = additional;
|
||||||
this.isDownPayment = isDownPayment;
|
this.isDownPayment = isDownPayment;
|
||||||
this.isReAged = isReAged;
|
this.isReAged = isReAged;
|
||||||
@@ -269,14 +270,6 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
return installments.stream().filter(i -> !i.isDownPayment()).reduce((first, second) -> second).orElseThrow();
|
return installments.stream().filter(i -> !i.isDownPayment()).reduce((first, second) -> second).orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal defaultToNullIfZero(final BigDecimal value) {
|
|
||||||
BigDecimal result = value;
|
|
||||||
if (BigDecimal.ZERO.compareTo(value) == 0) {
|
|
||||||
result = null;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Money getCreditedPrincipal(final MonetaryCurrency currency) {
|
public Money getCreditedPrincipal(final MonetaryCurrency currency) {
|
||||||
return Money.of(currency, this.creditedPrincipal);
|
return Money.of(currency, this.creditedPrincipal);
|
||||||
}
|
}
|
||||||
@@ -393,6 +386,106 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
.plus(getPenaltyChargesOutstanding(currency));
|
.plus(getPenaltyChargesOutstanding(currency));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPrincipal(final BigDecimal principal) {
|
||||||
|
this.principal = setScaleAndDefaultToNullIfZero(principal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrincipalCompleted(final BigDecimal principalCompleted) {
|
||||||
|
this.principalCompleted = setScaleAndDefaultToNullIfZero(principalCompleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrincipalWrittenOff(final BigDecimal principalWrittenOff) {
|
||||||
|
this.principalWrittenOff = setScaleAndDefaultToNullIfZero(principalWrittenOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterestCharged(final BigDecimal interestCharged) {
|
||||||
|
this.interestCharged = setScaleAndDefaultToNullIfZero(interestCharged);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterestPaid(final BigDecimal interestPaid) {
|
||||||
|
this.interestPaid = setScaleAndDefaultToNullIfZero(interestPaid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterestWaived(final BigDecimal interestWaived) {
|
||||||
|
this.interestWaived = setScaleAndDefaultToNullIfZero(interestWaived);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterestWrittenOff(final BigDecimal interestWrittenOff) {
|
||||||
|
this.interestWrittenOff = setScaleAndDefaultToNullIfZero(interestWrittenOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterestAccrued(final BigDecimal interestAccrued) {
|
||||||
|
this.interestAccrued = setScaleAndDefaultToNullIfZero(interestAccrued);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRescheduleInterestPortion(final BigDecimal rescheduleInterestPortion) {
|
||||||
|
this.rescheduleInterestPortion = setScaleAndDefaultToNullIfZero(rescheduleInterestPortion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeeChargesCharged(final BigDecimal feeChargesCharged) {
|
||||||
|
this.feeChargesCharged = setScaleAndDefaultToNullIfZero(feeChargesCharged);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeeChargesPaid(final BigDecimal feeChargesPaid) {
|
||||||
|
this.feeChargesPaid = setScaleAndDefaultToNullIfZero(feeChargesPaid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeeChargesWrittenOff(final BigDecimal feeChargesWrittenOff) {
|
||||||
|
this.feeChargesWrittenOff = setScaleAndDefaultToNullIfZero(feeChargesWrittenOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeeChargesWaived(final BigDecimal feeChargesWaived) {
|
||||||
|
this.feeChargesWaived = setScaleAndDefaultToNullIfZero(feeChargesWaived);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeeAccrued(final BigDecimal feeAccrued) {
|
||||||
|
this.feeAccrued = setScaleAndDefaultToNullIfZero(feeAccrued);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPenaltyCharges(final BigDecimal penaltyCharges) {
|
||||||
|
this.penaltyCharges = setScaleAndDefaultToNullIfZero(penaltyCharges);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPenaltyChargesPaid(final BigDecimal penaltyChargesPaid) {
|
||||||
|
this.penaltyChargesPaid = setScaleAndDefaultToNullIfZero(penaltyChargesPaid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPenaltyChargesWrittenOff(final BigDecimal penaltyChargesWrittenOff) {
|
||||||
|
this.penaltyChargesWrittenOff = setScaleAndDefaultToNullIfZero(penaltyChargesWrittenOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPenaltyChargesWaived(final BigDecimal penaltyChargesWaived) {
|
||||||
|
this.penaltyChargesWaived = setScaleAndDefaultToNullIfZero(penaltyChargesWaived);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPenaltyAccrued(final BigDecimal penaltyAccrued) {
|
||||||
|
this.penaltyAccrued = setScaleAndDefaultToNullIfZero(penaltyAccrued);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalPaidInAdvance(final BigDecimal totalPaidInAdvance) {
|
||||||
|
this.totalPaidInAdvance = setScaleAndDefaultToNullIfZero(totalPaidInAdvance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalPaidLate(final BigDecimal totalPaidLate) {
|
||||||
|
this.totalPaidLate = setScaleAndDefaultToNullIfZero(totalPaidLate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreditedPrincipal(final BigDecimal creditedPrincipal) {
|
||||||
|
this.creditedPrincipal = setScaleAndDefaultToNullIfZero(creditedPrincipal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreditedInterest(final BigDecimal creditedInterest) {
|
||||||
|
this.creditedInterest = setScaleAndDefaultToNullIfZero(creditedInterest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreditedFee(final BigDecimal creditedFee) {
|
||||||
|
this.creditedFee = setScaleAndDefaultToNullIfZero(creditedFee);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreditedPenalty(final BigDecimal creditedPenalty) {
|
||||||
|
this.creditedPenalty = setScaleAndDefaultToNullIfZero(creditedPenalty);
|
||||||
|
}
|
||||||
|
|
||||||
void updateLoan(final Loan loan) {
|
void updateLoan(final Loan loan) {
|
||||||
this.loan = loan;
|
this.loan = loan;
|
||||||
}
|
}
|
||||||
@@ -436,19 +529,19 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
this.obligationsMet = false;
|
this.obligationsMet = false;
|
||||||
this.obligationsMetOnDate = null;
|
this.obligationsMetOnDate = null;
|
||||||
if (this.creditedPrincipal != null) {
|
if (this.creditedPrincipal != null) {
|
||||||
this.principal = this.principal.subtract(this.creditedPrincipal);
|
setPrincipal(this.principal != null ? this.principal.subtract(this.creditedPrincipal) : null);
|
||||||
this.creditedPrincipal = null;
|
this.creditedPrincipal = null;
|
||||||
}
|
}
|
||||||
if (this.creditedInterest != null) {
|
if (this.creditedInterest != null) {
|
||||||
this.interestCharged = this.interestCharged.subtract(this.creditedInterest);
|
setInterestCharged(this.interestCharged != null ? this.interestCharged.subtract(this.creditedInterest) : null);
|
||||||
this.creditedInterest = null;
|
this.creditedInterest = null;
|
||||||
}
|
}
|
||||||
if (this.creditedFee != null) {
|
if (this.creditedFee != null) {
|
||||||
this.feeChargesCharged = this.feeChargesCharged.subtract(this.creditedFee);
|
setFeeChargesCharged(this.feeChargesCharged != null ? this.feeChargesCharged.subtract(this.creditedFee) : null);
|
||||||
this.creditedFee = null;
|
this.creditedFee = null;
|
||||||
}
|
}
|
||||||
if (this.creditedPenalty != null) {
|
if (this.creditedPenalty != null) {
|
||||||
this.penaltyCharges = this.penaltyCharges.subtract(this.creditedPenalty);
|
setPenaltyCharges(this.penaltyCharges != null ? this.penaltyCharges.subtract(this.creditedPenalty) : null);
|
||||||
this.creditedPenalty = null;
|
this.creditedPenalty = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -464,6 +557,14 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
this.penaltyCharges = null;
|
this.penaltyCharges = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void resetInterestDue() {
|
||||||
|
this.interestCharged = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetPrincipalDue() {
|
||||||
|
this.principal = null;
|
||||||
|
}
|
||||||
|
|
||||||
public interface PaymentFunction {
|
public interface PaymentFunction {
|
||||||
|
|
||||||
Money accept(LocalDate transactionDate, Money transactionAmountRemaining);
|
Money accept(LocalDate transactionDate, Money transactionAmountRemaining);
|
||||||
@@ -483,7 +584,6 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Money payPenaltyChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
public Money payPenaltyChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money penaltyPortionOfTransaction = Money.zero(currency);
|
Money penaltyPortionOfTransaction = Money.zero(currency);
|
||||||
|
|
||||||
@@ -493,24 +593,20 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
|
|
||||||
final Money penaltyChargesDue = getPenaltyChargesOutstanding(currency);
|
final Money penaltyChargesDue = getPenaltyChargesOutstanding(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(penaltyChargesDue)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(penaltyChargesDue)) {
|
||||||
this.penaltyChargesPaid = getPenaltyChargesPaid(currency).plus(penaltyChargesDue).getAmount();
|
setPenaltyChargesPaid(getPenaltyChargesPaid(currency).plus(penaltyChargesDue).getAmount());
|
||||||
penaltyPortionOfTransaction = penaltyPortionOfTransaction.plus(penaltyChargesDue);
|
penaltyPortionOfTransaction = penaltyPortionOfTransaction.plus(penaltyChargesDue);
|
||||||
} else {
|
} else {
|
||||||
this.penaltyChargesPaid = getPenaltyChargesPaid(currency).plus(transactionAmountRemaining).getAmount();
|
setPenaltyChargesPaid(getPenaltyChargesPaid(currency).plus(transactionAmountRemaining).getAmount());
|
||||||
penaltyPortionOfTransaction = penaltyPortionOfTransaction.plus(transactionAmountRemaining);
|
penaltyPortionOfTransaction = penaltyPortionOfTransaction.plus(transactionAmountRemaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.penaltyChargesPaid = defaultToNullIfZero(this.penaltyChargesPaid);
|
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, penaltyPortionOfTransaction);
|
trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, penaltyPortionOfTransaction);
|
||||||
|
|
||||||
return penaltyPortionOfTransaction;
|
return penaltyPortionOfTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money payFeeChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
public Money payFeeChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money feePortionOfTransaction = Money.zero(currency);
|
Money feePortionOfTransaction = Money.zero(currency);
|
||||||
if (transactionAmountRemaining.isZero()) {
|
if (transactionAmountRemaining.isZero()) {
|
||||||
@@ -518,24 +614,20 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
}
|
}
|
||||||
final Money feeChargesDue = getFeeChargesOutstanding(currency);
|
final Money feeChargesDue = getFeeChargesOutstanding(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(feeChargesDue)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(feeChargesDue)) {
|
||||||
this.feeChargesPaid = getFeeChargesPaid(currency).plus(feeChargesDue).getAmount();
|
setFeeChargesPaid(getFeeChargesPaid(currency).plus(feeChargesDue).getAmount());
|
||||||
feePortionOfTransaction = feePortionOfTransaction.plus(feeChargesDue);
|
feePortionOfTransaction = feePortionOfTransaction.plus(feeChargesDue);
|
||||||
} else {
|
} else {
|
||||||
this.feeChargesPaid = getFeeChargesPaid(currency).plus(transactionAmountRemaining).getAmount();
|
setFeeChargesPaid(getFeeChargesPaid(currency).plus(transactionAmountRemaining).getAmount());
|
||||||
feePortionOfTransaction = feePortionOfTransaction.plus(transactionAmountRemaining);
|
feePortionOfTransaction = feePortionOfTransaction.plus(transactionAmountRemaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.feeChargesPaid = defaultToNullIfZero(this.feeChargesPaid);
|
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, feePortionOfTransaction);
|
trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, feePortionOfTransaction);
|
||||||
|
|
||||||
return feePortionOfTransaction;
|
return feePortionOfTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money payInterestComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
public Money payInterestComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money interestPortionOfTransaction = Money.zero(currency);
|
Money interestPortionOfTransaction = Money.zero(currency);
|
||||||
if (transactionAmountRemaining.isZero()) {
|
if (transactionAmountRemaining.isZero()) {
|
||||||
@@ -543,24 +635,20 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
}
|
}
|
||||||
final Money interestDue = getInterestOutstanding(currency);
|
final Money interestDue = getInterestOutstanding(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(interestDue)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(interestDue)) {
|
||||||
this.interestPaid = getInterestPaid(currency).plus(interestDue).getAmount();
|
setInterestPaid(getInterestPaid(currency).plus(interestDue).getAmount());
|
||||||
interestPortionOfTransaction = interestPortionOfTransaction.plus(interestDue);
|
interestPortionOfTransaction = interestPortionOfTransaction.plus(interestDue);
|
||||||
} else {
|
} else {
|
||||||
this.interestPaid = getInterestPaid(currency).plus(transactionAmountRemaining).getAmount();
|
setInterestPaid(getInterestPaid(currency).plus(transactionAmountRemaining).getAmount());
|
||||||
interestPortionOfTransaction = interestPortionOfTransaction.plus(transactionAmountRemaining);
|
interestPortionOfTransaction = interestPortionOfTransaction.plus(transactionAmountRemaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.interestPaid = defaultToNullIfZero(this.interestPaid);
|
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, interestPortionOfTransaction);
|
trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, interestPortionOfTransaction);
|
||||||
|
|
||||||
return interestPortionOfTransaction;
|
return interestPortionOfTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money payPrincipalComponent(final LocalDate transactionDate, final Money transactionAmount) {
|
public Money payPrincipalComponent(final LocalDate transactionDate, final Money transactionAmount) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmount.getCurrency();
|
final MonetaryCurrency currency = transactionAmount.getCurrency();
|
||||||
Money principalPortionOfTransaction = Money.zero(currency);
|
Money principalPortionOfTransaction = Money.zero(currency);
|
||||||
if (transactionAmount.isZero()) {
|
if (transactionAmount.isZero()) {
|
||||||
@@ -568,17 +656,14 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
}
|
}
|
||||||
final Money principalDue = getPrincipalOutstanding(currency);
|
final Money principalDue = getPrincipalOutstanding(currency);
|
||||||
if (transactionAmount.isGreaterThanOrEqualTo(principalDue)) {
|
if (transactionAmount.isGreaterThanOrEqualTo(principalDue)) {
|
||||||
this.principalCompleted = getPrincipalCompleted(currency).plus(principalDue).getAmount();
|
setPrincipalCompleted(getPrincipalCompleted(currency).plus(principalDue).getAmount());
|
||||||
principalPortionOfTransaction = principalPortionOfTransaction.plus(principalDue);
|
principalPortionOfTransaction = principalPortionOfTransaction.plus(principalDue);
|
||||||
} else {
|
} else {
|
||||||
this.principalCompleted = getPrincipalCompleted(currency).plus(transactionAmount).getAmount();
|
setPrincipalCompleted(getPrincipalCompleted(currency).plus(transactionAmount).getAmount());
|
||||||
principalPortionOfTransaction = principalPortionOfTransaction.plus(transactionAmount);
|
principalPortionOfTransaction = principalPortionOfTransaction.plus(transactionAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.principalCompleted = defaultToNullIfZero(this.principalCompleted);
|
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, principalPortionOfTransaction);
|
trackAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, principalPortionOfTransaction);
|
||||||
|
|
||||||
return principalPortionOfTransaction;
|
return principalPortionOfTransaction;
|
||||||
@@ -592,15 +677,13 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
}
|
}
|
||||||
final Money interestDue = getInterestOutstanding(currency);
|
final Money interestDue = getInterestOutstanding(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(interestDue)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(interestDue)) {
|
||||||
this.interestWaived = getInterestWaived(currency).plus(interestDue).getAmount();
|
setInterestWaived(getInterestWaived(currency).plus(interestDue).getAmount());
|
||||||
waivedInterestPortionOfTransaction = waivedInterestPortionOfTransaction.plus(interestDue);
|
waivedInterestPortionOfTransaction = waivedInterestPortionOfTransaction.plus(interestDue);
|
||||||
} else {
|
} else {
|
||||||
this.interestWaived = getInterestWaived(currency).plus(transactionAmountRemaining).getAmount();
|
setInterestWaived(getInterestWaived(currency).plus(transactionAmountRemaining).getAmount());
|
||||||
waivedInterestPortionOfTransaction = waivedInterestPortionOfTransaction.plus(transactionAmountRemaining);
|
waivedInterestPortionOfTransaction = waivedInterestPortionOfTransaction.plus(transactionAmountRemaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.interestWaived = defaultToNullIfZero(this.interestWaived);
|
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
return waivedInterestPortionOfTransaction;
|
return waivedInterestPortionOfTransaction;
|
||||||
@@ -612,17 +695,15 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
if (transactionAmountRemaining.isZero()) {
|
if (transactionAmountRemaining.isZero()) {
|
||||||
return waivedPenaltyChargesPortionOfTransaction;
|
return waivedPenaltyChargesPortionOfTransaction;
|
||||||
}
|
}
|
||||||
final Money penanltiesDue = getPenaltyChargesOutstanding(currency);
|
final Money penaltiesDue = getPenaltyChargesOutstanding(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(penanltiesDue)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(penaltiesDue)) {
|
||||||
this.penaltyChargesWaived = getPenaltyChargesWaived(currency).plus(penanltiesDue).getAmount();
|
setPenaltyChargesWaived(getPenaltyChargesWaived(currency).plus(penaltiesDue).getAmount());
|
||||||
waivedPenaltyChargesPortionOfTransaction = waivedPenaltyChargesPortionOfTransaction.plus(penanltiesDue);
|
waivedPenaltyChargesPortionOfTransaction = waivedPenaltyChargesPortionOfTransaction.plus(penaltiesDue);
|
||||||
} else {
|
} else {
|
||||||
this.penaltyChargesWaived = getPenaltyChargesWaived(currency).plus(transactionAmountRemaining).getAmount();
|
setPenaltyChargesWaived(getPenaltyChargesWaived(currency).plus(transactionAmountRemaining).getAmount());
|
||||||
waivedPenaltyChargesPortionOfTransaction = waivedPenaltyChargesPortionOfTransaction.plus(transactionAmountRemaining);
|
waivedPenaltyChargesPortionOfTransaction = waivedPenaltyChargesPortionOfTransaction.plus(transactionAmountRemaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.penaltyChargesWaived = defaultToNullIfZero(this.penaltyChargesWaived);
|
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
return waivedPenaltyChargesPortionOfTransaction;
|
return waivedPenaltyChargesPortionOfTransaction;
|
||||||
@@ -636,55 +717,43 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
}
|
}
|
||||||
final Money feesDue = getFeeChargesOutstanding(currency);
|
final Money feesDue = getFeeChargesOutstanding(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(feesDue)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(feesDue)) {
|
||||||
this.feeChargesWaived = getFeeChargesWaived(currency).plus(feesDue).getAmount();
|
setFeeChargesWaived(getFeeChargesWaived(currency).plus(feesDue).getAmount());
|
||||||
waivedFeeChargesPortionOfTransaction = waivedFeeChargesPortionOfTransaction.plus(feesDue);
|
waivedFeeChargesPortionOfTransaction = waivedFeeChargesPortionOfTransaction.plus(feesDue);
|
||||||
} else {
|
} else {
|
||||||
this.feeChargesWaived = getFeeChargesWaived(currency).plus(transactionAmountRemaining).getAmount();
|
setFeeChargesWaived(getFeeChargesWaived(currency).plus(transactionAmountRemaining).getAmount());
|
||||||
waivedFeeChargesPortionOfTransaction = waivedFeeChargesPortionOfTransaction.plus(transactionAmountRemaining);
|
waivedFeeChargesPortionOfTransaction = waivedFeeChargesPortionOfTransaction.plus(transactionAmountRemaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.feeChargesWaived = defaultToNullIfZero(this.feeChargesWaived);
|
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
return waivedFeeChargesPortionOfTransaction;
|
return waivedFeeChargesPortionOfTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money writeOffOutstandingPrincipal(final LocalDate transactionDate, final MonetaryCurrency currency) {
|
public Money writeOffOutstandingPrincipal(final LocalDate transactionDate, final MonetaryCurrency currency) {
|
||||||
|
|
||||||
final Money principalDue = getPrincipalOutstanding(currency);
|
final Money principalDue = getPrincipalOutstanding(currency);
|
||||||
this.principalWrittenOff = defaultToNullIfZero(principalDue.getAmount());
|
setPrincipalWrittenOff(principalDue.getAmount());
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
return principalDue;
|
return principalDue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money writeOffOutstandingInterest(final LocalDate transactionDate, final MonetaryCurrency currency) {
|
public Money writeOffOutstandingInterest(final LocalDate transactionDate, final MonetaryCurrency currency) {
|
||||||
|
|
||||||
final Money interestDue = getInterestOutstanding(currency);
|
final Money interestDue = getInterestOutstanding(currency);
|
||||||
this.interestWrittenOff = defaultToNullIfZero(interestDue.getAmount());
|
setInterestWrittenOff(interestDue.getAmount());
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
return interestDue;
|
return interestDue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money writeOffOutstandingFeeCharges(final LocalDate transactionDate, final MonetaryCurrency currency) {
|
public Money writeOffOutstandingFeeCharges(final LocalDate transactionDate, final MonetaryCurrency currency) {
|
||||||
final Money feeChargesOutstanding = getFeeChargesOutstanding(currency);
|
final Money feeChargesOutstanding = getFeeChargesOutstanding(currency);
|
||||||
this.feeChargesWrittenOff = defaultToNullIfZero(feeChargesOutstanding.getAmount());
|
setFeeChargesWrittenOff(feeChargesOutstanding.getAmount());
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
return feeChargesOutstanding;
|
return feeChargesOutstanding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money writeOffOutstandingPenaltyCharges(final LocalDate transactionDate, final MonetaryCurrency currency) {
|
public Money writeOffOutstandingPenaltyCharges(final LocalDate transactionDate, final MonetaryCurrency currency) {
|
||||||
final Money penaltyChargesOutstanding = getPenaltyChargesOutstanding(currency);
|
final Money penaltyChargesOutstanding = getPenaltyChargesOutstanding(currency);
|
||||||
this.penaltyChargesWrittenOff = defaultToNullIfZero(penaltyChargesOutstanding.getAmount());
|
setPenaltyChargesWrittenOff(penaltyChargesOutstanding.getAmount());
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
return penaltyChargesOutstanding;
|
return penaltyChargesOutstanding;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -694,32 +763,29 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
|
|
||||||
public void updateChargePortion(final Money feeChargesDue, final Money feeChargesWaived, final Money feeChargesWrittenOff,
|
public void updateChargePortion(final Money feeChargesDue, final Money feeChargesWaived, final Money feeChargesWrittenOff,
|
||||||
final Money penaltyChargesDue, final Money penaltyChargesWaived, final Money penaltyChargesWrittenOff) {
|
final Money penaltyChargesDue, final Money penaltyChargesWaived, final Money penaltyChargesWrittenOff) {
|
||||||
this.feeChargesCharged = MathUtil.zeroToNull(MathUtil.toBigDecimal(feeChargesDue));
|
setFeeChargesCharged(feeChargesDue.getAmount());
|
||||||
this.feeChargesWaived = MathUtil.zeroToNull(MathUtil.toBigDecimal(feeChargesWaived));
|
setFeeChargesWaived(feeChargesWaived.getAmount());
|
||||||
this.feeChargesWrittenOff = MathUtil.zeroToNull(MathUtil.toBigDecimal(feeChargesWrittenOff));
|
setFeeChargesWrittenOff(feeChargesWrittenOff.getAmount());
|
||||||
this.penaltyCharges = MathUtil.zeroToNull(MathUtil.toBigDecimal(penaltyChargesDue));
|
setPenaltyCharges(penaltyChargesDue.getAmount());
|
||||||
this.penaltyChargesWaived = MathUtil.zeroToNull(MathUtil.toBigDecimal(penaltyChargesWaived));
|
setPenaltyChargesWaived(penaltyChargesWaived.getAmount());
|
||||||
this.penaltyChargesWrittenOff = MathUtil.zeroToNull(MathUtil.toBigDecimal(penaltyChargesWrittenOff));
|
setPenaltyChargesWrittenOff(penaltyChargesWrittenOff.getAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToChargePortion(final Money feeChargesDue, final Money feeChargesWaived, final Money feeChargesWrittenOff,
|
public void addToChargePortion(final Money feeChargesDue, final Money feeChargesWaived, final Money feeChargesWrittenOff,
|
||||||
final Money penaltyChargesDue, final Money penaltyChargesWaived, final Money penaltyChargesWrittenOff) {
|
final Money penaltyChargesDue, final Money penaltyChargesWaived, final Money penaltyChargesWrittenOff) {
|
||||||
this.feeChargesCharged = MathUtil.zeroToNull(MathUtil.add(MathUtil.toBigDecimal(feeChargesDue), this.feeChargesCharged));
|
setFeeChargesCharged(MathUtil.add(feeChargesDue.getAmount(), this.feeChargesCharged));
|
||||||
this.feeChargesWaived = MathUtil.zeroToNull(MathUtil.add(MathUtil.toBigDecimal(feeChargesWaived), this.feeChargesWaived));
|
setFeeChargesWaived(MathUtil.add(feeChargesWaived.getAmount(), this.feeChargesWaived));
|
||||||
this.feeChargesWrittenOff = MathUtil
|
setFeeChargesWrittenOff(MathUtil.add(feeChargesWrittenOff.getAmount(), this.feeChargesWrittenOff));
|
||||||
.zeroToNull(MathUtil.add(MathUtil.toBigDecimal(feeChargesWrittenOff), this.feeChargesWrittenOff));
|
setPenaltyCharges(MathUtil.add(penaltyChargesDue.getAmount(), this.penaltyCharges));
|
||||||
this.penaltyCharges = MathUtil.zeroToNull(MathUtil.add(MathUtil.toBigDecimal(penaltyChargesDue), this.penaltyCharges));
|
setPenaltyChargesWaived(MathUtil.add(penaltyChargesWaived.getAmount(), this.penaltyChargesWaived));
|
||||||
this.penaltyChargesWaived = MathUtil
|
setPenaltyChargesWrittenOff(MathUtil.add(penaltyChargesWrittenOff.getAmount(), this.penaltyChargesWrittenOff));
|
||||||
.zeroToNull(MathUtil.add(MathUtil.toBigDecimal(penaltyChargesWaived), this.penaltyChargesWaived));
|
|
||||||
this.penaltyChargesWrittenOff = MathUtil
|
|
||||||
.zeroToNull(MathUtil.add(MathUtil.toBigDecimal(penaltyChargesWrittenOff), this.penaltyChargesWrittenOff));
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(getObligationsMetOnDate(), feeChargesDue.getCurrency());
|
checkIfRepaymentPeriodObligationsAreMet(getObligationsMetOnDate(), feeChargesDue.getCurrency());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateAccrualPortion(final Money interest, final Money feeCharges, final Money penalityCharges) {
|
public void updateAccrualPortion(final Money interest, final Money feeCharges, final Money penalityCharges) {
|
||||||
this.interestAccrued = MathUtil.zeroToNull(MathUtil.toBigDecimal(interest));
|
setInterestAccrued(interest.getAmount());
|
||||||
this.feeAccrued = MathUtil.zeroToNull(MathUtil.toBigDecimal(feeCharges));
|
setFeeAccrued(feeCharges.getAmount());
|
||||||
this.penaltyAccrued = MathUtil.zeroToNull(MathUtil.toBigDecimal(penalityCharges));
|
setPenaltyAccrued(penalityCharges.getAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateObligationsMet(final MonetaryCurrency currency, final LocalDate transactionDate) {
|
public void updateObligationsMet(final MonetaryCurrency currency, final LocalDate transactionDate) {
|
||||||
@@ -735,9 +801,9 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
private void trackAdvanceAndLateTotalsForRepaymentPeriod(final LocalDate transactionDate, final MonetaryCurrency currency,
|
private void trackAdvanceAndLateTotalsForRepaymentPeriod(final LocalDate transactionDate, final MonetaryCurrency currency,
|
||||||
final Money amountPaidInRepaymentPeriod) {
|
final Money amountPaidInRepaymentPeriod) {
|
||||||
if (isInAdvance(transactionDate)) {
|
if (isInAdvance(transactionDate)) {
|
||||||
this.totalPaidInAdvance = asMoney(this.totalPaidInAdvance, currency).plus(amountPaidInRepaymentPeriod).getAmount();
|
setTotalPaidInAdvance(asMoney(this.totalPaidInAdvance, currency).plus(amountPaidInRepaymentPeriod).getAmount());
|
||||||
} else if (isLatePayment(transactionDate)) {
|
} else if (isLatePayment(transactionDate)) {
|
||||||
this.totalPaidLate = asMoney(this.totalPaidLate, currency).plus(amountPaidInRepaymentPeriod).getAmount();
|
setTotalPaidLate(asMoney(this.totalPaidLate, currency).plus(amountPaidInRepaymentPeriod).getAmount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,7 +851,7 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateInterestCharged(final BigDecimal interestCharged) {
|
public void updateInterestCharged(final BigDecimal interestCharged) {
|
||||||
this.interestCharged = interestCharged;
|
setInterestCharged(interestCharged);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateObligationMet(final Boolean obligationMet) {
|
public void updateObligationMet(final Boolean obligationMet) {
|
||||||
@@ -797,72 +863,71 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updatePrincipal(final BigDecimal principal) {
|
public void updatePrincipal(final BigDecimal principal) {
|
||||||
this.principal = principal;
|
setPrincipal(principal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToPrincipal(final LocalDate transactionDate, final Money transactionAmount) {
|
public void addToPrincipal(final LocalDate transactionDate, final Money transactionAmount) {
|
||||||
if (this.principal == null) {
|
if (this.principal == null) {
|
||||||
this.principal = transactionAmount.getAmount();
|
setPrincipal(transactionAmount.getAmount());
|
||||||
} else {
|
} else {
|
||||||
this.principal = this.principal.add(transactionAmount.getAmount());
|
setPrincipal(this.principal.add(transactionAmount.getAmount()));
|
||||||
}
|
}
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, transactionAmount.getCurrency());
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, transactionAmount.getCurrency());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToInterest(final LocalDate transactionDate, final Money transactionAmount) {
|
public void addToInterest(final LocalDate transactionDate, final Money transactionAmount) {
|
||||||
if (this.interestCharged == null) {
|
if (this.interestCharged == null) {
|
||||||
this.interestCharged = transactionAmount.getAmount();
|
setInterestCharged(transactionAmount.getAmount());
|
||||||
} else {
|
} else {
|
||||||
this.interestCharged = this.interestCharged.add(transactionAmount.getAmount());
|
setInterestCharged(this.interestCharged.add(transactionAmount.getAmount()));
|
||||||
}
|
}
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, transactionAmount.getCurrency());
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, transactionAmount.getCurrency());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToCreditedInterest(final BigDecimal amount) {
|
public void addToCreditedInterest(final BigDecimal amount) {
|
||||||
if (this.creditedInterest == null) {
|
if (this.creditedInterest == null) {
|
||||||
this.creditedInterest = amount;
|
setCreditedInterest(amount);
|
||||||
} else {
|
} else {
|
||||||
this.creditedInterest = this.creditedInterest.add(amount);
|
setCreditedInterest(this.creditedInterest.add(amount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToCreditedPrincipal(final BigDecimal amount) {
|
public void addToCreditedPrincipal(final BigDecimal amount) {
|
||||||
if (this.creditedPrincipal == null) {
|
if (this.creditedPrincipal == null) {
|
||||||
this.creditedPrincipal = amount;
|
setCreditedPrincipal(amount);
|
||||||
} else {
|
} else {
|
||||||
this.creditedPrincipal = this.creditedPrincipal.add(amount);
|
setCreditedPrincipal(this.creditedPrincipal.add(amount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToCreditedFee(final BigDecimal amount) {
|
public void addToCreditedFee(final BigDecimal amount) {
|
||||||
if (this.creditedFee == null) {
|
if (this.creditedFee == null) {
|
||||||
this.creditedFee = amount;
|
setCreditedFee(amount);
|
||||||
} else {
|
} else {
|
||||||
this.creditedFee = this.creditedFee.add(amount);
|
setCreditedFee(this.creditedFee.add(amount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToCreditedPenalty(final BigDecimal amount) {
|
public void addToCreditedPenalty(final BigDecimal amount) {
|
||||||
if (this.creditedPenalty == null) {
|
if (this.creditedPenalty == null) {
|
||||||
this.creditedPenalty = amount;
|
setCreditedPenalty(amount);
|
||||||
} else {
|
} else {
|
||||||
this.creditedPenalty = this.creditedPenalty.add(amount);
|
setCreditedPenalty(this.creditedPenalty.add(amount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/********** UNPAY COMPONENTS ****/
|
/********** UNPAY COMPONENTS ****/
|
||||||
|
|
||||||
public Money unpayPenaltyChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
public Money unpayPenaltyChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money penaltyPortionOfTransactionDeducted;
|
Money penaltyPortionOfTransactionDeducted;
|
||||||
|
|
||||||
final Money penaltyChargesCompleted = getPenaltyChargesPaid(currency);
|
final Money penaltyChargesCompleted = getPenaltyChargesPaid(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(penaltyChargesCompleted)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(penaltyChargesCompleted)) {
|
||||||
this.penaltyChargesPaid = Money.zero(currency).getAmount();
|
this.penaltyChargesPaid = null;
|
||||||
penaltyPortionOfTransactionDeducted = penaltyChargesCompleted;
|
penaltyPortionOfTransactionDeducted = penaltyChargesCompleted;
|
||||||
} else {
|
} else {
|
||||||
this.penaltyChargesPaid = penaltyChargesCompleted.minus(transactionAmountRemaining).getAmount();
|
setPenaltyChargesPaid(penaltyChargesCompleted.minus(transactionAmountRemaining).getAmount());
|
||||||
penaltyPortionOfTransactionDeducted = transactionAmountRemaining;
|
penaltyPortionOfTransactionDeducted = transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -872,63 +937,57 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Money unpayFeeChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
public Money unpayFeeChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money feePortionOfTransactionDeducted;
|
Money feePortionOfTransactionDeducted;
|
||||||
|
|
||||||
final Money feeChargesCompleted = getFeeChargesPaid(currency);
|
final Money feeChargesCompleted = getFeeChargesPaid(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(feeChargesCompleted)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(feeChargesCompleted)) {
|
||||||
this.feeChargesPaid = Money.zero(currency).getAmount();
|
this.feeChargesPaid = null;
|
||||||
feePortionOfTransactionDeducted = feeChargesCompleted;
|
feePortionOfTransactionDeducted = feeChargesCompleted;
|
||||||
} else {
|
} else {
|
||||||
this.feeChargesPaid = feeChargesCompleted.minus(transactionAmountRemaining).getAmount();
|
setFeeChargesPaid(feeChargesCompleted.minus(transactionAmountRemaining).getAmount());
|
||||||
feePortionOfTransactionDeducted = transactionAmountRemaining;
|
feePortionOfTransactionDeducted = transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
reduceAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, feePortionOfTransactionDeducted);
|
reduceAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, feePortionOfTransactionDeducted);
|
||||||
|
|
||||||
return feePortionOfTransactionDeducted;
|
return feePortionOfTransactionDeducted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money unpayInterestComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
public Money unpayInterestComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money interestPortionOfTransactionDeducted;
|
Money interestPortionOfTransactionDeducted;
|
||||||
|
|
||||||
final Money interestCompleted = getInterestPaid(currency);
|
final Money interestCompleted = getInterestPaid(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(interestCompleted)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(interestCompleted)) {
|
||||||
this.interestPaid = Money.zero(currency).getAmount();
|
this.interestPaid = null;
|
||||||
interestPortionOfTransactionDeducted = interestCompleted;
|
interestPortionOfTransactionDeducted = interestCompleted;
|
||||||
} else {
|
} else {
|
||||||
this.interestPaid = interestCompleted.minus(transactionAmountRemaining).getAmount();
|
setInterestPaid(interestCompleted.minus(transactionAmountRemaining).getAmount());
|
||||||
interestPortionOfTransactionDeducted = transactionAmountRemaining;
|
interestPortionOfTransactionDeducted = transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
reduceAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, interestPortionOfTransactionDeducted);
|
reduceAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, interestPortionOfTransactionDeducted);
|
||||||
|
|
||||||
return interestPortionOfTransactionDeducted;
|
return interestPortionOfTransactionDeducted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money unpayPrincipalComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
public Money unpayPrincipalComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money principalPortionOfTransactionDeducted;
|
Money principalPortionOfTransactionDeducted;
|
||||||
|
|
||||||
final Money principalCompleted = getPrincipalCompleted(currency);
|
final Money principalCompleted = getPrincipalCompleted(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(principalCompleted)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(principalCompleted)) {
|
||||||
this.principalCompleted = Money.zero(currency).getAmount();
|
this.principalCompleted = null;
|
||||||
principalPortionOfTransactionDeducted = principalCompleted;
|
principalPortionOfTransactionDeducted = principalCompleted;
|
||||||
} else {
|
} else {
|
||||||
this.principalCompleted = principalCompleted.minus(transactionAmountRemaining).getAmount();
|
setPrincipalCompleted(principalCompleted.minus(transactionAmountRemaining).getAmount());
|
||||||
principalPortionOfTransactionDeducted = transactionAmountRemaining;
|
principalPortionOfTransactionDeducted = transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
|
||||||
|
|
||||||
reduceAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, principalPortionOfTransactionDeducted);
|
reduceAdvanceAndLateTotalsForRepaymentPeriod(transactionDate, currency, principalPortionOfTransactionDeducted);
|
||||||
|
|
||||||
return principalPortionOfTransactionDeducted;
|
return principalPortionOfTransactionDeducted;
|
||||||
@@ -936,23 +995,22 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
|
|
||||||
private void reduceAdvanceAndLateTotalsForRepaymentPeriod(final LocalDate transactionDate, final MonetaryCurrency currency,
|
private void reduceAdvanceAndLateTotalsForRepaymentPeriod(final LocalDate transactionDate, final MonetaryCurrency currency,
|
||||||
final Money amountDeductedInRepaymentPeriod) {
|
final Money amountDeductedInRepaymentPeriod) {
|
||||||
|
|
||||||
if (isInAdvance(transactionDate)) {
|
if (isInAdvance(transactionDate)) {
|
||||||
Money mTotalPaidInAdvance = Money.of(currency, this.totalPaidInAdvance);
|
final Money mTotalPaidInAdvance = Money.of(currency, this.totalPaidInAdvance);
|
||||||
|
|
||||||
if (mTotalPaidInAdvance.isLessThan(amountDeductedInRepaymentPeriod)
|
if (mTotalPaidInAdvance.isLessThan(amountDeductedInRepaymentPeriod)
|
||||||
|| mTotalPaidInAdvance.isEqualTo(amountDeductedInRepaymentPeriod)) {
|
|| mTotalPaidInAdvance.isEqualTo(amountDeductedInRepaymentPeriod)) {
|
||||||
this.totalPaidInAdvance = Money.zero(currency).getAmount();
|
this.totalPaidInAdvance = null;
|
||||||
} else {
|
} else {
|
||||||
this.totalPaidInAdvance = mTotalPaidInAdvance.minus(amountDeductedInRepaymentPeriod).getAmount();
|
setTotalPaidInAdvance(mTotalPaidInAdvance.minus(amountDeductedInRepaymentPeriod).getAmount());
|
||||||
}
|
}
|
||||||
} else if (isLatePayment(transactionDate)) {
|
} else if (isLatePayment(transactionDate)) {
|
||||||
Money mTotalPaidLate = Money.of(currency, this.totalPaidLate);
|
final Money mTotalPaidLate = Money.of(currency, this.totalPaidLate);
|
||||||
|
|
||||||
if (mTotalPaidLate.isLessThan(amountDeductedInRepaymentPeriod) || mTotalPaidLate.isEqualTo(amountDeductedInRepaymentPeriod)) {
|
if (mTotalPaidLate.isLessThan(amountDeductedInRepaymentPeriod) || mTotalPaidLate.isEqualTo(amountDeductedInRepaymentPeriod)) {
|
||||||
this.totalPaidLate = Money.zero(currency).getAmount();
|
this.totalPaidLate = null;
|
||||||
} else {
|
} else {
|
||||||
this.totalPaidLate = mTotalPaidLate.minus(amountDeductedInRepaymentPeriod).getAmount();
|
setTotalPaidLate(mTotalPaidLate.minus(amountDeductedInRepaymentPeriod).getAmount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -983,14 +1041,6 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
resetInterestDue();
|
resetInterestDue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetInterestDue() {
|
|
||||||
this.interestCharged = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetPrincipalDue() {
|
|
||||||
this.principal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum PaymentAction {
|
public enum PaymentAction {
|
||||||
PAY, //
|
PAY, //
|
||||||
UNPAY //
|
UNPAY //
|
||||||
@@ -1155,4 +1205,14 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
private static boolean nonNullAndEqual(Object a, Object b) {
|
private static boolean nonNullAndEqual(Object a, Object b) {
|
||||||
return a != null && b != null && Objects.equals(a, b);
|
return a != null && b != null && Objects.equals(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BigDecimal setScaleAndDefaultToNullIfZero(final BigDecimal value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return value.setScale(6, MoneyHelper.getRoundingMode());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+209
@@ -0,0 +1,209 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.loanaccount.domain;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.mockStatic;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
|
|
||||||
|
class LoanRepaymentScheduleInstallmentTest {
|
||||||
|
|
||||||
|
private static final int SCALE = 6;
|
||||||
|
private static final int PRECISION = 19;
|
||||||
|
private static final MockedStatic<MoneyHelper> MONEY_HELPER = mockStatic(MoneyHelper.class);
|
||||||
|
private static final MathContext MATH_CONTEXT = new MathContext(PRECISION, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
private LoanRepaymentScheduleInstallment installment;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void init() {
|
||||||
|
MONEY_HELPER.when(MoneyHelper::getRoundingMode).thenReturn(RoundingMode.HALF_EVEN);
|
||||||
|
MONEY_HELPER.when(MoneyHelper::getMathContext).thenReturn(MATH_CONTEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
final Loan loan = mock(Loan.class);
|
||||||
|
installment = new LoanRepaymentScheduleInstallment(loan, 1, LocalDate.now(ZoneId.systemDefault()),
|
||||||
|
LocalDate.now(ZoneId.systemDefault()).plusMonths(1), BigDecimal.valueOf(1000), BigDecimal.valueOf(100),
|
||||||
|
BigDecimal.valueOf(50), BigDecimal.valueOf(25), BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, false,
|
||||||
|
false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void tearDown() {
|
||||||
|
MONEY_HELPER.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPrincipalSetters() {
|
||||||
|
testBigDecimalSetter(installment::setPrincipal, installment::getPrincipal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPrincipalCompletedSetters() {
|
||||||
|
testBigDecimalSetter(installment::setPrincipalCompleted, installment::getPrincipalCompleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPrincipalWrittenOffSetters() {
|
||||||
|
testBigDecimalSetter(installment::setPrincipalWrittenOff, installment::getPrincipalWrittenOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testInterestChargedSetters() {
|
||||||
|
testBigDecimalSetter(installment::setInterestCharged, installment::getInterestCharged);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testInterestPaidSetters() {
|
||||||
|
testBigDecimalSetter(installment::setInterestPaid, installment::getInterestPaid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testInterestWaivedSetters() {
|
||||||
|
testBigDecimalSetter(installment::setInterestWaived, installment::getInterestWaived);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testInterestWrittenOffSetters() {
|
||||||
|
testBigDecimalSetter(installment::setInterestWrittenOff, installment::getInterestWrittenOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testInterestAccruedSetters() {
|
||||||
|
testBigDecimalSetter(installment::setInterestAccrued, installment::getInterestAccrued);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRescheduleInterestPortionSetters() {
|
||||||
|
testBigDecimalSetter(installment::setRescheduleInterestPortion, installment::getRescheduleInterestPortion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFeeChargesChargedSetters() {
|
||||||
|
testBigDecimalSetter(installment::setFeeChargesCharged, installment::getFeeChargesCharged);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFeeChargesPaidSetters() {
|
||||||
|
testBigDecimalSetter(installment::setFeeChargesPaid, installment::getFeeChargesPaid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFeeChargesWrittenOffSetters() {
|
||||||
|
testBigDecimalSetter(installment::setFeeChargesWrittenOff, installment::getFeeChargesWrittenOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFeeChargesWaivedSetters() {
|
||||||
|
testBigDecimalSetter(installment::setFeeChargesWaived, installment::getFeeChargesWaived);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFeeAccruedSetters() {
|
||||||
|
testBigDecimalSetter(installment::setFeeAccrued, installment::getFeeAccrued);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPenaltyChargesSetters() {
|
||||||
|
testBigDecimalSetter(installment::setPenaltyCharges, installment::getPenaltyCharges);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPenaltyChargesPaidSetters() {
|
||||||
|
testBigDecimalSetter(installment::setPenaltyChargesPaid, installment::getPenaltyChargesPaid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPenaltyChargesWrittenOffSetters() {
|
||||||
|
testBigDecimalSetter(installment::setPenaltyChargesWrittenOff, installment::getPenaltyChargesWrittenOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPenaltyChargesWaivedSetters() {
|
||||||
|
testBigDecimalSetter(installment::setPenaltyChargesWaived, installment::getPenaltyChargesWaived);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPenaltyAccruedSetters() {
|
||||||
|
testBigDecimalSetter(installment::setPenaltyAccrued, installment::getPenaltyAccrued);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTotalPaidInAdvanceSetters() {
|
||||||
|
testBigDecimalSetter(installment::setTotalPaidInAdvance, installment::getTotalPaidInAdvance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTotalPaidLateSetters() {
|
||||||
|
testBigDecimalSetter(installment::setTotalPaidLate, installment::getTotalPaidLate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreditedAmountsSetters() {
|
||||||
|
testBigDecimalSetter(installment::setCreditedPrincipal, installment::getCreditedPrincipal);
|
||||||
|
testBigDecimalSetter(installment::setCreditedInterest, installment::getCreditedInterest);
|
||||||
|
testBigDecimalSetter(installment::setCreditedFee, installment::getCreditedFee);
|
||||||
|
testBigDecimalSetter(installment::setCreditedPenalty, installment::getCreditedPenalty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPrecisionAndScale() {
|
||||||
|
final BigDecimal value = new BigDecimal("123456789.123456789");
|
||||||
|
|
||||||
|
// Test that value is properly scaled
|
||||||
|
installment.setPrincipal(value);
|
||||||
|
assertEquals(SCALE, installment.getPrincipal().scale());
|
||||||
|
|
||||||
|
// Test that value is properly rounded
|
||||||
|
final BigDecimal expected = new BigDecimal("123456789.123457");
|
||||||
|
assertEquals(expected, installment.getPrincipal());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testBigDecimalSetter(final Consumer<BigDecimal> setter, final Supplier<BigDecimal> getter) {
|
||||||
|
// Test non-zero value
|
||||||
|
final BigDecimal value = new BigDecimal("123.456789");
|
||||||
|
setter.accept(value);
|
||||||
|
assertEquals(value.setScale(SCALE, RoundingMode.HALF_EVEN), getter.get());
|
||||||
|
|
||||||
|
// Test zero value
|
||||||
|
setter.accept(BigDecimal.ZERO);
|
||||||
|
assertNull(getter.get());
|
||||||
|
|
||||||
|
// Test null value
|
||||||
|
setter.accept(null);
|
||||||
|
assertNull(getter.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -26,11 +26,13 @@ import static org.mockito.ArgumentMatchers.anyList;
|
|||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.inOrder;
|
import static org.mockito.Mockito.inOrder;
|
||||||
|
import static org.mockito.Mockito.mockStatic;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -50,6 +52,7 @@ import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
|||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanAccountDelinquencyPauseChangedBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanAccountDelinquencyPauseChangedBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanDelinquencyRangeChangeBusinessEvent;
|
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanDelinquencyRangeChangeBusinessEvent;
|
||||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||||
|
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction;
|
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket;
|
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket;
|
||||||
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucketMappingsRepository;
|
import org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucketMappingsRepository;
|
||||||
@@ -79,19 +82,24 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleIns
|
|||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
|
||||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.InOrder;
|
import org.mockito.InOrder;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class DelinquencyWritePlatformServiceRangeChangeEventTest {
|
public class DelinquencyWritePlatformServiceRangeChangeEventTest {
|
||||||
|
|
||||||
|
private static final MockedStatic<MoneyHelper> MONEY_HELPER = mockStatic(MoneyHelper.class);
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private DelinquencyBucketParseAndValidator dataValidatorBucket;
|
private DelinquencyBucketParseAndValidator dataValidatorBucket;
|
||||||
@Mock
|
@Mock
|
||||||
@@ -127,6 +135,11 @@ public class DelinquencyWritePlatformServiceRangeChangeEventTest {
|
|||||||
|
|
||||||
private DelinquencyWritePlatformServiceImpl underTest;
|
private DelinquencyWritePlatformServiceImpl underTest;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void init() {
|
||||||
|
MONEY_HELPER.when(MoneyHelper::getRoundingMode).thenReturn(RoundingMode.HALF_EVEN);
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
|
ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "Asia/Kolkata", null));
|
||||||
@@ -143,6 +156,11 @@ public class DelinquencyWritePlatformServiceRangeChangeEventTest {
|
|||||||
delinquencyWritePlatformServiceHelper);
|
delinquencyWritePlatformServiceHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void cleanUp() {
|
||||||
|
MONEY_HELPER.close();
|
||||||
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
ThreadLocalContextUtil.reset();
|
ThreadLocalContextUtil.reset();
|
||||||
|
|||||||
+10
-10
@@ -5348,8 +5348,8 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
|
|||||||
|
|
||||||
ArrayList<HashMap> loanSchedule = LOAN_TRANSACTION_HELPER.getLoanRepaymentSchedule(REQUEST_SPEC, RESPONSE_SPEC, loanID);
|
ArrayList<HashMap> loanSchedule = LOAN_TRANSACTION_HELPER.getLoanRepaymentSchedule(REQUEST_SPEC, RESPONSE_SPEC, loanID);
|
||||||
assertEquals(2, loanSchedule.size());
|
assertEquals(2, loanSchedule.size());
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("penaltyChargesDue"));
|
assertEquals(0, loanSchedule.get(1).get("penaltyChargesDue"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
assertEquals(0, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
||||||
assertEquals(1000.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
assertEquals(1000.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
||||||
assertEquals(1000.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
assertEquals(1000.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
||||||
LocalDate targetDate = LocalDate.of(2022, 9, 7);
|
LocalDate targetDate = LocalDate.of(2022, 9, 7);
|
||||||
@@ -5944,10 +5944,10 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
|
|||||||
|
|
||||||
ArrayList<HashMap> loanSchedule = LOAN_TRANSACTION_HELPER.getLoanRepaymentSchedule(REQUEST_SPEC, RESPONSE_SPEC, loanID);
|
ArrayList<HashMap> loanSchedule = LOAN_TRANSACTION_HELPER.getLoanRepaymentSchedule(REQUEST_SPEC, RESPONSE_SPEC, loanID);
|
||||||
assertEquals(2, loanSchedule.size());
|
assertEquals(2, loanSchedule.size());
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("feeChargesDue"));
|
assertEquals(0, loanSchedule.get(1).get("feeChargesDue"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("feeChargesOutstanding"));
|
assertEquals(0, loanSchedule.get(1).get("feeChargesOutstanding"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("penaltyChargesDue"));
|
assertEquals(0, loanSchedule.get(1).get("penaltyChargesDue"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
assertEquals(0, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
||||||
assertEquals(1000.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
assertEquals(1000.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
||||||
assertEquals(1000.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
assertEquals(1000.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
||||||
LocalDate targetDate = LocalDate.of(2022, 9, 7);
|
LocalDate targetDate = LocalDate.of(2022, 9, 7);
|
||||||
@@ -6013,11 +6013,11 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
|
|||||||
assertEquals(0, loanSchedule.get(1).get("feeChargesOutstanding"));
|
assertEquals(0, loanSchedule.get(1).get("feeChargesOutstanding"));
|
||||||
assertEquals(0, loanSchedule.get(1).get("feeChargesWaived"));
|
assertEquals(0, loanSchedule.get(1).get("feeChargesWaived"));
|
||||||
assertEquals(10.0f, loanSchedule.get(1).get("penaltyChargesDue"));
|
assertEquals(10.0f, loanSchedule.get(1).get("penaltyChargesDue"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("penaltyChargesWaived"));
|
assertEquals(0, loanSchedule.get(1).get("penaltyChargesWaived"));
|
||||||
assertEquals(10.0f, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
assertEquals(10.0f, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
||||||
assertEquals(1010.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
assertEquals(1010.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
||||||
assertEquals(1010.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
assertEquals(1010.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("totalWaivedForPeriod"));
|
assertEquals(0, loanSchedule.get(1).get("totalWaivedForPeriod"));
|
||||||
|
|
||||||
loanSummary = LOAN_TRANSACTION_HELPER.getLoanDetail(REQUEST_SPEC, RESPONSE_SPEC, loanID, "summary");
|
loanSummary = LOAN_TRANSACTION_HELPER.getLoanDetail(REQUEST_SPEC, RESPONSE_SPEC, loanID, "summary");
|
||||||
assertEquals(10.0f, loanSummary.get("penaltyChargesCharged"));
|
assertEquals(10.0f, loanSummary.get("penaltyChargesCharged"));
|
||||||
@@ -6146,13 +6146,13 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
|
|||||||
assertEquals(2, loanSchedule.size());
|
assertEquals(2, loanSchedule.size());
|
||||||
assertEquals(10.0f, loanSchedule.get(1).get("feeChargesDue"));
|
assertEquals(10.0f, loanSchedule.get(1).get("feeChargesDue"));
|
||||||
assertEquals(10.0f, loanSchedule.get(1).get("feeChargesOutstanding"));
|
assertEquals(10.0f, loanSchedule.get(1).get("feeChargesOutstanding"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("feeChargesWaived"));
|
assertEquals(0, loanSchedule.get(1).get("feeChargesWaived"));
|
||||||
assertEquals(10.0f, loanSchedule.get(1).get("penaltyChargesDue"));
|
assertEquals(10.0f, loanSchedule.get(1).get("penaltyChargesDue"));
|
||||||
assertEquals(0, loanSchedule.get(1).get("penaltyChargesWaived"));
|
assertEquals(0, loanSchedule.get(1).get("penaltyChargesWaived"));
|
||||||
assertEquals(10.0f, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
assertEquals(10.0f, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
||||||
assertEquals(1020.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
assertEquals(1020.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
||||||
assertEquals(1020.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
assertEquals(1020.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("totalWaivedForPeriod"));
|
assertEquals(0, loanSchedule.get(1).get("totalWaivedForPeriod"));
|
||||||
|
|
||||||
loanSummary = LOAN_TRANSACTION_HELPER.getLoanDetail(REQUEST_SPEC, RESPONSE_SPEC, loanID, "summary");
|
loanSummary = LOAN_TRANSACTION_HELPER.getLoanDetail(REQUEST_SPEC, RESPONSE_SPEC, loanID, "summary");
|
||||||
assertEquals(10.0f, loanSummary.get("penaltyChargesCharged"));
|
assertEquals(10.0f, loanSummary.get("penaltyChargesCharged"));
|
||||||
|
|||||||
+8
-8
@@ -173,10 +173,10 @@ public class LoanSpecificDueDateChargeAfterMaturityTest extends BaseLoanIntegrat
|
|||||||
|
|
||||||
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec, loanID);
|
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec, loanID);
|
||||||
assertEquals(2, loanSchedule.size());
|
assertEquals(2, loanSchedule.size());
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("feeChargesDue"));
|
assertEquals(0, loanSchedule.get(1).get("feeChargesDue"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("feeChargesOutstanding"));
|
assertEquals(0, loanSchedule.get(1).get("feeChargesOutstanding"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("penaltyChargesDue"));
|
assertEquals(0, loanSchedule.get(1).get("penaltyChargesDue"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
assertEquals(0, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
||||||
assertEquals(10000.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
assertEquals(10000.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
||||||
assertEquals(10000.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
assertEquals(10000.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
||||||
targetDate = LocalDate.of(2011, 4, 5);
|
targetDate = LocalDate.of(2011, 4, 5);
|
||||||
@@ -306,10 +306,10 @@ public class LoanSpecificDueDateChargeAfterMaturityTest extends BaseLoanIntegrat
|
|||||||
|
|
||||||
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec, loanID);
|
ArrayList<HashMap> loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec, loanID);
|
||||||
assertEquals(2, loanSchedule.size());
|
assertEquals(2, loanSchedule.size());
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("feeChargesDue"));
|
assertEquals(0, loanSchedule.get(1).get("feeChargesDue"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("feeChargesOutstanding"));
|
assertEquals(0, loanSchedule.get(1).get("feeChargesOutstanding"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("penaltyChargesDue"));
|
assertEquals(0, loanSchedule.get(1).get("penaltyChargesDue"));
|
||||||
assertEquals(0.0f, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
assertEquals(0, loanSchedule.get(1).get("penaltyChargesOutstanding"));
|
||||||
assertEquals(10000.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
assertEquals(10000.0f, loanSchedule.get(1).get("totalDueForPeriod"));
|
||||||
assertEquals(10000.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
assertEquals(10000.0f, loanSchedule.get(1).get("totalOutstandingForPeriod"));
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -844,7 +844,7 @@ public class SchedulerJobsTestResults extends IntegrationTest {
|
|||||||
ArrayList<HashMap> repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec,
|
ArrayList<HashMap> repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec,
|
||||||
loanID);
|
loanID);
|
||||||
|
|
||||||
Assertions.assertEquals(0.0f, repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
Assertions.assertEquals(0, repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
||||||
"Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job");
|
"Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job");
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1085,7 +1085,7 @@ public class SchedulerJobsTestResults extends IntegrationTest {
|
|||||||
this.schedulerJobHelper.executeAndAwaitJob(jobName);
|
this.schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||||
List<HashMap> repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec,
|
List<HashMap> repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec,
|
||||||
loanID);
|
loanID);
|
||||||
Assertions.assertEquals(0.0f, repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
Assertions.assertEquals(0, repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
||||||
"Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job");
|
"Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job");
|
||||||
|
|
||||||
LocalDate lastBusinessDateBeforeFastForward = LocalDate.of(2019, 4, 2);
|
LocalDate lastBusinessDateBeforeFastForward = LocalDate.of(2019, 4, 2);
|
||||||
@@ -1153,7 +1153,7 @@ public class SchedulerJobsTestResults extends IntegrationTest {
|
|||||||
this.schedulerJobHelper.executeAndAwaitJob(jobName);
|
this.schedulerJobHelper.executeAndAwaitJob(jobName);
|
||||||
List<HashMap> repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec,
|
List<HashMap> repaymentScheduleDataAfter = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec,
|
||||||
loanID2);
|
loanID2);
|
||||||
Assertions.assertEquals(0.0f, repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
Assertions.assertEquals(0, repaymentScheduleDataAfter.get(1).get("penaltyChargesDue"),
|
||||||
"Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job");
|
"Verifying From Penalty Charges due fot first Repayment after Successful completion of Scheduler Job");
|
||||||
|
|
||||||
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 5, 3));
|
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, LocalDate.of(2020, 5, 3));
|
||||||
|
|||||||
Reference in New Issue
Block a user