From c0859f4fdacc13600c0a4623941dec16a8199f2d Mon Sep 17 00:00:00 2001 From: a7med3del1973 Date: Fri, 4 Jul 2025 21:21:38 +0300 Subject: [PATCH] FINERACT-2182: Group creation fails due to NullPointerException when random-account-number=enabled --- .../service/AccountNumberGenerator.java | 50 +++++++----- .../AccountNumberGeneratorTest.java | 78 +++++++++++++++++++ 2 files changed, 110 insertions(+), 18 deletions(-) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountNumberGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountNumberGenerator.java index 2106ce8fa..8205b1657 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountNumberGenerator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountNumberGenerator.java @@ -193,28 +193,42 @@ public class AccountNumberGenerator { return accountNumber; } - private Boolean checkAccountNumberConflict(Map propertyMap, AccountNumberFormat accountNumberFormat, + public Boolean checkAccountNumberConflict(Map propertyMap, AccountNumberFormat accountNumberFormat, String accountNumber) { String entityType = propertyMap.get(ENTITY_TYPE); - Boolean randomNumberConflict = false; - if (entityType.equals("client")) { // avoid duplication it will loop until it finds new random account no. - - Client client = this.clientRepository.getClientByAccountNumber(accountNumber); - if (client != null) { - randomNumberConflict = true; - } - } else if (entityType.equals("loan")) { - Loan loan = this.loanRepository.findLoanAccountByAccountNumber(accountNumber); - if (loan != null) { - randomNumberConflict = true; - } - } else if (entityType.equals("savingsAccount")) { - SavingsAccount savingsAccount = this.savingsAccountRepository.findSavingsAccountByAccountNumber(accountNumber); - if (savingsAccount != null) { - randomNumberConflict = true; - } + if (entityType == null) { // No entityType in map -> cannot check for conflicts. + return false; } + + boolean randomNumberConflict = false; + + switch (entityType) { + case "client": // avoid duplication it will loop until it finds new random account no. + Client client = this.clientRepository.getClientByAccountNumber(accountNumber); + if (client != null) { + randomNumberConflict = true; + } + break; + + case "loan": + Loan loan = this.loanRepository.findLoanAccountByAccountNumber(accountNumber); + if (loan != null) { + randomNumberConflict = true; + } + break; + + case "savingsAccount": + SavingsAccount savingsAccount = this.savingsAccountRepository.findSavingsAccountByAccountNumber(accountNumber); + if (savingsAccount != null) { + randomNumberConflict = true; + } + break; + + default: + break; + } + return randomNumberConflict; } diff --git a/fineract-provider/src/test/java/org/apache/fineract/portfolio/account/jobs/executestandinginstructions/AccountNumberGeneratorTest.java b/fineract-provider/src/test/java/org/apache/fineract/portfolio/account/jobs/executestandinginstructions/AccountNumberGeneratorTest.java index f10034389..29290fe7a 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/portfolio/account/jobs/executestandinginstructions/AccountNumberGeneratorTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/portfolio/account/jobs/executestandinginstructions/AccountNumberGeneratorTest.java @@ -22,6 +22,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.util.HashMap; +import java.util.Map; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormat; import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; @@ -142,4 +144,80 @@ public class AccountNumberGeneratorTest { String accountNumber = generator.generate(share, format); assertThat(accountNumber).isEqualTo("000000321"); } + + @Test + public void testCheckAccountNumberConflict_nullEntityType_returnsFalse() { + Map props = new HashMap<>(); + boolean result = generator.checkAccountNumberConflict(props, null, "12345"); + assertThat(result).isFalse(); + } + + @Test + public void testCheckAccountNumberConflict_clientNoConflict() { + Map props = new HashMap<>(); + props.put("entityType", "client"); + when(clientRepo.getClientByAccountNumber("12345")).thenReturn(null); + + boolean result = generator.checkAccountNumberConflict(props, null, "12345"); + assertThat(result).isFalse(); + } + + @Test + public void testCheckAccountNumberConflict_clientWithConflict() { + Map props = new HashMap<>(); + props.put("entityType", "client"); + when(clientRepo.getClientByAccountNumber("12345")).thenReturn(mock(Client.class)); + + boolean result = generator.checkAccountNumberConflict(props, null, "12345"); + assertThat(result).isTrue(); + } + + @Test + public void testCheckAccountNumberConflict_loanNoConflict() { + Map props = new HashMap<>(); + props.put("entityType", "loan"); + when(loanRepo.findLoanAccountByAccountNumber("77777")).thenReturn(null); + + boolean result = generator.checkAccountNumberConflict(props, null, "77777"); + assertThat(result).isFalse(); + } + + @Test + public void testCheckAccountNumberConflict_loanWithConflict() { + Map props = new HashMap<>(); + props.put("entityType", "loan"); + when(loanRepo.findLoanAccountByAccountNumber("77777")).thenReturn(mock(Loan.class)); + + boolean result = generator.checkAccountNumberConflict(props, null, "77777"); + assertThat(result).isTrue(); + } + + @Test + public void testCheckAccountNumberConflict_savingsNoConflict() { + Map props = new HashMap<>(); + props.put("entityType", "savingsAccount"); + when(savingsRepo.findSavingsAccountByAccountNumber("55555")).thenReturn(null); + + boolean result = generator.checkAccountNumberConflict(props, null, "55555"); + assertThat(result).isFalse(); + } + + @Test + public void testCheckAccountNumberConflict_savingsWithConflict() { + Map props = new HashMap<>(); + props.put("entityType", "savingsAccount"); + when(savingsRepo.findSavingsAccountByAccountNumber("55555")).thenReturn(mock(SavingsAccount.class)); + + boolean result = generator.checkAccountNumberConflict(props, null, "55555"); + assertThat(result).isTrue(); + } + + @Test + public void testCheckAccountNumberConflict_unknownEntityType_returnsFalse() { + Map props = new HashMap<>(); + props.put("entityType", "foobar"); + + boolean result = generator.checkAccountNumberConflict(props, null, "12345"); + assertThat(result).isFalse(); + } }