From 1f00bb6d33284c5bc6d974ecbf7eb00938d400fe Mon Sep 17 00:00:00 2001 From: Jose Alberto Hernandez Date: Fri, 26 Jan 2024 14:56:01 -0600 Subject: [PATCH] FINERACT-1971: Fix Delinquency bucket error upon Loan product editing --- .../loanproduct/domain/LoanProduct.java | 2 +- .../LoanProductReadPlatformServiceImpl.java | 2 +- ...tWritePlatformServiceJpaRepositoryImpl.java | 18 ++++++++++++------ .../DelinquencyBucketsIntegrationTest.java | 8 ++++++++ .../common/loans/LoanTransactionHelper.java | 7 +++++++ 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java index 8bf064ae5..6db51d8e5 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java @@ -209,7 +209,7 @@ public class LoanProduct extends AbstractPersistableCustom { private Integer overAppliedNumber; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "delinquency_bucket_id") + @JoinColumn(name = "delinquency_bucket_id", nullable = true) private DelinquencyBucket delinquencyBucket; @Column(name = "enable_installment_level_delinquency", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java index a672db512..91b10f463 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java @@ -501,7 +501,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo final boolean isRatesEnabled = false; // Delinquency Buckets - final Long delinquencyBucketId = rs.getLong("delinquencyBucketId"); + final Long delinquencyBucketId = JdbcSupport.getLong(rs, "delinquencyBucketId"); final String delinquencyBucketName = rs.getString("delinquencyBucketName"); final DelinquencyBucketData delinquencyBucket = new DelinquencyBucketData(delinquencyBucketId, delinquencyBucketName, new ArrayList<>()); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java index 6f94cbda3..f06014aa2 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java @@ -127,9 +127,8 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro loanRepaymentScheduleTransactionProcessorFactory.determineProcessor(loanTransactionProcessingStrategyCode).getName()); if (command.parameterExists("delinquencyBucketId")) { - DelinquencyBucket delinquencyBucket = this.delinquencyBucketRepository - .getReferenceById(command.longValueOfParameterNamed("delinquencyBucketId")); - loanProduct.setDelinquencyBucket(delinquencyBucket); + loanProduct + .setDelinquencyBucket(findDelinquencyBucketIdIfProvided(command.longValueOfParameterNamed("delinquencyBucketId"))); } this.loanProductRepository.saveAndFlush(loanProduct); @@ -168,6 +167,15 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro return fund; } + private DelinquencyBucket findDelinquencyBucketIdIfProvided(final Long delinquencyBucketId) { + DelinquencyBucket delinquencyBucket = null; + if (delinquencyBucketId != null) { + delinquencyBucket = delinquencyBucketRepository.findById(delinquencyBucketId) + .orElseThrow(() -> new FundNotFoundException(delinquencyBucketId)); + } + return delinquencyBucket; + } + @Transactional @Override public CommandProcessingResult updateLoanProduct(final Long loanProductId, final JsonCommand command) { @@ -201,9 +209,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro } if (changes.containsKey("delinquencyBucketId")) { - final Long delinquencyBucketId = (Long) changes.get("delinquencyBucketId"); - final DelinquencyBucket delinquencyBucket = this.delinquencyBucketRepository.getReferenceById(delinquencyBucketId); - product.setDelinquencyBucket(delinquencyBucket); + product.setDelinquencyBucket(findDelinquencyBucketIdIfProvided((Long) changes.get("delinquencyBucketId"))); } if (changes.containsKey("transactionProcessingStrategyCode")) { diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyBucketsIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyBucketsIntegrationTest.java index 80b8e9669..9b3953a6d 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyBucketsIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyBucketsIntegrationTest.java @@ -285,12 +285,20 @@ public class DelinquencyBucketsIntegrationTest { // Loan product creation without Delinquency bucket GetLoanProductsProductIdResponse getLoanProductResponse = createLoanProduct(loanTransactionHelper, null, null); assertNotNull(getLoanProductResponse); + assertNull(getLoanProductResponse.getDelinquencyBucket().getId()); // Loan product creation with Delinquency bucket getLoanProductResponse = createLoanProduct(loanTransactionHelper, Math.toIntExact(delinquencyBucket.getId()), null); assertNotNull(getLoanProductResponse); log.info("Loan Product Bucket Name: {}", getLoanProductResponse.getDelinquencyBucket().getName()); assertEquals(getLoanProductResponse.getDelinquencyBucket().getName(), delinquencyBucket.getName()); + + // Update Loan product to remove the Delinquency bucket + final Long loanProductId = getLoanProductResponse.getId(); + loanTransactionHelper.updateLoanProduct(loanProductId, "{delinquencyBucketId: null}"); + getLoanProductResponse = loanTransactionHelper.getLoanProduct(loanProductId.intValue()); + assertNotNull(getLoanProductResponse); + assertNull(getLoanProductResponse.getDelinquencyBucket().getId()); } @Test diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java index c00dcac23..3d3de0628 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java @@ -100,6 +100,7 @@ import org.apache.poi.ss.usermodel.Workbook; public class LoanTransactionHelper extends IntegrationTest { public static final String DATE_TIME_FORMAT = "dd MMMM yyyy HH:mm"; + private static final String LOAN_PRODUCTS_URL = "/fineract-provider/api/v1/loanproducts"; private static final String CREATE_LOAN_PRODUCT_URL = "/fineract-provider/api/v1/loanproducts?" + Utils.TENANT_IDENTIFIER; private static final String APPLY_LOAN_URL = "/fineract-provider/api/v1/loans?" + Utils.TENANT_IDENTIFIER; private static final String LOAN_ACCOUNT_URL = "/fineract-provider/api/v1/loans"; @@ -1975,4 +1976,10 @@ public class LoanTransactionHelper extends IntegrationTest { final String ADD_CHARGES_URL = LOAN_ACCOUNT_URL + "/" + loanId + "/charges?" + Utils.TENANT_IDENTIFIER; return Utils.performServerPost(requestSpec, responseSpec, ADD_CHARGES_URL, request, jsonAttributeToGetBack); } + + public Object updateLoanProduct(final Long loanProductId, final String request) { + final String UPDATE_LOAN_PRODUCT_URL = LOAN_PRODUCTS_URL + "/" + loanProductId + "?" + Utils.TENANT_IDENTIFIER; + return Utils.performServerPut(requestSpec, responseSpec, UPDATE_LOAN_PRODUCT_URL, request, null); + } + }