FINERACT-2174: Allow for recognition of Interest on first day end of day - Introducing the flag
This commit is contained in:
committed by
Adam Saghy
parent
7d0474cc17
commit
3a5888ee4b
+1
-1
@@ -244,7 +244,7 @@ public class LoansApiResource {
|
||||
LoanApiConstants.isTopup, LoanApiConstants.loanIdToClose, LoanApiConstants.topupAmount,
|
||||
LoanApiConstants.clientActiveLoanOptions, LoanApiConstants.datatables, LoanProductConstants.RATES_PARAM_NAME,
|
||||
LoanApiConstants.MULTIDISBURSE_DETAILS_PARAMNAME, LoanApiConstants.EMI_AMOUNT_VARIATIONS_PARAMNAME,
|
||||
LoanApiConstants.COLLECTION_PARAMNAME));
|
||||
LoanApiConstants.COLLECTION_PARAMNAME, LoanApiConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE));
|
||||
|
||||
private static final Set<String> LOAN_APPROVAL_DATA_PARAMETERS = new HashSet<>(Arrays.asList("approvalDate", "approvalAmount"));
|
||||
private static final Set<String> GLIM_ACCOUNTS_DATA_PARAMETERS = new HashSet<>(Arrays.asList("glimId", "groupId", "clientId",
|
||||
|
||||
+6
@@ -1204,6 +1204,8 @@ final class LoansApiResourceSwagger {
|
||||
@Schema(description = "List of GetLoansLoanIdLoanTermVariations")
|
||||
public List<GetLoansLoanIdLoanTermVariations> loanTermVariations;
|
||||
public StringEnumOptionData chargeOffBehaviour;
|
||||
@Schema(example = "false")
|
||||
public Boolean interestRecognitionOnDisbursementDate;
|
||||
}
|
||||
|
||||
@Schema(description = "GetLoansResponse")
|
||||
@@ -1303,6 +1305,8 @@ final class LoansApiResourceSwagger {
|
||||
public Boolean enableAutoRepaymentForDownPayment;
|
||||
@Schema(example = "10.00")
|
||||
public BigDecimal fixedEmiAmount;
|
||||
@Schema(example = "false")
|
||||
public Boolean interestRecognitionOnDisbursementDate;
|
||||
|
||||
public List<PostLoansRequestChargeData> charges;
|
||||
|
||||
@@ -1473,6 +1477,8 @@ final class LoansApiResourceSwagger {
|
||||
public BigDecimal disbursedAmountPercentageForDownPayment;
|
||||
@Schema(example = "false")
|
||||
public Boolean enableAutoRepaymentForDownPayment;
|
||||
@Schema(example = "false")
|
||||
public Boolean interestRecognitionOnDisbursementDate;
|
||||
|
||||
static final class PutLoansLoanIdChanges {
|
||||
|
||||
|
||||
+7
-3
@@ -266,6 +266,7 @@ public class LoanAccountData {
|
||||
private Boolean enableDownPayment;
|
||||
private BigDecimal disbursedAmountPercentageForDownPayment;
|
||||
private Boolean enableAutoRepaymentForDownPayment;
|
||||
private Boolean interestRecognitionOnDisbursementDate;
|
||||
|
||||
private EnumOptionData loanScheduleType;
|
||||
private EnumOptionData loanScheduleProcessingType;
|
||||
@@ -419,7 +420,8 @@ public class LoanAccountData {
|
||||
.setIsEqualAmortization(product.isEqualAmortization())
|
||||
.setFixedPrincipalPercentagePerInstallment(product.getFixedPrincipalPercentagePerInstallment())
|
||||
.setDelinquent(CollectionData.template()).setDisallowExpectedDisbursements(product.getDisallowExpectedDisbursements())
|
||||
.setLoanScheduleType(product.getLoanScheduleType()).setLoanScheduleProcessingType(product.getLoanScheduleProcessingType());
|
||||
.setLoanScheduleType(product.getLoanScheduleType()).setLoanScheduleProcessingType(product.getLoanScheduleProcessingType())
|
||||
.setInterestRecognitionOnDisbursementDate(product.isInterestRecognitionOnDisbursementDate());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -456,7 +458,8 @@ public class LoanAccountData {
|
||||
LocalDate lastClosedBusinessDate, LocalDate overpaidOnDate, final boolean chargedOff, final boolean enableDownPayment,
|
||||
final BigDecimal disbursedAmountPercentageForDownPayment, final boolean enableAutoRepaymentForDownPayment,
|
||||
final boolean enableInstallmentLevelDelinquency, final EnumOptionData loanScheduleType,
|
||||
final EnumOptionData loanScheduleProcessingType, final Integer fixedLength, final StringEnumOptionData chargeOffBehaviour) {
|
||||
final EnumOptionData loanScheduleProcessingType, final Integer fixedLength, final StringEnumOptionData chargeOffBehaviour,
|
||||
final boolean isInterestRecognitionOnDisbursementDate) {
|
||||
|
||||
final CollectionData delinquent = CollectionData.template();
|
||||
|
||||
@@ -501,7 +504,8 @@ public class LoanAccountData {
|
||||
.setEnableAutoRepaymentForDownPayment(enableAutoRepaymentForDownPayment)
|
||||
.setEnableInstallmentLevelDelinquency(enableInstallmentLevelDelinquency).setLoanScheduleType(loanScheduleType)
|
||||
.setLoanScheduleProcessingType(loanScheduleProcessingType).setFixedLength(fixedLength)
|
||||
.setChargeOffBehaviour(chargeOffBehaviour);
|
||||
.setChargeOffBehaviour(chargeOffBehaviour)
|
||||
.setInterestRecognitionOnDisbursementDate(isInterestRecognitionOnDisbursementDate);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+15
-1
@@ -518,6 +518,12 @@ public class LoanScheduleAssembler {
|
||||
fixedLength = this.fromApiJsonHelper.extractIntegerWithLocaleNamed(LoanProductConstants.FIXED_LENGTH, element);
|
||||
}
|
||||
|
||||
Boolean interestRecognitionOnDisbursementDate = loanProduct.getLoanProductRelatedDetail().isInterestRecognitionOnDisbursementDate();
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanApiConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE, element)) {
|
||||
interestRecognitionOnDisbursementDate = this.fromApiJsonHelper
|
||||
.extractBooleanNamed(LoanApiConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE, element);
|
||||
}
|
||||
|
||||
return LoanApplicationTerms.assembleFrom(applicationCurrency.toData(), loanTermFrequency, loanTermPeriodFrequencyType,
|
||||
numberOfRepayments, repaymentEvery, repaymentPeriodFrequencyType, nthDay, weekDayType, amortizationMethod, interestMethod,
|
||||
interestRatePerPeriod, interestRatePeriodFrequencyType, annualNominalInterestRate, interestCalculationPeriodMethod,
|
||||
@@ -535,7 +541,7 @@ public class LoanScheduleAssembler {
|
||||
loanScheduleType, loanScheduleProcessingType, fixedLength,
|
||||
loanProduct.getLoanProductRelatedDetail().isEnableAccrualActivityPosting(),
|
||||
loanProduct.getLoanProductRelatedDetail().getSupportedInterestRefundTypes(),
|
||||
loanProduct.getLoanProductRelatedDetail().getChargeOffBehaviour());
|
||||
loanProduct.getLoanProductRelatedDetail().getChargeOffBehaviour(), interestRecognitionOnDisbursementDate);
|
||||
}
|
||||
|
||||
private CalendarInstance createCalendarForSameAsRepayment(final Integer repaymentEvery,
|
||||
@@ -1452,6 +1458,14 @@ public class LoanScheduleAssembler {
|
||||
}
|
||||
loanProductRelatedDetail.setDisbursedAmountPercentageForDownPayment(disbursedAmountPercentageDownPayment);
|
||||
}
|
||||
|
||||
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE,
|
||||
loanProductRelatedDetail.isInterestRecognitionOnDisbursementDate())) {
|
||||
final boolean newValue = command
|
||||
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE);
|
||||
changes.put(LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE, newValue);
|
||||
loanProductRelatedDetail.updateInterestRecognitionOnDisbursementDate(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
public Pair<Loan, Map<String, Object>> assembleLoanApproval(AppUser currentUser, JsonCommand command, Long loanId) {
|
||||
|
||||
+18
-1
@@ -169,7 +169,8 @@ public final class LoanApplicationValidator {
|
||||
LoanApiConstants.DISALLOW_EXPECTED_DISBURSEMENTS, LoanApiConstants.FRAUD_ATTRIBUTE_NAME,
|
||||
LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE, LoanProductConstants.FIXED_LENGTH,
|
||||
LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, LoanProductConstants.ENABLE_DOWN_PAYMENT,
|
||||
LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT, LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT));
|
||||
LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT, LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT,
|
||||
LoanApiConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE));
|
||||
public static final String LOANAPPLICATION_UNDO = "loanapplication.undo";
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
@@ -760,6 +761,14 @@ public final class LoanApplicationValidator {
|
||||
validateTransactionProcessingStrategy(transactionProcessingStrategy, loanProduct);
|
||||
|
||||
fixedLengthValidations(element);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanApiConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE, element)) {
|
||||
if (!LoanScheduleType.PROGRESSIVE.equals(loanProduct.getLoanProductRelatedDetail().getLoanScheduleType())) {
|
||||
List<String> unsupportedParameterList = new ArrayList<>();
|
||||
unsupportedParameterList.add(LoanApiConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE);
|
||||
throw new UnsupportedParameterException(unsupportedParameterList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fixedLengthValidations(final JsonElement element) {
|
||||
@@ -1442,6 +1451,14 @@ public final class LoanApplicationValidator {
|
||||
|
||||
loanProductDataValidator.validateRepaymentPeriodWithGraceSettings(numberOfRepayments, graceOnPrincipalPayment,
|
||||
graceOnInterestPayment, graceOnInterestCharged, recurringMoratoriumOnPrincipalPeriods, baseDataValidator);
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(LoanApiConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE, element)) {
|
||||
if (!LoanScheduleType.PROGRESSIVE.equals(loanProduct.getLoanProductRelatedDetail().getLoanScheduleType())) {
|
||||
List<String> unsupportedParameterList = new ArrayList<>();
|
||||
unsupportedParameterList.add(LoanApiConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE);
|
||||
throw new UnsupportedParameterException(unsupportedParameterList);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ public final class LoanScheduleValidator {
|
||||
LoanApiConstants.daysInYearTypeParameterName, LoanApiConstants.fixedPrincipalPercentagePerInstallmentParamName,
|
||||
LoanProductConstants.FIXED_LENGTH, LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY,
|
||||
LoanProductConstants.ENABLE_DOWN_PAYMENT, LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT,
|
||||
LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT));
|
||||
LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT, LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE));
|
||||
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
|
||||
|
||||
+4
-2
@@ -702,7 +702,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
+ " topup.topup_amount as topupAmount, l.last_closed_business_date as lastClosedBusinessDate,l.overpaidon_date as overpaidOnDate, "
|
||||
+ " l.is_charged_off as isChargedOff, l.charge_off_reason_cv_id as chargeOffReasonId, codec.code_value as chargeOffReason, l.charged_off_on_date as chargedOffOnDate, l.enable_down_payment as enableDownPayment, l.disbursed_amount_percentage_for_down_payment as disbursedAmountPercentageForDownPayment, l.enable_auto_repayment_for_down_payment as enableAutoRepaymentForDownPayment,"
|
||||
+ " cobu.username as chargedOffByUsername, cobu.firstname as chargedOffByFirstname, cobu.lastname as chargedOffByLastname, l.loan_schedule_type as loanScheduleType, l.loan_schedule_processing_type as loanScheduleProcessingType, "
|
||||
+ " l.charge_off_behaviour as chargeOffBehaviour " //
|
||||
+ " l.charge_off_behaviour as chargeOffBehaviour, l.interest_recognition_on_disbursement_date as interestRecognitionOnDisbursementDate " //
|
||||
+ " from m_loan l" //
|
||||
+ " join m_product_loan lp on lp.id = l.product_id" //
|
||||
+ " left join m_loan_recalculation_details lir on lir.loan_id = l.id join m_currency rc on rc."
|
||||
@@ -1068,6 +1068,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
final LoanScheduleProcessingType loanScheduleProcessingType = LoanScheduleProcessingType.valueOf(loanScheduleProcessingTypeStr);
|
||||
final Integer fixedLength = JdbcSupport.getInteger(rs, "fixedLength");
|
||||
final LoanChargeOffBehaviour chargeOffBehaviour = LoanChargeOffBehaviour.valueOf(rs.getString("chargeOffBehaviour"));
|
||||
final boolean interestRecognitionOnDisbursementDate = rs.getBoolean("interestRecognitionOnDisbursementDate");
|
||||
|
||||
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
|
||||
clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||
@@ -1086,7 +1087,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
fixedPrincipalPercentagePerInstallment, delinquencyRange, disallowExpectedDisbursements, isFraud,
|
||||
lastClosedBusinessDate, overpaidOnDate, isChargedOff, enableDownPayment, disbursedAmountPercentageForDownPayment,
|
||||
enableAutoRepaymentForDownPayment, enableInstallmentLevelDelinquency, loanScheduleType.asEnumOptionData(),
|
||||
loanScheduleProcessingType.asEnumOptionData(), fixedLength, chargeOffBehaviour.getValueAsStringEnumOptionData());
|
||||
loanScheduleProcessingType.asEnumOptionData(), fixedLength, chargeOffBehaviour.getValueAsStringEnumOptionData(),
|
||||
interestRecognitionOnDisbursementDate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -185,7 +185,7 @@ public final class LoanProductDataValidator {
|
||||
LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, LoanProductConstants.LOAN_SCHEDULE_TYPE,
|
||||
LoanProductConstants.LOAN_SCHEDULE_PROCESSING_TYPE, LoanProductConstants.FIXED_LENGTH,
|
||||
LoanProductConstants.ENABLE_ACCRUAL_ACTIVITY_POSTING, LoanProductConstants.SUPPORTED_INTEREST_REFUND_TYPES,
|
||||
LoanProductConstants.CHARGE_OFF_BEHAVIOUR));
|
||||
LoanProductConstants.CHARGE_OFF_BEHAVIOUR, LoanProductConstants.INTEREST_RECOGNITION_ON_DISBURSEMENT_DATE));
|
||||
|
||||
private static final String[] SUPPORTED_LOAN_CONFIGURABLE_ATTRIBUTES = { LoanProductConstants.amortizationTypeParamName,
|
||||
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyCodeParamName,
|
||||
|
||||
+3
-2
@@ -265,7 +265,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
+ "lpr.is_compounding_to_be_posted_as_transaction as isCompoundingToBePostedAsTransaction, "
|
||||
+ "lpr.allow_compounding_on_eod as allowCompoundingOnEod, "
|
||||
+ "lpr.disallow_interest_calc_on_past_due as disallowInterestCalculationOnPastDue, "
|
||||
+ "lp.hold_guarantee_funds as holdGuaranteeFunds, "
|
||||
+ "lp.hold_guarantee_funds as holdGuaranteeFunds, lp.interest_recognition_on_disbursement_date as interestRecognitionOnDisbursementDate, "
|
||||
+ "lp.principal_threshold_for_last_installment as principalThresholdForLastInstallment, "
|
||||
+ "lp.fixed_principal_percentage_per_installment fixedPrincipalPercentagePerInstallment, "
|
||||
+ "lp.sync_expected_with_disbursement_date as syncExpectedWithDisbursementDate, "
|
||||
@@ -547,6 +547,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
}
|
||||
final String chargeOffBehaviourStr = rs.getString("chargeOffBehaviour");
|
||||
final LoanChargeOffBehaviour loanChargeOffBehaviour = LoanChargeOffBehaviour.valueOf(chargeOffBehaviourStr);
|
||||
final boolean interestRecognitionOnDisbursementDate = rs.getBoolean("interestRecognitionOnDisbursementDate");
|
||||
|
||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||
@@ -570,7 +571,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
enableAutoRepaymentForDownPayment, advancedPaymentData, creditAllocationData, repaymentStartDateType,
|
||||
enableInstallmentLevelDelinquency, loanScheduleType.asEnumOptionData(), loanScheduleProcessingType.asEnumOptionData(),
|
||||
fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes,
|
||||
loanChargeOffBehaviour.getValueAsStringEnumOptionData());
|
||||
loanChargeOffBehaviour.getValueAsStringEnumOptionData(), interestRecognitionOnDisbursementDate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -98,7 +98,7 @@ public class DefaultScheduledDateGeneratorTest {
|
||||
Money.of(fromApplicationCurrency(dollarCurrency), ZERO), false, null, EMPTY_LIST, BigDecimal.valueOf(36_000L), null,
|
||||
DaysInMonthType.ACTUAL, DaysInYearType.ACTUAL, false, null, null, null, null, null, ZERO, null, NONE, null, ZERO,
|
||||
EMPTY_LIST, true, 0, false, holidayDetailDTO, false, false, false, null, false, false, null, false, DISBURSEMENT_DATE,
|
||||
submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null, null);
|
||||
submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null, null, false);
|
||||
|
||||
// when
|
||||
List<? extends LoanScheduleModelPeriod> result = underTest.generateRepaymentPeriods(mathContext, expectedDisbursementDate,
|
||||
@@ -169,8 +169,8 @@ public class DefaultScheduledDateGeneratorTest {
|
||||
dueRepaymentPeriodDate, null, null, null, null, null, Money.of(fromApplicationCurrency(dollarCurrency), ZERO), false, null,
|
||||
EMPTY_LIST, BigDecimal.valueOf(36_000L), null, DaysInMonthType.ACTUAL, DaysInYearType.ACTUAL, false, null, null, null, null,
|
||||
null, ZERO, null, NONE, null, ZERO, EMPTY_LIST, true, 0, false, holidayDetailDTO, false, false, false, null, false, false,
|
||||
null, false, DISBURSEMENT_DATE, submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null,
|
||||
null);
|
||||
null, false, DISBURSEMENT_DATE, submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null, null,
|
||||
false);
|
||||
}
|
||||
|
||||
private HolidayDetailDTO createHolidayDTO() {
|
||||
|
||||
Reference in New Issue
Block a user