FINERACT-1905: Distribution logic fix
This commit is contained in:
+22
-6
@@ -410,6 +410,10 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money penaltyPortionOfTransaction = Money.zero(currency);
|
Money penaltyPortionOfTransaction = Money.zero(currency);
|
||||||
|
|
||||||
|
if (transactionAmountRemaining.isZero()) {
|
||||||
|
return penaltyPortionOfTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
this.penaltyChargesPaid = getPenaltyChargesPaid(currency).plus(penaltyChargesDue).getAmount();
|
||||||
@@ -432,7 +436,9 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money feePortionOfTransaction = Money.zero(currency);
|
Money feePortionOfTransaction = Money.zero(currency);
|
||||||
|
if (transactionAmountRemaining.isZero()) {
|
||||||
|
return feePortionOfTransaction;
|
||||||
|
}
|
||||||
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();
|
this.feeChargesPaid = getFeeChargesPaid(currency).plus(feeChargesDue).getAmount();
|
||||||
@@ -455,7 +461,9 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money interestPortionOfTransaction = Money.zero(currency);
|
Money interestPortionOfTransaction = Money.zero(currency);
|
||||||
|
if (transactionAmountRemaining.isZero()) {
|
||||||
|
return interestPortionOfTransaction;
|
||||||
|
}
|
||||||
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();
|
this.interestPaid = getInterestPaid(currency).plus(interestDue).getAmount();
|
||||||
@@ -478,7 +486,9 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money principalPortionOfTransaction = Money.zero(currency);
|
Money principalPortionOfTransaction = Money.zero(currency);
|
||||||
|
if (transactionAmountRemaining.isZero()) {
|
||||||
|
return principalPortionOfTransaction;
|
||||||
|
}
|
||||||
final Money principalDue = getPrincipalOutstanding(currency);
|
final Money principalDue = getPrincipalOutstanding(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(principalDue)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(principalDue)) {
|
||||||
this.principalCompleted = getPrincipalCompleted(currency).plus(principalDue).getAmount();
|
this.principalCompleted = getPrincipalCompleted(currency).plus(principalDue).getAmount();
|
||||||
@@ -500,7 +510,9 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
public Money waiveInterestComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
public Money waiveInterestComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money waivedInterestPortionOfTransaction = Money.zero(currency);
|
Money waivedInterestPortionOfTransaction = Money.zero(currency);
|
||||||
|
if (transactionAmountRemaining.isZero()) {
|
||||||
|
return waivedInterestPortionOfTransaction;
|
||||||
|
}
|
||||||
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();
|
this.interestWaived = getInterestWaived(currency).plus(interestDue).getAmount();
|
||||||
@@ -520,7 +532,9 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
public Money waivePenaltyChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
public Money waivePenaltyChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money waivedPenaltyChargesPortionOfTransaction = Money.zero(currency);
|
Money waivedPenaltyChargesPortionOfTransaction = Money.zero(currency);
|
||||||
|
if (transactionAmountRemaining.isZero()) {
|
||||||
|
return waivedPenaltyChargesPortionOfTransaction;
|
||||||
|
}
|
||||||
final Money penanltiesDue = getPenaltyChargesOutstanding(currency);
|
final Money penanltiesDue = getPenaltyChargesOutstanding(currency);
|
||||||
if (transactionAmountRemaining.isGreaterThanOrEqualTo(penanltiesDue)) {
|
if (transactionAmountRemaining.isGreaterThanOrEqualTo(penanltiesDue)) {
|
||||||
this.penaltyChargesWaived = getPenaltyChargesWaived(currency).plus(penanltiesDue).getAmount();
|
this.penaltyChargesWaived = getPenaltyChargesWaived(currency).plus(penanltiesDue).getAmount();
|
||||||
@@ -540,7 +554,9 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
|||||||
public Money waiveFeeChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
public Money waiveFeeChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||||
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
|
||||||
Money waivedFeeChargesPortionOfTransaction = Money.zero(currency);
|
Money waivedFeeChargesPortionOfTransaction = Money.zero(currency);
|
||||||
|
if (transactionAmountRemaining.isZero()) {
|
||||||
|
return waivedFeeChargesPortionOfTransaction;
|
||||||
|
}
|
||||||
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();
|
this.feeChargesWaived = getFeeChargesWaived(currency).plus(feesDue).getAmount();
|
||||||
|
|||||||
+112
-67
@@ -56,15 +56,6 @@ public class DuePenFeeIntPriInAdvancePriPenFeeIntLoanRepaymentScheduleTransactio
|
|||||||
return STRATEGY_NAME;
|
return STRATEGY_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTransactionInAdvanceOfInstallment(final int currentInstallmentIndex,
|
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LocalDate transactionDate) {
|
|
||||||
|
|
||||||
final LoanRepaymentScheduleInstallment currentInstallment = installments.get(currentInstallmentIndex);
|
|
||||||
|
|
||||||
return transactionDate.isBefore(currentInstallment.getDueDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For early/'in advance' repayments
|
* For early/'in advance' repayments
|
||||||
*/
|
*/
|
||||||
@@ -73,8 +64,106 @@ public class DuePenFeeIntPriInAdvancePriPenFeeIntLoanRepaymentScheduleTransactio
|
|||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction, final Money paymentInAdvance,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction, final Money paymentInAdvance,
|
||||||
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings, Set<LoanCharge> charges) {
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings, Set<LoanCharge> charges) {
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, paymentInAdvance, transactionMappings,
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
charges);
|
|
||||||
|
final MonetaryCurrency currency = paymentInAdvance.getCurrency();
|
||||||
|
Money transactionAmountRemaining = paymentInAdvance;
|
||||||
|
Money principalPortion = Money.zero(currency);
|
||||||
|
Money interestPortion = Money.zero(currency);
|
||||||
|
Money feeChargesPortion = Money.zero(currency);
|
||||||
|
Money penaltyChargesPortion = Money.zero(currency);
|
||||||
|
|
||||||
|
if (loanTransaction.isChargesWaiver()) {
|
||||||
|
penaltyChargesPortion = currentInstallment.waivePenaltyChargesComponent(transactionDate,
|
||||||
|
loanTransaction.getPenaltyChargesPortion(currency));
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||||
|
|
||||||
|
feeChargesPortion = currentInstallment.waiveFeeChargesComponent(transactionDate,
|
||||||
|
loanTransaction.getFeeChargesPortion(currency));
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||||
|
|
||||||
|
} else if (loanTransaction.isInterestWaiver()) {
|
||||||
|
interestPortion = currentInstallment.waiveInterestComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||||
|
|
||||||
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
} else if (loanTransaction.isChargePayment()) {
|
||||||
|
if (loanTransaction.isPenaltyPayment()) {
|
||||||
|
penaltyChargesPortion = currentInstallment.payPenaltyChargesComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||||
|
} else {
|
||||||
|
feeChargesPortion = currentInstallment.payFeeChargesComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||||
|
}
|
||||||
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
} else {
|
||||||
|
boolean ignoreDueDateCheck = false;
|
||||||
|
boolean rerun = false;
|
||||||
|
|
||||||
|
List<LoanCharge> orderedLoanChargesByDueDate = charges.stream().filter(LoanCharge::isActive).filter(LoanCharge::isNotFullyPaid)
|
||||||
|
.filter(loanCharge -> loanCharge.getEffectiveDueDate() == null
|
||||||
|
|| !loanCharge.getEffectiveDueDate().isAfter(transactionDate))
|
||||||
|
.sorted(LoanChargeEffectiveDueDateComparator.INSTANCE).toList();
|
||||||
|
Money calculatedPenaltyCharge = Money.zero(currency);
|
||||||
|
Money calculatedFeeCharge = Money.zero(currency);
|
||||||
|
// Calculate the amount of due charges
|
||||||
|
for (LoanCharge charge : orderedLoanChargesByDueDate) {
|
||||||
|
if (charge.isPenaltyCharge()) {
|
||||||
|
calculatedPenaltyCharge = calculatedPenaltyCharge.add(charge.getAmount(currency));
|
||||||
|
} else {
|
||||||
|
calculatedFeeCharge = calculatedFeeCharge.add(charge.getAmount(currency));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
Money subPenaltyPortion;
|
||||||
|
if (!ignoreDueDateCheck) {
|
||||||
|
if (calculatedPenaltyCharge.isGreaterThan(transactionAmountRemaining)) {
|
||||||
|
calculatedPenaltyCharge = transactionAmountRemaining;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
calculatedPenaltyCharge = transactionAmountRemaining;
|
||||||
|
}
|
||||||
|
subPenaltyPortion = currentInstallment.payPenaltyChargesComponent(transactionDate, calculatedPenaltyCharge);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(subPenaltyPortion);
|
||||||
|
penaltyChargesPortion = penaltyChargesPortion.add(subPenaltyPortion);
|
||||||
|
|
||||||
|
Money subFeePortion;
|
||||||
|
if (!ignoreDueDateCheck) {
|
||||||
|
if (calculatedFeeCharge.isGreaterThan(transactionAmountRemaining)) {
|
||||||
|
calculatedFeeCharge = transactionAmountRemaining;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
calculatedFeeCharge = transactionAmountRemaining;
|
||||||
|
}
|
||||||
|
subFeePortion = currentInstallment.payFeeChargesComponent(transactionDate, calculatedFeeCharge);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(subFeePortion);
|
||||||
|
feeChargesPortion = feeChargesPortion.add(subFeePortion);
|
||||||
|
|
||||||
|
Money subInterestPortion;
|
||||||
|
if (ignoreDueDateCheck || !transactionDate.isBefore(currentInstallment.getDueDate())) {
|
||||||
|
subInterestPortion = currentInstallment.payInterestComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(subInterestPortion);
|
||||||
|
interestPortion = interestPortion.add(subInterestPortion);
|
||||||
|
}
|
||||||
|
|
||||||
|
Money subPrincipalPortion = currentInstallment.payPrincipalComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(subPrincipalPortion);
|
||||||
|
principalPortion = principalPortion.add(subPrincipalPortion);
|
||||||
|
// If the transactionAmountRemaining is greater than zero, rerun the allocation without due date check
|
||||||
|
// to distribute the in advance portions
|
||||||
|
if (transactionAmountRemaining.isGreaterThanZero()) {
|
||||||
|
ignoreDueDateCheck = true;
|
||||||
|
}
|
||||||
|
rerun = !rerun;
|
||||||
|
} while (ignoreDueDateCheck && rerun);
|
||||||
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
}
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(loanTransaction, currentInstallment,
|
||||||
|
principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -131,66 +220,22 @@ public class DuePenFeeIntPriInAdvancePriPenFeeIntLoanRepaymentScheduleTransactio
|
|||||||
}
|
}
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
} else {
|
} else {
|
||||||
boolean ignoreDueDateCheck = false;
|
Money subPenaltyPortion = currentInstallment.payPenaltyChargesComponent(transactionDate, transactionAmountRemaining);
|
||||||
boolean rerun = false;
|
transactionAmountRemaining = transactionAmountRemaining.minus(subPenaltyPortion);
|
||||||
|
penaltyChargesPortion = penaltyChargesPortion.add(subPenaltyPortion);
|
||||||
|
|
||||||
List<LoanCharge> orderedLoanChargesByDueDate = charges.stream().filter(LoanCharge::isActive).filter(LoanCharge::isNotFullyPaid)
|
Money subFeePortion = currentInstallment.payFeeChargesComponent(transactionDate, transactionAmountRemaining);
|
||||||
.filter(loanCharge -> loanCharge.getEffectiveDueDate() == null
|
transactionAmountRemaining = transactionAmountRemaining.minus(subFeePortion);
|
||||||
|| !loanCharge.getEffectiveDueDate().isAfter(transactionDate))
|
feeChargesPortion = feeChargesPortion.add(subFeePortion);
|
||||||
.sorted(LoanChargeEffectiveDueDateComparator.INSTANCE).toList();
|
|
||||||
Money calculatedPenaltyCharge = Money.zero(currency);
|
|
||||||
Money calculatedFeeCharge = Money.zero(currency);
|
|
||||||
// Calculate the amount of due charges
|
|
||||||
for (LoanCharge charge : orderedLoanChargesByDueDate) {
|
|
||||||
if (charge.isPenaltyCharge()) {
|
|
||||||
calculatedPenaltyCharge = calculatedPenaltyCharge.add(charge.getAmount(currency));
|
|
||||||
} else {
|
|
||||||
calculatedFeeCharge = calculatedFeeCharge.add(charge.getAmount(currency));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
Money subInterestPortion = currentInstallment.payInterestComponent(transactionDate, transactionAmountRemaining);
|
||||||
Money subPenaltyPortion;
|
transactionAmountRemaining = transactionAmountRemaining.minus(subInterestPortion);
|
||||||
if (!ignoreDueDateCheck) {
|
interestPortion = interestPortion.add(subInterestPortion);
|
||||||
if (calculatedPenaltyCharge.isGreaterThan(transactionAmountRemaining)) {
|
|
||||||
calculatedPenaltyCharge = transactionAmountRemaining;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
calculatedPenaltyCharge = transactionAmountUnprocessed;
|
|
||||||
}
|
|
||||||
subPenaltyPortion = currentInstallment.payPenaltyChargesComponent(transactionDate, calculatedPenaltyCharge);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subPenaltyPortion);
|
|
||||||
penaltyChargesPortion = penaltyChargesPortion.add(subPenaltyPortion);
|
|
||||||
|
|
||||||
Money subFeePortion;
|
Money subPrincipalPortion = currentInstallment.payPrincipalComponent(transactionDate, transactionAmountRemaining);
|
||||||
if (!ignoreDueDateCheck) {
|
transactionAmountRemaining = transactionAmountRemaining.minus(subPrincipalPortion);
|
||||||
if (calculatedFeeCharge.isGreaterThan(transactionAmountRemaining)) {
|
principalPortion = principalPortion.add(subPrincipalPortion);
|
||||||
calculatedFeeCharge = transactionAmountRemaining;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
calculatedFeeCharge = transactionAmountUnprocessed;
|
|
||||||
}
|
|
||||||
subFeePortion = currentInstallment.payFeeChargesComponent(transactionDate, calculatedFeeCharge);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subFeePortion);
|
|
||||||
feeChargesPortion = feeChargesPortion.add(subFeePortion);
|
|
||||||
|
|
||||||
Money subInterestPortion;
|
|
||||||
if (ignoreDueDateCheck || !transactionDate.isBefore(currentInstallment.getDueDate())) {
|
|
||||||
subInterestPortion = currentInstallment.payInterestComponent(transactionDate, transactionAmountRemaining);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subInterestPortion);
|
|
||||||
interestPortion = interestPortion.add(subInterestPortion);
|
|
||||||
}
|
|
||||||
|
|
||||||
Money subPrincipalPortion = currentInstallment.payPrincipalComponent(transactionDate, transactionAmountRemaining);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subPrincipalPortion);
|
|
||||||
principalPortion = principalPortion.add(subPrincipalPortion);
|
|
||||||
// If the transactionAmountRemaining is greater than zero, rerun the allocation without due date check
|
|
||||||
// to distribute the in advance portions
|
|
||||||
if (transactionAmountRemaining.isGreaterThanZero()) {
|
|
||||||
ignoreDueDateCheck = true;
|
|
||||||
}
|
|
||||||
rerun = !rerun;
|
|
||||||
} while (ignoreDueDateCheck && rerun);
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
}
|
}
|
||||||
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
|||||||
+88
-100
@@ -56,109 +56,17 @@ public class DuePenIntPriFeeInAdvancePenIntPriFeeLoanRepaymentScheduleTransactio
|
|||||||
return STRATEGY_NAME;
|
return STRATEGY_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isTransactionInAdvanceOfInstallment(final int currentInstallmentIndex,
|
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LocalDate transactionDate) {
|
|
||||||
|
|
||||||
final LoanRepaymentScheduleInstallment currentInstallment = installments.get(currentInstallmentIndex);
|
|
||||||
|
|
||||||
return transactionDate.isBefore(currentInstallment.getDueDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For early/'in advance' repayments
|
* For early/'in advance' repayments
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
protected Money handleTransactionThatIsPaymentInAdvanceOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction, final Money paymentInAdvance,
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction, final Money inAdvancePayment,
|
||||||
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings, Set<LoanCharge> charges) {
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings, Set<LoanCharge> charges) {
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
final MonetaryCurrency currency = paymentInAdvance.getCurrency();
|
|
||||||
Money transactionAmountRemaining = paymentInAdvance;
|
|
||||||
Money principalPortion = Money.zero(currency);
|
|
||||||
Money interestPortion = Money.zero(currency);
|
|
||||||
Money feeChargesPortion = Money.zero(currency);
|
|
||||||
Money penaltyChargesPortion = Money.zero(currency);
|
|
||||||
|
|
||||||
if (loanTransaction.isChargesWaiver()) {
|
final MonetaryCurrency currency = inAdvancePayment.getCurrency();
|
||||||
penaltyChargesPortion = currentInstallment.waivePenaltyChargesComponent(transactionDate,
|
Money transactionAmountRemaining = inAdvancePayment;
|
||||||
loanTransaction.getPenaltyChargesPortion(currency));
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
|
||||||
|
|
||||||
feeChargesPortion = currentInstallment.waiveFeeChargesComponent(transactionDate,
|
|
||||||
loanTransaction.getFeeChargesPortion(currency));
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
|
||||||
|
|
||||||
} else if (loanTransaction.isInterestWaiver()) {
|
|
||||||
interestPortion = currentInstallment.waiveInterestComponent(transactionDate, transactionAmountRemaining);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
|
||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
|
||||||
} else if (loanTransaction.isChargePayment()) {
|
|
||||||
if (loanTransaction.isPenaltyPayment()) {
|
|
||||||
penaltyChargesPortion = currentInstallment.payPenaltyChargesComponent(transactionDate, transactionAmountRemaining);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
|
||||||
} else {
|
|
||||||
feeChargesPortion = currentInstallment.payFeeChargesComponent(transactionDate, transactionAmountRemaining);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
|
||||||
}
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
|
||||||
} else {
|
|
||||||
// In advance penalty, interest, principal, fee
|
|
||||||
|
|
||||||
Money subPenaltyPortion;
|
|
||||||
subPenaltyPortion = currentInstallment.payPenaltyChargesComponent(transactionDate, transactionAmountRemaining);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subPenaltyPortion);
|
|
||||||
penaltyChargesPortion = penaltyChargesPortion.add(subPenaltyPortion);
|
|
||||||
|
|
||||||
Money subInterestPortion;
|
|
||||||
subInterestPortion = currentInstallment.payInterestComponent(transactionDate, transactionAmountRemaining);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subInterestPortion);
|
|
||||||
interestPortion = interestPortion.add(subInterestPortion);
|
|
||||||
|
|
||||||
Money subPrincipalPortion = currentInstallment.payPrincipalComponent(transactionDate, transactionAmountRemaining);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subPrincipalPortion);
|
|
||||||
principalPortion = principalPortion.add(subPrincipalPortion);
|
|
||||||
|
|
||||||
Money subFeePortion;
|
|
||||||
subFeePortion = currentInstallment.payFeeChargesComponent(transactionDate, transactionAmountRemaining);
|
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subFeePortion);
|
|
||||||
feeChargesPortion = feeChargesPortion.add(subFeePortion);
|
|
||||||
|
|
||||||
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
|
||||||
}
|
|
||||||
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
|
||||||
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(loanTransaction, currentInstallment,
|
|
||||||
principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion));
|
|
||||||
}
|
|
||||||
return transactionAmountRemaining;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For late repayments
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
|
||||||
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction,
|
|
||||||
final Money transactionAmountUnprocessed, List<LoanTransactionToRepaymentScheduleMapping> transactionMappings,
|
|
||||||
Set<LoanCharge> charges) {
|
|
||||||
|
|
||||||
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, transactionAmountUnprocessed,
|
|
||||||
transactionMappings, charges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For normal on-time repayments
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
|
||||||
final LoanTransaction loanTransaction, final Money transactionAmountUnprocessed,
|
|
||||||
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings, Set<LoanCharge> charges) {
|
|
||||||
|
|
||||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
|
||||||
|
|
||||||
final MonetaryCurrency currency = transactionAmountUnprocessed.getCurrency();
|
|
||||||
Money transactionAmountRemaining = transactionAmountUnprocessed;
|
|
||||||
Money principalPortion = Money.zero(currency);
|
Money principalPortion = Money.zero(currency);
|
||||||
Money interestPortion = Money.zero(currency);
|
Money interestPortion = Money.zero(currency);
|
||||||
Money feeChargesPortion = Money.zero(currency);
|
Money feeChargesPortion = Money.zero(currency);
|
||||||
@@ -214,7 +122,7 @@ public class DuePenIntPriFeeInAdvancePenIntPriFeeLoanRepaymentScheduleTransactio
|
|||||||
calculatedPenaltyCharge = transactionAmountRemaining;
|
calculatedPenaltyCharge = transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
calculatedPenaltyCharge = transactionAmountUnprocessed;
|
calculatedPenaltyCharge = transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
subPenaltyPortion = currentInstallment.payPenaltyChargesComponent(transactionDate, calculatedPenaltyCharge);
|
subPenaltyPortion = currentInstallment.payPenaltyChargesComponent(transactionDate, calculatedPenaltyCharge);
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subPenaltyPortion);
|
transactionAmountRemaining = transactionAmountRemaining.minus(subPenaltyPortion);
|
||||||
@@ -227,9 +135,11 @@ public class DuePenIntPriFeeInAdvancePenIntPriFeeLoanRepaymentScheduleTransactio
|
|||||||
interestPortion = interestPortion.add(subInterestPortion);
|
interestPortion = interestPortion.add(subInterestPortion);
|
||||||
}
|
}
|
||||||
|
|
||||||
Money subPrincipalPortion = currentInstallment.payPrincipalComponent(transactionDate, transactionAmountRemaining);
|
if (ignoreDueDateCheck || !transactionDate.isBefore(currentInstallment.getDueDate())) {
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subPrincipalPortion);
|
Money subPrincipalPortion = currentInstallment.payPrincipalComponent(transactionDate, transactionAmountRemaining);
|
||||||
principalPortion = principalPortion.add(subPrincipalPortion);
|
transactionAmountRemaining = transactionAmountRemaining.minus(subPrincipalPortion);
|
||||||
|
principalPortion = principalPortion.add(subPrincipalPortion);
|
||||||
|
}
|
||||||
|
|
||||||
Money subFeePortion;
|
Money subFeePortion;
|
||||||
if (!ignoreDueDateCheck) {
|
if (!ignoreDueDateCheck) {
|
||||||
@@ -237,7 +147,7 @@ public class DuePenIntPriFeeInAdvancePenIntPriFeeLoanRepaymentScheduleTransactio
|
|||||||
calculatedFeeCharge = transactionAmountRemaining;
|
calculatedFeeCharge = transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
calculatedFeeCharge = transactionAmountUnprocessed;
|
calculatedFeeCharge = transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
subFeePortion = currentInstallment.payFeeChargesComponent(transactionDate, calculatedFeeCharge);
|
subFeePortion = currentInstallment.payFeeChargesComponent(transactionDate, calculatedFeeCharge);
|
||||||
transactionAmountRemaining = transactionAmountRemaining.minus(subFeePortion);
|
transactionAmountRemaining = transactionAmountRemaining.minus(subFeePortion);
|
||||||
@@ -259,6 +169,84 @@ public class DuePenIntPriFeeInAdvancePenIntPriFeeLoanRepaymentScheduleTransactio
|
|||||||
return transactionAmountRemaining;
|
return transactionAmountRemaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For late repayments
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Money handleTransactionThatIsALateRepaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
|
final List<LoanRepaymentScheduleInstallment> installments, final LoanTransaction loanTransaction, final Money latePayment,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings, Set<LoanCharge> charges) {
|
||||||
|
|
||||||
|
return handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction, latePayment, transactionMappings,
|
||||||
|
charges);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For normal on-time repayments
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Money handleTransactionThatIsOnTimePaymentOfInstallment(final LoanRepaymentScheduleInstallment currentInstallment,
|
||||||
|
final LoanTransaction loanTransaction, final Money onTimePayment,
|
||||||
|
List<LoanTransactionToRepaymentScheduleMapping> transactionMappings, Set<LoanCharge> charges) {
|
||||||
|
|
||||||
|
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||||
|
|
||||||
|
final MonetaryCurrency currency = onTimePayment.getCurrency();
|
||||||
|
Money transactionAmountRemaining = onTimePayment;
|
||||||
|
Money principalPortion = Money.zero(currency);
|
||||||
|
Money interestPortion = Money.zero(currency);
|
||||||
|
Money feeChargesPortion = Money.zero(currency);
|
||||||
|
Money penaltyChargesPortion = Money.zero(currency);
|
||||||
|
|
||||||
|
if (loanTransaction.isChargesWaiver()) {
|
||||||
|
penaltyChargesPortion = currentInstallment.waivePenaltyChargesComponent(transactionDate,
|
||||||
|
loanTransaction.getPenaltyChargesPortion(currency));
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||||
|
|
||||||
|
feeChargesPortion = currentInstallment.waiveFeeChargesComponent(transactionDate,
|
||||||
|
loanTransaction.getFeeChargesPortion(currency));
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||||
|
|
||||||
|
} else if (loanTransaction.isInterestWaiver()) {
|
||||||
|
interestPortion = currentInstallment.waiveInterestComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(interestPortion);
|
||||||
|
|
||||||
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
} else if (loanTransaction.isChargePayment()) {
|
||||||
|
if (loanTransaction.isPenaltyPayment()) {
|
||||||
|
penaltyChargesPortion = currentInstallment.payPenaltyChargesComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(penaltyChargesPortion);
|
||||||
|
} else {
|
||||||
|
feeChargesPortion = currentInstallment.payFeeChargesComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(feeChargesPortion);
|
||||||
|
}
|
||||||
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
} else {
|
||||||
|
Money subPenaltyPortion = currentInstallment.payPenaltyChargesComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(subPenaltyPortion);
|
||||||
|
penaltyChargesPortion = penaltyChargesPortion.add(subPenaltyPortion);
|
||||||
|
|
||||||
|
Money subInterestPortion = currentInstallment.payInterestComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(subInterestPortion);
|
||||||
|
interestPortion = interestPortion.add(subInterestPortion);
|
||||||
|
|
||||||
|
Money subPrincipalPortion = currentInstallment.payPrincipalComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(subPrincipalPortion);
|
||||||
|
principalPortion = principalPortion.add(subPrincipalPortion);
|
||||||
|
|
||||||
|
Money subFeePortion = currentInstallment.payFeeChargesComponent(transactionDate, transactionAmountRemaining);
|
||||||
|
transactionAmountRemaining = transactionAmountRemaining.minus(subFeePortion);
|
||||||
|
feeChargesPortion = feeChargesPortion.add(subFeePortion);
|
||||||
|
|
||||||
|
loanTransaction.updateComponents(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
|
||||||
|
}
|
||||||
|
if (principalPortion.plus(interestPortion).plus(feeChargesPortion).plus(penaltyChargesPortion).isGreaterThanZero()) {
|
||||||
|
transactionMappings.add(LoanTransactionToRepaymentScheduleMapping.createFrom(loanTransaction, currentInstallment,
|
||||||
|
principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion));
|
||||||
|
}
|
||||||
|
return transactionAmountRemaining;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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
|
||||||
|
|||||||
+1065
File diff suppressed because it is too large
Load Diff
+1029
File diff suppressed because it is too large
Load Diff
+420
-25
@@ -19,6 +19,7 @@
|
|||||||
package org.apache.fineract.integrationtests;
|
package org.apache.fineract.integrationtests;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
@@ -30,8 +31,12 @@ import io.restassured.specification.RequestSpecification;
|
|||||||
import io.restassured.specification.ResponseSpecification;
|
import io.restassured.specification.ResponseSpecification;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import org.apache.fineract.client.models.BusinessDateRequest;
|
import org.apache.fineract.client.models.BusinessDateRequest;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||||
|
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest;
|
||||||
|
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdResponse;
|
||||||
|
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
|
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
|
||||||
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
|
||||||
@@ -49,6 +54,7 @@ import org.apache.fineract.integrationtests.common.loans.LoanRescheduleRequestTe
|
|||||||
import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
|
import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker;
|
||||||
import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
|
import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
|
||||||
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
|
||||||
|
import org.apache.fineract.integrationtests.inlinecob.InlineLoanCOBHelper;
|
||||||
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;
|
||||||
@@ -64,7 +70,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
private BusinessDateHelper businessDateHelper;
|
private BusinessDateHelper businessDateHelper;
|
||||||
private LoanTransactionHelper loanTransactionHelper;
|
private LoanTransactionHelper loanTransactionHelper;
|
||||||
private LoanRescheduleRequestHelper loanRescheduleRequestHelper;
|
private LoanRescheduleRequestHelper loanRescheduleRequestHelper;
|
||||||
|
private InlineLoanCOBHelper inlineLoanCOBHelper;
|
||||||
private AccountHelper accountHelper;
|
private AccountHelper accountHelper;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@@ -78,6 +84,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
this.loanRescheduleRequestHelper = new LoanRescheduleRequestHelper(this.requestSpec, this.responseSpec);
|
this.loanRescheduleRequestHelper = new LoanRescheduleRequestHelper(this.requestSpec, this.responseSpec);
|
||||||
this.businessDateHelper = new BusinessDateHelper();
|
this.businessDateHelper = new BusinessDateHelper();
|
||||||
this.accountHelper = new AccountHelper(this.requestSpec, this.responseSpec);
|
this.accountHelper = new AccountHelper(this.requestSpec, this.responseSpec);
|
||||||
|
inlineLoanCOBHelper = new InlineLoanCOBHelper(requestSpec, responseSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scenario1:
|
// Scenario1:
|
||||||
@@ -104,12 +111,12 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
|
|
||||||
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
|
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", true));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", true));
|
||||||
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "1", "1", "0",
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "1", "0",
|
||||||
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "1", "1", "1", "0",
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "30", "30", "1", "0",
|
||||||
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
"01 January 2023", "01 January 2023");
|
"01 January 2023", "01 January 2023");
|
||||||
|
|
||||||
@@ -216,12 +223,12 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
|
|
||||||
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false));
|
||||||
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "1", "1", "0",
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "1", "0",
|
||||||
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "1", "1", "1", "0",
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "30", "30", "1", "0",
|
||||||
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
"01 January 2023", "01 January 2023");
|
"01 January 2023", "01 January 2023");
|
||||||
|
|
||||||
@@ -324,12 +331,12 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
|
|
||||||
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false));
|
||||||
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "1", "1", "0",
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "1", "0",
|
||||||
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "1", "1", "1", "0",
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "30", "30", "1", "0",
|
||||||
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
"01 January 2023", "01 January 2023");
|
"01 January 2023", "01 January 2023");
|
||||||
|
|
||||||
@@ -441,12 +448,12 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
|
|
||||||
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false));
|
||||||
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "1", "3", "0",
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "3", "0",
|
||||||
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "3", "1", "3", "0",
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "90", "30", "3", "0",
|
||||||
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
"01 January 2023", "01 January 2023");
|
"01 January 2023", "01 January 2023");
|
||||||
|
|
||||||
@@ -530,12 +537,12 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
|
|
||||||
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false));
|
||||||
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "1", "3", "0",
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "3", "0",
|
||||||
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "3", "1", "3", "0",
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "90", "30", "3", "0",
|
||||||
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
"01 January 2023", "01 January 2023");
|
"01 January 2023", "01 January 2023");
|
||||||
|
|
||||||
@@ -678,12 +685,12 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
|
|
||||||
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "20", false));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "20", false));
|
||||||
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "1", "1", "0",
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "1", "0",
|
||||||
LoanProductTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
LoanProductTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
||||||
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "1", "1", "1", "0",
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "30", "30", "1", "0",
|
||||||
LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
||||||
"01 January 2023", "01 January 2023");
|
"01 January 2023", "01 January 2023");
|
||||||
|
|
||||||
@@ -753,12 +760,12 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
|
|
||||||
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
|
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "15", true));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "15", true));
|
||||||
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "1", "1", "0",
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "1", "0",
|
||||||
LoanProductTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
LoanProductTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
||||||
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "1", "1", "1", "0",
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "30", "30", "1", "0",
|
||||||
LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
||||||
"01 January 2023", "01 January 2023");
|
"01 January 2023", "01 January 2023");
|
||||||
|
|
||||||
@@ -890,12 +897,12 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "20", false));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "20", false));
|
||||||
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
|
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "15", true));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "15", true));
|
||||||
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "1", "1", "0",
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "1", "0",
|
||||||
LoanProductTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
LoanProductTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
||||||
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "1", "1", "1", "0",
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "30", "30", "1", "0",
|
||||||
LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
||||||
"01 January 2023", "01 January 2023");
|
"01 January 2023", "01 January 2023");
|
||||||
|
|
||||||
@@ -909,7 +916,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
loanStatusHashMap = loanTransactionHelper.disburseLoanWithTransactionAmount("01 January 2023", loanID, "1000");
|
loanStatusHashMap = loanTransactionHelper.disburseLoanWithTransactionAmount("01 January 2023", loanID, "1000");
|
||||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||||
|
|
||||||
final String requestJSON = new LoanRescheduleRequestTestBuilder().updateRescheduleFromDate("1 February 2023")
|
final String requestJSON = new LoanRescheduleRequestTestBuilder().updateRescheduleFromDate("31 January 2023")
|
||||||
.updateAdjustedDueDate("01 March 2023").updateSubmittedOnDate("25 January 2023").updateGraceOnPrincipal(null)
|
.updateAdjustedDueDate("01 March 2023").updateSubmittedOnDate("25 January 2023").updateGraceOnPrincipal(null)
|
||||||
.updateGraceOnInterest(null).updateExtraTerms(null).build(loanID.toString());
|
.updateGraceOnInterest(null).updateExtraTerms(null).build(loanID.toString());
|
||||||
final HashMap<String, String> map = new HashMap<>();
|
final HashMap<String, String> map = new HashMap<>();
|
||||||
@@ -1114,12 +1121,12 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "20", false));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "20", false));
|
||||||
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
|
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "15", true));
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "15", true));
|
||||||
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "1", "1", "0",
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "1", "0",
|
||||||
LoanProductTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
LoanProductTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
||||||
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "1", "1", "1", "0",
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "30", "30", "1", "0",
|
||||||
LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
||||||
"01 January 2023", "01 January 2023");
|
"01 January 2023", "01 January 2023");
|
||||||
|
|
||||||
@@ -1133,7 +1140,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
loanStatusHashMap = loanTransactionHelper.disburseLoanWithTransactionAmount("01 January 2023", loanID, "1000");
|
loanStatusHashMap = loanTransactionHelper.disburseLoanWithTransactionAmount("01 January 2023", loanID, "1000");
|
||||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||||
|
|
||||||
final String requestJSON = new LoanRescheduleRequestTestBuilder().updateRescheduleFromDate("1 February 2023")
|
final String requestJSON = new LoanRescheduleRequestTestBuilder().updateRescheduleFromDate("31 January 2023")
|
||||||
.updateAdjustedDueDate("01 March 2023").updateSubmittedOnDate("25 January 2023").updateGraceOnPrincipal(null)
|
.updateAdjustedDueDate("01 March 2023").updateSubmittedOnDate("25 January 2023").updateGraceOnPrincipal(null)
|
||||||
.updateGraceOnInterest(null).updateExtraTerms(null).build(loanID.toString());
|
.updateGraceOnInterest(null).updateExtraTerms(null).build(loanID.toString());
|
||||||
final HashMap<String, String> map = new HashMap<>();
|
final HashMap<String, String> map = new HashMap<>();
|
||||||
@@ -1397,13 +1404,401 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scenario10:
|
||||||
|
// DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY
|
||||||
|
// 1. Disburse the loan
|
||||||
|
// 2. Snooze fee
|
||||||
|
// 3. Merchant issued refund (partial)
|
||||||
|
// 4. Charge adjustment (same day)
|
||||||
|
// 5. Merchant issued refund (rest)
|
||||||
|
@Test
|
||||||
|
public void scenario10() {
|
||||||
|
try {
|
||||||
|
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
||||||
|
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
|
||||||
|
.date("2023.05.14").dateFormat("yyyy.MM.dd").locale("en"));
|
||||||
|
GlobalConfigurationHelper.updateChargeAccrualDateConfiguration(requestSpec, responseSpec, "submitted-date");
|
||||||
|
|
||||||
|
final Account assetAccount = this.accountHelper.createAssetAccount();
|
||||||
|
final Account incomeAccount = this.accountHelper.createIncomeAccount();
|
||||||
|
final Account expenseAccount = this.accountHelper.createExpenseAccount();
|
||||||
|
final Account overpaymentAccount = this.accountHelper.createLiabilityAccount();
|
||||||
|
|
||||||
|
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "3.65", false));
|
||||||
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "1", "0",
|
||||||
|
LoanProductTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
||||||
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "30", "30", "1", "0",
|
||||||
|
LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY,
|
||||||
|
"14 May 2023", "14 May 2023");
|
||||||
|
|
||||||
|
HashMap<String, Object> loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||||
|
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||||
|
|
||||||
|
loanStatusHashMap = loanTransactionHelper.approveLoan("14 May 2023", loanID);
|
||||||
|
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||||
|
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||||
|
|
||||||
|
loanStatusHashMap = loanTransactionHelper.disburseLoanWithTransactionAmount("14 May 2023", loanID, "127.95");
|
||||||
|
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||||
|
|
||||||
|
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
|
||||||
|
.date("2023.06.11").dateFormat("yyyy.MM.dd").locale("en"));
|
||||||
|
|
||||||
|
final String requestJSON = new LoanRescheduleRequestTestBuilder().updateRescheduleFromDate("13 June 2023")
|
||||||
|
.updateAdjustedDueDate("13 July 2023").updateSubmittedOnDate("11 June 2023").updateGraceOnPrincipal(null)
|
||||||
|
.updateGraceOnInterest(null).updateExtraTerms(null).build(loanID.toString());
|
||||||
|
|
||||||
|
final HashMap<String, String> map = new HashMap<>();
|
||||||
|
map.put("locale", "en");
|
||||||
|
map.put("dateFormat", "dd MMMM yyyy");
|
||||||
|
map.put("approvedOnDate", "11 June 2023");
|
||||||
|
final String aproveRequestJSON = new Gson().toJson(map);
|
||||||
|
|
||||||
|
Integer loanRescheduleRequestId = this.loanRescheduleRequestHelper.createLoanRescheduleRequest(requestJSON);
|
||||||
|
this.loanRescheduleRequestHelper.approveLoanRescheduleRequest(loanRescheduleRequestId, aproveRequestJSON);
|
||||||
|
Integer penalty1LoanChargeId = loanTransactionHelper.addChargesForLoan(loanID,
|
||||||
|
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee), "13 July 2023", "3.65"));
|
||||||
|
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
|
||||||
|
.date("2023.06.12").dateFormat("yyyy.MM.dd").locale("en"));
|
||||||
|
inlineLoanCOBHelper.executeInlineCOB(List.of(loanID.longValue()));
|
||||||
|
|
||||||
|
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails((long) loanID);
|
||||||
|
assertEquals(131.6, loanDetails.getSummary().getTotalOutstanding());
|
||||||
|
assertEquals(131.6, loanDetails.getRepaymentSchedule().getTotalOutstanding());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesPaid());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesOutstanding());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesOutstanding());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalPaid());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding());
|
||||||
|
assertTrue(loanDetails.getStatus().getActive());
|
||||||
|
|
||||||
|
assertNull(loanDetails.getTransactions().get(0).getReversedOnDate());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(0).getTransactionRelations().isEmpty());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(0).getType().getDisbursement());
|
||||||
|
assertEquals(127.95, loanDetails.getTransactions().get(0).getAmount());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(0).getPrincipalPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(0).getPenaltyChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(0).getOverpaymentPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(0).getInterestPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(0).getFeeChargesPortion());
|
||||||
|
assertEquals(127.95, loanDetails.getTransactions().get(0).getOutstandingLoanBalance());
|
||||||
|
|
||||||
|
assertNull(loanDetails.getTransactions().get(1).getReversedOnDate());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(1).getTransactionRelations().isEmpty());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(1).getType().getAccrual());
|
||||||
|
assertEquals(3.65, loanDetails.getTransactions().get(1).getAmount());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(1).getPrincipalPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(1).getPenaltyChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(1).getOverpaymentPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(1).getInterestPortion());
|
||||||
|
assertEquals(3.65, loanDetails.getTransactions().get(1).getFeeChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(1).getOutstandingLoanBalance());
|
||||||
|
|
||||||
|
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
|
||||||
|
.date("2023.06.17").dateFormat("yyyy.MM.dd").locale("en"));
|
||||||
|
PostLoansLoanIdTransactionsResponse merchantIssuedRefund1 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID),
|
||||||
|
new PostLoansLoanIdTransactionsRequest().locale("en").dateFormat("dd MMMM yyyy").transactionDate("17 June 2023")
|
||||||
|
.transactionAmount(125.0));
|
||||||
|
|
||||||
|
loanDetails = loanTransactionHelper.getLoanDetails((long) loanID);
|
||||||
|
assertEquals(6.6, loanDetails.getSummary().getTotalOutstanding());
|
||||||
|
assertEquals(6.6, loanDetails.getRepaymentSchedule().getTotalOutstanding());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesPaid());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesOutstanding());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesOutstanding());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalDue());
|
||||||
|
assertEquals(125.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalPaid());
|
||||||
|
assertEquals(2.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding());
|
||||||
|
assertTrue(loanDetails.getStatus().getActive());
|
||||||
|
|
||||||
|
assertNull(loanDetails.getTransactions().get(2).getReversedOnDate());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(2).getTransactionRelations().isEmpty());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(2).getType().getMerchantIssuedRefund());
|
||||||
|
assertEquals(125.0, loanDetails.getTransactions().get(2).getAmount());
|
||||||
|
assertEquals(125.0, loanDetails.getTransactions().get(2).getPrincipalPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(2).getPenaltyChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(2).getOverpaymentPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(2).getInterestPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(2).getFeeChargesPortion());
|
||||||
|
assertEquals(2.95, loanDetails.getTransactions().get(2).getOutstandingLoanBalance());
|
||||||
|
|
||||||
|
PostLoansLoanIdChargesChargeIdResponse chargeAdjustmentResponse = this.loanTransactionHelper.chargeAdjustment((long) loanID,
|
||||||
|
(long) penalty1LoanChargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(3.65));
|
||||||
|
|
||||||
|
loanDetails = loanTransactionHelper.getLoanDetails((long) loanID);
|
||||||
|
assertEquals(2.95, loanDetails.getSummary().getTotalOutstanding());
|
||||||
|
assertEquals(2.95, loanDetails.getRepaymentSchedule().getTotalOutstanding());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesDue());
|
||||||
|
assertEquals(0.70, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesPaid());
|
||||||
|
assertEquals(2.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesOutstanding());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesOutstanding());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalDue());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding());
|
||||||
|
assertTrue(loanDetails.getStatus().getActive());
|
||||||
|
|
||||||
|
assertNull(loanDetails.getTransactions().get(3).getReversedOnDate());
|
||||||
|
assertFalse(loanDetails.getTransactions().get(3).getTransactionRelations().isEmpty());
|
||||||
|
assertEquals((long) penalty1LoanChargeId,
|
||||||
|
loanDetails.getTransactions().get(3).getTransactionRelations().iterator().next().getToLoanCharge());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(3).getType().getChargeAdjustment());
|
||||||
|
assertEquals(3.65, loanDetails.getTransactions().get(3).getAmount());
|
||||||
|
assertEquals(2.95, loanDetails.getTransactions().get(3).getPrincipalPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(3).getPenaltyChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(3).getOverpaymentPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(3).getInterestPortion());
|
||||||
|
assertEquals(0.7, loanDetails.getTransactions().get(3).getFeeChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(3).getOutstandingLoanBalance());
|
||||||
|
|
||||||
|
PostLoansLoanIdTransactionsResponse merchantIssuedRefund2 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID),
|
||||||
|
new PostLoansLoanIdTransactionsRequest().locale("en").dateFormat("dd MMMM yyyy").transactionDate("17 June 2023")
|
||||||
|
.transactionAmount(2.95));
|
||||||
|
|
||||||
|
loanDetails = loanTransactionHelper.getLoanDetails((long) loanID);
|
||||||
|
assertEquals(0.0, loanDetails.getSummary().getTotalOutstanding());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getTotalOutstanding());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesDue());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesOutstanding());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesOutstanding());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalDue());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding());
|
||||||
|
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
|
||||||
|
|
||||||
|
assertNull(loanDetails.getTransactions().get(4).getReversedOnDate());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(4).getTransactionRelations().isEmpty());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(4).getType().getMerchantIssuedRefund());
|
||||||
|
assertEquals(2.95, loanDetails.getTransactions().get(4).getAmount());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(4).getPrincipalPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(4).getPenaltyChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(4).getOverpaymentPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(4).getInterestPortion());
|
||||||
|
assertEquals(2.95, loanDetails.getTransactions().get(4).getFeeChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(4).getOutstandingLoanBalance());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
|
||||||
|
GlobalConfigurationHelper.updateChargeAccrualDateConfiguration(requestSpec, responseSpec, "due-date");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scenario11:
|
||||||
|
// DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY
|
||||||
|
// 1. Disburse the loan
|
||||||
|
// 2. Snooze fee
|
||||||
|
// 3. Merchant issued refund (partial)
|
||||||
|
// 4. Charge adjustment (same day)
|
||||||
|
// 5. Merchant issued refund (rest)
|
||||||
|
@Test
|
||||||
|
public void scenario11() {
|
||||||
|
try {
|
||||||
|
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.TRUE);
|
||||||
|
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
|
||||||
|
.date("2023.05.14").dateFormat("yyyy.MM.dd").locale("en"));
|
||||||
|
GlobalConfigurationHelper.updateChargeAccrualDateConfiguration(requestSpec, responseSpec, "submitted-date");
|
||||||
|
|
||||||
|
final Account assetAccount = this.accountHelper.createAssetAccount();
|
||||||
|
final Account incomeAccount = this.accountHelper.createIncomeAccount();
|
||||||
|
final Account expenseAccount = this.accountHelper.createExpenseAccount();
|
||||||
|
final Account overpaymentAccount = this.accountHelper.createLiabilityAccount();
|
||||||
|
|
||||||
|
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
|
||||||
|
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "3.65", false));
|
||||||
|
final Integer loanProductID = createLoanProductWithNoAccountingNoInterest("1000", "30", "1", "0",
|
||||||
|
LoanProductTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
|
assetAccount, incomeAccount, expenseAccount, overpaymentAccount);
|
||||||
|
final Integer clientID = ClientHelper.createClient(requestSpec, responseSpec, "01 January 2023");
|
||||||
|
|
||||||
|
final Integer loanID = applyForLoanApplication(clientID, loanProductID, "1000", "30", "30", "1", "0",
|
||||||
|
LoanApplicationTestBuilder.DUE_PENALTY_FEE_INTEREST_PRINCIPAL_IN_ADVANCE_PRINCIPAL_PENALTY_FEE_INTEREST_STRATEGY,
|
||||||
|
"14 May 2023", "14 May 2023");
|
||||||
|
|
||||||
|
HashMap<String, Object> loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
|
||||||
|
LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
|
||||||
|
|
||||||
|
loanStatusHashMap = loanTransactionHelper.approveLoan("14 May 2023", loanID);
|
||||||
|
LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
|
||||||
|
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
|
||||||
|
|
||||||
|
loanStatusHashMap = loanTransactionHelper.disburseLoanWithTransactionAmount("14 May 2023", loanID, "127.95");
|
||||||
|
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||||
|
|
||||||
|
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
|
||||||
|
.date("2023.06.11").dateFormat("yyyy.MM.dd").locale("en"));
|
||||||
|
|
||||||
|
final String requestJSON = new LoanRescheduleRequestTestBuilder().updateRescheduleFromDate("13 June 2023")
|
||||||
|
.updateAdjustedDueDate("13 July 2023").updateSubmittedOnDate("11 June 2023").updateGraceOnPrincipal(null)
|
||||||
|
.updateGraceOnInterest(null).updateExtraTerms(null).build(loanID.toString());
|
||||||
|
|
||||||
|
final HashMap<String, String> map = new HashMap<>();
|
||||||
|
map.put("locale", "en");
|
||||||
|
map.put("dateFormat", "dd MMMM yyyy");
|
||||||
|
map.put("approvedOnDate", "11 June 2023");
|
||||||
|
final String aproveRequestJSON = new Gson().toJson(map);
|
||||||
|
|
||||||
|
Integer loanRescheduleRequestId = this.loanRescheduleRequestHelper.createLoanRescheduleRequest(requestJSON);
|
||||||
|
this.loanRescheduleRequestHelper.approveLoanRescheduleRequest(loanRescheduleRequestId, aproveRequestJSON);
|
||||||
|
Integer penalty1LoanChargeId = loanTransactionHelper.addChargesForLoan(loanID,
|
||||||
|
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee), "13 July 2023", "3.65"));
|
||||||
|
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
|
||||||
|
.date("2023.06.12").dateFormat("yyyy.MM.dd").locale("en"));
|
||||||
|
inlineLoanCOBHelper.executeInlineCOB(List.of(loanID.longValue()));
|
||||||
|
|
||||||
|
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails((long) loanID);
|
||||||
|
assertEquals(131.6, loanDetails.getSummary().getTotalOutstanding());
|
||||||
|
assertEquals(131.6, loanDetails.getRepaymentSchedule().getTotalOutstanding());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesPaid());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesOutstanding());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesOutstanding());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalPaid());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding());
|
||||||
|
assertTrue(loanDetails.getStatus().getActive());
|
||||||
|
|
||||||
|
assertNull(loanDetails.getTransactions().get(0).getReversedOnDate());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(0).getTransactionRelations().isEmpty());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(0).getType().getDisbursement());
|
||||||
|
assertEquals(127.95, loanDetails.getTransactions().get(0).getAmount());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(0).getPrincipalPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(0).getPenaltyChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(0).getOverpaymentPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(0).getInterestPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(0).getFeeChargesPortion());
|
||||||
|
assertEquals(127.95, loanDetails.getTransactions().get(0).getOutstandingLoanBalance());
|
||||||
|
|
||||||
|
assertNull(loanDetails.getTransactions().get(1).getReversedOnDate());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(1).getTransactionRelations().isEmpty());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(1).getType().getAccrual());
|
||||||
|
assertEquals(3.65, loanDetails.getTransactions().get(1).getAmount());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(1).getPrincipalPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(1).getPenaltyChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(1).getOverpaymentPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(1).getInterestPortion());
|
||||||
|
assertEquals(3.65, loanDetails.getTransactions().get(1).getFeeChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(1).getOutstandingLoanBalance());
|
||||||
|
|
||||||
|
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
|
||||||
|
.date("2023.06.17").dateFormat("yyyy.MM.dd").locale("en"));
|
||||||
|
|
||||||
|
PostLoansLoanIdTransactionsResponse merchantIssuedRefund1 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID),
|
||||||
|
new PostLoansLoanIdTransactionsRequest().locale("en").dateFormat("dd MMMM yyyy").transactionDate("17 June 2023")
|
||||||
|
.transactionAmount(125.0));
|
||||||
|
|
||||||
|
loanDetails = loanTransactionHelper.getLoanDetails((long) loanID);
|
||||||
|
assertEquals(6.6, loanDetails.getSummary().getTotalOutstanding());
|
||||||
|
assertEquals(6.6, loanDetails.getRepaymentSchedule().getTotalOutstanding());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesPaid());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesOutstanding());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesOutstanding());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalDue());
|
||||||
|
assertEquals(125.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalPaid());
|
||||||
|
assertEquals(2.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding());
|
||||||
|
assertTrue(loanDetails.getStatus().getActive());
|
||||||
|
|
||||||
|
assertNull(loanDetails.getTransactions().get(2).getReversedOnDate());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(2).getTransactionRelations().isEmpty());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(2).getType().getMerchantIssuedRefund());
|
||||||
|
assertEquals(125.0, loanDetails.getTransactions().get(2).getAmount());
|
||||||
|
assertEquals(125.0, loanDetails.getTransactions().get(2).getPrincipalPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(2).getPenaltyChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(2).getOverpaymentPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(2).getInterestPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(2).getFeeChargesPortion());
|
||||||
|
assertEquals(2.95, loanDetails.getTransactions().get(2).getOutstandingLoanBalance());
|
||||||
|
|
||||||
|
PostLoansLoanIdChargesChargeIdResponse chargeAdjustmentResponse = this.loanTransactionHelper.chargeAdjustment((long) loanID,
|
||||||
|
(long) penalty1LoanChargeId, new PostLoansLoanIdChargesChargeIdRequest().amount(3.65));
|
||||||
|
|
||||||
|
loanDetails = loanTransactionHelper.getLoanDetails((long) loanID);
|
||||||
|
assertEquals(2.95, loanDetails.getSummary().getTotalOutstanding());
|
||||||
|
assertEquals(2.95, loanDetails.getRepaymentSchedule().getTotalOutstanding());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesDue());
|
||||||
|
assertEquals(0.70, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesPaid());
|
||||||
|
assertEquals(2.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesOutstanding());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesOutstanding());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalDue());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding());
|
||||||
|
assertTrue(loanDetails.getStatus().getActive());
|
||||||
|
|
||||||
|
assertNull(loanDetails.getTransactions().get(3).getReversedOnDate());
|
||||||
|
assertFalse(loanDetails.getTransactions().get(3).getTransactionRelations().isEmpty());
|
||||||
|
assertEquals((long) penalty1LoanChargeId,
|
||||||
|
loanDetails.getTransactions().get(3).getTransactionRelations().iterator().next().getToLoanCharge());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(3).getType().getChargeAdjustment());
|
||||||
|
assertEquals(3.65, loanDetails.getTransactions().get(3).getAmount());
|
||||||
|
assertEquals(2.95, loanDetails.getTransactions().get(3).getPrincipalPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(3).getPenaltyChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(3).getOverpaymentPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(3).getInterestPortion());
|
||||||
|
assertEquals(0.7, loanDetails.getTransactions().get(3).getFeeChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(3).getOutstandingLoanBalance());
|
||||||
|
|
||||||
|
PostLoansLoanIdTransactionsResponse merchantIssuedRefund2 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID),
|
||||||
|
new PostLoansLoanIdTransactionsRequest().locale("en").dateFormat("dd MMMM yyyy").transactionDate("17 June 2023")
|
||||||
|
.transactionAmount(2.95));
|
||||||
|
|
||||||
|
loanDetails = loanTransactionHelper.getLoanDetails((long) loanID);
|
||||||
|
assertEquals(0.0, loanDetails.getSummary().getTotalOutstanding());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getTotalOutstanding());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesDue());
|
||||||
|
assertEquals(3.65, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getFeeChargesOutstanding());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesDue());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPenaltyChargesOutstanding());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalDue());
|
||||||
|
assertEquals(127.95, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalPaid());
|
||||||
|
assertEquals(0.0, loanDetails.getRepaymentSchedule().getPeriods().get(1).getPrincipalOutstanding());
|
||||||
|
assertTrue(loanDetails.getStatus().getClosedObligationsMet());
|
||||||
|
|
||||||
|
assertNull(loanDetails.getTransactions().get(4).getReversedOnDate());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(4).getTransactionRelations().isEmpty());
|
||||||
|
assertTrue(loanDetails.getTransactions().get(4).getType().getMerchantIssuedRefund());
|
||||||
|
assertEquals(2.95, loanDetails.getTransactions().get(4).getAmount());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(4).getPrincipalPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(4).getPenaltyChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(4).getOverpaymentPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(4).getInterestPortion());
|
||||||
|
assertEquals(2.95, loanDetails.getTransactions().get(4).getFeeChargesPortion());
|
||||||
|
assertEquals(0.0, loanDetails.getTransactions().get(4).getOutstandingLoanBalance());
|
||||||
|
} finally {
|
||||||
|
GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE);
|
||||||
|
GlobalConfigurationHelper.updateChargeAccrualDateConfiguration(requestSpec, responseSpec, "due-date");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID, final String principal,
|
private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID, final String principal,
|
||||||
final String loanTermFrequency, final String repaymentAfterEvery, final String numberOfRepayments, final String interestRate,
|
final String loanTermFrequency, final String repaymentAfterEvery, final String numberOfRepayments, final String interestRate,
|
||||||
final String repaymentStrategy, final String expectedDisbursementDate, final String submittedOnDate) {
|
final String repaymentStrategy, final String expectedDisbursementDate, final String submittedOnDate) {
|
||||||
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
|
LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------");
|
||||||
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(principal)
|
final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal(principal)
|
||||||
.withLoanTermFrequency(loanTermFrequency).withLoanTermFrequencyAsMonths().withNumberOfRepayments(numberOfRepayments)
|
.withLoanTermFrequency(loanTermFrequency).withLoanTermFrequencyAsDays().withNumberOfRepayments(numberOfRepayments)
|
||||||
.withRepaymentEveryAfter(repaymentAfterEvery).withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod(interestRate)
|
.withRepaymentEveryAfter(repaymentAfterEvery).withRepaymentFrequencyTypeAsDays().withInterestRatePerPeriod(interestRate)
|
||||||
.withInterestTypeAsFlatBalance().withAmortizationTypeAsEqualPrincipalPayments().withRepaymentStrategy(repaymentStrategy)
|
.withInterestTypeAsFlatBalance().withAmortizationTypeAsEqualPrincipalPayments().withRepaymentStrategy(repaymentStrategy)
|
||||||
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod().withExpectedDisbursementDate(expectedDisbursementDate)
|
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod().withExpectedDisbursementDate(expectedDisbursementDate)
|
||||||
.withSubmittedOnDate(submittedOnDate).withLoanType("individual").build(clientID.toString(), loanProductID.toString(), null);
|
.withSubmittedOnDate(submittedOnDate).withLoanType("individual").build(clientID.toString(), loanProductID.toString(), null);
|
||||||
@@ -1413,8 +1808,8 @@ public class DueDateRespectiveLoanRepaymentScheduleTest {
|
|||||||
private Integer createLoanProductWithNoAccountingNoInterest(final String principal, final String repaymentAfterEvery,
|
private Integer createLoanProductWithNoAccountingNoInterest(final String principal, final String repaymentAfterEvery,
|
||||||
final String numberOfRepayments, final String interestRate, final String repaymentStrategy, final Account... accounts) {
|
final String numberOfRepayments, final String interestRate, final String repaymentStrategy, final Account... accounts) {
|
||||||
LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
|
LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------");
|
||||||
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(principal).withRepaymentTypeAsMonth()
|
final String loanProductJSON = new LoanProductTestBuilder().withPrincipal(principal).withRepaymentTypeAsDays()
|
||||||
.withRepaymentAfterEvery(repaymentAfterEvery).withNumberOfRepayments(numberOfRepayments).withRepaymentTypeAsMonth()
|
.withRepaymentAfterEvery(repaymentAfterEvery).withNumberOfRepayments(numberOfRepayments)
|
||||||
.withinterestRatePerPeriod(interestRate).withInterestRateFrequencyTypeAsMonths().withRepaymentStrategy(repaymentStrategy)
|
.withinterestRatePerPeriod(interestRate).withInterestRateFrequencyTypeAsMonths().withRepaymentStrategy(repaymentStrategy)
|
||||||
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRulePeriodicAccrual(accounts)
|
.withAmortizationTypeAsEqualPrincipalPayment().withInterestTypeAsFlat().withAccountingRulePeriodicAccrual(accounts)
|
||||||
.withDaysInMonth("30").withDaysInYear("365").withMoratorium("0", "0").build(null);
|
.withDaysInMonth("30").withDaysInYear("365").withMoratorium("0", "0").build(null);
|
||||||
|
|||||||
Reference in New Issue
Block a user