Skip to content

Commit e2f481f

Browse files
Jose Alberto Hernandezadamsaghy
authored andcommitted
FINERACT-2181: Capitalized Income and Buy Down Fees accounting values are still displayed on loan product after feature disabled
1 parent 9e15e45 commit e2f481f

6 files changed

Lines changed: 88 additions & 28 deletions

File tree

fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingHelper.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,15 @@ public GLAccount getAccountByIdAndType(final String paramName, final List<GLAcco
559559
return glAccount;
560560
}
561561

562+
public void deleteProductToGLAccountMapping(final Long loanProductId, final PortfolioProductType portfolioProductType,
563+
final int accountTypeId) {
564+
final ProductToGLAccountMapping accountMapping = this.accountMappingRepository.findCoreProductToFinAccountMapping(loanProductId,
565+
portfolioProductType.getValue(), accountTypeId);
566+
if (accountMapping != null && accountMapping.getGlAccount() != null) {
567+
this.accountMappingRepository.delete(accountMapping);
568+
}
569+
}
570+
562571
public void deleteProductToGLAccountMapping(final Long loanProductId, final PortfolioProductType portfolioProductType) {
563572
final List<ProductToGLAccountMapping> productToGLAccountMappings = this.accountMappingRepository
564573
.findByProductIdAndProductType(loanProductId, portfolioProductType.getValue());

fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingWritePlatformService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public interface ProductToGLAccountMappingWritePlatformService {
3030
void createSavingProductToGLAccountMapping(Long savingProductId, JsonCommand command, DepositAccountType accountType);
3131

3232
Map<String, Object> updateLoanProductToGLAccountMapping(Long loanProductId, JsonCommand command, boolean accountingRuleChanged,
33-
AccountingRuleType accountingRuleTypeId);
33+
AccountingRuleType accountingRuleTypeId, boolean enableIncomeCapitalization, boolean enableBuyDownFee);
3434

3535
Map<String, Object> updateSavingsProductToGLAccountMapping(Long savingsProductId, JsonCommand command, boolean accountingRuleChanged,
3636
int accountingRuleTypeId, DepositAccountType accountType);

fineract-loan/src/main/java/org/apache/fineract/accounting/productaccountmapping/service/LoanProductToGLAccountMappingHelper.java

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,8 @@ private void populateChangesForCashBasedAccounting(final Map<String, Object> cha
255255
* @param accountingRuleType
256256
*/
257257
public void handleChangesToLoanProductToGLAccountMappings(final Long loanProductId, final Map<String, Object> changes,
258-
final JsonElement element, final AccountingRuleType accountingRuleType) {
258+
final JsonElement element, final AccountingRuleType accountingRuleType, final boolean enableIncomeCapitalization,
259+
final boolean enableBuyDownFee) {
259260
switch (accountingRuleType) {
260261
case NONE:
261262
break;
@@ -365,12 +366,22 @@ public void handleChangesToLoanProductToGLAccountMappings(final Long loanProduct
365366
mergeLoanToIncomeAccountMappingChanges(element, LoanProductAccountingParams.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(),
366367
loanProductId, AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY.getValue(),
367368
AccrualAccountsForLoan.INCOME_FROM_GOODWILL_CREDIT_PENALTY.toString(), changes);
368-
mergeLoanToIncomeAccountMappingChanges(element, LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue(),
369-
loanProductId, AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.getValue(),
370-
AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.toString(), changes);
371-
mergeLoanToIncomeAccountMappingChanges(element, LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue(), loanProductId,
372-
AccrualAccountsForLoan.INCOME_FROM_BUY_DOWN.getValue(), AccrualAccountsForLoan.INCOME_FROM_BUY_DOWN.toString(),
373-
changes);
369+
if (!enableIncomeCapitalization) {
370+
deleteProductToGLAccountMapping(loanProductId, PortfolioProductType.LOAN,
371+
AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.getValue());
372+
} else {
373+
mergeLoanToIncomeAccountMappingChanges(element, LoanProductAccountingParams.INCOME_FROM_CAPITALIZATION.getValue(),
374+
loanProductId, AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.getValue(),
375+
AccrualAccountsForLoan.INCOME_FROM_CAPITALIZATION.toString(), changes);
376+
}
377+
if (!enableBuyDownFee) {
378+
deleteProductToGLAccountMapping(loanProductId, PortfolioProductType.LOAN,
379+
AccrualAccountsForLoan.INCOME_FROM_BUY_DOWN.getValue());
380+
} else {
381+
mergeLoanToIncomeAccountMappingChanges(element, LoanProductAccountingParams.INCOME_FROM_BUY_DOWN.getValue(),
382+
loanProductId, AccrualAccountsForLoan.INCOME_FROM_BUY_DOWN.getValue(),
383+
AccrualAccountsForLoan.INCOME_FROM_BUY_DOWN.toString(), changes);
384+
}
374385

375386
// expenses
376387
mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.LOSSES_WRITTEN_OFF.getValue(), loanProductId,
@@ -384,15 +395,26 @@ public void handleChangesToLoanProductToGLAccountMappings(final Long loanProduct
384395
mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.CHARGE_OFF_FRAUD_EXPENSE.getValue(),
385396
loanProductId, AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(),
386397
AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.toString(), changes);
387-
mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), loanProductId,
388-
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue(), AccrualAccountsForLoan.BUY_DOWN_EXPENSE.toString(), changes);
398+
if (!enableBuyDownFee) {
399+
deleteProductToGLAccountMapping(loanProductId, PortfolioProductType.LOAN,
400+
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue());
401+
} else {
402+
mergeLoanToExpenseAccountMappingChanges(element, LoanProductAccountingParams.BUY_DOWN_EXPENSE.getValue(), loanProductId,
403+
AccrualAccountsForLoan.BUY_DOWN_EXPENSE.getValue(), AccrualAccountsForLoan.BUY_DOWN_EXPENSE.toString(),
404+
changes);
405+
}
389406

390407
// liabilities
391408
mergeLoanToLiabilityAccountMappingChanges(element, LoanProductAccountingParams.OVERPAYMENT.getValue(), loanProductId,
392409
CashAccountsForLoan.OVERPAYMENT.getValue(), CashAccountsForLoan.OVERPAYMENT.toString(), changes);
393-
mergeLoanToLiabilityAccountMappingChanges(element, LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue(),
394-
loanProductId, AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY.getValue(),
395-
AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY.toString(), changes);
410+
if (!enableBuyDownFee && !enableIncomeCapitalization) {
411+
deleteProductToGLAccountMapping(loanProductId, PortfolioProductType.LOAN,
412+
AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY.getValue());
413+
} else {
414+
mergeLoanToLiabilityAccountMappingChanges(element, LoanProductAccountingParams.DEFERRED_INCOME_LIABILITY.getValue(),
415+
loanProductId, AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY.getValue(),
416+
AccrualAccountsForLoan.DEFERRED_INCOME_LIABILITY.toString(), changes);
417+
}
396418
break;
397419
}
398420
}

fineract-provider/src/main/java/org/apache/fineract/accounting/productaccountmapping/service/ProductToGLAccountMappingWritePlatformServiceImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ public void createShareProductToGLAccountMapping(final Long shareProductId, fina
369369
@Override
370370
@Transactional
371371
public Map<String, Object> updateLoanProductToGLAccountMapping(final Long loanProductId, final JsonCommand command,
372-
final boolean accountingRuleChanged, final AccountingRuleType accountingRuleType) {
372+
final boolean accountingRuleChanged, final AccountingRuleType accountingRuleType, final boolean enableIncomeCapitalization,
373+
final boolean enableBuyDownFee) {
373374
/***
374375
* Variable tracks all accounting mapping properties that have been updated
375376
***/
@@ -389,7 +390,7 @@ public Map<String, Object> updateLoanProductToGLAccountMapping(final Long loanPr
389390
} /*** else examine and update individual changes ***/
390391
else {
391392
this.loanProductToGLAccountMappingHelper.handleChangesToLoanProductToGLAccountMappings(loanProductId, changes, element,
392-
accountingRuleType);
393+
accountingRuleType, enableIncomeCapitalization, enableBuyDownFee);
393394
this.loanProductToGLAccountMappingHelper.updatePaymentChannelToFundSourceMappings(command, element, loanProductId, changes);
394395
this.loanProductToGLAccountMappingHelper.updateChargesToIncomeAccountMappings(command, element, loanProductId, changes);
395396
this.loanProductToGLAccountMappingHelper.updateChargeOffReasonToExpenseAccountMappings(command, element, loanProductId,

fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,20 @@ public CommandProcessingResult updateLoanProduct(final Long loanProductId, final
258258
}
259259
}
260260

261+
boolean enableIncomeCapitalization = product.getLoanProductRelatedDetail().isEnableIncomeCapitalization();
262+
if (changes.containsKey(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME)) {
263+
enableIncomeCapitalization = (boolean) changes.get(LoanProductConstants.ENABLE_INCOME_CAPITALIZATION_PARAM_NAME);
264+
}
265+
boolean enableBuyDownFee = product.getLoanProductRelatedDetail().isEnableBuyDownFee();
266+
if (changes.containsKey(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME)) {
267+
enableBuyDownFee = (boolean) changes.get(LoanProductConstants.ENABLE_BUY_DOWN_FEE_PARAM_NAME);
268+
}
269+
261270
// accounting related changes
262271
final boolean accountingTypeChanged = changes.containsKey("accountingRule");
263272
final Map<String, Object> accountingMappingChanges = this.accountMappingWritePlatformService
264-
.updateLoanProductToGLAccountMapping(product.getId(), command, accountingTypeChanged, product.getAccountingRule());
273+
.updateLoanProductToGLAccountMapping(product.getId(), command, accountingTypeChanged, product.getAccountingRule(),
274+
enableIncomeCapitalization, enableBuyDownFee);
265275
changes.putAll(accountingMappingChanges);
266276

267277
if (changes.containsKey(LoanProductConstants.RATES_PARAM_NAME)) {

integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductTest.java

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,12 @@ public void testIncomeCapitalizationUpdateProduct() {
156156
loanProductsProductIdResponse.getCapitalizedIncomeType().getCode());
157157

158158
loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(),
159-
new PutLoanProductsProductIdRequest().enableIncomeCapitalization(false)
159+
new PutLoanProductsProductIdRequest()
160160
.incomeFromCapitalizationAccountId(interestIncomeAccount.getAccountID().longValue())
161161
.capitalizedIncomeType(PutLoanProductsProductIdRequest.CapitalizedIncomeTypeEnum.INTEREST));
162-
163-
final GetLoanProductsProductIdResponse updatedLoanProductsProductIdResponse = loanProductHelper
162+
GetLoanProductsProductIdResponse updatedLoanProductsProductIdResponse = loanProductHelper
164163
.retrieveLoanProductById(loanProductsResponse.getResourceId());
165-
Assertions.assertEquals(Boolean.FALSE, updatedLoanProductsProductIdResponse.getEnableIncomeCapitalization());
164+
Assertions.assertEquals(Boolean.TRUE, updatedLoanProductsProductIdResponse.getEnableIncomeCapitalization());
166165
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getCapitalizedIncomeCalculationType());
167166
Assertions.assertEquals(LoanCapitalizedIncomeCalculationType.FLAT.getCode(),
168167
updatedLoanProductsProductIdResponse.getCapitalizedIncomeCalculationType().getCode());
@@ -172,6 +171,14 @@ public void testIncomeCapitalizationUpdateProduct() {
172171
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getAccountingMappings());
173172
Assertions.assertEquals(interestIncomeAccount.getAccountID().longValue(),
174173
updatedLoanProductsProductIdResponse.getAccountingMappings().getIncomeFromCapitalizationAccount().getId());
174+
175+
loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(),
176+
new PutLoanProductsProductIdRequest().enableIncomeCapitalization(false));
177+
178+
updatedLoanProductsProductIdResponse = loanProductHelper.retrieveLoanProductById(loanProductsResponse.getResourceId());
179+
Assertions.assertEquals(Boolean.FALSE, updatedLoanProductsProductIdResponse.getEnableIncomeCapitalization());
180+
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getAccountingMappings());
181+
Assertions.assertNull(updatedLoanProductsProductIdResponse.getAccountingMappings().getIncomeFromCapitalizationAccount());
175182
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getCapitalizedIncomeType());
176183
Assertions.assertEquals(LoanCapitalizedIncomeType.INTEREST.getCode(),
177184
updatedLoanProductsProductIdResponse.getCapitalizedIncomeType().getCode());
@@ -355,28 +362,39 @@ public void testBuyDownFeeUpdateProduct() {
355362
loanProductsProductIdResponse.getAccountingMappings().getIncomeFromBuyDownAccount().getId());
356363

357364
loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(),
358-
new PutLoanProductsProductIdRequest().enableBuyDownFee(false)
365+
new PutLoanProductsProductIdRequest()
359366
.buyDownFeeIncomeType(PutLoanProductsProductIdRequest.BuyDownFeeIncomeTypeEnum.INTEREST)
360367
.incomeFromBuyDownAccountId(interestIncomeAccount.getAccountID().longValue()));
361368

362-
final GetLoanProductsProductIdResponse updatedLoanProductsProductIdResponse = loanProductHelper
369+
GetLoanProductsProductIdResponse updatedLoanProductsProductIdResponse = loanProductHelper
363370
.retrieveLoanProductById(loanProductsResponse.getResourceId());
364-
Assertions.assertEquals(Boolean.FALSE, updatedLoanProductsProductIdResponse.getEnableBuyDownFee());
365-
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeCalculationType());
366-
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(),
367-
updatedLoanProductsProductIdResponse.getBuyDownFeeCalculationType().getCode());
368-
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeStrategy());
371+
Assertions.assertEquals(Boolean.TRUE, updatedLoanProductsProductIdResponse.getEnableBuyDownFee());
369372
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(),
370373
updatedLoanProductsProductIdResponse.getBuyDownFeeStrategy().getCode());
371374
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeIncomeType());
372375
Assertions.assertEquals(LoanBuyDownFeeIncomeType.INTEREST.getCode(),
373376
updatedLoanProductsProductIdResponse.getBuyDownFeeIncomeType().getCode());
374-
375377
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getAccountingMappings());
376378
Assertions.assertEquals(buyDownExpenseAccount.getAccountID().longValue(),
377379
updatedLoanProductsProductIdResponse.getAccountingMappings().getBuyDownExpenseAccount().getId());
378380
Assertions.assertEquals(interestIncomeAccount.getAccountID().longValue(),
379381
updatedLoanProductsProductIdResponse.getAccountingMappings().getIncomeFromBuyDownAccount().getId());
382+
383+
loanProductHelper.updateLoanProductById(loanProductsResponse.getResourceId(),
384+
new PutLoanProductsProductIdRequest().enableBuyDownFee(false));
385+
386+
updatedLoanProductsProductIdResponse = loanProductHelper.retrieveLoanProductById(loanProductsResponse.getResourceId());
387+
Assertions.assertEquals(Boolean.FALSE, updatedLoanProductsProductIdResponse.getEnableBuyDownFee());
388+
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeCalculationType());
389+
Assertions.assertEquals(LoanBuyDownFeeCalculationType.FLAT.getCode(),
390+
updatedLoanProductsProductIdResponse.getBuyDownFeeCalculationType().getCode());
391+
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeStrategy());
392+
Assertions.assertEquals(LoanBuyDownFeeStrategy.EQUAL_AMORTIZATION.getCode(),
393+
updatedLoanProductsProductIdResponse.getBuyDownFeeStrategy().getCode());
394+
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getBuyDownFeeIncomeType());
395+
Assertions.assertNotNull(updatedLoanProductsProductIdResponse.getAccountingMappings());
396+
Assertions.assertNull(updatedLoanProductsProductIdResponse.getAccountingMappings().getBuyDownExpenseAccount());
397+
Assertions.assertNull(updatedLoanProductsProductIdResponse.getAccountingMappings().getIncomeFromBuyDownAccount());
380398
}
381399

382400
@Test

0 commit comments

Comments
 (0)