adamsaghy commented on code in PR #4000:
URL: https://github.com/apache/fineract/pull/4000#discussion_r1700006731
##########
fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanSummaryData.java:
##########
@@ -236,44 +225,37 @@ public static LoanSummaryData
withOnlyCurrencyData(CurrencyData currencyData) {
return LoanSummaryData.builder().currency(currencyData).build();
}
- private static BigDecimal
computeTotalAccruedDueInterestAmount(Collection<LoanSchedulePeriodData>
periods) {
- final LocalDate businessDate = DateUtils.getBusinessLocalDate();
- return periods.stream().filter(period ->
!period.getDownPaymentPeriod() && businessDate.isAfter(period.getDueDate()))
- .map(period ->
period.getTotalAccruedInterest()).reduce(BigDecimal.ZERO, BigDecimal::add);
+ private static BigDecimal
computeTotalUnpaidPayableDueInterestAmount(Collection<LoanSchedulePeriodData>
periods,
+ final LocalDate businessDate) {
+ return periods.stream().filter(period ->
!period.getDownPaymentPeriod() && businessDate.compareTo(period.getDueDate())
>= 0)
+ .map(period ->
period.getInterestOutstanding()).reduce(BigDecimal.ZERO, BigDecimal::add);
}
- private static BigDecimal
computeTotalInterestPaidDueAmount(Collection<LoanSchedulePeriodData> periods) {
- final LocalDate businessDate = DateUtils.getBusinessLocalDate();
- return periods.stream().filter(period ->
!period.getDownPaymentPeriod() && businessDate.isAfter(period.getDueDate()))
- .map(period ->
period.getInterestPaid()).reduce(BigDecimal.ZERO, BigDecimal::add);
- }
+ private static BigDecimal
computeTotalUnpaidPayableNotDueInterestAmountOnActualPeriod(final
Collection<LoanSchedulePeriodData> periods,
+ final LocalDate businessDate, final CurrencyData currency) {
+ // Default value equal to Zero
+ BigDecimal totalAccruedNotDueInterestAmount = BigDecimal.ZERO;
+ // Find the current Period (If exists one) based on the Business date
+ final Optional<LoanSchedulePeriodData> optCurrentPeriod =
periods.stream()
+ .filter(period -> !period.getDownPaymentPeriod() &&
period.isActualPeriod(businessDate)).findFirst();
- private static BigDecimal
computeTotalAccruedNotDueInterestAmountOnActualPeriod(Collection<LoanSchedulePeriodData>
periods) {
- final LocalDate businessDate = DateUtils.getBusinessLocalDate();
- return periods.stream()
- .filter(period -> !period.getDownPaymentPeriod() &&
isActualPeriod(period) && businessDate.isBefore(period.getDueDate()))
- .map(period ->
period.getTotalAccruedInterest()).reduce(BigDecimal.ZERO, BigDecimal::add);
- }
+ if (optCurrentPeriod.isPresent()) {
+ final LoanSchedulePeriodData currentPeriod =
optCurrentPeriod.get();
+ final long daysPassed =
DateUtils.getDifferenceInDays(currentPeriod.getFromDate(), businessDate);
- private static BigDecimal
computeTotalInterestPaidNotDueAmountOnActualPeriod(Collection<LoanSchedulePeriodData>
periods) {
- final LocalDate businessDate = DateUtils.getBusinessLocalDate();
- return periods.stream()
- .filter(period -> !period.getDownPaymentPeriod() &&
isActualPeriod(period) && businessDate.isBefore(period.getDueDate()))
- .map(period ->
period.getInterestPaid()).reduce(BigDecimal.ZERO, BigDecimal::add);
- }
+ if (daysPassed == 1) { // First day
+ totalAccruedNotDueInterestAmount =
currentPeriod.getRatePerDay();
- private static boolean isActualPeriod(LoanSchedulePeriodData period) {
- final LocalDate businessDate = DateUtils.getBusinessLocalDate();
- boolean actualPeriod = false;
- if (period.getPeriod() != null) {
- if (period.getPeriod() == 1) {
- actualPeriod = ((businessDate.isEqual(period.getFromDate()) ||
businessDate.isAfter(period.getFromDate()))
- && businessDate.isBefore(period.getDueDate()));
- } else {
- actualPeriod = (businessDate.isAfter(period.getFromDate()) &&
businessDate.isBefore(period.getDueDate()));
+ } else if (daysPassed >= 2) { // Rest of the days
Review Comment:
you cannot calculate it by multiplying with the number of days the rate per
day....
Rate per day is not correct. Due to rounding, the daily interest amount can
be vary. You need to calculate it recursively for each day till hit the actual
current date:
calculate the daily interest rate for 1st day -> total interest charged
divided by number of remaining days in period (period is 1 month length and its
August, then 31) -> round it accordingly the rounding mode and use the number
of digits after decimal from currency
calculate the daily interest rate for 2nd day -> (total interest charged -
calculated, rounded daily interest rate for 1st day ) divided by number of
remaining days in period (30) -> round it accordingly the rounding mode and use
the number of digits after decimal from currency
and so on till last day
Example:
Interest charged for period 32
Number of days for period 31
1st day interest: 1.03 after rounding and the next 14 day interest is 1.03,
but on the 16th day, it will be 1.04 hence the accumulating rounding remainders.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]