diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/group/data/CenterData.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/group/data/CenterData.java index 98df9b5f27f..75480ed8445 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/group/data/CenterData.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/group/data/CenterData.java @@ -259,6 +259,10 @@ public CalendarData getCollectionMeetingCalendar() { return collectionMeetingCalendar; } + public String getExternalId() { + return this.externalId; + } + public String getStaffName() { return this.staffName; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/CentersApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/CentersApiResourceSwagger.java index edfdb422193..cb90c6e95bc 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/CentersApiResourceSwagger.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/CentersApiResourceSwagger.java @@ -94,6 +94,8 @@ private GetCentersStatus() {} public Boolean active; @Schema(example = "Center 1") public String name; + @Schema(example = "EXT-001") + public String externalId; @Schema(example = "1") public Long officeId; @Schema(example = "Head Office") @@ -119,6 +121,8 @@ private GetCentersCenterIdResponse() {} public Boolean active; @Schema(example = "First Center (No groups)") public String name; + @Schema(example = "EXT-001") + public String externalId; @Schema(example = "1") public Long officeId; @Schema(example = "Head Office") diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/GroupsApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/GroupsApiResourceSwagger.java index a7805647e55..4dbd951d1f0 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/GroupsApiResourceSwagger.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/api/GroupsApiResourceSwagger.java @@ -138,6 +138,8 @@ private GetGroupsStatus() {} public Long id; @Schema(example = "AnotherGroup") public String name; + @Schema(example = "000-1A") + public String externalId; public GetGroupsStatus status; @Schema(example = "false") public Boolean active; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/AllGroupTypesDataMapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/AllGroupTypesDataMapper.java index 3a0ede7aca3..f59f6ac927e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/AllGroupTypesDataMapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/AllGroupTypesDataMapper.java @@ -80,7 +80,8 @@ public GroupGeneralData mapRow(final ResultSet rs, @SuppressWarnings("unused") f final Long id = rs.getLong("id"); final String accountNo = rs.getString("accountNumber"); final String name = rs.getString("name"); - final String externalId = rs.getString("externalId"); + final String rawExternalId = rs.getString("externalId"); + final String externalId = rawExternalId != null && !rawExternalId.isBlank() ? rawExternalId : "null"; final Integer statusEnum = JdbcSupport.getInteger(rs, "statusEnum"); final EnumOptionData status = ClientEnumerations.status(statusEnum); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/CenterReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/CenterReadPlatformServiceImpl.java index fff763625a4..01605a25b29 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/CenterReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/CenterReadPlatformServiceImpl.java @@ -146,7 +146,8 @@ public CenterData mapRow(final ResultSet rs, @SuppressWarnings("unused") final i final Integer statusEnum = JdbcSupport.getInteger(rs, "statusEnum"); final EnumOptionData status = GroupingTypeEnumerations.status(statusEnum); final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate"); - final String externalId = rs.getString("externalId"); + final String rawExternalId = rs.getString("externalId"); + final String externalId = rawExternalId != null && !rawExternalId.isBlank() ? rawExternalId : "null"; final Long officeId = rs.getLong("officeId"); final String officeName = rs.getString("officeName"); final Long staffId = JdbcSupport.getLong(rs, "staffId"); @@ -267,7 +268,8 @@ public GroupGeneralData mapRow(final ResultSet rs, @SuppressWarnings("unused") f final Long id = rs.getLong("id"); final String accountNo = rs.getString("accountNo"); final String name = rs.getString("name"); - final String externalId = rs.getString("externalId"); + final String rawExternalId = rs.getString("externalId"); + final String externalId = rawExternalId != null && !rawExternalId.isBlank() ? rawExternalId : "null"; final Integer statusEnum = JdbcSupport.getInteger(rs, "statusEnum"); final EnumOptionData status = ClientEnumerations.status(statusEnum); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java index 830412c52a6..9adad8816bc 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -123,7 +124,10 @@ private CommandProcessingResult createGroupingType(final JsonCommand command, fi try { final String accountNo = command.stringValueOfParameterNamed(GroupingTypesApiConstants.accountNoParamName); final String name = command.stringValueOfParameterNamed(GroupingTypesApiConstants.nameParamName); - final String externalId = command.stringValueOfParameterNamed(GroupingTypesApiConstants.externalIdParamName); + String externalId = command.stringValueOfParameterNamed(GroupingTypesApiConstants.externalIdParamName); + if (StringUtils.isBlank(externalId)) { + externalId = UUID.randomUUID().toString(); + } final AppUser currentUser = this.context.authenticatedUser(); Long officeId = null; diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CenterIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CenterIntegrationTest.java index e64b6d6b60d..bee6d09be3d 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CenterIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CenterIntegrationTest.java @@ -103,6 +103,19 @@ public void testFullCenterCreation() { Assertions.assertArrayEquals(center.getGroupMembers(), groupMembers); } + @Test + public void testCenterCreationWithoutExternalIdGeneratesOne() { + int officeId = new OfficeHelper().createOffice(LocalDate.of(2007, 7, 1)).getResourceId().intValue(); + String name = "TestNoExternalId" + new Timestamp(new java.util.Date().getTime()); + int resourceId = CenterHelper.createCenter(name, officeId, requestSpec, responseSpec); + CenterDomain center = CenterHelper.retrieveByID(resourceId, requestSpec, responseSpec); + + Assertions.assertNotNull(center); + Assertions.assertNotNull(center.getExternalId()); + Assertions.assertFalse(center.getExternalId().isBlank()); + Assertions.assertNotEquals("null", center.getExternalId()); + } + @Test public void testListCenters() { ArrayList paginatedList = CenterHelper.paginatedListCenters(requestSpec, responseSpec); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java index 3e85e5a51c6..9da122cfde4 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.UUID; import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.CollateralManagementHelper; import org.apache.fineract.integrationtests.common.GroupHelper; @@ -100,6 +101,25 @@ public void checkGroupFunctions() { // groupID); } + @Test + public void testGroupCreationWithoutExternalIdGeneratesOne() { + final Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, "04 March 2011", null); + GroupHelper.verifyGroupCreatedOnServer(this.requestSpec, this.responseSpec, groupID); + + final String externalId = GroupHelper.getGroupExternalId(this.requestSpec, this.responseSpec, groupID); + Assertions.assertNotNull(externalId); + Assertions.assertFalse(externalId.isBlank()); + assertNotEquals("null", externalId); + } + + @Test + public void testGroupCreationWithExternalIdIsPersisted() { + final String externalId = UUID.randomUUID().toString(); + final Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec, "04 March 2011", externalId); + GroupHelper.verifyGroupCreatedOnServer(this.requestSpec, this.responseSpec, groupID); + GroupHelper.verifyGroupDetails(this.requestSpec, this.responseSpec, groupID, "externalId", externalId); + } + @Test public void assignStaffToGroup() { Integer groupID = GroupHelper.createGroup(this.requestSpec, this.responseSpec); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GroupHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GroupHelper.java index b6cabe39563..ff4f96ee7ed 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GroupHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GroupHelper.java @@ -72,6 +72,17 @@ public static Integer createGroup(final RequestSpecification requestSpec, final return Utils.performServerPost(requestSpec, responseSpec, CREATE_GROUP_URL, getTestGroupAsJSON(true, activationDate), "groupId"); } + // TODO: Rewrite to use fineract-client instead! + // Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long, + // org.apache.fineract.client.models.PostLoansLoanIdRequest) + @Deprecated(forRemoval = true) + public static Integer createGroup(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final String activationDate, final String externalId) { + LOG.info("---------------------------------CREATING A GROUP---------------------------------------------"); + return Utils.performServerPost(requestSpec, responseSpec, CREATE_GROUP_URL, getTestGroupAsJSON(true, activationDate, externalId), + "groupId"); + } + // TODO: Rewrite to use fineract-client instead! // Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long, // org.apache.fineract.client.models.PostLoansLoanIdRequest) @@ -189,10 +200,20 @@ public static Object assignStaffInheritStaffForClientAccounts(final RequestSpeci // org.apache.fineract.client.models.PostLoansLoanIdRequest) @Deprecated(forRemoval = true) public static String getTestGroupAsJSON(final boolean active, final String activationDate) { + return getTestGroupAsJSON(active, activationDate, UUID.randomUUID().toString()); + } + + // TODO: Rewrite to use fineract-client instead! + // Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long, + // org.apache.fineract.client.models.PostLoansLoanIdRequest) + @Deprecated(forRemoval = true) + public static String getTestGroupAsJSON(final boolean active, final String activationDate, final String externalId) { final HashMap map = new HashMap<>(); map.put("officeId", "1"); map.put("name", randomNameGenerator("Group_Name_", 5)); - map.put("externalId", UUID.randomUUID().toString()); + if (externalId != null) { + map.put("externalId", externalId); + } map.put("dateFormat", "dd MMMM yyyy"); map.put("locale", "en"); if (active) { @@ -296,6 +317,17 @@ public static void verifyGroupDetails(final RequestSpecification requestSpec, fi assertEquals(expectedValue, responseValue, "ERROR IN CREATING THE GROUP"); } + // TODO: Rewrite to use fineract-client instead! + // Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long, + // org.apache.fineract.client.models.PostLoansLoanIdRequest) + @Deprecated(forRemoval = true) + public static String getGroupExternalId(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, + final Integer generatedGroupID) { + LOG.info("------------------------------CHECK GROUP EXTERNAL ID------------------------------------\n"); + final String GROUP_URL = "/fineract-provider/api/v1/groups/" + generatedGroupID + "?" + Utils.TENANT_IDENTIFIER; + return Utils.performServerGet(requestSpec, responseSpec, GROUP_URL, "externalId"); + } + // TODO: Rewrite to use fineract-client instead! // Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long, // org.apache.fineract.client.models.PostLoansLoanIdRequest)