Changing all proportional charges to be expressed in percentage points rather than as a fraction.
diff --git a/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java b/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
index 9488c60..1ea1bdf 100644
--- a/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
+++ b/service/src/main/java/io/mifos/individuallending/IndividualLendingPatternFactory.java
@@ -112,7 +112,7 @@
final ChargeDefinition processingFee = charge(
PROCESSING_FEE_NAME,
Action.OPEN,
- BigDecimal.valueOf(0.01),
+ BigDecimal.ONE,
ENTRY,
PROCESSING_FEE_INCOME);
processingFee.setReadOnly(false);
@@ -120,7 +120,7 @@
final ChargeDefinition loanOriginationFee = charge(
LOAN_ORIGINATION_FEE_NAME,
Action.APPROVE,
- BigDecimal.valueOf(0.01),
+ BigDecimal.ONE,
ENTRY,
ORIGINATION_FEE_INCOME);
loanOriginationFee.setReadOnly(false);
@@ -128,7 +128,7 @@
final ChargeDefinition loanFundsAllocation = charge(
LOAN_FUNDS_ALLOCATION_ID,
Action.APPROVE,
- BigDecimal.valueOf(1.00),
+ BigDecimal.valueOf(100),
LOAN_FUNDS_SOURCE,
PENDING_DISBURSAL);
loanFundsAllocation.setReadOnly(true);
@@ -136,7 +136,7 @@
final ChargeDefinition disbursementFee = charge(
DISBURSEMENT_FEE_NAME,
Action.DISBURSE,
- BigDecimal.valueOf(0.001),
+ BigDecimal.valueOf(0.1),
ENTRY,
DISBURSEMENT_FEE_INCOME);
disbursementFee.setReadOnly(false);
@@ -150,7 +150,7 @@
disbursePayment.setToAccountDesignator(ENTRY);
disbursePayment.setProportionalTo(ChargeProportionalDesignator.PRINCIPAL_ADJUSTMENT_DESIGNATOR.getValue());
disbursePayment.setChargeMethod(ChargeDefinition.ChargeMethod.PROPORTIONAL);
- disbursePayment.setAmount(BigDecimal.ONE);
+ disbursePayment.setAmount(BigDecimal.valueOf(100));
disbursePayment.setReadOnly(true);
final ChargeDefinition trackPrincipalDisbursePayment = new ChargeDefinition();
@@ -162,14 +162,14 @@
trackPrincipalDisbursePayment.setToAccountDesignator(CUSTOMER_LOAN);
trackPrincipalDisbursePayment.setProportionalTo(ChargeProportionalDesignator.PRINCIPAL_ADJUSTMENT_DESIGNATOR.getValue());
trackPrincipalDisbursePayment.setChargeMethod(ChargeDefinition.ChargeMethod.PROPORTIONAL);
- trackPrincipalDisbursePayment.setAmount(BigDecimal.ONE);
+ trackPrincipalDisbursePayment.setAmount(BigDecimal.valueOf(100));
trackPrincipalDisbursePayment.setReadOnly(true);
//TODO: Make payable at time of ACCEPT_PAYMENT but accrued at MARK_LATE
final ChargeDefinition lateFee = charge(
LATE_FEE_NAME,
Action.MARK_LATE,
- BigDecimal.valueOf(0.01),
+ BigDecimal.ONE,
CUSTOMER_LOAN,
LATE_FEE_INCOME);
lateFee.setAccrueAction(Action.MARK_LATE.name());
@@ -181,7 +181,7 @@
final ChargeDefinition writeOffAllowanceCharge = charge(
ALLOW_FOR_WRITE_OFF_NAME,
Action.MARK_LATE,
- BigDecimal.valueOf(0.30),
+ BigDecimal.valueOf(30),
PENDING_DISBURSAL,
ARREARS_ALLOWANCE);
writeOffAllowanceCharge.setProportionalTo(ChargeProportionalDesignator.RUNNING_BALANCE_DESIGNATOR.getValue());
@@ -190,7 +190,7 @@
final ChargeDefinition interestCharge = charge(
INTEREST_NAME,
Action.ACCEPT_PAYMENT,
- BigDecimal.ONE,
+ BigDecimal.valueOf(100),
CUSTOMER_LOAN,
INTEREST_INCOME);
interestCharge.setForCycleSizeUnit(ChronoUnit.YEARS);
@@ -209,7 +209,7 @@
customerRepaymentCharge.setToAccountDesignator(ENTRY);
customerRepaymentCharge.setProportionalTo(ChargeProportionalDesignator.REPAYMENT_DESIGNATOR.getValue());
customerRepaymentCharge.setChargeMethod(ChargeDefinition.ChargeMethod.PROPORTIONAL);
- customerRepaymentCharge.setAmount(BigDecimal.ONE);
+ customerRepaymentCharge.setAmount(BigDecimal.valueOf(100));
customerRepaymentCharge.setReadOnly(true);
final ChargeDefinition trackReturnPrincipalCharge = new ChargeDefinition();
@@ -221,15 +221,15 @@
trackReturnPrincipalCharge.setToAccountDesignator(LOANS_PAYABLE);
trackReturnPrincipalCharge.setProportionalTo(ChargeProportionalDesignator.PRINCIPAL_ADJUSTMENT_DESIGNATOR.getValue());
trackReturnPrincipalCharge.setChargeMethod(ChargeDefinition.ChargeMethod.PROPORTIONAL);
- trackReturnPrincipalCharge.setAmount(BigDecimal.ONE);
+ trackReturnPrincipalCharge.setAmount(BigDecimal.valueOf(100));
trackReturnPrincipalCharge.setReadOnly(true);
final ChargeDefinition disbursementReturnCharge = charge(
- RETURN_DISBURSEMENT_NAME,
- Action.CLOSE,
- BigDecimal.valueOf(1.0),
- PENDING_DISBURSAL,
- LOAN_FUNDS_SOURCE);
+ RETURN_DISBURSEMENT_NAME,
+ Action.CLOSE,
+ BigDecimal.valueOf(100),
+ PENDING_DISBURSAL,
+ LOAN_FUNDS_SOURCE);
disbursementReturnCharge.setProportionalTo(ChargeProportionalDesignator.RUNNING_BALANCE_DESIGNATOR.getValue());
disbursementReturnCharge.setReadOnly(true);
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java b/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java
index 67725d2..318db3b 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/CostComponentService.java
@@ -102,7 +102,7 @@
caseParameters.getMaximumBalance(),
BigDecimal.ZERO,
BigDecimal.ZERO,
- dataContextOfAction.getInterestAsFraction(),
+ dataContextOfAction.getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -121,7 +121,7 @@
caseParameters.getMaximumBalance(),
BigDecimal.ZERO,
BigDecimal.ZERO,
- dataContextOfAction.getInterestAsFraction(),
+ dataContextOfAction.getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -141,7 +141,7 @@
caseParameters.getMaximumBalance(),
BigDecimal.ZERO,
BigDecimal.ZERO,
- dataContextOfAction.getInterestAsFraction(),
+ dataContextOfAction.getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -198,7 +198,7 @@
caseParameters.getMaximumBalance(),
currentBalance,
disbursalSize,
- dataContextOfAction.getInterestAsFraction(),
+ dataContextOfAction.getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -238,7 +238,7 @@
caseParameters.getMaximumBalance(),
currentBalance,
BigDecimal.ZERO,
- dataContextOfAction.getInterestAsFraction(),
+ dataContextOfAction.getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -276,7 +276,7 @@
hypotheticalScheduledActions);
loanPaymentSize = getLoanPaymentSize(
currentBalance,
- dataContextOfAction.getInterestAsFraction(),
+ dataContextOfAction.getInterest(),
minorCurrencyUnitDigits,
hypotheticalScheduledCharges);
}
@@ -302,7 +302,7 @@
caseParameters.getMaximumBalance(),
currentBalance,
loanPaymentSize,
- dataContextOfAction.getInterestAsFraction(),
+ dataContextOfAction.getInterest(),
minorCurrencyUnitDigits,
true);
}
@@ -386,7 +386,7 @@
caseParameters.getMaximumBalance(),
currentBalance,
BigDecimal.ZERO,
- dataContextOfAction.getInterestAsFraction(),
+ dataContextOfAction.getInterest(),
minorCurrencyUnitDigits,
true);
}
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/DataContextOfAction.java b/service/src/main/java/io/mifos/individuallending/internal/service/DataContextOfAction.java
index af636fc..4cb7b5d 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/DataContextOfAction.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/DataContextOfAction.java
@@ -35,7 +35,6 @@
private final CaseEntity customerCase;
private final CaseParameters caseParameters;
private final List<AccountAssignment> oneTimeAccountAssignments;
- private final BigDecimal interestAsFraction;
DataContextOfAction(final @Nonnull ProductEntity product,
final @Nonnull CaseEntity customerCase,
@@ -45,7 +44,6 @@
this.customerCase = customerCase;
this.caseParameters = caseParameters;
this.oneTimeAccountAssignments = oneTimeAccountAssignments == null ? Collections.emptyList() : oneTimeAccountAssignments;
- interestAsFraction = customerCase.getInterest().divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_EVEN);;
}
public @Nonnull ProductEntity getProduct() {
@@ -72,7 +70,7 @@
return getCompoundIdentifer() + "." + action.name();
}
- BigDecimal getInterestAsFraction() {
- return interestAsFraction;
+ BigDecimal getInterest() {
+ return customerCase.getInterest();
}
}
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java b/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java
index 0f77033..6320deb 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/IndividualLoanService.java
@@ -57,7 +57,7 @@
final BigDecimal loanPaymentSize = CostComponentService.getLoanPaymentSize(
dataContextOfAction.getCaseParameters().getMaximumBalance(),
- dataContextOfAction.getInterestAsFraction(),
+ dataContextOfAction.getInterest(),
minorCurrencyUnitDigits,
scheduledCharges);
@@ -66,7 +66,7 @@
minorCurrencyUnitDigits,
scheduledCharges,
loanPaymentSize,
- dataContextOfAction.getInterestAsFraction());
+ dataContextOfAction.getInterest());
final Set<ChargeName> chargeNames = scheduledCharges.stream()
.map(IndividualLoanService::chargeNameFromChargeDefinition)
diff --git a/service/src/main/java/io/mifos/individuallending/internal/service/PeriodChargeCalculator.java b/service/src/main/java/io/mifos/individuallending/internal/service/PeriodChargeCalculator.java
index 39bb325..91281cc 100644
--- a/service/src/main/java/io/mifos/individuallending/internal/service/PeriodChargeCalculator.java
+++ b/service/src/main/java/io/mifos/individuallending/internal/service/PeriodChargeCalculator.java
@@ -58,12 +58,17 @@
scheduledCharge.getChargeDefinition().getChargeMethod() == ChargeDefinition.ChargeMethod.INTEREST;
}
- static BigDecimal chargeAmountPerPeriod(final ScheduledCharge scheduledCharge, final BigDecimal amount, final int precision)
+ static BigDecimal chargeAmountPerPeriod(
+ final ScheduledCharge scheduledCharge,
+ final BigDecimal amountInPercentagePoints,
+ final int precision)
{
+ final BigDecimal amountAsFraction = amountInPercentagePoints.divide(BigDecimal.valueOf(100), 4, BigDecimal.ROUND_HALF_EVEN);
+
final ChargeDefinition chargeDefinition = scheduledCharge.getChargeDefinition();
final ScheduledAction scheduledAction = scheduledCharge.getScheduledAction();
if (chargeDefinition.getForCycleSizeUnit() == null)
- return amount;
+ return amountAsFraction;
final BigDecimal actionPeriodDuration
= BigDecimal.valueOf(
@@ -87,7 +92,7 @@
final int accrualPeriodsInActionPeriod = actionPeriodDuration.divide(
accrualPeriodDuration.orElse(actionPeriodDuration), precision, BigDecimal.ROUND_HALF_EVEN)
.intValueExact();
- final BigDecimal rateForAccrualPeriod = amount.divide(
+ final BigDecimal rateForAccrualPeriod = amountAsFraction.divide(
accrualPeriodsInCycle, precision, BigDecimal.ROUND_HALF_EVEN);
return createCompoundedRate(rateForAccrualPeriod, accrualPeriodsInActionPeriod, precision);
}
@@ -96,4 +101,4 @@
{
return Stream.generate(() -> interestRate).limit(periodCount).collect(RateCollectors.compound(precision));
}
-}
+}
\ No newline at end of file
diff --git a/service/src/test/java/io/mifos/individuallending/internal/service/PeriodChargeCalculatorTest.java b/service/src/test/java/io/mifos/individuallending/internal/service/PeriodChargeCalculatorTest.java
index 0961727..71e7b42 100644
--- a/service/src/test/java/io/mifos/individuallending/internal/service/PeriodChargeCalculatorTest.java
+++ b/service/src/test/java/io/mifos/individuallending/internal/service/PeriodChargeCalculatorTest.java
@@ -96,7 +96,7 @@
expectedPeriodRates.put(getPeriod(initialDate, 1, 1), dailyInterestRate);
return new TestCase("simpleCase")
- .interest(BigDecimal.valueOf(0.01))
+ .interest(BigDecimal.ONE)
.scheduledCharges(scheduledCharges)
.precision(20)
.expectedPeriodRates(expectedPeriodRates);
@@ -117,7 +117,7 @@
expectedPeriodRates.put(getPeriod(initialDate, 2, 2), PeriodChargeCalculator.createCompoundedRate(dailyInterestRate, 2, 20));
return new TestCase("bitOfCompoundingCase")
- .interest(BigDecimal.valueOf(0.10))
+ .interest(BigDecimal.TEN)
.scheduledCharges(scheduledCharges)
.precision(20)
.expectedPeriodRates(expectedPeriodRates);
@@ -135,7 +135,7 @@
expectedPeriodRates.put(getPeriod(initialDate, 2, 2), BigDecimal.ZERO.setScale(20, BigDecimal.ROUND_UNNECESSARY));
return new TestCase("zeroInterestPerPeriod")
- .interest(BigDecimal.valueOf(0.00))
+ .interest(BigDecimal.ZERO)
.scheduledCharges(scheduledCharges)
.precision(20)
.expectedPeriodRates(expectedPeriodRates);