From 125c8b4db28465624f442e8242862ebc0eadbb73 Mon Sep 17 00:00:00 2001 From: Jose Alberto Hernandez Date: Wed, 13 Aug 2025 19:00:22 -0500 Subject: [PATCH] FINERACT-2326: Extract out external dependencies from Client and Group entity --- .../portfolio/client/domain/Client.java | 14 ---- .../portfolio/group/domain/Group.java | 68 +++---------------- ...WritePlatformServiceJpaRepositoryImpl.java | 14 ++-- ...WritePlatformServiceJpaRepositoryImpl.java | 35 +++++----- 4 files changed, 36 insertions(+), 95 deletions(-) diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java index a70cb8cf6..60fafa98a 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java @@ -29,7 +29,6 @@ import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OneToOne; import jakarta.persistence.Table; -import jakarta.persistence.Transient; import jakarta.persistence.UniqueConstraint; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @@ -135,9 +134,6 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom { @JoinTable(name = "m_group_client", joinColumns = @JoinColumn(name = "client_id"), inverseJoinColumns = @JoinColumn(name = "group_id")) private Set groups; - @Transient - private boolean accountNumberRequiresAutoGeneration = false; - @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "closure_reason_cv_id") private CodeValue closureReason; @@ -237,7 +233,6 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom { if (StringUtils.isBlank(accountNo)) { this.accountNumber = new RandomPasswordGenerator(19).generate(); - this.accountNumberRequiresAutoGeneration = true; } else { this.accountNumber = accountNo; } @@ -327,21 +322,12 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom { } - public boolean isAccountNumberRequiresAutoGeneration() { - return this.accountNumberRequiresAutoGeneration; - } - - public void setAccountNumberRequiresAutoGeneration(final boolean accountNumberRequiresAutoGeneration) { - this.accountNumberRequiresAutoGeneration = accountNumberRequiresAutoGeneration; - } - public boolean identifiedBy(final Long clientId) { return getId().equals(clientId); } public void updateAccountNo(final String accountIdentifier) { this.accountNumber = accountIdentifier; - this.accountNumberRequiresAutoGeneration = false; } public void activate(final AppUser currentUser, final DateTimeFormatter formatter, final LocalDate activationLocalDate) { diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java index e67b706ae..a03593cd5 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java @@ -28,7 +28,6 @@ import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; -import jakarta.persistence.Transient; import java.time.LocalDate; import java.util.ArrayList; import java.util.HashSet; @@ -36,6 +35,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import lombok.Getter; +import lombok.Setter; import org.apache.commons.lang3.StringUtils; import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.core.api.JsonCommand; @@ -57,6 +58,8 @@ import org.apache.fineract.portfolio.group.exception.InvalidGroupStateTransition import org.apache.fineract.useradministration.domain.AppUser; @Entity +@Getter +@Setter @Table(name = "m_group") public final class Group extends AbstractPersistableCustom { @@ -130,9 +133,6 @@ public final class Group extends AbstractPersistableCustom { @Column(name = "account_no", length = 20, unique = true, nullable = false) private String accountNumber; - @Transient - private boolean accountNumberRequiresAutoGeneration = false; - @OneToMany(mappedBy = "group", cascade = CascadeType.REMOVE) private Set groupRole; @@ -166,6 +166,12 @@ public final class Group extends AbstractPersistableCustom { final List dataValidationErrors = new ArrayList<>(); + if (StringUtils.isBlank(accountNo)) { + this.accountNumber = new RandomPasswordGenerator(19).generate(); + } else { + this.accountNumber = accountNo; + } + this.office = office; this.staff = staff; this.groupLevel = groupLevel; @@ -175,10 +181,7 @@ public final class Group extends AbstractPersistableCustom { this.parent.addChild(this); } - if (StringUtils.isBlank(accountNo)) { - this.accountNumber = new RandomPasswordGenerator(19).generate(); - this.accountNumberRequiresAutoGeneration = true; - } else { + if (!StringUtils.isBlank(accountNo)) { this.accountNumber = accountNo; } @@ -339,14 +342,6 @@ public final class Group extends AbstractPersistableCustom { return actualChanges; } - public LocalDate getSubmittedOnDate() { - return this.submittedOnDate; - } - - public LocalDate getActivationDate() { - return this.activationDate; - } - public List associateClients(final Set clientMembersSet) { final List differences = new ArrayList<>(); for (final Client client : clientMembersSet) { @@ -434,30 +429,6 @@ public final class Group extends AbstractPersistableCustom { this.staff = null; } - public GroupLevel getGroupLevel() { - return this.groupLevel; - } - - public Staff getStaff() { - return this.staff; - } - - public void setStaff(final Staff staff) { - this.staff = staff; - } - - public Group getParent() { - return this.parent; - } - - public void setParent(final Group parent) { - this.parent = parent; - } - - public Office getOffice() { - return this.office; - } - public boolean isCenter() { return this.groupLevel.isCenter(); } @@ -689,10 +660,6 @@ public final class Group extends AbstractPersistableCustom { } } - public Set getClientMembers() { - return this.clientMembers; - } - // StaffAssignmentHistory[during center creation] public void captureStaffHistoryDuringCenterCreation(final Staff newStaff, final LocalDate assignmentDate) { if (this.isCenter() && this.isActive() && staff != null) { @@ -732,21 +699,8 @@ public final class Group extends AbstractPersistableCustom { return latestRecordWithNoEndDate; } - public boolean isAccountNumberRequiresAutoGeneration() { - return this.accountNumberRequiresAutoGeneration; - } - - public void setAccountNumberRequiresAutoGeneration(final boolean accountNumberRequiresAutoGeneration) { - this.accountNumberRequiresAutoGeneration = accountNumberRequiresAutoGeneration; - } - public void updateAccountNo(final String accountIdentifier) { this.accountNumber = accountIdentifier; - this.accountNumberRequiresAutoGeneration = false; - } - - public void setGroupMembers(List groupMembers) { - this.groupMembers = groupMembers; } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index 74b53fd87..540ecedeb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -288,7 +288,14 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP savingsProductId, savingsAccountId, dataOfBirth, gender, clientType, clientClassification, legalForm.getValue(), isStaff); + // Account Number generation this.clientRepository.saveAndFlush(newClient); + if (StringUtils.isBlank(accountNo)) { + AccountNumberFormat accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(EntityAccountType.CLIENT); + newClient.updateAccountNo(accountNumberGenerator.generate(newClient, accountNumberFormat)); + this.clientRepository.saveAndFlush(newClient); + } + boolean rollbackTransaction = false; if (newClient.isActive()) { validateParentGroupRulesBeforeClientActivation(newClient); @@ -296,13 +303,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP final CommandWrapper commandWrapper = new CommandWrapperBuilder().activateClient(null).build(); rollbackTransaction = this.commandProcessingService.validateRollbackCommand(commandWrapper, currentUser); } - this.clientRepository.saveAndFlush(newClient); - if (newClient.isAccountNumberRequiresAutoGeneration()) { - AccountNumberFormat accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(EntityAccountType.CLIENT); - newClient.updateAccountNo(accountNumberGenerator.generate(newClient, accountNumberFormat)); - this.clientRepository.saveAndFlush(newClient); - } final Locale locale = command.extractLocale(); final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale); @@ -1101,4 +1102,5 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP .withEntityExternalId(client.getExternalId()) // .build(); } + } 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 1de72234e..1b5e2ad35 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 @@ -29,6 +29,7 @@ import java.util.Map; import java.util.Set; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.fineract.commands.domain.CommandWrapper; import org.apache.fineract.commands.service.CommandProcessingService; @@ -186,17 +187,18 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group rollbackTransaction = this.commandProcessingService.validateRollbackCommand(commandWrapper, currentUser); } - // pre-save to generate id for use in group hierarchy this.groupRepository.save(newGroup); + // Account Number generation + if (StringUtils.isBlank(accountNo)) { + generateAccountNumber(newGroup); + } + /* * Generate hierarchy for a new center/group and all the child groups if they exist */ newGroup.generateHierarchy(); - /* Generate account number if required */ - generateAccountNumberIfRequired(newGroup); - this.groupRepository.saveAndFlush(newGroup); newGroup.captureStaffHistoryDuringCenterCreation(staff, activationDate); @@ -229,20 +231,17 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group } } - private void generateAccountNumberIfRequired(Group newGroup) { - if (newGroup.isAccountNumberRequiresAutoGeneration()) { - EntityAccountType entityAccountType = null; - AccountNumberFormat accountNumberFormat = null; - if (newGroup.isCenter()) { - entityAccountType = EntityAccountType.CENTER; - accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(entityAccountType); - newGroup.updateAccountNo(this.accountNumberGenerator.generateCenterAccountNumber(newGroup, accountNumberFormat)); - } else { - entityAccountType = EntityAccountType.GROUP; - accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(entityAccountType); - newGroup.updateAccountNo(this.accountNumberGenerator.generateGroupAccountNumber(newGroup, accountNumberFormat)); - } - + private void generateAccountNumber(Group newGroup) { + EntityAccountType entityAccountType = null; + AccountNumberFormat accountNumberFormat = null; + if (newGroup.isCenter()) { + entityAccountType = EntityAccountType.CENTER; + accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(entityAccountType); + newGroup.updateAccountNo(this.accountNumberGenerator.generateCenterAccountNumber(newGroup, accountNumberFormat)); + } else { + entityAccountType = EntityAccountType.GROUP; + accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(entityAccountType); + newGroup.updateAccountNo(this.accountNumberGenerator.generateGroupAccountNumber(newGroup, accountNumberFormat)); } }