FINERACT-2326: Extract out external dependencies from Client and Group entity

This commit is contained in:
Jose Alberto Hernandez
2025-08-15 22:53:14 +02:00
committed by Arnold Gálovics
parent 37f31ecb14
commit 125c8b4db2
4 changed files with 36 additions and 95 deletions
@@ -29,7 +29,6 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne; import jakarta.persistence.OneToOne;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import jakarta.persistence.UniqueConstraint; import jakarta.persistence.UniqueConstraint;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
@@ -135,9 +134,6 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom<Long> {
@JoinTable(name = "m_group_client", joinColumns = @JoinColumn(name = "client_id"), inverseJoinColumns = @JoinColumn(name = "group_id")) @JoinTable(name = "m_group_client", joinColumns = @JoinColumn(name = "client_id"), inverseJoinColumns = @JoinColumn(name = "group_id"))
private Set<Group> groups; private Set<Group> groups;
@Transient
private boolean accountNumberRequiresAutoGeneration = false;
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "closure_reason_cv_id") @JoinColumn(name = "closure_reason_cv_id")
private CodeValue closureReason; private CodeValue closureReason;
@@ -237,7 +233,6 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom<Long> {
if (StringUtils.isBlank(accountNo)) { if (StringUtils.isBlank(accountNo)) {
this.accountNumber = new RandomPasswordGenerator(19).generate(); this.accountNumber = new RandomPasswordGenerator(19).generate();
this.accountNumberRequiresAutoGeneration = true;
} else { } else {
this.accountNumber = accountNo; this.accountNumber = accountNo;
} }
@@ -327,21 +322,12 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom<Long> {
} }
public boolean isAccountNumberRequiresAutoGeneration() {
return this.accountNumberRequiresAutoGeneration;
}
public void setAccountNumberRequiresAutoGeneration(final boolean accountNumberRequiresAutoGeneration) {
this.accountNumberRequiresAutoGeneration = accountNumberRequiresAutoGeneration;
}
public boolean identifiedBy(final Long clientId) { public boolean identifiedBy(final Long clientId) {
return getId().equals(clientId); return getId().equals(clientId);
} }
public void updateAccountNo(final String accountIdentifier) { public void updateAccountNo(final String accountIdentifier) {
this.accountNumber = accountIdentifier; this.accountNumber = accountIdentifier;
this.accountNumberRequiresAutoGeneration = false;
} }
public void activate(final AppUser currentUser, final DateTimeFormatter formatter, final LocalDate activationLocalDate) { public void activate(final AppUser currentUser, final DateTimeFormatter formatter, final LocalDate activationLocalDate) {
@@ -28,7 +28,6 @@ import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@@ -36,6 +35,8 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.codes.domain.CodeValue;
import org.apache.fineract.infrastructure.core.api.JsonCommand; 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; import org.apache.fineract.useradministration.domain.AppUser;
@Entity @Entity
@Getter
@Setter
@Table(name = "m_group") @Table(name = "m_group")
public final class Group extends AbstractPersistableCustom<Long> { public final class Group extends AbstractPersistableCustom<Long> {
@@ -130,9 +133,6 @@ public final class Group extends AbstractPersistableCustom<Long> {
@Column(name = "account_no", length = 20, unique = true, nullable = false) @Column(name = "account_no", length = 20, unique = true, nullable = false)
private String accountNumber; private String accountNumber;
@Transient
private boolean accountNumberRequiresAutoGeneration = false;
@OneToMany(mappedBy = "group", cascade = CascadeType.REMOVE) @OneToMany(mappedBy = "group", cascade = CascadeType.REMOVE)
private Set<GroupRole> groupRole; private Set<GroupRole> groupRole;
@@ -166,6 +166,12 @@ public final class Group extends AbstractPersistableCustom<Long> {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
if (StringUtils.isBlank(accountNo)) {
this.accountNumber = new RandomPasswordGenerator(19).generate();
} else {
this.accountNumber = accountNo;
}
this.office = office; this.office = office;
this.staff = staff; this.staff = staff;
this.groupLevel = groupLevel; this.groupLevel = groupLevel;
@@ -175,10 +181,7 @@ public final class Group extends AbstractPersistableCustom<Long> {
this.parent.addChild(this); this.parent.addChild(this);
} }
if (StringUtils.isBlank(accountNo)) { if (!StringUtils.isBlank(accountNo)) {
this.accountNumber = new RandomPasswordGenerator(19).generate();
this.accountNumberRequiresAutoGeneration = true;
} else {
this.accountNumber = accountNo; this.accountNumber = accountNo;
} }
@@ -339,14 +342,6 @@ public final class Group extends AbstractPersistableCustom<Long> {
return actualChanges; return actualChanges;
} }
public LocalDate getSubmittedOnDate() {
return this.submittedOnDate;
}
public LocalDate getActivationDate() {
return this.activationDate;
}
public List<String> associateClients(final Set<Client> clientMembersSet) { public List<String> associateClients(final Set<Client> clientMembersSet) {
final List<String> differences = new ArrayList<>(); final List<String> differences = new ArrayList<>();
for (final Client client : clientMembersSet) { for (final Client client : clientMembersSet) {
@@ -434,30 +429,6 @@ public final class Group extends AbstractPersistableCustom<Long> {
this.staff = null; 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() { public boolean isCenter() {
return this.groupLevel.isCenter(); return this.groupLevel.isCenter();
} }
@@ -689,10 +660,6 @@ public final class Group extends AbstractPersistableCustom<Long> {
} }
} }
public Set<Client> getClientMembers() {
return this.clientMembers;
}
// StaffAssignmentHistory[during center creation] // StaffAssignmentHistory[during center creation]
public void captureStaffHistoryDuringCenterCreation(final Staff newStaff, final LocalDate assignmentDate) { public void captureStaffHistoryDuringCenterCreation(final Staff newStaff, final LocalDate assignmentDate) {
if (this.isCenter() && this.isActive() && staff != null) { if (this.isCenter() && this.isActive() && staff != null) {
@@ -732,21 +699,8 @@ public final class Group extends AbstractPersistableCustom<Long> {
return latestRecordWithNoEndDate; return latestRecordWithNoEndDate;
} }
public boolean isAccountNumberRequiresAutoGeneration() {
return this.accountNumberRequiresAutoGeneration;
}
public void setAccountNumberRequiresAutoGeneration(final boolean accountNumberRequiresAutoGeneration) {
this.accountNumberRequiresAutoGeneration = accountNumberRequiresAutoGeneration;
}
public void updateAccountNo(final String accountIdentifier) { public void updateAccountNo(final String accountIdentifier) {
this.accountNumber = accountIdentifier; this.accountNumber = accountIdentifier;
this.accountNumberRequiresAutoGeneration = false;
}
public void setGroupMembers(List<Group> groupMembers) {
this.groupMembers = groupMembers;
} }
} }
@@ -288,7 +288,14 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
savingsProductId, savingsAccountId, dataOfBirth, gender, clientType, clientClassification, legalForm.getValue(), savingsProductId, savingsAccountId, dataOfBirth, gender, clientType, clientClassification, legalForm.getValue(),
isStaff); isStaff);
// Account Number generation
this.clientRepository.saveAndFlush(newClient); 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; boolean rollbackTransaction = false;
if (newClient.isActive()) { if (newClient.isActive()) {
validateParentGroupRulesBeforeClientActivation(newClient); validateParentGroupRulesBeforeClientActivation(newClient);
@@ -296,13 +303,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final CommandWrapper commandWrapper = new CommandWrapperBuilder().activateClient(null).build(); final CommandWrapper commandWrapper = new CommandWrapperBuilder().activateClient(null).build();
rollbackTransaction = this.commandProcessingService.validateRollbackCommand(commandWrapper, currentUser); rollbackTransaction = this.commandProcessingService.validateRollbackCommand(commandWrapper, currentUser);
} }
this.clientRepository.saveAndFlush(newClient); 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 Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale); final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(command.dateFormat()).withLocale(locale);
@@ -1101,4 +1102,5 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
.withEntityExternalId(client.getExternalId()) // .withEntityExternalId(client.getExternalId()) //
.build(); .build();
} }
} }
@@ -29,6 +29,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.fineract.commands.domain.CommandWrapper; import org.apache.fineract.commands.domain.CommandWrapper;
import org.apache.fineract.commands.service.CommandProcessingService; import org.apache.fineract.commands.service.CommandProcessingService;
@@ -186,17 +187,18 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
rollbackTransaction = this.commandProcessingService.validateRollbackCommand(commandWrapper, currentUser); rollbackTransaction = this.commandProcessingService.validateRollbackCommand(commandWrapper, currentUser);
} }
// pre-save to generate id for use in group hierarchy
this.groupRepository.save(newGroup); 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 * Generate hierarchy for a new center/group and all the child groups if they exist
*/ */
newGroup.generateHierarchy(); newGroup.generateHierarchy();
/* Generate account number if required */
generateAccountNumberIfRequired(newGroup);
this.groupRepository.saveAndFlush(newGroup); this.groupRepository.saveAndFlush(newGroup);
newGroup.captureStaffHistoryDuringCenterCreation(staff, activationDate); newGroup.captureStaffHistoryDuringCenterCreation(staff, activationDate);
@@ -229,20 +231,17 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
} }
} }
private void generateAccountNumberIfRequired(Group newGroup) { private void generateAccountNumber(Group newGroup) {
if (newGroup.isAccountNumberRequiresAutoGeneration()) { EntityAccountType entityAccountType = null;
EntityAccountType entityAccountType = null; AccountNumberFormat accountNumberFormat = null;
AccountNumberFormat accountNumberFormat = null; if (newGroup.isCenter()) {
if (newGroup.isCenter()) { entityAccountType = EntityAccountType.CENTER;
entityAccountType = EntityAccountType.CENTER; accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(entityAccountType);
accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(entityAccountType); newGroup.updateAccountNo(this.accountNumberGenerator.generateCenterAccountNumber(newGroup, accountNumberFormat));
newGroup.updateAccountNo(this.accountNumberGenerator.generateCenterAccountNumber(newGroup, accountNumberFormat)); } else {
} else { entityAccountType = EntityAccountType.GROUP;
entityAccountType = EntityAccountType.GROUP; accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(entityAccountType);
accountNumberFormat = this.accountNumberFormatRepository.findByAccountType(entityAccountType); newGroup.updateAccountNo(this.accountNumberGenerator.generateGroupAccountNumber(newGroup, accountNumberFormat));
newGroup.updateAccountNo(this.accountNumberGenerator.generateGroupAccountNumber(newGroup, accountNumberFormat));
}
} }
} }