cleaning up group validations

This commit is contained in:
Vishwas Babu A J
2014-11-03 21:09:02 +05:30
parent 7d0ac6bf29
commit 702ecd480f
9 changed files with 179 additions and 146 deletions
@@ -34,9 +34,13 @@ public interface ConfigurationDomainService {
Long retrievePasswordLiveTime();
Long retrieveGraceOnPenaltyPostingPeriod();
boolean isSavingsInterestPostingAtCurrentPeriodEnd();
Integer retrieveFinancialYearBeginningMonth();
public Integer retrieveMinAllowedClientsInGroup();
public Integer retrieveMaxAllowedClientsInGroup();
}
@@ -113,7 +113,7 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
return property.getValue();
}
@Override
public Long retrieveGraceOnPenaltyPostingPeriod() {
final String propertyName = "grace-on-penalty-posting";
@@ -121,7 +121,6 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
return property.getValue();
}
@Override
public boolean isPasswordForcedResetEnable() {
final String propertyName = "force-password-reset-days";
@@ -135,21 +134,36 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
return property.getValue();
}
@Override
public boolean isSavingsInterestPostingAtCurrentPeriodEnd() {
final String propertyName = "savings-interest-posting-current-period-end";
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
return property.isEnabled();
}
@Override
public Integer retrieveFinancialYearBeginningMonth() {
final String propertyName = "financial-year-beginning-month";
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
if(property.isEnabled())
return property.getValue().intValue();
return 1;
if (property.isEnabled()) return property.getValue().intValue();
return 1;
}
@Override
public Integer retrieveMinAllowedClientsInGroup() {
final String propertyName = "min-clients-in-group";
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
if (property.isEnabled()) { return property.getValue().intValue(); }
return null;
}
@Override
public Integer retrieveMaxAllowedClientsInGroup() {
final String propertyName = "max-clients-in-group";
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
if (property.isEnabled()) { return property.getValue().intValue(); }
return null;
}
}
@@ -298,12 +298,11 @@ public final class Client extends AbstractPersistable<Long> {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
validateNameParts(dataValidationErrors);
validateActivationDate(dataValidationErrors);
validateClientsGroupRules(dataValidationErrors);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
public boolean isAccountNumberRequiresAutoGeneration() {
return this.accountNumberRequiresAutoGeneration;
}
@@ -449,7 +448,6 @@ public final class Client extends AbstractPersistable<Long> {
actualChanges.put(ClientApiConstants.savingsProductIdParamName, newValue);
}
if (command.isChangeInLongParameterNamed(ClientApiConstants.genderIdParamName, genderId())) {
final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.genderIdParamName);
actualChanges.put(ClientApiConstants.genderIdParamName, newValue);
@@ -465,7 +463,6 @@ public final class Client extends AbstractPersistable<Long> {
actualChanges.put(ClientApiConstants.clientClassificationIdParamName, newValue);
}
final String dateFormatAsInput = command.dateFormat();
final String localeAsInput = command.locale();
@@ -490,7 +487,7 @@ public final class Client extends AbstractPersistable<Long> {
this.dateOfBirth = newValue.toDate();
}
if (command.isChangeInLocalDateParameterNamed(ClientApiConstants.submittedOnDateParamName,getSubmittedOnDate())) {
if (command.isChangeInLocalDateParameterNamed(ClientApiConstants.submittedOnDateParamName, getSubmittedOnDate())) {
final String valueAsInput = command.stringValueOfParameterNamed(ClientApiConstants.submittedOnDateParamName);
actualChanges.put(ClientApiConstants.submittedOnDateParamName, valueAsInput);
actualChanges.put(ClientApiConstants.dateFormatParamName, dateFormatAsInput);
@@ -507,7 +504,6 @@ public final class Client extends AbstractPersistable<Long> {
return actualChanges;
}
private void validateNameParts(final List<ApiParameterError> dataValidationErrors) {
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
@@ -571,18 +567,6 @@ public final class Client extends AbstractPersistable<Long> {
}
}
}
/*
* To become a part of a group, group may have set of criteria to be met
* before client can become member of it. This method is placeholder for
* such validation.
*/
private void validateClientsGroupRules(final List<ApiParameterError> dataValidationErrors) {
for (Group group : this.groups) {
group.validateGroupHasMoreThanRequiredNumberOfClientsAngLogError(dataValidationErrors);
}
}
private void deriveDisplayName() {
@@ -18,6 +18,7 @@ import org.mifosplatform.commands.service.CommandProcessingService;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -42,6 +43,7 @@ import org.mifosplatform.portfolio.client.exception.InvalidClientSavingProductEx
import org.mifosplatform.portfolio.client.exception.InvalidClientStateTransitionException;
import org.mifosplatform.portfolio.group.domain.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepository;
import org.mifosplatform.portfolio.group.exception.GroupMemberCountNotInPermissibleRangeException;
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
@@ -82,6 +84,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
private final SavingsProductRepository savingsProductRepository;
private final SavingsApplicationProcessWritePlatformService savingsApplicationProcessWritePlatformService;
private final CommandProcessingService commandProcessingService;
private final ConfigurationDomainService configurationDomainService;
@Autowired
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -91,7 +94,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final CodeValueRepositoryWrapper codeValueRepository, final LoanRepository loanRepository,
final SavingsAccountRepository savingsRepository, final SavingsProductRepository savingsProductRepository,
final SavingsApplicationProcessWritePlatformService savingsApplicationProcessWritePlatformService,
final CommandProcessingService commandProcessingService) {
final CommandProcessingService commandProcessingService, final ConfigurationDomainService configurationDomainService) {
this.context = context;
this.clientRepository = clientRepository;
this.officeRepository = officeRepository;
@@ -106,6 +109,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
this.savingsProductRepository = savingsProductRepository;
this.savingsApplicationProcessWritePlatformService = savingsApplicationProcessWritePlatformService;
this.commandProcessingService = commandProcessingService;
this.configurationDomainService = configurationDomainService;
}
@Transactional
@@ -215,6 +219,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
clientType, clientClassification, command);
boolean rollbackTransaction = false;
if (newClient.isActive()) {
validateParentGroupRulesBeforeClientActivation(newClient);
final CommandWrapper commandWrapper = new CommandWrapperBuilder().activateClient(null).build();
rollbackTransaction = this.commandProcessingService.validateCommand(commandWrapper, currentUser);
}
@@ -275,7 +280,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
}
clientForUpdate.updateStaff(newStaff);
}
if (changes.containsKey(ClientApiConstants.genderIdParamName)) {
final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.genderIdParamName);
@@ -351,6 +356,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
this.fromApiJsonDeserializer.validateActivation(command);
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
validateParentGroupRulesBeforeClientActivation(client);
final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
@@ -568,4 +574,22 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
.build();
}
/*
* To become a part of a group, group may have set of criteria to be met
* before client can become member of it.
*/
private void validateParentGroupRulesBeforeClientActivation(Client client) {
Integer minNumberOfClients = configurationDomainService.retrieveMinAllowedClientsInGroup();
Integer maxNumberOfClients = configurationDomainService.retrieveMaxAllowedClientsInGroup();
for (Group group : client.getGroups()) {
/**
* Since this Client has not yet been associated with the group,
* reduce maxNumberOfClients by 1
**/
final boolean validationsuccess = group.isGroupsClientCountWithinMaxRange(maxNumberOfClients - 1);
if (!validationsuccess) { throw new GroupMemberCountNotInPermissibleRangeException(group.getId(), minNumberOfClients,
maxNumberOfClients); }
}
}
}
@@ -117,19 +117,20 @@ public final class Group extends AbstractPersistable<Long> {
@ManyToOne(optional = true)
@JoinColumn(name = "submittedon_userid", nullable = true)
private AppUser submittedBy;
// JPA default constructor for entity
// JPA default constructor for entity
protected Group() {
this.name = null;
this.externalId = null;
this.clientMembers = new HashSet<>();
}
}
public static Group newGroup(final Office office, final Staff staff, final Group parent, final GroupLevel groupLevel,
final String name, final String externalId, final boolean active, final LocalDate activationDate,
final Set<Client> clientMembers, final Set<Group> groupMembers, final LocalDate submittedOnDate, final AppUser currentUser) {
// By default new group is created in PENDING status, unless explicitly status is set to active
// By default new group is created in PENDING status, unless explicitly
// status is set to active
GroupingTypeStatus status = GroupingTypeStatus.PENDING;
LocalDate groupActivationDate = null;
if (active) {
@@ -144,7 +145,7 @@ public final class Group extends AbstractPersistable<Long> {
private Group(final Office office, final Staff staff, final Group parent, final GroupLevel groupLevel, final String name,
final String externalId, final GroupingTypeStatus status, final LocalDate activationDate, final Set<Client> clientMembers,
final Set<Group> groupMembers, final LocalDate submittedOnDate, final AppUser currentUser) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
this.office = office;
@@ -175,24 +176,23 @@ public final class Group extends AbstractPersistable<Long> {
this.submittedBy = currentUser;
associateClients(clientMembers);
/*
* Always keep status change at the bottom, as status change rule depends on the attribute's value
* Always keep status change at the bottom, as status change rule
* depends on the attribute's value
*/
setStatus(activationDate, currentUser, status, dataValidationErrors);
throwExceptionIfErrors(dataValidationErrors);
}
private void setStatus(final LocalDate activationDate, final AppUser loginUser, final GroupingTypeStatus status,
final List<ApiParameterError> dataValidationErrors) {
if (status.isActive()) {
activate(loginUser, activationDate, dataValidationErrors);
}
else{
} else {
this.status = status.getValue();
}
@@ -201,13 +201,11 @@ public final class Group extends AbstractPersistable<Long> {
private void activate(final AppUser currentUser, final LocalDate activationLocalDate, final List<ApiParameterError> dataValidationErrors) {
validateStatusNotEqualToActiveAndLogError(dataValidationErrors);
validateRequiredNumberOfClientPerGroupAngLogError(dataValidationErrors);
if (dataValidationErrors.isEmpty()) {
this.status = GroupingTypeStatus.ACTIVE.getValue();
setActivationDate(activationLocalDate.toDate(), currentUser, dataValidationErrors);
}
}
public void activate(final AppUser currentUser, final LocalDate activationLocalDate) {
@@ -215,10 +213,10 @@ public final class Group extends AbstractPersistable<Long> {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
activate(currentUser, activationLocalDate, dataValidationErrors);
throwExceptionIfErrors(dataValidationErrors);
}
private void setActivationDate(final Date activationDate, final AppUser loginUser, final List<ApiParameterError> dataValidationErrors){
private void setActivationDate(final Date activationDate, final AppUser loginUser, final List<ApiParameterError> dataValidationErrors) {
if (activationDate != null) {
this.activationDate = activationDate;
@@ -226,7 +224,7 @@ public final class Group extends AbstractPersistable<Long> {
}
validateActivationDate(dataValidationErrors);
}
public boolean isActivatedAfter(final LocalDate submittedOn) {
@@ -238,7 +236,7 @@ public final class Group extends AbstractPersistable<Long> {
}
public boolean isActive() {
return this.status != null ? GroupingTypeStatus.fromInt(this.status).isActive(): false;
return this.status != null ? GroupingTypeStatus.fromInt(this.status).isActive() : false;
}
private boolean isDateInTheFuture(final LocalDate localDate) {
@@ -313,15 +311,6 @@ public final class Group extends AbstractPersistable<Long> {
}
public List<String> associateClients(final Set<Client> clientMembersSet) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final List<String> newlyAssociatedClients = associateClients(clientMembersSet, dataValidationErrors);
throwExceptionIfErrors(dataValidationErrors);
return newlyAssociatedClients;
}
public List<String> associateClients(final Set<Client> clientMembersSet, final List<ApiParameterError> dataValidationErrors) {
final List<String> differences = new ArrayList<>();
for (final Client client : clientMembersSet) {
if (hasClientAsMember(client)) { throw new ClientExistInGroupException(client.getId(), getId()); }
@@ -329,13 +318,6 @@ public final class Group extends AbstractPersistable<Long> {
differences.add(client.getId().toString());
}
/*
* Minimum and maximum number of client rule is applicable only for active group
*/
if (isActive()) {
validateGroupHasMoreThanRequiredNumberOfClientsAngLogError(dataValidationErrors);
}
return differences;
}
@@ -352,7 +334,7 @@ public final class Group extends AbstractPersistable<Long> {
return differences;
}
public boolean hasClientAsMember(final Client client) {
return this.clientMembers.contains(client);
}
@@ -425,6 +407,10 @@ public final class Group extends AbstractPersistable<Long> {
return this.groupLevel.isCenter();
}
public boolean isGroup() {
return this.groupLevel.isGroup();
}
public boolean isTransferInProgress() {
return GroupingTypeStatus.fromInt(this.status).isTransferInProgress();
}
@@ -512,7 +498,6 @@ public final class Group extends AbstractPersistable<Long> {
.getParent().getId(), group.getId());
}
this.groupMembers.add(group);
differences.add(group.getId().toString());
}
@@ -535,76 +520,55 @@ public final class Group extends AbstractPersistable<Long> {
return differences;
}
public void validateRequiredNumberOfClientPerGroupAngLogError(final List<ApiParameterError> dataValidationErrors) {
public Boolean isGroupsClientCountWithinMinMaxRange(Integer minClients, Integer maxClients) {
if (!hasGroupRequiredNumberOfClients()) {
if (maxClients == null && minClients == null) { return true; }
// This validation not strictly related to a parameter, that is the
// reason parameterName is set null
final String parameterName = null;
final String globalisationMessageCode = "error.msg.group.activation.without.required.number.of.members";
final String defaultUserMessage = "Group should have number of members between " + this.groupLevel.getMinClients() + " and "
+ this.groupLevel.getMaxClients();
final ApiParameterError error = ApiParameterError.parameterError(globalisationMessageCode, defaultUserMessage, parameterName);
dataValidationErrors.add(error);
// set minClients or maxClients to 0 if null
if (minClients == null) {
minClients = 0;
}
}
private Boolean hasGroupRequiredNumberOfClients() {
/*
* If maximum clients required per group is set to zero or less then zero
* then irrespective of minimum required number, below condition returns true
* that means this is rule is not validated
*/
if (this.clientMembers.size() >= this.groupLevel.getMinClients()
&& (this.clientMembers.size() < this.groupLevel.getMaxClients() || this.groupLevel.getMaxClients() <= 0)) { return true; }
if (maxClients == null) {
maxClients = Integer.MAX_VALUE;
}
Set<Client> activeClientMembers = getActiveClientMembers();
if (activeClientMembers.size() >= minClients && activeClientMembers.size() <= maxClients) { return true; }
return false;
}
public void validateGroupHasMoreThanRequiredNumberOfClientsAngLogError(final List<ApiParameterError> dataValidationErrors) {
if (hasGroupMoreThanRequiredNumberOfClients()) {
// This validation not strictly related to a parameter, that is the
// reason parameterName is set null
final String parameterName = null;
final String globalisationMessageCode = "error.msg.group.can.not.have.more.than.required.number.of.members";
final String defaultUserMessage = "Group should have number of members between " + this.groupLevel.getMinClients() + " and "
+ this.groupLevel.getMaxClients();
final ApiParameterError error = ApiParameterError.parameterError(globalisationMessageCode, defaultUserMessage, parameterName);
dataValidationErrors.add(error);
public Boolean isGroupsClientCountWithinMaxRange(Integer maxClients) {
Set<Client> activeClientMembers = getActiveClientMembers();
if (maxClients == null) {
return true;
} else if (activeClientMembers.size() <= maxClients) {
return true;
} else {
return false;
}
}
private Boolean hasGroupMoreThanRequiredNumberOfClients(){
/*
* If maximum clients required per group is set to zero or less then zero
* then below condition returns always false
* that means this is rule is not validated and group can have unlimited number of clients.
*/
if (this.clientMembers.size() > this.groupLevel.getMaxClients() && this.groupLevel.getMaxClients() > 0) { return true; }
return false;
public Set<Client> getActiveClientMembers() {
Set<Client> activeClientMembers = new HashSet<>();
for (Client client : this.clientMembers) {
if (client.isActive()) {
activeClientMembers.add(client);
}
}
return activeClientMembers;
}
private void validateActivationDate(final List<ApiParameterError> dataValidationErrors) {
if (getSubmittedOnDate() != null && isDateInTheFuture(getSubmittedOnDate())) {
final String defaultUserMessage = "Submitted on date cannot be in the future.";
final String globalisationMessageCode = "error.msg.group.submittedOnDate.in.the.future";
final ApiParameterError error = ApiParameterError.parameterError(globalisationMessageCode ,
defaultUserMessage, GroupingTypesApiConstants.submittedOnDateParamName, this.submittedOnDate);
final ApiParameterError error = ApiParameterError.parameterError(globalisationMessageCode, defaultUserMessage,
GroupingTypesApiConstants.submittedOnDateParamName, this.submittedOnDate);
dataValidationErrors.add(error);
}
@@ -638,11 +602,11 @@ public final class Group extends AbstractPersistable<Long> {
}
}
private void validateStatusNotEqualToActiveAndLogError(final List<ApiParameterError> dataValidationErrors){
private void validateStatusNotEqualToActiveAndLogError(final List<ApiParameterError> dataValidationErrors) {
if (isActive()) {
final String defaultUserMessage = "Cannot activate group. Group is already active.";
final String globalisationMessageCode = "error.msg.group.already.active";
final String globalisationMessageCode = "error.msg.group.already.active";
final ApiParameterError error = ApiParameterError.parameterError(globalisationMessageCode, defaultUserMessage,
GroupingTypesApiConstants.activeParamName, true);
dataValidationErrors.add(error);
@@ -30,12 +30,6 @@ public class GroupLevel extends AbstractPersistable<Long> {
@Column(name = "can_have_clients", nullable = false)
private boolean canHaveClients = false;
@Column(name = "min_clients", nullable = false)
private final Long minClients;
@Column(name = "max_clients", nullable = false)
private final Long maxClients;
public GroupLevel() {
this.parentId = null;
@@ -43,22 +37,17 @@ public class GroupLevel extends AbstractPersistable<Long> {
this.levelName = null;
this.recursable = false;
this.canHaveClients = false;
this.minClients = null;
this.maxClients = null;
}
public GroupLevel(final Long parentId, final boolean isSuperParent, final String levelName, final boolean recursable,
final boolean canHaveClients, final Long minClients, final Long maxClients) {
final boolean canHaveClients) {
this.superParent = isSuperParent;
this.parentId = parentId;
this.levelName = levelName;
this.recursable = recursable;
this.canHaveClients = canHaveClients;
this.minClients = minClients;
this.maxClients = maxClients;
}
public Long getParentId() {
@@ -88,12 +77,9 @@ public class GroupLevel extends AbstractPersistable<Long> {
public boolean isCenter() {
return this.levelName.equalsIgnoreCase("Center");
}
public Long getMinClients(){
return this.minClients;
}
public Long getMaxClients(){
return this.maxClients;
public boolean isGroup() {
return this.levelName.equalsIgnoreCase("Group");
}
}
@@ -0,0 +1,17 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.group.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class GroupMemberCountNotInPermissibleRangeException extends AbstractPlatformDomainRuleException {
public GroupMemberCountNotInPermissibleRangeException(final Long groupId, final Integer minClients, final Integer maxClients) {
super("error.msg.group.members.count.must.be.in.permissible.range", "Number of members in the group with Id " + groupId
+ " should be between " + minClients + " and " + maxClients, groupId, minClients, maxClients);
}
}
@@ -19,6 +19,7 @@ import org.mifosplatform.commands.service.CommandProcessingService;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -47,6 +48,7 @@ import org.mifosplatform.portfolio.group.domain.GroupRepositoryWrapper;
import org.mifosplatform.portfolio.group.domain.GroupTypes;
import org.mifosplatform.portfolio.group.exception.GroupAccountExistsException;
import org.mifosplatform.portfolio.group.exception.GroupHasNoStaffException;
import org.mifosplatform.portfolio.group.exception.GroupMemberCountNotInPermissibleRangeException;
import org.mifosplatform.portfolio.group.exception.GroupMustBePendingToBeDeletedException;
import org.mifosplatform.portfolio.group.exception.InvalidGroupLevelException;
import org.mifosplatform.portfolio.group.exception.InvalidGroupStateTransitionException;
@@ -85,6 +87,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
private final SavingsAccountRepository savingsRepository;
private final CommandProcessingService commandProcessingService;
private final CalendarInstanceRepository calendarInstanceRepository;
private final ConfigurationDomainService configurationDomainService;
@Autowired
public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -93,7 +96,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
final GroupLevelRepository groupLevelRepository, final GroupingTypesDataValidator fromApiJsonDeserializer,
final LoanRepository loanRepository, final SavingsAccountRepository savingsRepository,
final CodeValueRepositoryWrapper codeValueRepository, final CommandProcessingService commandProcessingService,
final CalendarInstanceRepository calendarInstanceRepository) {
final CalendarInstanceRepository calendarInstanceRepository, final ConfigurationDomainService configurationDomainService) {
this.context = context;
this.groupRepository = groupRepository;
this.clientRepositoryWrapper = clientRepositoryWrapper;
@@ -107,6 +110,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
this.codeValueRepository = codeValueRepository;
this.commandProcessingService = commandProcessingService;
this.calendarInstanceRepository = calendarInstanceRepository;
this.configurationDomainService = configurationDomainService;
}
private CommandProcessingResult createGroupingType(final JsonCommand command, final GroupTypes groupingType, final Long centerId) {
@@ -157,6 +161,11 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
boolean rollbackTransaction = false;
if (newGroup.isActive()) {
// validate Group creation rules for Group
if (newGroup.isGroup()) {
validateGroupRulesBeforeActivation(newGroup);
}
if (newGroup.isCenter()) {
final CommandWrapper commandWrapper = new CommandWrapperBuilder().activateCenter(null).build();
rollbackTransaction = this.commandProcessingService.validateCommand(commandWrapper, currentUser);
@@ -226,6 +235,10 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
final Group group = this.groupRepository.findOneWithNotFoundDetection(groupId);
if (group.isGroup()) {
validateGroupRulesBeforeActivation(group);
}
final LocalDate activationDate = command.localDateValueOfParameterNamed("activationDate");
validateOfficeOpeningDateisAfterGroupOrCenterOpeningDate(group.getOffice(), group.getGroupLevel(), activationDate);
@@ -245,6 +258,20 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
}
}
private void validateGroupRulesBeforeActivation(final Group group) {
Integer minClients = configurationDomainService.retrieveMinAllowedClientsInGroup();
Integer maxClients = configurationDomainService.retrieveMaxAllowedClientsInGroup();
boolean isGroupClientCountValid = group.isGroupsClientCountWithinMinMaxRange(minClients, maxClients);
if (!isGroupClientCountValid) { throw new GroupMemberCountNotInPermissibleRangeException(group.getId(), minClients, maxClients); }
}
public void validateGroupRulesBeforeClientAssociation(final Group group) {
Integer minClients = configurationDomainService.retrieveMinAllowedClientsInGroup();
Integer maxClients = configurationDomainService.retrieveMaxAllowedClientsInGroup();
boolean isGroupClientCountValid = group.isGroupsClientCountWithinMaxRange(maxClients);
if (!isGroupClientCountValid) { throw new GroupMemberCountNotInPermissibleRangeException(group.getId(), minClients, maxClients); }
}
@Transactional
@Override
public CommandProcessingResult updateCenter(final Long centerId, final JsonCommand command) {
@@ -645,6 +672,10 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
final Map<String, Object> actualChanges = new HashMap<>();
final List<String> changes = groupForUpdate.associateClients(clientMembers);
if (groupForUpdate.isGroup()) {
validateGroupRulesBeforeClientAssociation(groupForUpdate);
}
if (!changes.isEmpty()) {
actualChanges.put(GroupingTypesApiConstants.clientMembersParamName, changes);
}
@@ -0,0 +1,9 @@
INSERT INTO `c_configuration` (`id`, `name`,`value`, `enabled`, `description`)
VALUES (NULL, 'min-clients-in-group', '5', '0',"Minimum number of Clients that a Group should have");
INSERT INTO `c_configuration` (`id`, `name`, `value`, `enabled`, `description`)
VALUES (NULL, 'max-clients-in-group', '5', '0', "Maximum number of Clients that a Group can have");
ALTER TABLE `m_group_level`
DROP COLUMN `min_clients`,
DROP COLUMN `max_clients`;