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:
   It is still incorrect! Like i said earlier, 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]

Reply via email to