Skip to content

Commit

Permalink
FINERACT-1981: Introduce Interest should not be calculated on past du…
Browse files Browse the repository at this point in the history
…e principal amount
  • Loading branch information
janez89 committed Nov 27, 2024
1 parent 2e89c40 commit 4012a13
Show file tree
Hide file tree
Showing 16 changed files with 200 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@
"null",
"boolean"
]
},
{
"default": null,
"name": "disallowInterestCalculationOnPastDue",
"type": [
"null",
"boolean"
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@
"null",
"boolean"
]
},
{
"default": null,
"name": "disallowInterestCalculationOnPastDue",
"type": [
"null",
"boolean"
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class LoanInterestRecalculationData {
private Boolean isCompoundingToBePostedAsTransaction;
private CalendarData compoundingCalendarData;
private Boolean allowCompoundingOnEod;
private Boolean disallowInterestCalculationOnPastDue;

public LoanInterestRecalculationData(final Long id, final Long loanId, final EnumOptionData interestRecalculationCompoundingType,
final EnumOptionData rescheduleStrategyType, final CalendarData calendarData,
Expand All @@ -56,7 +57,7 @@ public LoanInterestRecalculationData(final Long id, final Long loanId, final Enu
final EnumOptionData recalculationCompoundingFrequencyType, final Integer recalculationCompoundingFrequencyInterval,
final EnumOptionData recalculationCompoundingFrequencyNthDay, final EnumOptionData recalculationCompoundingFrequencyWeekday,
final Integer recalculationCompoundingFrequencyOnDay, final Boolean isCompoundingToBePostedAsTransaction,
final Boolean allowCompoundingOnEod) {
final Boolean allowCompoundingOnEod, final Boolean disallowInterestCalculationOnPastDue) {
this.id = id;
this.loanId = loanId;
this.interestRecalculationCompoundingType = interestRecalculationCompoundingType;
Expand All @@ -75,6 +76,7 @@ public LoanInterestRecalculationData(final Long id, final Long loanId, final Enu
this.compoundingCalendarData = compoundingCalendarData;
this.isCompoundingToBePostedAsTransaction = isCompoundingToBePostedAsTransaction;
this.allowCompoundingOnEod = allowCompoundingOnEod;
this.disallowInterestCalculationOnPastDue = disallowInterestCalculationOnPastDue;
}

public LoanInterestRecalculationData withCalendarData(final CalendarData calendarData, CalendarData compoundingCalendarData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ public class LoanInterestRecalculationDetails extends AbstractPersistableCustom<
@Column(name = "allow_compounding_on_eod")
private Boolean allowCompoundingOnEod;

@Column(name = "disallow_interest_calc_on_past_due")
private Boolean disallowInterestCalculationOnPastDue;

protected LoanInterestRecalculationDetails() {
// Default constructor for jpa repository
}
Expand All @@ -96,7 +99,7 @@ private LoanInterestRecalculationDetails(final Integer interestRecalculationComp
final Integer restFrequencyType, final Integer restInterval, final Integer restFrequencyNthDay, Integer restFrequencyWeekday,
Integer restFrequencyOnDay, Integer compoundingFrequencyType, Integer compoundingInterval, Integer compoundingFrequencyNthDay,
Integer compoundingFrequencyWeekday, Integer compoundingFrequencyOnDay, final boolean isCompoundingToBePostedAsTransaction,
final boolean allowCompoundingOnEod) {
final boolean allowCompoundingOnEod, final boolean disallowInterestCalculationOnPastDue) {
this.interestRecalculationCompoundingMethod = interestRecalculationCompoundingMethod;
this.rescheduleStrategyMethod = rescheduleStrategyMethod;
this.restFrequencyNthDay = restFrequencyNthDay;
Expand All @@ -111,6 +114,7 @@ private LoanInterestRecalculationDetails(final Integer interestRecalculationComp
this.compoundingInterval = compoundingInterval;
this.isCompoundingToBePostedAsTransaction = isCompoundingToBePostedAsTransaction;
this.allowCompoundingOnEod = allowCompoundingOnEod;
this.disallowInterestCalculationOnPastDue = disallowInterestCalculationOnPastDue;
}

public static LoanInterestRecalculationDetails createFrom(
Expand All @@ -127,7 +131,8 @@ public static LoanInterestRecalculationDetails createFrom(
loanProductInterestRecalculationDetails.getCompoundingFrequencyWeekday(),
loanProductInterestRecalculationDetails.getCompoundingFrequencyOnDay(),
loanProductInterestRecalculationDetails.getIsCompoundingToBePostedAsTransaction(),
loanProductInterestRecalculationDetails.allowCompoundingOnEod());
loanProductInterestRecalculationDetails.allowCompoundingOnEod(),
loanProductInterestRecalculationDetails.disallowInterestCalculationOnPastDue());
}

public void updateLoan(final Loan loan) {
Expand Down Expand Up @@ -189,4 +194,8 @@ public boolean isCompoundingToBePostedAsTransaction() {
public boolean allowCompoundingOnEod() {
return this.allowCompoundingOnEod;
}

public Boolean disallowInterestCalculationOnPastDue() {
return disallowInterestCalculationOnPastDue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public interface LoanProductConstants {
String recalculationCompoundingFrequencyNthDayParamName = "recalculationCompoundingFrequencyNthDayType";
String recalculationCompoundingFrequencyOnDayParamName = "recalculationCompoundingFrequencyOnDayType";
String isCompoundingToBePostedAsTransactionParamName = "isCompoundingToBePostedAsTransaction";
String disallowInterestCalculationOnPastDueParamName = "disallowInterestCalculationOnPastDue";

// Guarantee related
String holdGuaranteeFundsParamName = "holdGuaranteeFunds";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ private PostLoanProductsRequest() {}
public Boolean isCompoundingToBePostedAsTransaction;
@Schema(example = "false")
public Boolean allowCompoundingOnEod;
@Schema(example = "false")
public Boolean disallowInterestCalculationOnPastDue;

// Accounting
@Schema(example = "3")
Expand Down Expand Up @@ -518,6 +520,8 @@ private GetLoanProductsPreClosureInterestCalculationStrategy() {}
public GetLoanProductsPreClosureInterestCalculationStrategy preClosureInterestCalculationStrategy;
@Schema(example = "true")
public Boolean isArrearsBasedOnOriginalSchedule;
@Schema(example = "false")
public Boolean disallowInterestCalculationOnPastDue;
@Schema(example = "true")
public Boolean isCompoundingToBePostedAsTransaction;
@Schema(example = "true")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1166,7 +1166,7 @@ calendarData, getRecalculationRestFrequencyType(), getRecalculationRestFrequency
getInterestRecalculationRestOnDayType(), compoundingCalendarData, getRecalculationCompoundingFrequencyType(),
getRecalculationCompoundingFrequencyInterval(), getInterestRecalculationCompoundingNthDayType(),
getInterestRecalculationCompoundingWeekDayType(), getInterestRecalculationCompoundingOnDayType(),
isCompoundingToBePostedAsTransaction(), allowCompoundingOnEod());
isCompoundingToBePostedAsTransaction(), allowCompoundingOnEod(), disallowInterestCalculationOnPastDue());
}

private EnumOptionData getRescheduleStrategyType() {
Expand Down Expand Up @@ -1263,6 +1263,11 @@ public Boolean allowCompoundingOnEod() {
return isInterestRecalculationEnabled() ? this.interestRecalculationData.isAllowCompoundingOnEod() : null;
}

@SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL")
public Boolean disallowInterestCalculationOnPastDue() {
return isInterestRecalculationEnabled() ? this.interestRecalculationData.disallowInterestCalculationOnPastDue() : null;
}

public void setLoanProductConfigurableAttributes(LoanProductConfigurableAttributes loanProductConfigurableAttributes) {
this.allowAttributeOverrides = loanProductConfigurableAttributes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class LoanProductInterestRecalculationData implements Serializable {
private final boolean isCompoundingToBePostedAsTransaction;
private final EnumOptionData preClosureInterestCalculationStrategy;
private final boolean allowCompoundingOnEod;
private final Boolean disallowInterestCalculationOnPastDue;

public LoanProductInterestRecalculationData(final Long id, final Long productId,
final EnumOptionData interestRecalculationCompoundingType, final EnumOptionData rescheduleStrategyType,
Expand All @@ -59,7 +60,8 @@ public LoanProductInterestRecalculationData(final Long id, final Long productId,
final Integer recalculationCompoundingFrequencyInterval, final EnumOptionData recalculationCompoundingFrequencyNthDay,
final EnumOptionData recalculationCompoundingFrequencyWeekday, final Integer recalculationCompoundingFrequencyOnDay,
final boolean isArrearsBasedOnOriginalSchedule, boolean isCompoundingToBePostedAsTransaction,
final EnumOptionData preCloseInterestCalculationStrategy, final boolean allowCompoundingOnEod) {
final EnumOptionData preCloseInterestCalculationStrategy, final boolean allowCompoundingOnEod,
final Boolean disallowInterestCalculationOnPastDue) {
this.id = id;
this.productId = productId;
this.interestRecalculationCompoundingType = interestRecalculationCompoundingType;
Expand All @@ -78,6 +80,7 @@ public LoanProductInterestRecalculationData(final Long id, final Long productId,
this.preClosureInterestCalculationStrategy = preCloseInterestCalculationStrategy;
this.isCompoundingToBePostedAsTransaction = isCompoundingToBePostedAsTransaction;
this.allowCompoundingOnEod = allowCompoundingOnEod;
this.disallowInterestCalculationOnPastDue = disallowInterestCalculationOnPastDue;
}

public static LoanProductInterestRecalculationData sensibleDefaultsForNewLoanProductCreation() {
Expand All @@ -101,12 +104,15 @@ public static LoanProductInterestRecalculationData sensibleDefaultsForNewLoanPro
final EnumOptionData preCloseInterestCalculationStrategy = preCloseInterestCalculationStrategy(
LoanPreClosureInterestCalculationStrategy.TILL_PRE_CLOSURE_DATE);
final boolean allowCompoundingOnEod = false;
final boolean disallowInterestCalculationOnPastDue = false;

return new LoanProductInterestRecalculationData(id, productId, interestRecalculationCompoundingType, rescheduleStrategyType,
recalculationRestFrequencyType, recalculationRestFrequencyInterval, recalculationRestFrequencyNthDay,
recalculationRestFrequencyWeekday, recalculationRestFrequencyOnDay, recalculationCompoundingFrequencyType,
recalculationCompoundingFrequencyInterval, recalculationCompoundingFrequencyNthDay,
recalculationCompoundingFrequencyWeekday, recalculationCompoundingFrequencyOnDay, isArrearsBasedOnOriginalSchedule,
isCompoundingToBePostedAsTransaction, preCloseInterestCalculationStrategy, allowCompoundingOnEod);
isCompoundingToBePostedAsTransaction, preCloseInterestCalculationStrategy, allowCompoundingOnEod,
disallowInterestCalculationOnPastDue);
}

public boolean isArrearsBasedOnOriginalSchedule() {
Expand All @@ -124,4 +130,8 @@ public boolean isIsArrearsBasedOnOriginalSchedule() {
public boolean isIsCompoundingToBePostedAsTransaction() {
return isCompoundingToBePostedAsTransaction;
}

public Boolean disallowInterestCalculationOnPastDue() {
return disallowInterestCalculationOnPastDue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public class LoanProductInterestRecalculationDetails extends AbstractPersistable
@Column(name = "allow_compounding_on_eod")
private Boolean allowCompoundingOnEod;

@Column(name = "disallow_interest_calc_on_past_due")
private Boolean disallowInterestCalculationOnPastDue;

protected LoanProductInterestRecalculationDetails() {
//
}
Expand Down Expand Up @@ -162,11 +165,14 @@ public static LoanProductInterestRecalculationDetails createFrom(final JsonComma
final boolean isCompoundingToBePostedAsTransaction = command
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.isCompoundingToBePostedAsTransactionParamName);

final boolean disallowInterestCalculationOnPastDue = command
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.disallowInterestCalculationOnPastDueParamName);

return new LoanProductInterestRecalculationDetails(interestRecalculationCompoundingMethod, loanRescheduleStrategyMethod,
recurrenceFrequency, recurrenceInterval, recurrenceOnNthDay, recurrenceOnDay, recurrenceOnWeekday,
compoundingRecurrenceFrequency, compoundingInterval, compoundingRecurrenceOnNthDay, compoundingRecurrenceOnDay,
compoundingRecurrenceOnWeekday, isArrearsBasedOnOriginalSchedule, preCloseInterestCalculationStrategy,
isCompoundingToBePostedAsTransaction, allowCompoundingOnEod);
isCompoundingToBePostedAsTransaction, allowCompoundingOnEod, disallowInterestCalculationOnPastDue);
}

private LoanProductInterestRecalculationDetails(final Integer interestRecalculationCompoundingMethod,
Expand All @@ -175,7 +181,8 @@ private LoanProductInterestRecalculationDetails(final Integer interestRecalculat
Integer compoundingFrequencyType, Integer compoundingInterval, final Integer compoundingFrequencyNthDay,
final Integer compoundingFrequencyOnDay, final Integer compoundingFrequencyWeekday,
final boolean isArrearsBasedOnOriginalSchedule, final Integer preCloseInterestCalculationStrategy,
final boolean isCompoundingToBePostedAsTransaction, final boolean allowCompoundingOnEod) {
final boolean isCompoundingToBePostedAsTransaction, final boolean allowCompoundingOnEod,
final boolean disallowInterestCalculationOnPastDue) {
this.interestRecalculationCompoundingMethod = interestRecalculationCompoundingMethod;
this.rescheduleStrategyMethod = rescheduleStrategyMethod;
this.restFrequencyType = restFrequencyType;
Expand All @@ -192,6 +199,7 @@ private LoanProductInterestRecalculationDetails(final Integer interestRecalculat
this.preClosureInterestCalculationStrategy = preCloseInterestCalculationStrategy;
this.isCompoundingToBePostedAsTransaction = isCompoundingToBePostedAsTransaction;
this.allowCompoundingOnEod = allowCompoundingOnEod;
this.disallowInterestCalculationOnPastDue = disallowInterestCalculationOnPastDue;
}

public void updateProduct(final LoanProduct loanProduct) {
Expand Down Expand Up @@ -406,6 +414,13 @@ public void update(final JsonCommand command, final Map<String, Object> actualCh
this.isCompoundingToBePostedAsTransaction = newValue;
}

if (command.isChangeInBooleanParameterNamed(LoanProductConstants.disallowInterestCalculationOnPastDueParamName,
this.disallowInterestCalculationOnPastDue)) {
final boolean newValue = command
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.disallowInterestCalculationOnPastDueParamName);
actualChanges.put(LoanProductConstants.disallowInterestCalculationOnPastDueParamName, newValue);
this.disallowInterestCalculationOnPastDue = newValue;
}
}

public RecalculationFrequencyType getRestFrequencyType() {
Expand Down Expand Up @@ -463,4 +478,8 @@ public Boolean getIsCompoundingToBePostedAsTransaction() {
public Boolean allowCompoundingOnEod() {
return this.allowCompoundingOnEod;
}

public Boolean disallowInterestCalculationOnPastDue() {
return disallowInterestCalculationOnPastDue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,10 @@ private void recalculateInterestForDate(LocalDate currentDate, ProgressiveTransa

private void adjustOverduePrincipalForInstallment(LocalDate currentDate, LoanRepaymentScheduleInstallment currentInstallment,
Money overduePrincipal, Money aggregatedOverDuePrincipal, ProgressiveTransactionCtx ctx) {
if (currentInstallment.getLoan().getLoanInterestRecalculationDetails().disallowInterestCalculationOnPastDue()) {
return;
}

LocalDate fromDate = currentInstallment.getFromDate();
LocalDate toDate = currentInstallment.getDueDate();
boolean hasUpdate = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ public String loanSchema() {
+ " lir.compounding_frequency_on_day as compoundingFrequencyOnDay, "
+ " lir.is_compounding_to_be_posted_as_transaction as isCompoundingToBePostedAsTransaction, "
+ " lir.allow_compounding_on_eod as allowCompoundingOnEod, "
+ " lir.disallow_interest_calc_on_past_due as disallowInterestCalculationOnPastDue, "
+ " l.is_floating_interest_rate as isFloatingInterestRate, "
+ " l.interest_rate_differential as interestRateDifferential, "
+ " l.create_standing_instruction_at_disbursement as createStandingInstructionAtDisbursement, "
Expand Down Expand Up @@ -1037,11 +1038,12 @@ public LoanAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") fi

final Boolean isCompoundingToBePostedAsTransaction = rs.getBoolean("isCompoundingToBePostedAsTransaction");
final Boolean allowCompoundingOnEod = rs.getBoolean("allowCompoundingOnEod");
final Boolean disallowInterestCalculationOnPastDue = rs.getBoolean("disallowInterestCalculationOnPastDue");
interestRecalculationData = new LoanInterestRecalculationData(lprId, productId, interestRecalculationCompoundingType,
rescheduleStrategyType, calendarData, restFrequencyType, restFrequencyInterval, restFrequencyNthDayEnum,
restFrequencyWeekDayEnum, restFrequencyOnDay, compoundingCalendarData, compoundingFrequencyType,
compoundingInterval, compoundingFrequencyNthDayEnum, compoundingFrequencyWeekDayEnum, compoundingFrequencyOnDay,
isCompoundingToBePostedAsTransaction, allowCompoundingOnEod);
isCompoundingToBePostedAsTransaction, allowCompoundingOnEod, disallowInterestCalculationOnPastDue);
}

final boolean canUseForTopup = rs.getBoolean("canUseForTopup");
Expand Down
Loading

0 comments on commit 4012a13

Please sign in to comment.