FINERACT-2330: Buy-Down fees Accounting for non merchant product
This commit is contained in:
committed by
Arnold Gálovics
parent
125c8b4db2
commit
6bbc4bd3f3
+2
-1
@@ -30,7 +30,8 @@ public interface ProductToGLAccountMappingWritePlatformService {
|
|||||||
void createSavingProductToGLAccountMapping(Long savingProductId, JsonCommand command, DepositAccountType accountType);
|
void createSavingProductToGLAccountMapping(Long savingProductId, JsonCommand command, DepositAccountType accountType);
|
||||||
|
|
||||||
Map<String, Object> updateLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command, boolean accountingRuleChanged,
|
Map<String, Object> updateLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command, boolean accountingRuleChanged,
|
||||||
AccountingRuleType accountingRuleTypeId, boolean enableIncomeCapitalization, boolean enableBuyDownFee);
|
AccountingRuleType accountingRuleTypeId, boolean enableIncomeCapitalization, boolean enableBuyDownFee,
|
||||||
|
boolean merchantBuyDownFee);
|
||||||
|
|
||||||
Map<String, Object> updateSavingsProductToGLAccountMapping(Long savingsProductId, JsonCommand command, boolean accountingRuleChanged,
|
Map<String, Object> updateSavingsProductToGLAccountMapping(Long savingsProductId, JsonCommand command, boolean accountingRuleChanged,
|
||||||
int accountingRuleTypeId, DepositAccountType accountType);
|
int accountingRuleTypeId, DepositAccountType accountType);
|
||||||
|
|||||||
+1
@@ -1751,6 +1751,7 @@ public class LoanProductsRequestFactory {
|
|||||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)//
|
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)//
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.INTEREST)//
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.INTEREST)//
|
||||||
.enableBuyDownFee(true)//
|
.enableBuyDownFee(true)//
|
||||||
|
.merchantBuyDownFee(true)//
|
||||||
.buyDownExpenseAccountId(accountTypeResolver.resolve(DefaultAccountType.BUY_DOWN_EXPENSE))//
|
.buyDownExpenseAccountId(accountTypeResolver.resolve(DefaultAccountType.BUY_DOWN_EXPENSE))//
|
||||||
.incomeFromBuyDownAccountId(accountTypeResolver.resolve(DefaultAccountType.INCOME_FROM_BUY_DOWN));//
|
.incomeFromBuyDownAccountId(accountTypeResolver.resolve(DefaultAccountType.INCOME_FROM_BUY_DOWN));//
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -256,7 +256,7 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
|
|||||||
*/
|
*/
|
||||||
public void handleChangesToLoanProductToGLAccountMappings(final Long loanProductId, final Map<String, Object> changes,
|
public void handleChangesToLoanProductToGLAccountMappings(final Long loanProductId, final Map<String, Object> changes,
|
||||||
final JsonElement element, final AccountingRuleType accountingRuleType, final boolean enableIncomeCapitalization,
|
final JsonElement element, final AccountingRuleType accountingRuleType, final boolean enableIncomeCapitalization,
|
||||||
final boolean enableBuyDownFee) {
|
final boolean enableBuyDownFee, final boolean merchantBuyDownFee) {
|
||||||
switch (accountingRuleType) {
|
switch (accountingRuleType) {
|
||||||
case NONE:
|
case NONE:
|
||||||
break;
|
break;
|
||||||
@@ -399,9 +399,11 @@ public class LoanProductToGLAccountMappingHelper extends ProductToGLAccountMappi
|
|||||||
deleteProductToGLAccountMapping(loanProductId, PortfolioProductType.LOAN,
|
deleteProductToGLAccountMapping(loanProductId, PortfolioProductType.LOAN,
|
||||||
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue());
|
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue());
|
||||||
} else {
|
} else {
|
||||||
mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), loanProductId,
|
if (merchantBuyDownFee) {
|
||||||
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue(), AccrualAccountsForLoan.BUY_DOWN_EXPENSE.toString(),
|
mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(),
|
||||||
changes);
|
loanProductId, AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue(),
|
||||||
|
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.toString(), changes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// liabilities
|
// liabilities
|
||||||
|
|||||||
+1
@@ -46,5 +46,6 @@ public class AccountingBridgeDataDTO {
|
|||||||
private Long chargeOffReasonCodeValue;
|
private Long chargeOffReasonCodeValue;
|
||||||
private boolean isWrittenOff;
|
private boolean isWrittenOff;
|
||||||
private List<AccountingBridgeLoanTransactionDTO> newLoanTransactions = new ArrayList<>();
|
private List<AccountingBridgeLoanTransactionDTO> newLoanTransactions = new ArrayList<>();
|
||||||
|
private boolean merchantBuyDownFee;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -288,6 +288,7 @@ public class LoanAccountData {
|
|||||||
private StringEnumOptionData buyDownFeeCalculationType;
|
private StringEnumOptionData buyDownFeeCalculationType;
|
||||||
private StringEnumOptionData buyDownFeeStrategy;
|
private StringEnumOptionData buyDownFeeStrategy;
|
||||||
private StringEnumOptionData buyDownFeeIncomeType;
|
private StringEnumOptionData buyDownFeeIncomeType;
|
||||||
|
private Boolean merchantBuyDownFee;
|
||||||
|
|
||||||
public static LoanAccountData importInstanceIndividual(EnumOptionData loanTypeEnumOption, Long clientId, Long productId,
|
public static LoanAccountData importInstanceIndividual(EnumOptionData loanTypeEnumOption, Long clientId, Long productId,
|
||||||
Long loanOfficerId, LocalDate submittedOnDate, Long fundId, BigDecimal principal, Integer numberOfRepayments,
|
Long loanOfficerId, LocalDate submittedOnDate, Long fundId, BigDecimal principal, Integer numberOfRepayments,
|
||||||
@@ -483,7 +484,8 @@ public class LoanAccountData {
|
|||||||
final boolean enableIncomeCapitalization, final StringEnumOptionData capitalizedIncomeCalculationType,
|
final boolean enableIncomeCapitalization, final StringEnumOptionData capitalizedIncomeCalculationType,
|
||||||
final StringEnumOptionData capitalizedIncomeStrategy, StringEnumOptionData capitalizedIncomeType,
|
final StringEnumOptionData capitalizedIncomeStrategy, StringEnumOptionData capitalizedIncomeType,
|
||||||
final boolean enableBuyDownFee, final StringEnumOptionData buyDownFeeCalculationType,
|
final boolean enableBuyDownFee, final StringEnumOptionData buyDownFeeCalculationType,
|
||||||
final StringEnumOptionData buyDownFeeStrategy, final StringEnumOptionData buyDownFeeIncomeType) {
|
final StringEnumOptionData buyDownFeeStrategy, final StringEnumOptionData buyDownFeeIncomeType,
|
||||||
|
final boolean merchantBuyDownFee) {
|
||||||
|
|
||||||
final CollectionData delinquent = CollectionData.template();
|
final CollectionData delinquent = CollectionData.template();
|
||||||
|
|
||||||
@@ -533,7 +535,8 @@ public class LoanAccountData {
|
|||||||
.setCapitalizedIncomeCalculationType(capitalizedIncomeCalculationType)
|
.setCapitalizedIncomeCalculationType(capitalizedIncomeCalculationType)
|
||||||
.setCapitalizedIncomeStrategy(capitalizedIncomeStrategy).setCapitalizedIncomeType(capitalizedIncomeType)
|
.setCapitalizedIncomeStrategy(capitalizedIncomeStrategy).setCapitalizedIncomeType(capitalizedIncomeType)
|
||||||
.setEnableBuyDownFee(enableBuyDownFee).setBuyDownFeeCalculationType(buyDownFeeCalculationType)
|
.setEnableBuyDownFee(enableBuyDownFee).setBuyDownFeeCalculationType(buyDownFeeCalculationType)
|
||||||
.setBuyDownFeeStrategy(buyDownFeeStrategy).setBuyDownFeeIncomeType(buyDownFeeIncomeType);
|
.setBuyDownFeeStrategy(buyDownFeeStrategy).setBuyDownFeeIncomeType(buyDownFeeIncomeType)
|
||||||
|
.setMerchantBuyDownFee(merchantBuyDownFee);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+17
-5
@@ -246,6 +246,7 @@ public final class LoanApplicationTerms {
|
|||||||
private LoanBuyDownFeeCalculationType buyDownFeeCalculationType;
|
private LoanBuyDownFeeCalculationType buyDownFeeCalculationType;
|
||||||
private LoanBuyDownFeeStrategy buyDownFeeStrategy;
|
private LoanBuyDownFeeStrategy buyDownFeeStrategy;
|
||||||
private LoanBuyDownFeeIncomeType buyDownFeeIncomeType;
|
private LoanBuyDownFeeIncomeType buyDownFeeIncomeType;
|
||||||
|
private boolean merchantBuyDownFee;
|
||||||
|
|
||||||
private LoanApplicationTerms(Builder builder) {
|
private LoanApplicationTerms(Builder builder) {
|
||||||
this.currency = builder.currency;
|
this.currency = builder.currency;
|
||||||
@@ -290,6 +291,7 @@ public final class LoanApplicationTerms {
|
|||||||
this.buyDownFeeCalculationType = builder.buyDownFeeCalculationType;
|
this.buyDownFeeCalculationType = builder.buyDownFeeCalculationType;
|
||||||
this.buyDownFeeStrategy = builder.buyDownFeeStrategy;
|
this.buyDownFeeStrategy = builder.buyDownFeeStrategy;
|
||||||
this.buyDownFeeIncomeType = builder.buyDownFeeIncomeType;
|
this.buyDownFeeIncomeType = builder.buyDownFeeIncomeType;
|
||||||
|
this.merchantBuyDownFee = builder.merchantBuyDownFee;
|
||||||
this.interestMethod = builder.interestMethod;
|
this.interestMethod = builder.interestMethod;
|
||||||
this.allowPartialPeriodInterestCalcualtion = builder.allowPartialPeriodInterestCalculation;
|
this.allowPartialPeriodInterestCalcualtion = builder.allowPartialPeriodInterestCalculation;
|
||||||
}
|
}
|
||||||
@@ -330,6 +332,7 @@ public final class LoanApplicationTerms {
|
|||||||
private LoanBuyDownFeeCalculationType buyDownFeeCalculationType;
|
private LoanBuyDownFeeCalculationType buyDownFeeCalculationType;
|
||||||
private LoanBuyDownFeeStrategy buyDownFeeStrategy;
|
private LoanBuyDownFeeStrategy buyDownFeeStrategy;
|
||||||
private LoanBuyDownFeeIncomeType buyDownFeeIncomeType;
|
private LoanBuyDownFeeIncomeType buyDownFeeIncomeType;
|
||||||
|
private boolean merchantBuyDownFee;
|
||||||
private boolean allowPartialPeriodInterestCalculation;
|
private boolean allowPartialPeriodInterestCalculation;
|
||||||
|
|
||||||
public Builder interestMethod(InterestMethod interestMethod) {
|
public Builder interestMethod(InterestMethod interestMethod) {
|
||||||
@@ -492,6 +495,11 @@ public final class LoanApplicationTerms {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder merchantBuyDownFee(boolean value) {
|
||||||
|
this.merchantBuyDownFee = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public LoanApplicationTerms build() {
|
public LoanApplicationTerms build() {
|
||||||
return new LoanApplicationTerms(this);
|
return new LoanApplicationTerms(this);
|
||||||
}
|
}
|
||||||
@@ -570,7 +578,8 @@ public final class LoanApplicationTerms {
|
|||||||
final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
||||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
||||||
final boolean enableBuyDownFee, final LoanBuyDownFeeCalculationType buyDownFeeCalculationType,
|
final boolean enableBuyDownFee, final LoanBuyDownFeeCalculationType buyDownFeeCalculationType,
|
||||||
final LoanBuyDownFeeStrategy buyDownFeeStrategy, final LoanBuyDownFeeIncomeType buyDownFeeIncomeType) {
|
final LoanBuyDownFeeStrategy buyDownFeeStrategy, final LoanBuyDownFeeIncomeType buyDownFeeIncomeType,
|
||||||
|
final boolean merchantBuyDownFee) {
|
||||||
|
|
||||||
final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
|
final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
|
||||||
final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
|
final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
|
||||||
@@ -592,7 +601,7 @@ public final class LoanApplicationTerms {
|
|||||||
fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
||||||
interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
|
interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
|
||||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType, merchantBuyDownFee);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,7 +679,8 @@ public final class LoanApplicationTerms {
|
|||||||
loanProductRelatedDetail.isEnableIncomeCapitalization(), loanProductRelatedDetail.getCapitalizedIncomeCalculationType(),
|
loanProductRelatedDetail.isEnableIncomeCapitalization(), loanProductRelatedDetail.getCapitalizedIncomeCalculationType(),
|
||||||
loanProductRelatedDetail.getCapitalizedIncomeStrategy(), loanProductRelatedDetail.getCapitalizedIncomeType(),
|
loanProductRelatedDetail.getCapitalizedIncomeStrategy(), loanProductRelatedDetail.getCapitalizedIncomeType(),
|
||||||
loanProductRelatedDetail.isEnableBuyDownFee(), loanProductRelatedDetail.getBuyDownFeeCalculationType(),
|
loanProductRelatedDetail.isEnableBuyDownFee(), loanProductRelatedDetail.getBuyDownFeeCalculationType(),
|
||||||
loanProductRelatedDetail.getBuyDownFeeStrategy(), loanProductRelatedDetail.getBuyDownFeeIncomeType());
|
loanProductRelatedDetail.getBuyDownFeeStrategy(), loanProductRelatedDetail.getBuyDownFeeIncomeType(),
|
||||||
|
loanProductRelatedDetail.isMerchantBuyDownFee());
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanApplicationTerms(final CurrencyData currency, final Integer loanTermFrequency,
|
private LoanApplicationTerms(final CurrencyData currency, final Integer loanTermFrequency,
|
||||||
@@ -705,7 +715,8 @@ public final class LoanApplicationTerms {
|
|||||||
final boolean enableIncomeCapitalization, final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
final boolean enableIncomeCapitalization, final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
||||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
||||||
final boolean enableBuyDownFee, final LoanBuyDownFeeCalculationType buyDownFeeCalculationType,
|
final boolean enableBuyDownFee, final LoanBuyDownFeeCalculationType buyDownFeeCalculationType,
|
||||||
final LoanBuyDownFeeStrategy buyDownFeeStrategy, final LoanBuyDownFeeIncomeType buyDownFeeIncomeType) {
|
final LoanBuyDownFeeStrategy buyDownFeeStrategy, final LoanBuyDownFeeIncomeType buyDownFeeIncomeType,
|
||||||
|
final boolean merchantBuyDownFee) {
|
||||||
|
|
||||||
this.currency = currency;
|
this.currency = currency;
|
||||||
this.loanTermFrequency = loanTermFrequency;
|
this.loanTermFrequency = loanTermFrequency;
|
||||||
@@ -815,6 +826,7 @@ public final class LoanApplicationTerms {
|
|||||||
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
||||||
this.buyDownFeeStrategy = buyDownFeeStrategy;
|
this.buyDownFeeStrategy = buyDownFeeStrategy;
|
||||||
this.buyDownFeeIncomeType = buyDownFeeIncomeType;
|
this.buyDownFeeIncomeType = buyDownFeeIncomeType;
|
||||||
|
this.merchantBuyDownFee = merchantBuyDownFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
|
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
|
||||||
@@ -1679,7 +1691,7 @@ public final class LoanApplicationTerms {
|
|||||||
this.chargeOffBehaviour, this.interestRecognitionOnDisbursementDate, this.daysInYearCustomStrategy,
|
this.chargeOffBehaviour, this.interestRecognitionOnDisbursementDate, this.daysInYearCustomStrategy,
|
||||||
this.enableIncomeCapitalization, this.capitalizedIncomeCalculationType, this.capitalizedIncomeStrategy,
|
this.enableIncomeCapitalization, this.capitalizedIncomeCalculationType, this.capitalizedIncomeStrategy,
|
||||||
this.capitalizedIncomeType, this.installmentAmountInMultiplesOf, this.enableBuyDownFee, this.buyDownFeeCalculationType,
|
this.capitalizedIncomeType, this.installmentAmountInMultiplesOf, this.enableBuyDownFee, this.buyDownFeeCalculationType,
|
||||||
this.buyDownFeeStrategy, this.buyDownFeeIncomeType);
|
this.buyDownFeeStrategy, this.buyDownFeeIncomeType, this.merchantBuyDownFee);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoanProductMinimumRepaymentScheduleRelatedDetail toLoanProductRelatedDetailMinimumData() {
|
public LoanProductMinimumRepaymentScheduleRelatedDetail toLoanProductRelatedDetailMinimumData() {
|
||||||
|
|||||||
+3
-3
@@ -59,13 +59,13 @@ public class LoanAccountingBridgeMapper {
|
|||||||
currencyCode, loan.getSummary().getTotalInterestCharged(), loan.isCashBasedAccountingEnabledOnLoanProduct(),
|
currencyCode, loan.getSummary().getTotalInterestCharged(), loan.isCashBasedAccountingEnabledOnLoanProduct(),
|
||||||
loan.isUpfrontAccrualAccountingEnabledOnLoanProduct(), loan.isPeriodicAccrualAccountingEnabledOnLoanProduct(),
|
loan.isUpfrontAccrualAccountingEnabledOnLoanProduct(), loan.isPeriodicAccrualAccountingEnabledOnLoanProduct(),
|
||||||
isAccountTransfer, false, loan.isFraud(), loan.fetchChargeOffReasonId(), loan.isClosedWrittenOff(),
|
isAccountTransfer, false, loan.isFraud(), loan.fetchChargeOffReasonId(), loan.isClosedWrittenOff(),
|
||||||
newLoanTransactionsBeforeChargeOff);
|
newLoanTransactionsBeforeChargeOff, loan.getLoanProductRelatedDetail().isMerchantBuyDownFee());
|
||||||
|
|
||||||
AccountingBridgeDataDTO afterChargeOff = new AccountingBridgeDataDTO(loan.getId(), loan.productId(), loan.getOfficeId(),
|
AccountingBridgeDataDTO afterChargeOff = new AccountingBridgeDataDTO(loan.getId(), loan.productId(), loan.getOfficeId(),
|
||||||
currencyCode, loan.getSummary().getTotalInterestCharged(), loan.isCashBasedAccountingEnabledOnLoanProduct(),
|
currencyCode, loan.getSummary().getTotalInterestCharged(), loan.isCashBasedAccountingEnabledOnLoanProduct(),
|
||||||
loan.isUpfrontAccrualAccountingEnabledOnLoanProduct(), loan.isPeriodicAccrualAccountingEnabledOnLoanProduct(),
|
loan.isUpfrontAccrualAccountingEnabledOnLoanProduct(), loan.isPeriodicAccrualAccountingEnabledOnLoanProduct(),
|
||||||
isAccountTransfer, true, loan.isFraud(), loan.fetchChargeOffReasonId(), loan.isClosedWrittenOff(),
|
isAccountTransfer, true, loan.isFraud(), loan.fetchChargeOffReasonId(), loan.isClosedWrittenOff(),
|
||||||
newLoanTransactionsAfterChargeOff);
|
newLoanTransactionsAfterChargeOff, loan.getLoanProductRelatedDetail().isMerchantBuyDownFee());
|
||||||
|
|
||||||
List<AccountingBridgeDataDTO> result = new ArrayList<>();
|
List<AccountingBridgeDataDTO> result = new ArrayList<>();
|
||||||
result.add(beforeChargeOff);
|
result.add(beforeChargeOff);
|
||||||
@@ -86,7 +86,7 @@ public class LoanAccountingBridgeMapper {
|
|||||||
loan.getSummary().getTotalInterestCharged(), loan.isCashBasedAccountingEnabledOnLoanProduct(),
|
loan.getSummary().getTotalInterestCharged(), loan.isCashBasedAccountingEnabledOnLoanProduct(),
|
||||||
loan.isUpfrontAccrualAccountingEnabledOnLoanProduct(), loan.isPeriodicAccrualAccountingEnabledOnLoanProduct(),
|
loan.isUpfrontAccrualAccountingEnabledOnLoanProduct(), loan.isPeriodicAccrualAccountingEnabledOnLoanProduct(),
|
||||||
isAccountTransfer, loan.isChargedOff(), loan.isFraud(), loan.fetchChargeOffReasonId(), loan.isClosedWrittenOff(),
|
isAccountTransfer, loan.isChargedOff(), loan.isFraud(), loan.fetchChargeOffReasonId(), loan.isClosedWrittenOff(),
|
||||||
newLoanTransactions);
|
newLoanTransactions, loan.getLoanProductRelatedDetail().isMerchantBuyDownFee());
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountingBridgeLoanTransactionDTO mapToLoanTransactionData(final LoanTransaction transaction, final String currencyCode) {
|
public AccountingBridgeLoanTransactionDTO mapToLoanTransactionData(final LoanTransaction transaction, final String currencyCode) {
|
||||||
|
|||||||
+1
@@ -183,4 +183,5 @@ public interface LoanProductConstants {
|
|||||||
String BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME = "buyDownFeeCalculationType";
|
String BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME = "buyDownFeeCalculationType";
|
||||||
String BUY_DOWN_FEE_STRATEGY_PARAM_NAME = "buyDownFeeStrategy";
|
String BUY_DOWN_FEE_STRATEGY_PARAM_NAME = "buyDownFeeStrategy";
|
||||||
String BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME = "buyDownFeeIncomeType";
|
String BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME = "buyDownFeeIncomeType";
|
||||||
|
String MERCHANT_BUY_DOWN_FEE_PARAM_NAME = "merchantBuyDownFee";
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -213,6 +213,8 @@ public final class LoanProductsApiResourceSwagger {
|
|||||||
public String buyDownFeeStrategy;
|
public String buyDownFeeStrategy;
|
||||||
@Schema(example = "FEE", allowableValues = { "FEE", "INTEREST" })
|
@Schema(example = "FEE", allowableValues = { "FEE", "INTEREST" })
|
||||||
public String buyDownFeeIncomeType;
|
public String buyDownFeeIncomeType;
|
||||||
|
@Schema(example = "false")
|
||||||
|
public Boolean merchantBuyDownFee;
|
||||||
|
|
||||||
// Interest Recalculation
|
// Interest Recalculation
|
||||||
@Schema(example = "false")
|
@Schema(example = "false")
|
||||||
@@ -693,6 +695,8 @@ public final class LoanProductsApiResourceSwagger {
|
|||||||
public StringEnumOptionData buyDownFeeStrategy;
|
public StringEnumOptionData buyDownFeeStrategy;
|
||||||
@Schema(example = "FEE")
|
@Schema(example = "FEE")
|
||||||
public StringEnumOptionData buyDownFeeIncomeType;
|
public StringEnumOptionData buyDownFeeIncomeType;
|
||||||
|
@Schema(example = "false")
|
||||||
|
public Boolean merchantBuyDownFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Schema(description = "GetLoanProductsTemplateResponse")
|
@Schema(description = "GetLoanProductsTemplateResponse")
|
||||||
@@ -1157,6 +1161,8 @@ public final class LoanProductsApiResourceSwagger {
|
|||||||
public StringEnumOptionData buyDownFeeCalculationType;
|
public StringEnumOptionData buyDownFeeCalculationType;
|
||||||
@Schema(example = "EQUAL_AMORTIZATION")
|
@Schema(example = "EQUAL_AMORTIZATION")
|
||||||
public StringEnumOptionData buyDownFeeStrategy;
|
public StringEnumOptionData buyDownFeeStrategy;
|
||||||
|
@Schema(example = "false")
|
||||||
|
public Boolean merchantBuyDownFee;
|
||||||
@Schema(example = "FEE")
|
@Schema(example = "FEE")
|
||||||
public StringEnumOptionData buyDownFeeIncomeType;
|
public StringEnumOptionData buyDownFeeIncomeType;
|
||||||
public List<StringEnumOptionData> buyDownFeeCalculationTypeOptions;
|
public List<StringEnumOptionData> buyDownFeeCalculationTypeOptions;
|
||||||
@@ -1505,6 +1511,8 @@ public final class LoanProductsApiResourceSwagger {
|
|||||||
public StringEnumOptionData buyDownFeeStrategy;
|
public StringEnumOptionData buyDownFeeStrategy;
|
||||||
@Schema(example = "FEE")
|
@Schema(example = "FEE")
|
||||||
public StringEnumOptionData buyDownFeeIncomeType;
|
public StringEnumOptionData buyDownFeeIncomeType;
|
||||||
|
@Schema(example = "false")
|
||||||
|
public Boolean merchantBuyDownFee;
|
||||||
public List<StringEnumOptionData> buyDownFeeCalculationTypeOptions;
|
public List<StringEnumOptionData> buyDownFeeCalculationTypeOptions;
|
||||||
public List<StringEnumOptionData> buyDownFeeStrategyOptions;
|
public List<StringEnumOptionData> buyDownFeeStrategyOptions;
|
||||||
public List<StringEnumOptionData> buyDownFeeIncomeTypeOptions;
|
public List<StringEnumOptionData> buyDownFeeIncomeTypeOptions;
|
||||||
@@ -1787,6 +1795,8 @@ public final class LoanProductsApiResourceSwagger {
|
|||||||
public String buyDownFeeStrategy;
|
public String buyDownFeeStrategy;
|
||||||
@Schema(example = "FEE", allowableValues = { "FEE", "INTEREST" })
|
@Schema(example = "FEE", allowableValues = { "FEE", "INTEREST" })
|
||||||
public String buyDownFeeIncomeType;
|
public String buyDownFeeIncomeType;
|
||||||
|
@Schema(example = "false")
|
||||||
|
public Boolean merchantBuyDownFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class AdvancedPaymentData {
|
public static final class AdvancedPaymentData {
|
||||||
|
|||||||
+13
-5
@@ -256,6 +256,7 @@ public class LoanProductData implements Serializable {
|
|||||||
private StringEnumOptionData buyDownFeeCalculationType;
|
private StringEnumOptionData buyDownFeeCalculationType;
|
||||||
private StringEnumOptionData buyDownFeeStrategy;
|
private StringEnumOptionData buyDownFeeStrategy;
|
||||||
private StringEnumOptionData buyDownFeeIncomeType;
|
private StringEnumOptionData buyDownFeeIncomeType;
|
||||||
|
private boolean merchantBuyDownFee;
|
||||||
private List<StringEnumOptionData> buyDownFeeCalculationTypeOptions;
|
private List<StringEnumOptionData> buyDownFeeCalculationTypeOptions;
|
||||||
private List<StringEnumOptionData> buyDownFeeStrategyOptions;
|
private List<StringEnumOptionData> buyDownFeeStrategyOptions;
|
||||||
private List<StringEnumOptionData> buyDownFeeIncomeTypeOptions;
|
private List<StringEnumOptionData> buyDownFeeIncomeTypeOptions;
|
||||||
@@ -371,6 +372,7 @@ public class LoanProductData implements Serializable {
|
|||||||
final StringEnumOptionData buyDownFeeCalculationType = null;
|
final StringEnumOptionData buyDownFeeCalculationType = null;
|
||||||
final StringEnumOptionData buyDownFeeStrategy = null;
|
final StringEnumOptionData buyDownFeeStrategy = null;
|
||||||
final StringEnumOptionData buyDownFeeIncomeType = null;
|
final StringEnumOptionData buyDownFeeIncomeType = null;
|
||||||
|
final boolean merchantBuyDownFee = false;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -394,7 +396,7 @@ public class LoanProductData implements Serializable {
|
|||||||
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
||||||
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
||||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType, merchantBuyDownFee);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,6 +509,7 @@ public class LoanProductData implements Serializable {
|
|||||||
final StringEnumOptionData buyDownFeeCalculationType = null;
|
final StringEnumOptionData buyDownFeeCalculationType = null;
|
||||||
final StringEnumOptionData buyDownFeeStrategy = null;
|
final StringEnumOptionData buyDownFeeStrategy = null;
|
||||||
final StringEnumOptionData buyDownFeeIncomeType = null;
|
final StringEnumOptionData buyDownFeeIncomeType = null;
|
||||||
|
final boolean merchantBuyDownFee = false;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -530,7 +533,7 @@ public class LoanProductData implements Serializable {
|
|||||||
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
||||||
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
||||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType, merchantBuyDownFee);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,6 +653,7 @@ public class LoanProductData implements Serializable {
|
|||||||
final StringEnumOptionData buyDownFeeCalculationType = null;
|
final StringEnumOptionData buyDownFeeCalculationType = null;
|
||||||
final StringEnumOptionData buyDownFeeStrategy = null;
|
final StringEnumOptionData buyDownFeeStrategy = null;
|
||||||
final StringEnumOptionData buyDownFeeIncomeType = null;
|
final StringEnumOptionData buyDownFeeIncomeType = null;
|
||||||
|
final boolean merchantBuyDownFee = false;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -673,7 +677,7 @@ public class LoanProductData implements Serializable {
|
|||||||
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
||||||
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
||||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType, merchantBuyDownFee);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,6 +791,7 @@ public class LoanProductData implements Serializable {
|
|||||||
final StringEnumOptionData buyDownFeeCalculationType = null;
|
final StringEnumOptionData buyDownFeeCalculationType = null;
|
||||||
final StringEnumOptionData buyDownFeeStrategy = null;
|
final StringEnumOptionData buyDownFeeStrategy = null;
|
||||||
final StringEnumOptionData buyDownFeeIncomeType = null;
|
final StringEnumOptionData buyDownFeeIncomeType = null;
|
||||||
|
final boolean merchantBuyDownFee = false;
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -810,7 +815,7 @@ public class LoanProductData implements Serializable {
|
|||||||
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour,
|
||||||
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
interestRecognitionOnDisbursementDate, daysInYearTypeCustomStrategy, enableIncomeCapitalization,
|
||||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType, merchantBuyDownFee);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map<String, Object> accountingMappings,
|
public static LoanProductData withAccountingDetails(final LoanProductData productData, final Map<String, Object> accountingMappings,
|
||||||
@@ -869,7 +874,7 @@ public class LoanProductData implements Serializable {
|
|||||||
final StringEnumOptionData capitalizedIncomeCalculationType, final StringEnumOptionData capitalizedIncomeStrategy,
|
final StringEnumOptionData capitalizedIncomeCalculationType, final StringEnumOptionData capitalizedIncomeStrategy,
|
||||||
final StringEnumOptionData capitalizedIncomeType, final boolean enableBuyDownFee,
|
final StringEnumOptionData capitalizedIncomeType, final boolean enableBuyDownFee,
|
||||||
final StringEnumOptionData buyDownFeeCalculationType, final StringEnumOptionData buyDownFeeStrategy,
|
final StringEnumOptionData buyDownFeeCalculationType, final StringEnumOptionData buyDownFeeStrategy,
|
||||||
final StringEnumOptionData buyDownFeeIncomeType) {
|
final StringEnumOptionData buyDownFeeIncomeType, final boolean merchantBuyDownFee) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.shortName = shortName;
|
this.shortName = shortName;
|
||||||
@@ -934,6 +939,7 @@ public class LoanProductData implements Serializable {
|
|||||||
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
||||||
this.buyDownFeeStrategy = buyDownFeeStrategy;
|
this.buyDownFeeStrategy = buyDownFeeStrategy;
|
||||||
this.buyDownFeeIncomeType = buyDownFeeIncomeType;
|
this.buyDownFeeIncomeType = buyDownFeeIncomeType;
|
||||||
|
this.merchantBuyDownFee = merchantBuyDownFee;
|
||||||
|
|
||||||
this.chargeOptions = null;
|
this.chargeOptions = null;
|
||||||
this.penaltyOptions = null;
|
this.penaltyOptions = null;
|
||||||
@@ -1238,6 +1244,8 @@ public class LoanProductData implements Serializable {
|
|||||||
this.buyDownFeeCalculationTypeOptions = buyDownFeeCalculationTypeOptions;
|
this.buyDownFeeCalculationTypeOptions = buyDownFeeCalculationTypeOptions;
|
||||||
this.buyDownFeeStrategyOptions = buyDownFeeStrategyOptions;
|
this.buyDownFeeStrategyOptions = buyDownFeeStrategyOptions;
|
||||||
this.buyDownFeeIncomeTypeOptions = buyDownFeeIncomeTypeOptions;
|
this.buyDownFeeIncomeTypeOptions = buyDownFeeIncomeTypeOptions;
|
||||||
|
|
||||||
|
this.merchantBuyDownFee = productData.isMerchantBuyDownFee();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<ChargeData> nullIfEmpty(final Collection<ChargeData> charges) {
|
private Collection<ChargeData> nullIfEmpty(final Collection<ChargeData> charges) {
|
||||||
|
|||||||
+4
-2
@@ -287,7 +287,8 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
|||||||
final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
final LoanCapitalizedIncomeCalculationType capitalizedIncomeCalculationType,
|
||||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
||||||
final boolean enableBuyDownFee, final LoanBuyDownFeeCalculationType buyDownFeeCalculationType,
|
final boolean enableBuyDownFee, final LoanBuyDownFeeCalculationType buyDownFeeCalculationType,
|
||||||
final LoanBuyDownFeeStrategy buyDownFeeStrategy, final LoanBuyDownFeeIncomeType buyDownFeeIncomeType) {
|
final LoanBuyDownFeeStrategy buyDownFeeStrategy, final LoanBuyDownFeeIncomeType buyDownFeeIncomeType,
|
||||||
|
final boolean merchantBuyDownFee) {
|
||||||
this.fund = fund;
|
this.fund = fund;
|
||||||
this.transactionProcessingStrategyCode = transactionProcessingStrategyCode;
|
this.transactionProcessingStrategyCode = transactionProcessingStrategyCode;
|
||||||
|
|
||||||
@@ -339,7 +340,8 @@ public class LoanProduct extends AbstractPersistableCustom<Long> {
|
|||||||
enableAutoRepaymentForDownPayment, loanScheduleType, loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting,
|
enableAutoRepaymentForDownPayment, loanScheduleType, loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting,
|
||||||
supportedInterestRefundTypes, chargeOffBehaviour, isInterestRecognitionOnDisbursementDate, daysInYearCustomStrategy,
|
supportedInterestRefundTypes, chargeOffBehaviour, isInterestRecognitionOnDisbursementDate, daysInYearCustomStrategy,
|
||||||
enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType,
|
enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType,
|
||||||
installmentAmountInMultiplesOf, enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
installmentAmountInMultiplesOf, enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType,
|
||||||
|
merchantBuyDownFee);
|
||||||
|
|
||||||
this.loanProductMinMaxConstraints = new LoanProductMinMaxConstraints(defaultMinPrincipal, defaultMaxPrincipal,
|
this.loanProductMinMaxConstraints = new LoanProductMinMaxConstraints(defaultMinPrincipal, defaultMaxPrincipal,
|
||||||
defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod, defaultMinNumberOfInstallments,
|
defaultMinNominalInterestRatePerPeriod, defaultMaxNominalInterestRatePerPeriod, defaultMinNumberOfInstallments,
|
||||||
|
|||||||
+7
-3
@@ -204,6 +204,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
@Column(name = "buy_down_fee_income_type")
|
@Column(name = "buy_down_fee_income_type")
|
||||||
private LoanBuyDownFeeIncomeType buyDownFeeIncomeType;
|
private LoanBuyDownFeeIncomeType buyDownFeeIncomeType;
|
||||||
|
|
||||||
|
@Column(name = "is_merchant_buy_down_fee")
|
||||||
|
private boolean merchantBuyDownFee = true;
|
||||||
|
|
||||||
@Column(name = "installment_amount_in_multiples_of")
|
@Column(name = "installment_amount_in_multiples_of")
|
||||||
private Integer installmentAmountInMultiplesOf;
|
private Integer installmentAmountInMultiplesOf;
|
||||||
|
|
||||||
@@ -226,7 +229,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
||||||
final Integer installmentAmountInMultiplesOf, final boolean enableBuyDownFee,
|
final Integer installmentAmountInMultiplesOf, final boolean enableBuyDownFee,
|
||||||
final LoanBuyDownFeeCalculationType buyDownFeeCalculationType, final LoanBuyDownFeeStrategy buyDownFeeStrategy,
|
final LoanBuyDownFeeCalculationType buyDownFeeCalculationType, final LoanBuyDownFeeStrategy buyDownFeeStrategy,
|
||||||
final LoanBuyDownFeeIncomeType buyDownFeeIncomeType) {
|
final LoanBuyDownFeeIncomeType buyDownFeeIncomeType, final boolean merchantBuyDownFee) {
|
||||||
|
|
||||||
final MonetaryCurrency currency = MonetaryCurrency.fromCurrencyData(currencyData);
|
final MonetaryCurrency currency = MonetaryCurrency.fromCurrencyData(currencyData);
|
||||||
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
|
||||||
@@ -238,7 +241,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
loanScheduleType, loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes,
|
loanScheduleType, loanScheduleProcessingType, fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes,
|
||||||
chargeOffBehaviour, interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
|
chargeOffBehaviour, interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
|
||||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, installmentAmountInMultiplesOf,
|
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, installmentAmountInMultiplesOf,
|
||||||
enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType, merchantBuyDownFee);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected LoanProductRelatedDetail() {
|
protected LoanProductRelatedDetail() {
|
||||||
@@ -264,7 +267,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
final LoanCapitalizedIncomeStrategy capitalizedIncomeStrategy, final LoanCapitalizedIncomeType capitalizedIncomeType,
|
||||||
final Integer installmentAmountInMultiplesOf, final boolean enableBuyDownFee,
|
final Integer installmentAmountInMultiplesOf, final boolean enableBuyDownFee,
|
||||||
final LoanBuyDownFeeCalculationType buyDownFeeCalculationType, final LoanBuyDownFeeStrategy buyDownFeeStrategy,
|
final LoanBuyDownFeeCalculationType buyDownFeeCalculationType, final LoanBuyDownFeeStrategy buyDownFeeStrategy,
|
||||||
final LoanBuyDownFeeIncomeType buyDownFeeIncomeType) {
|
final LoanBuyDownFeeIncomeType buyDownFeeIncomeType, final boolean merchantBuyDownFee) {
|
||||||
this.currency = currency;
|
this.currency = currency;
|
||||||
this.principal = defaultPrincipal;
|
this.principal = defaultPrincipal;
|
||||||
this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
|
this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
|
||||||
@@ -311,6 +314,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
|
|||||||
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
||||||
this.buyDownFeeStrategy = buyDownFeeStrategy;
|
this.buyDownFeeStrategy = buyDownFeeStrategy;
|
||||||
this.buyDownFeeIncomeType = buyDownFeeIncomeType;
|
this.buyDownFeeIncomeType = buyDownFeeIncomeType;
|
||||||
|
this.merchantBuyDownFee = merchantBuyDownFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer defaultToNullIfZero(final Integer value) {
|
private Integer defaultToNullIfZero(final Integer value) {
|
||||||
|
|||||||
+1
@@ -53,4 +53,5 @@
|
|||||||
<include relativeToChangelogFile="true" file="parts/1028_remove_suboptimal_indexes.xml"/>
|
<include relativeToChangelogFile="true" file="parts/1028_remove_suboptimal_indexes.xml"/>
|
||||||
<include relativeToChangelogFile="true" file="parts/1029_add_installment_amount_in_multiples_of_to_loan.xml"/>
|
<include relativeToChangelogFile="true" file="parts/1029_add_installment_amount_in_multiples_of_to_loan.xml"/>
|
||||||
<include relativeToChangelogFile="true" file="parts/1030_add_loan_undo_contract_termination_event.xml"/>
|
<include relativeToChangelogFile="true" file="parts/1030_add_loan_undo_contract_termination_event.xml"/>
|
||||||
|
<include relativeToChangelogFile="true" file="parts/1031_loan_merchant_buy_down_fee.xml"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
|
||||||
|
<changeSet author="fineract" id="1">
|
||||||
|
<addColumn tableName="m_loan">
|
||||||
|
<column name="is_merchant_buy_down_fee" type="boolean" defaultValueBoolean="true">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
</addColumn>
|
||||||
|
<addColumn tableName="m_product_loan">
|
||||||
|
<column name="is_merchant_buy_down_fee" type="boolean" defaultValueBoolean="true">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
+1
@@ -47,4 +47,5 @@ public class LoanDTO {
|
|||||||
private boolean markedAsFraud;
|
private boolean markedAsFraud;
|
||||||
private Long chargeOffReasonCodeValue;
|
private Long chargeOffReasonCodeValue;
|
||||||
private boolean markedAsWrittenOff;
|
private boolean markedAsWrittenOff;
|
||||||
|
private boolean merchantBuyDownFee;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -111,6 +111,7 @@ public class AccountingProcessorHelper {
|
|||||||
final boolean cashBasedAccountingEnabled = accountingBridgeData.isCashBasedAccountingEnabled();
|
final boolean cashBasedAccountingEnabled = accountingBridgeData.isCashBasedAccountingEnabled();
|
||||||
final boolean upfrontAccrualBasedAccountingEnabled = accountingBridgeData.isUpfrontAccrualBasedAccountingEnabled();
|
final boolean upfrontAccrualBasedAccountingEnabled = accountingBridgeData.isUpfrontAccrualBasedAccountingEnabled();
|
||||||
final boolean periodicAccrualBasedAccountingEnabled = accountingBridgeData.isPeriodicAccrualBasedAccountingEnabled();
|
final boolean periodicAccrualBasedAccountingEnabled = accountingBridgeData.isPeriodicAccrualBasedAccountingEnabled();
|
||||||
|
final boolean merchantBuyDownFee = accountingBridgeData.isMerchantBuyDownFee();
|
||||||
|
|
||||||
final List<AccountingBridgeLoanTransactionDTO> loanTransactionDTOs = accountingBridgeData.getNewLoanTransactions();
|
final List<AccountingBridgeLoanTransactionDTO> loanTransactionDTOs = accountingBridgeData.getNewLoanTransactions();
|
||||||
|
|
||||||
@@ -170,7 +171,7 @@ public class AccountingProcessorHelper {
|
|||||||
|
|
||||||
return new LoanDTO(loanId, loanProductId, officeId, currencyCode, cashBasedAccountingEnabled, upfrontAccrualBasedAccountingEnabled,
|
return new LoanDTO(loanId, loanProductId, officeId, currencyCode, cashBasedAccountingEnabled, upfrontAccrualBasedAccountingEnabled,
|
||||||
periodicAccrualBasedAccountingEnabled, newLoanTransactions, isLoanMarkedAsChargeOff, isLoanMarkedAsFraud,
|
periodicAccrualBasedAccountingEnabled, newLoanTransactions, isLoanMarkedAsChargeOff, isLoanMarkedAsFraud,
|
||||||
chargeOffReasonCodeValue, isLoanMarkedAsWrittenOff);
|
chargeOffReasonCodeValue, isLoanMarkedAsWrittenOff, merchantBuyDownFee);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProductToGLAccountMapping getChargeOffMappingByCodeValue(Long loanProductId, PortfolioProductType productType,
|
public ProductToGLAccountMapping getChargeOffMappingByCodeValue(Long loanProductId, PortfolioProductType productType,
|
||||||
|
|||||||
+3
-1
@@ -435,8 +435,10 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
|||||||
final BigDecimal amount = loanTransactionDTO.getAmount();
|
final BigDecimal amount = loanTransactionDTO.getAmount();
|
||||||
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
||||||
|
|
||||||
|
final AccrualAccountsForLoan debitAccountType = loanDTO.isMerchantBuyDownFee() ? AccrualAccountsForLoan.BUY_DOWN_EXPENSE
|
||||||
|
: AccrualAccountsForLoan.FUND_SOURCE;
|
||||||
if (MathUtil.isGreaterThanZero(amount)) {
|
if (MathUtil.isGreaterThanZero(amount)) {
|
||||||
this.helper.createJournalEntriesForLoan(office, currencyCode, AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue(),
|
this.helper.createJournalEntriesForLoan(office, currencyCode, debitAccountType.getValue(),
|
||||||
AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
|
AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
|
||||||
transactionDate, amount);
|
transactionDate, amount);
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-5
@@ -41,6 +41,7 @@ import org.apache.fineract.accounting.producttoaccountmapping.service.SavingsPro
|
|||||||
import org.apache.fineract.accounting.producttoaccountmapping.service.ShareProductToGLAccountMappingHelper;
|
import org.apache.fineract.accounting.producttoaccountmapping.service.ShareProductToGLAccountMappingHelper;
|
||||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||||
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
|
||||||
|
import org.apache.fineract.portfolio.loanproduct.LoanProductConstants;
|
||||||
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
import org.apache.fineract.portfolio.savings.DepositAccountType;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -61,6 +62,14 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
|||||||
final JsonElement element = this.fromApiJsonHelper.parse(command.json());
|
final JsonElement element = this.fromApiJsonHelper.parse(command.json());
|
||||||
final Integer accountingRuleTypeId = this.fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault());
|
final Integer accountingRuleTypeId = this.fromApiJsonHelper.extractIntegerNamed("accountingRule", element, Locale.getDefault());
|
||||||
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(accountingRuleTypeId);
|
final AccountingRuleType accountingRuleType = AccountingRuleType.fromInt(accountingRuleTypeId);
|
||||||
|
boolean merchantBuyDownFee = true;
|
||||||
|
if (fromApiJsonHelper.parameterExists(LoanProductConstants.MERCHANT_BUY_DOWN_FEE_PARAM_NAME, element)) {
|
||||||
|
final Boolean merchantBuyDownFeeParamValue = fromApiJsonHelper
|
||||||
|
.extractBooleanNamed(LoanProductConstants.MERCHANT_BUY_DOWN_FEE_PARAM_NAME, element);
|
||||||
|
if (merchantBuyDownFeeParamValue != null) {
|
||||||
|
merchantBuyDownFee = merchantBuyDownFeeParamValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (accountingRuleType) {
|
switch (accountingRuleType) {
|
||||||
case NONE:
|
case NONE:
|
||||||
@@ -207,9 +216,11 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
|||||||
this.loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
|
this.loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
|
||||||
LoanProductAccountingParams.CHARGE_OFF_FRAUD_EXPENSE.getValue(), loanProductId,
|
LoanProductAccountingParams.CHARGE_OFF_FRAUD_EXPENSE.getValue(), loanProductId,
|
||||||
AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue());
|
AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue());
|
||||||
this.loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
|
if (merchantBuyDownFee) {
|
||||||
LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), loanProductId,
|
this.loanProductToGLAccountMappingHelper.saveLoanToExpenseAccountMapping(element,
|
||||||
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue());
|
LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), loanProductId,
|
||||||
|
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
// liabilities
|
// liabilities
|
||||||
this.loanProductToGLAccountMappingHelper.saveLoanToLiabilityAccountMapping(element,
|
this.loanProductToGLAccountMappingHelper.saveLoanToLiabilityAccountMapping(element,
|
||||||
@@ -370,7 +381,7 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
|||||||
@Transactional
|
@Transactional
|
||||||
public Map<String, Object> updateLoanProductToGLAccountMapping(final Long loanProductId, final JsonCommand command,
|
public Map<String, Object> updateLoanProductToGLAccountMapping(final Long loanProductId, final JsonCommand command,
|
||||||
final boolean accountingRuleChanged, final AccountingRuleType accountingRuleType, final boolean enableIncomeCapitalization,
|
final boolean accountingRuleChanged, final AccountingRuleType accountingRuleType, final boolean enableIncomeCapitalization,
|
||||||
final boolean enableBuyDownFee) {
|
final boolean enableBuyDownFee, final boolean merchantBuyDownFee) {
|
||||||
/***
|
/***
|
||||||
* Variable tracks all accounting mapping properties that have been updated
|
* Variable tracks all accounting mapping properties that have been updated
|
||||||
***/
|
***/
|
||||||
@@ -390,7 +401,7 @@ public class ProductToGLAccountMappingWritePlatformServiceImpl implements Produc
|
|||||||
} /*** else examine and update individual changes ***/
|
} /*** else examine and update individual changes ***/
|
||||||
else {
|
else {
|
||||||
this.loanProductToGLAccountMappingHelper.handleChangesToLoanProductToGLAccountMappings(loanProductId, changes, element,
|
this.loanProductToGLAccountMappingHelper.handleChangesToLoanProductToGLAccountMappings(loanProductId, changes, element,
|
||||||
accountingRuleType, enableIncomeCapitalization, enableBuyDownFee);
|
accountingRuleType, enableIncomeCapitalization, enableBuyDownFee, merchantBuyDownFee);
|
||||||
this.loanProductToGLAccountMappingHelper.updatePaymentChannelToFundSourceMappings(command, element, loanProductId, changes);
|
this.loanProductToGLAccountMappingHelper.updatePaymentChannelToFundSourceMappings(command, element, loanProductId, changes);
|
||||||
this.loanProductToGLAccountMappingHelper.updateChargesToIncomeAccountMappings(command, element, loanProductId, changes);
|
this.loanProductToGLAccountMappingHelper.updateChargesToIncomeAccountMappings(command, element, loanProductId, changes);
|
||||||
this.loanProductToGLAccountMappingHelper.updateChargeOffReasonToExpenseAccountMappings(command, element, loanProductId,
|
this.loanProductToGLAccountMappingHelper.updateChargeOffReasonToExpenseAccountMappings(command, element, loanProductId,
|
||||||
|
|||||||
+2
-1
@@ -554,7 +554,8 @@ public class LoanScheduleAssembler {
|
|||||||
loanProduct.getLoanProductRelatedDetail().isEnableBuyDownFee(),
|
loanProduct.getLoanProductRelatedDetail().isEnableBuyDownFee(),
|
||||||
loanProduct.getLoanProductRelatedDetail().getBuyDownFeeCalculationType(),
|
loanProduct.getLoanProductRelatedDetail().getBuyDownFeeCalculationType(),
|
||||||
loanProduct.getLoanProductRelatedDetail().getBuyDownFeeStrategy(),
|
loanProduct.getLoanProductRelatedDetail().getBuyDownFeeStrategy(),
|
||||||
loanProduct.getLoanProductRelatedDetail().getBuyDownFeeIncomeType());
|
loanProduct.getLoanProductRelatedDetail().getBuyDownFeeIncomeType(),
|
||||||
|
loanProduct.getLoanProductRelatedDetail().isMerchantBuyDownFee());
|
||||||
}
|
}
|
||||||
|
|
||||||
private CalendarInstance createCalendarForSameAsRepayment(final Integer repaymentEvery,
|
private CalendarInstance createCalendarForSameAsRepayment(final Integer repaymentEvery,
|
||||||
|
|||||||
+1
-1
@@ -445,7 +445,7 @@ public class LoanAccrualsProcessingServiceImpl implements LoanAccrualsProcessing
|
|||||||
loan.getOfficeId(), loan.getCurrencyCode(), loan.getSummary().getTotalInterestCharged(),
|
loan.getOfficeId(), loan.getCurrencyCode(), loan.getSummary().getTotalInterestCharged(),
|
||||||
loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct(),
|
loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct(),
|
||||||
loan.isUpfrontAccrualAccountingEnabledOnLoanProduct(), loan.isPeriodicAccrualAccountingEnabledOnLoanProduct(), false,
|
loan.isUpfrontAccrualAccountingEnabledOnLoanProduct(), loan.isPeriodicAccrualAccountingEnabledOnLoanProduct(), false,
|
||||||
false, false, null, false, newTransactionDTOs);
|
false, false, null, false, newTransactionDTOs, loan.getLoanProductRelatedDetail().isMerchantBuyDownFee());
|
||||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -327,6 +327,8 @@ public class LoanProductAssembler {
|
|||||||
.enumValueOfParameterNamed(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, LoanBuyDownFeeStrategy.class);
|
.enumValueOfParameterNamed(LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, LoanBuyDownFeeStrategy.class);
|
||||||
final LoanBuyDownFeeIncomeType buyDownFeeIncomeType = command
|
final LoanBuyDownFeeIncomeType buyDownFeeIncomeType = command
|
||||||
.enumValueOfParameterNamed(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME, LoanBuyDownFeeIncomeType.class);
|
.enumValueOfParameterNamed(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME, LoanBuyDownFeeIncomeType.class);
|
||||||
|
final boolean merchantBuyDownFee = command
|
||||||
|
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.MERCHANT_BUY_DOWN_FEE_PARAM_NAME);
|
||||||
|
|
||||||
return new LoanProduct(fund, loanTransactionProcessingStrategy, loanProductPaymentAllocationRules, loanProductCreditAllocationRules,
|
return new LoanProduct(fund, loanTransactionProcessingStrategy, loanProductPaymentAllocationRules, loanProductCreditAllocationRules,
|
||||||
name, shortName, description, currency, principal, minPrincipal, maxPrincipal, interestRatePerPeriod,
|
name, shortName, description, currency, principal, minPrincipal, maxPrincipal, interestRatePerPeriod,
|
||||||
@@ -349,7 +351,8 @@ public class LoanProductAssembler {
|
|||||||
repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType, loanScheduleProcessingType, fixedLength,
|
repaymentStartDateType, enableInstallmentLevelDelinquency, loanScheduleType, loanScheduleProcessingType, fixedLength,
|
||||||
enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour, interestRecognitionOnDisbursementDate,
|
enableAccrualActivityPosting, supportedInterestRefundTypes, chargeOffBehaviour, interestRecognitionOnDisbursementDate,
|
||||||
daysInYearCustomStrategy, enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy,
|
daysInYearCustomStrategy, enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy,
|
||||||
capitalizedIncomeType, enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
capitalizedIncomeType, enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType,
|
||||||
|
merchantBuyDownFee);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
@@ -359,6 +359,13 @@ public class LoanProductRelatedDetailUpdateUtil {
|
|||||||
loanRepaymentScheduleDetail.setBuyDownFeeIncomeType(newValue);
|
loanRepaymentScheduleDetail.setBuyDownFeeIncomeType(newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.MERCHANT_BUY_DOWN_FEE_PARAM_NAME,
|
||||||
|
loanRepaymentScheduleDetail.isMerchantBuyDownFee())) {
|
||||||
|
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.MERCHANT_BUY_DOWN_FEE_PARAM_NAME);
|
||||||
|
actualChanges.put(LoanProductConstants.MERCHANT_BUY_DOWN_FEE_PARAM_NAME, newValue);
|
||||||
|
loanRepaymentScheduleDetail.setMerchantBuyDownFee(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -847,9 +847,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
|||||||
+ " l.enable_income_capitalization as enableIncomeCapitalization, "
|
+ " l.enable_income_capitalization as enableIncomeCapitalization, "
|
||||||
+ " l.capitalized_income_calculation_type as capitalizedIncomeCalculationType, "
|
+ " l.capitalized_income_calculation_type as capitalizedIncomeCalculationType, "
|
||||||
+ " l.capitalized_income_strategy as capitalizedIncomeStrategy, "
|
+ " l.capitalized_income_strategy as capitalizedIncomeStrategy, "
|
||||||
+ " l.capitalized_income_type as capitalizedIncomeType, " //
|
+ " l.capitalized_income_type as capitalizedIncomeType, l.is_merchant_buy_down_fee as merchantBuyDownFee, " //
|
||||||
+ " l.enable_buy_down_fee as enableBuyDownFee, " + " l.buy_down_fee_calculation_type as buyDownFeeCalculationType, "
|
+ " l.enable_buy_down_fee as enableBuyDownFee, l.buy_down_fee_calculation_type as buyDownFeeCalculationType, "
|
||||||
+ " l.buy_down_fee_strategy as buyDownFeeStrategy, " + " l.buy_down_fee_income_type as buyDownFeeIncomeType, "
|
+ " l.buy_down_fee_strategy as buyDownFeeStrategy, l.buy_down_fee_income_type as buyDownFeeIncomeType, "
|
||||||
+ " l.create_standing_instruction_at_disbursement as createStandingInstructionAtDisbursement, "
|
+ " l.create_standing_instruction_at_disbursement as createStandingInstructionAtDisbursement, "
|
||||||
+ " lpvi.minimum_gap as minimuminstallmentgap, lpvi.maximum_gap as maximuminstallmentgap, "
|
+ " lpvi.minimum_gap as minimuminstallmentgap, lpvi.maximum_gap as maximuminstallmentgap, "
|
||||||
+ " lp.can_use_for_topup as canUseForTopup, l.is_topup as isTopup, topup.closure_loan_id as closureLoanId, "
|
+ " lp.can_use_for_topup as canUseForTopup, l.is_topup as isTopup, topup.closure_loan_id as closureLoanId, "
|
||||||
@@ -1246,6 +1246,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
|||||||
rs.getString("buyDownFeeStrategy"));
|
rs.getString("buyDownFeeStrategy"));
|
||||||
final StringEnumOptionData buyDownFeeIncomeType = ApiFacingEnum.getStringEnumOptionData(LoanBuyDownFeeIncomeType.class,
|
final StringEnumOptionData buyDownFeeIncomeType = ApiFacingEnum.getStringEnumOptionData(LoanBuyDownFeeIncomeType.class,
|
||||||
rs.getString("buyDownFeeIncomeType"));
|
rs.getString("buyDownFeeIncomeType"));
|
||||||
|
final boolean merchantBuyDownFee = rs.getBoolean("merchantBuyDownFee");
|
||||||
|
|
||||||
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
|
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
|
||||||
clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
|
clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
|
||||||
@@ -1267,7 +1268,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
|||||||
loanScheduleProcessingType.asEnumOptionData(), fixedLength, chargeOffBehaviour.getValueAsStringEnumOptionData(),
|
loanScheduleProcessingType.asEnumOptionData(), fixedLength, chargeOffBehaviour.getValueAsStringEnumOptionData(),
|
||||||
interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
|
interestRecognitionOnDisbursementDate, daysInYearCustomStrategy, enableIncomeCapitalization,
|
||||||
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
capitalizedIncomeCalculationType, capitalizedIncomeStrategy, capitalizedIncomeType, enableBuyDownFee,
|
||||||
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType, merchantBuyDownFee);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-7
@@ -201,7 +201,8 @@ public final class LoanProductDataValidator {
|
|||||||
LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, LoanProductConstants.CAPITALIZED_INCOME_TYPE_PARAM_NAME,
|
LoanProductConstants.CAPITALIZED_INCOME_STRATEGY_PARAM_NAME, LoanProductConstants.CAPITALIZED_INCOME_TYPE_PARAM_NAME,
|
||||||
LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME,
|
LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, LoanProductConstants.BUY_DOWN_FEE_CALCULATION_TYPE_PARAM_NAME,
|
||||||
LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME,
|
LoanProductConstants.BUY_DOWN_FEE_STRATEGY_PARAM_NAME, LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME,
|
||||||
LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue()));
|
LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue(),
|
||||||
|
LoanProductConstants.MERCHANT_BUY_DOWN_FEE_PARAM_NAME));
|
||||||
|
|
||||||
private static final String[] SUPPORTED_LOAN_CONFIGURABLE_ATTRIBUTES = { LoanProductConstants.amortizationTypeParamName,
|
private static final String[] SUPPORTED_LOAN_CONFIGURABLE_ATTRIBUTES = { LoanProductConstants.amortizationTypeParamName,
|
||||||
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyCodeParamName,
|
LoanProductConstants.interestTypeParamName, LoanProductConstants.transactionProcessingStrategyCodeParamName,
|
||||||
@@ -2838,14 +2839,21 @@ public final class LoanProductDataValidator {
|
|||||||
baseDataValidator.reset().parameter(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME).value(buyDownFeeIncomeType)
|
baseDataValidator.reset().parameter(LoanProductConstants.BUY_DOWN_FEE_INCOME_TYPE_PARAM_NAME).value(buyDownFeeIncomeType)
|
||||||
.isOneOfEnumValues(LoanBuyDownFeeIncomeType.class)
|
.isOneOfEnumValues(LoanBuyDownFeeIncomeType.class)
|
||||||
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, true);
|
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, true);
|
||||||
|
Boolean merchantBuyDownFee = this.fromApiJsonHelper
|
||||||
|
.extractBooleanNamed(LoanProductConstants.MERCHANT_BUY_DOWN_FEE_PARAM_NAME, element);
|
||||||
|
baseDataValidator.reset().parameter(LoanProductConstants.MERCHANT_BUY_DOWN_FEE_PARAM_NAME).value(merchantBuyDownFee)
|
||||||
|
.ignoreIfNull().validateForBooleanValue();
|
||||||
|
|
||||||
// Accounting
|
// Accounting
|
||||||
if (AccountingValidations.isAccrualBasedAccounting(accountingRuleType)) {
|
if (AccountingValidations.isAccrualBasedAccounting(accountingRuleType)) {
|
||||||
final Long deferredIncomeLiabilityAccountId = this.fromApiJsonHelper
|
if (merchantBuyDownFee) {
|
||||||
.extractLongNamed(LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), element);
|
final Long deferredIncomeLiabilityAccountId = this.fromApiJsonHelper
|
||||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue())
|
.extractLongNamed(LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), element);
|
||||||
.value(deferredIncomeLiabilityAccountId).notNull()
|
baseDataValidator.reset().parameter(LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue())
|
||||||
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, true)
|
.value(deferredIncomeLiabilityAccountId).notNull()
|
||||||
.integerGreaterThanZero();
|
.cantBeBlankWhenParameterProvidedIs(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME, true)
|
||||||
|
.integerGreaterThanZero();
|
||||||
|
}
|
||||||
final Long incomeFromDeferredIncomeAccountId = this.fromApiJsonHelper
|
final Long incomeFromDeferredIncomeAccountId = this.fromApiJsonHelper
|
||||||
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue(), element);
|
.extractLongNamed(LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue(), element);
|
||||||
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue())
|
baseDataValidator.reset().parameter(LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue())
|
||||||
|
|||||||
+4
-2
@@ -299,7 +299,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
+ "lp.enable_income_capitalization as enableIncomeCapitalization, " //
|
+ "lp.enable_income_capitalization as enableIncomeCapitalization, " //
|
||||||
+ "lp.capitalized_income_calculation_type as capitalizedIncomeCalculationType, " //
|
+ "lp.capitalized_income_calculation_type as capitalizedIncomeCalculationType, " //
|
||||||
+ "lp.capitalized_income_strategy as capitalizedIncomeStrategy, " //
|
+ "lp.capitalized_income_strategy as capitalizedIncomeStrategy, " //
|
||||||
+ "lp.capitalized_income_type as capitalizedIncomeType, " //
|
+ "lp.capitalized_income_type as capitalizedIncomeType, lp.is_merchant_buy_down_fee as merchantBuyDownFee, " //
|
||||||
+ "lp.enable_buy_down_fee as enableBuyDownFee, " + "lp.buy_down_fee_calculation_type as buyDownFeeCalculationType, "
|
+ "lp.enable_buy_down_fee as enableBuyDownFee, " + "lp.buy_down_fee_calculation_type as buyDownFeeCalculationType, "
|
||||||
+ "lp.buy_down_fee_strategy as buyDownFeeStrategy, " + "lp.buy_down_fee_income_type as buyDownFeeIncomeType "
|
+ "lp.buy_down_fee_strategy as buyDownFeeStrategy, " + "lp.buy_down_fee_income_type as buyDownFeeIncomeType "
|
||||||
+ " from m_product_loan lp " + " left join m_fund f on f.id = lp.fund_id "
|
+ " from m_product_loan lp " + " left join m_fund f on f.id = lp.fund_id "
|
||||||
@@ -579,6 +579,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
rs.getString("buyDownFeeStrategy"));
|
rs.getString("buyDownFeeStrategy"));
|
||||||
final StringEnumOptionData buyDownFeeIncomeType = ApiFacingEnum.getStringEnumOptionData(LoanBuyDownFeeIncomeType.class,
|
final StringEnumOptionData buyDownFeeIncomeType = ApiFacingEnum.getStringEnumOptionData(LoanBuyDownFeeIncomeType.class,
|
||||||
rs.getString("buyDownFeeIncomeType"));
|
rs.getString("buyDownFeeIncomeType"));
|
||||||
|
final boolean merchantBuyDownFee = rs.getBoolean("merchantBuyDownFee");
|
||||||
|
|
||||||
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
return new LoanProductData(id, name, shortName, description, currency, principal, minPrincipal, maxPrincipal, tolerance,
|
||||||
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
numberOfRepayments, minNumberOfRepayments, maxNumberOfRepayments, repaymentEvery, interestRatePerPeriod,
|
||||||
@@ -604,7 +605,8 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
|||||||
fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes,
|
fixedLength, enableAccrualActivityPosting, supportedInterestRefundTypes,
|
||||||
loanChargeOffBehaviour.getValueAsStringEnumOptionData(), interestRecognitionOnDisbursementDate,
|
loanChargeOffBehaviour.getValueAsStringEnumOptionData(), interestRecognitionOnDisbursementDate,
|
||||||
daysInYearCustomStrategy, enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy,
|
daysInYearCustomStrategy, enableIncomeCapitalization, capitalizedIncomeCalculationType, capitalizedIncomeStrategy,
|
||||||
capitalizedIncome, enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType);
|
capitalizedIncome, enableBuyDownFee, buyDownFeeCalculationType, buyDownFeeStrategy, buyDownFeeIncomeType,
|
||||||
|
merchantBuyDownFee);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -263,6 +263,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
enableIncomeCapitalization = (boolean) changes.get(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME);
|
enableIncomeCapitalization = (boolean) changes.get(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME);
|
||||||
}
|
}
|
||||||
boolean enableBuyDownFee = product.getLoanProductRelatedDetail().isEnableBuyDownFee();
|
boolean enableBuyDownFee = product.getLoanProductRelatedDetail().isEnableBuyDownFee();
|
||||||
|
boolean merchantBuyDownFee = product.getLoanProductRelatedDetail().isMerchantBuyDownFee();
|
||||||
if (changes.containsKey(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME)) {
|
if (changes.containsKey(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME)) {
|
||||||
enableBuyDownFee = (boolean) changes.get(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME);
|
enableBuyDownFee = (boolean) changes.get(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME);
|
||||||
}
|
}
|
||||||
@@ -271,7 +272,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
|
|||||||
final boolean accountingTypeChanged = changes.containsKey("accountingRule");
|
final boolean accountingTypeChanged = changes.containsKey("accountingRule");
|
||||||
final Map<String, Object> accountingMappingChanges = this.accountMappingWritePlatformService
|
final Map<String, Object> accountingMappingChanges = this.accountMappingWritePlatformService
|
||||||
.updateLoanProductToGLAccountMapping(product.getId(), command, accountingTypeChanged, product.getAccountingRule(),
|
.updateLoanProductToGLAccountMapping(product.getId(), command, accountingTypeChanged, product.getAccountingRule(),
|
||||||
enableIncomeCapitalization, enableBuyDownFee);
|
enableIncomeCapitalization, enableBuyDownFee, merchantBuyDownFee);
|
||||||
changes.putAll(accountingMappingChanges);
|
changes.putAll(accountingMappingChanges);
|
||||||
|
|
||||||
if (changes.containsKey(LoanProductConstants.RATES_PARAM_NAME)) {
|
if (changes.containsKey(LoanProductConstants.RATES_PARAM_NAME)) {
|
||||||
|
|||||||
+2
-1
@@ -72,7 +72,8 @@ class CreateJournalEntriesForChargeOffLoanTest {
|
|||||||
transactionType, new BigDecimal("500.00"), new BigDecimal("500.00"), null, null, null, null, false, Collections.emptyList(),
|
transactionType, new BigDecimal("500.00"), new BigDecimal("500.00"), null, null, null, null, false, Collections.emptyList(),
|
||||||
Collections.emptyList(), false, "", null, null, null, null);
|
Collections.emptyList(), false, "", null, null, null, null);
|
||||||
|
|
||||||
loanDTO = new LoanDTO(1L, 1L, 1L, "USD", false, true, true, List.of(loanTransactionDTO), false, false, chargeOffReasonId, false);
|
loanDTO = new LoanDTO(1L, 1L, 1L, "USD", false, true, true, List.of(loanTransactionDTO), false, false, chargeOffReasonId, false,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+2
-2
@@ -91,7 +91,7 @@ public class DefaultScheduledDateGeneratorTest {
|
|||||||
DaysInMonthType.ACTUAL, DaysInYearType.ACTUAL, false, null, null, null, null, null, ZERO, null, NONE, null, ZERO,
|
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,
|
EMPTY_LIST, true, 0, false, holidayDetailDTO, false, false, false, null, false, false, null, false, DISBURSEMENT_DATE,
|
||||||
submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null, null, false, null, false, null, null,
|
submittedOnDate, CUMULATIVE, LoanScheduleProcessingType.HORIZONTAL, null, false, null, null, false, null, false, null, null,
|
||||||
null, false, null, null, null);
|
null, false, null, null, null, false);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
List<? extends LoanScheduleModelPeriod> result = underTest.generateRepaymentPeriods(mathContext, expectedDisbursementDate,
|
List<? extends LoanScheduleModelPeriod> result = underTest.generateRepaymentPeriods(mathContext, expectedDisbursementDate,
|
||||||
@@ -172,7 +172,7 @@ public class DefaultScheduledDateGeneratorTest {
|
|||||||
EMPTY_LIST, BigDecimal.valueOf(36_000L), null, DaysInMonthType.ACTUAL, DaysInYearType.ACTUAL, false, null, null, null, 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, 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, null, false, null, null, null, false, null, null, null);
|
false, null, false, null, null, null, false, null, null, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private HolidayDetailDTO createHolidayDTO() {
|
private HolidayDetailDTO createHolidayDTO() {
|
||||||
|
|||||||
+42
-2
@@ -271,7 +271,7 @@ public class LoanBuyDownFeeTest extends BaseLoanIntegrationTest {
|
|||||||
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
|
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
|
||||||
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())
|
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())
|
||||||
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue()).loanScheduleType("PROGRESSIVE")
|
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue()).loanScheduleType("PROGRESSIVE")
|
||||||
.loanScheduleProcessingType("HORIZONTAL").enableBuyDownFee(true)
|
.loanScheduleProcessingType("HORIZONTAL").enableBuyDownFee(true).merchantBuyDownFee(true)
|
||||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE).locale("en").dateFormat("dd MMMM yyyy");
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE).locale("en").dateFormat("dd MMMM yyyy");
|
||||||
@@ -496,7 +496,7 @@ public class LoanBuyDownFeeTest extends BaseLoanIntegrationTest {
|
|||||||
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
||||||
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
|
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
|
||||||
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
|
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue())
|
||||||
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
|
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
|
||||||
|
|
||||||
@@ -865,4 +865,44 @@ public class LoanBuyDownFeeTest extends BaseLoanIntegrationTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuyDownFeeForNonMerchant() {
|
||||||
|
runAt("10 September 2024", () -> {
|
||||||
|
deleteAllExternalEvents();
|
||||||
|
// Add initial buy down fee
|
||||||
|
|
||||||
|
final PostLoanProductsResponse loanProductsResponse = loanProductHelper
|
||||||
|
.createLoanProduct(createProgressiveLoanProductWithBuyDownFee().merchantBuyDownFee(false));
|
||||||
|
|
||||||
|
// Apply for the loan with proper progressive loan settings
|
||||||
|
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applyLP2ProgressiveLoanRequest(clientId,
|
||||||
|
loanProductsResponse.getResourceId(), "01 September 2024", 1000.0, 10.0, 12, null));
|
||||||
|
loanId = postLoansResponse.getLoanId();
|
||||||
|
loanTransactionHelper.approveLoan(loanId, approveLoanRequest(1000.0, "01 September 2024"));
|
||||||
|
disburseLoan(loanId, BigDecimal.valueOf(1000.0), "01 September 2024");
|
||||||
|
|
||||||
|
final Long buyDownFeeTransactionId = addBuyDownFeeForLoan(loanId, 400.0, "10 September 2024");
|
||||||
|
assertNotNull(buyDownFeeTransactionId);
|
||||||
|
|
||||||
|
verifyTransactions(loanId, //
|
||||||
|
transaction(1000.0, "Disbursement", "01 September 2024"), //
|
||||||
|
transaction(400.0, "Buy Down Fee", "10 September 2024"));
|
||||||
|
|
||||||
|
// Verify initial buy down fee (non merchant) accounting entries
|
||||||
|
verifyTRJournalEntries(buyDownFeeTransactionId, debit(fundSource, 400.0), credit(deferredIncomeLiabilityAccount, 400.0));
|
||||||
|
|
||||||
|
// Reverse Buy Down Fee (non merchant)
|
||||||
|
PostLoansLoanIdTransactionsResponse transactionsResponse = loanTransactionHelper.reverseLoanTransaction(loanId,
|
||||||
|
buyDownFeeTransactionId, new PostLoansLoanIdTransactionsTransactionIdRequest().dateFormat(DATETIME_PATTERN)
|
||||||
|
.transactionDate("10 September 2024").note("Buy Down Fee reversed").transactionAmount(0.0).locale("en"));
|
||||||
|
Assertions.assertNotNull(transactionsResponse);
|
||||||
|
Assertions.assertNotNull(transactionsResponse.getResourceId());
|
||||||
|
Assertions.assertEquals(transactionsResponse.getResourceId(), buyDownFeeTransactionId);
|
||||||
|
|
||||||
|
// Verify initial buy down fee (non merchant) reversed accounting entries
|
||||||
|
verifyTRJournalEntries(buyDownFeeTransactionId, debit(fundSource, 400.0), credit(deferredIncomeLiabilityAccount, 400.0),
|
||||||
|
credit(fundSource, 400.0), debit(deferredIncomeLiabilityAccount, 400.0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-8
@@ -259,7 +259,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
|
|||||||
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
||||||
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
|
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
|
||||||
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
|
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
|
||||||
|
|
||||||
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
|
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
|
||||||
@@ -339,7 +339,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
|
|||||||
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
.enableBuyDownFee(true).buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
||||||
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
|
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
|
||||||
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
|
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue()));
|
||||||
|
|
||||||
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
|
final GetLoanProductsProductIdResponse loanProductsProductIdResponse = loanProductHelper
|
||||||
@@ -404,7 +404,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
|
|||||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
||||||
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
|
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
|
||||||
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
|
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +414,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
|
|||||||
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
||||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
||||||
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
|
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
|
||||||
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
|
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,7 +424,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
|
|||||||
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
||||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
||||||
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
|
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
|
||||||
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
|
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,7 +434,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
|
|||||||
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
||||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||||
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())
|
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue()).merchantBuyDownFee(true)
|
||||||
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
|
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +444,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
|
|||||||
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
||||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE).merchantBuyDownFee(true)
|
||||||
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
|
.incomeFromBuyDownAccountId(feeIncomeAccount.getAccountID().longValue())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +454,7 @@ public class LoanProductTest extends BaseLoanIntegrationTest {
|
|||||||
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
() -> loanProductHelper.createLoanProduct(create4IProgressive().enableBuyDownFee(true)
|
||||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)
|
||||||
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
.buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE)
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.FEE).merchantBuyDownFee(true)
|
||||||
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())));
|
.buyDownExpenseAccountId(buyDownExpenseAccount.getAccountID().longValue())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -206,7 +206,7 @@ public class LoanTransactionTest extends BaseLoanIntegrationTest {
|
|||||||
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
|
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive()
|
||||||
.enableBuyDownFee(true).buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)//
|
.enableBuyDownFee(true).buyDownFeeStrategy(PostLoanProductsRequest.BuyDownFeeStrategyEnum.EQUAL_AMORTIZATION)//
|
||||||
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)//
|
.buyDownFeeCalculationType(PostLoanProductsRequest.BuyDownFeeCalculationTypeEnum.FLAT)//
|
||||||
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.INTEREST)//
|
.buyDownFeeIncomeType(PostLoanProductsRequest.BuyDownFeeIncomeTypeEnum.INTEREST).merchantBuyDownFee(true)//
|
||||||
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue()) //
|
.deferredIncomeLiabilityAccountId(deferredIncomeLiabilityAccount.getAccountID().longValue()) //
|
||||||
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue()) //
|
.incomeFromCapitalizationAccountId(feeIncomeAccount.getAccountID().longValue()) //
|
||||||
.capitalizedIncomeType(PostLoanProductsRequest.CapitalizedIncomeTypeEnum.FEE) //
|
.capitalizedIncomeType(PostLoanProductsRequest.CapitalizedIncomeTypeEnum.FEE) //
|
||||||
|
|||||||
+8
-2
@@ -167,6 +167,7 @@ public class LoanProductTestBuilder {
|
|||||||
private String chargeOffBehaviour;
|
private String chargeOffBehaviour;
|
||||||
private boolean interestRecognitionOnDisbursementDate = false;
|
private boolean interestRecognitionOnDisbursementDate = false;
|
||||||
private Boolean enableBuyDownFee = false;
|
private Boolean enableBuyDownFee = false;
|
||||||
|
private Boolean merchantBuyDownFee = false;
|
||||||
private String buyDownFeeCalculationType;
|
private String buyDownFeeCalculationType;
|
||||||
|
|
||||||
public String build() {
|
public String build() {
|
||||||
@@ -347,8 +348,8 @@ public class LoanProductTestBuilder {
|
|||||||
map.put("enableBuyDownFee", this.enableBuyDownFee);
|
map.put("enableBuyDownFee", this.enableBuyDownFee);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.buyDownFeeCalculationType != null) {
|
if (this.merchantBuyDownFee != null) {
|
||||||
map.put("buyDownFeeCalculationType", this.buyDownFeeCalculationType);
|
map.put("merchantBuyDownFee", this.merchantBuyDownFee);
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
@@ -921,6 +922,11 @@ public class LoanProductTestBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoanProductTestBuilder withMerchantBuyDownFee(final Boolean merchantBuyDownFee) {
|
||||||
|
this.merchantBuyDownFee = merchantBuyDownFee;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public LoanProductTestBuilder withBuyDownFeeCalculationType(final String buyDownFeeCalculationType) {
|
public LoanProductTestBuilder withBuyDownFeeCalculationType(final String buyDownFeeCalculationType) {
|
||||||
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
this.buyDownFeeCalculationType = buyDownFeeCalculationType;
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
Reference in New Issue
Block a user