MIFOSX-1325 Attach a group to center
This commit is contained in:
+88
-28
@@ -1261,6 +1261,22 @@
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>centers/{centerId}?command=associateGroups</td>
|
||||
<td><a href="#centers_associate_groups">Associate Groups</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>centers/{centerId}?command=disassociateGroups</td>
|
||||
<td><a href="#centers_disassociate_groups">Disassociate Groups</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>centers/{centerId}/accounts</td>
|
||||
@@ -4753,6 +4769,62 @@ Request Body:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="centers_associate_groups" name="centers_associate_groups" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h2>Associate Groups</h2>
|
||||
<p>This API allows to associate existing groups to a center.</p>
|
||||
<p>The groups are listed from the office to which the center is associated.</p>
|
||||
<p>If group(s) is already associated with center then API will result in an error.</p>
|
||||
</div>
|
||||
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/centers/{centerId}?command=associateGroups</code>
|
||||
<code class="method-request">POST centers/1?command=associateGroups
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"grouptMembers":[1,2]
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"officeId": 1,
|
||||
"groupId": 1,
|
||||
"resourceId": 1,
|
||||
"grouptMembers": [1,2]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="centers_disassociate_groups" name="centers_disassociate_groups" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h2>Disassociate Groups</h2>
|
||||
<p>This API allows to disassociate groups from a center.</p>
|
||||
</div>
|
||||
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/centers/{centerId}?command=disassociateGroups</code>
|
||||
<code class="method-request">POST center/1?command=disassociateGroups
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"grouptMembers":[1,2]
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"officeId": 1,
|
||||
"groupId": 1,
|
||||
"resourceId": 1,
|
||||
"grouptMembers": [1,2]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="centers_accounts" name="centers_accounts" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
@@ -5542,34 +5614,6 @@ Request Body:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a id="groups_associate_clients" name="groups_associate_clients" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
<h2>Associate Clients</h2>
|
||||
<p>This API allows to associate existing clients to a group.</p>
|
||||
<p>The clients are listed from the office to which the group is associated.</p>
|
||||
<p>If client(s) is already associated with group then API will result in an error.</p>
|
||||
</div>
|
||||
|
||||
<div class="method-example">
|
||||
<code class="method-declaration">POST https://Domain Name/api/v1/groups/{groupId}?command=associateClients</code>
|
||||
<code class="method-request">POST groups/1?command=associateClients
|
||||
Content-Type: application/json
|
||||
Request Body:
|
||||
{
|
||||
"clientMembers":[1,2]
|
||||
}
|
||||
</code>
|
||||
<code class="method-response">
|
||||
{
|
||||
"officeId": 1,
|
||||
"groupId": 1,
|
||||
"resourceId": 1,
|
||||
"clientMembers": [1,2]
|
||||
}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<a id="groups_transfer_clients" name="groups_transfer_clients" class="old-syle-anchor"> </a>
|
||||
<div class="method-section">
|
||||
<div class="method-description">
|
||||
@@ -31848,6 +31892,22 @@ No Request Body:
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>centers/{centerId}?command=associateGroups</td>
|
||||
<td><a href="#centers_associate_groups">Associate Groups</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>centers/{centerId}?command=disassociateGroups</td>
|
||||
<td><a href="#centers_disassociate_groups">Disassociate Groups</a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>centers/{centerId}/accounts</td>
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio_center', 'DISASSOCIATEGROUPS_CENTER', 'CENTER', 'DISASSOCIATEGROUPS', 0);
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio_center', 'ASSOCIATEGROUPS_CENTER', 'CENTER', 'ASSOCIATEGROUPS', 0);
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio_center', 'DISASSOCIATEGROUPS_CENTER_CHECKER', 'CENTER', 'DISASSOCIATEGROUPS_CHECKER', 0);
|
||||
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio_center', 'ASSOCIATEGROUPS_CENTER_CHECKER', 'CENTER', 'ASSOCIATEGROUPS_CHECKER', 0);
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `acc_gl_account`
|
||||
CHANGE COLUMN `name` `name` VARCHAR(200) NOT NULL AFTER `id`;
|
||||
+2
-2
@@ -52,7 +52,7 @@ public class GLAccountCommand {
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("GLAccount");
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.NAME.getValue()).value(this.name).notBlank().notExceedingLengthOf(45);
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.NAME.getValue()).value(this.name).notBlank().notExceedingLengthOf(200);
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.GL_CODE.getValue()).value(this.glCode).notBlank()
|
||||
.notExceedingLengthOf(45);
|
||||
@@ -85,7 +85,7 @@ public class GLAccountCommand {
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("GLAccount");
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.NAME.getValue()).value(this.name).ignoreIfNull().notBlank()
|
||||
.notExceedingLengthOf(45);
|
||||
.notExceedingLengthOf(200);
|
||||
|
||||
baseDataValidator.reset().parameter(GLAccountJsonInputParams.GL_CODE.getValue()).ignoreIfNull().value(this.glCode).notBlank()
|
||||
.notExceedingLengthOf(45);
|
||||
|
||||
@@ -327,6 +327,14 @@ public class CommandWrapper {
|
||||
return this.actionName.equalsIgnoreCase("CLOSE") && this.entityName.equalsIgnoreCase("CENTER");
|
||||
}
|
||||
|
||||
public boolean isCenterAssociateGroups() {
|
||||
return this.actionName.equalsIgnoreCase("ASSOCIATEGROUPS") && this.entityName.equalsIgnoreCase("CENTER");
|
||||
}
|
||||
|
||||
public boolean isCenterDisassociateGroups() {
|
||||
return this.actionName.equalsIgnoreCase("DISASSOCIATEGROUPS") && this.entityName.equalsIgnoreCase("CENTER");
|
||||
}
|
||||
|
||||
public boolean isClientIdentifierResource() {
|
||||
return this.entityName.equals("CLIENTIDENTIFIER");
|
||||
}
|
||||
|
||||
+18
@@ -1479,6 +1479,24 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/centers/" + centerId + "?command=close";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder associateGroupsToCenter(final Long centerId) {
|
||||
this.actionName = "ASSOCIATEGROUPS";
|
||||
this.entityName = "CENTER";
|
||||
this.entityId = centerId;
|
||||
this.groupId = centerId;
|
||||
this.href = "/groups/" + centerId + "?command=associateGroups";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder disassociateGroupsFromCenter(final Long centerId) {
|
||||
this.actionName = "DISASSOCIATEGROUPS";
|
||||
this.entityName = "CENTER";
|
||||
this.entityId = centerId;
|
||||
this.groupId = centerId;
|
||||
this.href = "/groups/" + centerId + "?command=disassociateGroups";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder createAccountingRule() {
|
||||
this.actionName = "CREATE";
|
||||
|
||||
+4
@@ -679,6 +679,10 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
handler = this.applicationContext.getBean("saveCenterCollectionSheetCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isCenterClose()) {
|
||||
handler = this.applicationContext.getBean("closeCenterCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isCenterDisassociateGroups()) {
|
||||
handler = this.applicationContext.getBean("disassociateGroupsFromCenterCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isCenterAssociateGroups()) {
|
||||
handler = this.applicationContext.getBean("associateGroupsToCenterCommandHandler", NewCommandSourceHandler.class);
|
||||
} else {
|
||||
throw new UnsupportedCommandException(wrapper.commandName());
|
||||
}
|
||||
|
||||
+9
-1
@@ -279,9 +279,17 @@ public class CentersApiResource {
|
||||
final CommandWrapper commandRequest = builder.closeCenter(centerId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
} else if (is(commandParam, "associateGroups")) {
|
||||
final CommandWrapper commandRequest = builder.associateGroupsToCenter(centerId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
} else if (is(commandParam, "disassociateGroups")) {
|
||||
final CommandWrapper commandRequest = builder.disassociateGroupsFromCenter(centerId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
return this.toApiJsonSerializer.serialize(result);
|
||||
} else {
|
||||
throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "activate", "generateCollectionSheet",
|
||||
"createRole" });
|
||||
"saveCollectionSheet", "close", "associateGroups", "disassociateGroups" });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.joda.time.format.DateTimeFormatter;
|
||||
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
@@ -44,6 +45,8 @@ import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.group.api.GroupingTypesApiConstants;
|
||||
import org.mifosplatform.portfolio.group.exception.ClientExistInGroupException;
|
||||
import org.mifosplatform.portfolio.group.exception.ClientNotInGroupException;
|
||||
import org.mifosplatform.portfolio.group.exception.GroupExistsInCenterException;
|
||||
import org.mifosplatform.portfolio.group.exception.GroupNotExistsInCenterException;
|
||||
import org.mifosplatform.portfolio.group.exception.InvalidGroupStateTransitionException;
|
||||
import org.mifosplatform.useradministration.domain.AppUser;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
@@ -518,4 +521,49 @@ public final class Group extends AbstractPersistable<Long> {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasGroupAsMember(final Group group) {
|
||||
return this.groupMembers.contains(group);
|
||||
}
|
||||
|
||||
public List<String> associateGroups(final Set<Group> groupMembersSet) {
|
||||
|
||||
final List<String> differences = new ArrayList<>();
|
||||
for (final Group group : groupMembersSet) {
|
||||
|
||||
if (group.isCenter()) {
|
||||
final String defaultUserMessage = "Center can not assigned as a child";
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.center.cannot.be.assigned.as.child", defaultUserMessage,
|
||||
group.getId());
|
||||
}
|
||||
|
||||
if (group.isChildGroup()) {
|
||||
final String defaultUserMessage = "Group is already associated with a center";
|
||||
throw new GeneralPlatformDomainRuleException("error.msg.group.already.associated.with.center", defaultUserMessage, group
|
||||
.getParent().getId(), group.getId());
|
||||
}
|
||||
|
||||
if (hasGroupAsMember(group)) { throw new GroupExistsInCenterException(getId(), group.getId()); }
|
||||
|
||||
this.groupMembers.add(group);
|
||||
differences.add(group.getId().toString());
|
||||
}
|
||||
|
||||
return differences;
|
||||
}
|
||||
|
||||
public List<String> disassociateGroups(Set<Group> groupMembersSet) {
|
||||
|
||||
final List<String> differences = new ArrayList<>();
|
||||
for (final Group group : groupMembersSet) {
|
||||
if (hasGroupAsMember(group)) {
|
||||
this.groupMembers.remove(group);
|
||||
differences.add(group.getId().toString());
|
||||
} else {
|
||||
throw new GroupNotExistsInCenterException(group.getId(), getId());
|
||||
}
|
||||
}
|
||||
|
||||
return differences;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package org.mifosplatform.portfolio.group.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
public class GroupExistsInCenterException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public GroupExistsInCenterException(final Long centerId, final Long groupId) {
|
||||
super("error.msg.group.is.already.member.of.center", "Group with identifier " + groupId
|
||||
+ " is already exists in Center with identifier " + centerId, groupId, centerId);
|
||||
}
|
||||
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package org.mifosplatform.portfolio.group.exception;
|
||||
|
||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||
|
||||
public class GroupNotExistsInCenterException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public GroupNotExistsInCenterException(final Long groupId, final Long centerId) {
|
||||
super("error.msg.group.not.in.center", "Group with identifier " + groupId + " is not exists in Center with identifier " + centerId,
|
||||
groupId, centerId);
|
||||
}
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.portfolio.group.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.group.service.GroupingTypesWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class AssociateGroupsToCenterCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final GroupingTypesWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public AssociateGroupsToCenterCommandHandler(final GroupingTypesWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.writePlatformService.associateGroupsToCenter(command.entityId(), command);
|
||||
}
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.mifosplatform.portfolio.group.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.group.service.GroupingTypesWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class DisassociateGroupsFromCenterCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final GroupingTypesWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public DisassociateGroupsFromCenterCommandHandler(final GroupingTypesWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(JsonCommand command) {
|
||||
return this.writePlatformService.disassociateGroupsToCenter(command.entityId(), command);
|
||||
}
|
||||
|
||||
}
|
||||
+40
@@ -476,4 +476,44 @@ public final class GroupingTypesDataValidator {
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
|
||||
}
|
||||
|
||||
public void validateForAssociateGroups(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
|
||||
final Set<String> supportedParameters = new HashSet<>(Arrays.asList(GroupingTypesApiConstants.groupMembersParamName));
|
||||
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group");
|
||||
final String[] groups = this.fromApiJsonHelper.extractArrayNamed(GroupingTypesApiConstants.groupMembersParamName, element);
|
||||
baseDataValidator.reset().parameter(GroupingTypesApiConstants.groupMembersParamName).value(groups).arrayNotEmpty();
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
|
||||
}
|
||||
|
||||
public void validateForDisassociateGroups(final String json) {
|
||||
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
|
||||
final Set<String> supportedParameters = new HashSet<>(Arrays.asList(GroupingTypesApiConstants.groupMembersParamName));
|
||||
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group");
|
||||
final String[] groups = this.fromApiJsonHelper.extractArrayNamed(GroupingTypesApiConstants.groupMembersParamName, element);
|
||||
baseDataValidator.reset().parameter(GroupingTypesApiConstants.groupMembersParamName).value(groups).arrayNotEmpty();
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
}
|
||||
+4
@@ -33,4 +33,8 @@ public interface GroupingTypesWritePlatformService {
|
||||
CommandProcessingResult associateClientsToGroup(Long groupId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult disassociateClientsFromGroup(Long groupId, JsonCommand command);
|
||||
|
||||
CommandProcessingResult associateGroupsToCenter(final Long centerId, final JsonCommand command);
|
||||
|
||||
CommandProcessingResult disassociateGroupsToCenter(final Long centerId, final JsonCommand command);
|
||||
}
|
||||
|
||||
+109
-1
@@ -25,6 +25,7 @@ import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.GeneralPlatformDomainRuleException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
@@ -33,6 +34,11 @@ import org.mifosplatform.organisation.office.exception.InvalidOfficeException;
|
||||
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
|
||||
import org.mifosplatform.organisation.staff.domain.Staff;
|
||||
import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.calendar.domain.Calendar;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarInstanceRepository;
|
||||
import org.mifosplatform.portfolio.calendar.domain.CalendarType;
|
||||
import org.mifosplatform.portfolio.client.domain.Client;
|
||||
import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper;
|
||||
import org.mifosplatform.portfolio.client.service.LoanStatusMapper;
|
||||
@@ -81,6 +87,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
private final CodeValueRepositoryWrapper codeValueRepository;
|
||||
private final SavingsAccountRepository savingsRepository;
|
||||
private final CommandProcessingService commandProcessingService;
|
||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||
|
||||
@Autowired
|
||||
public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
@@ -88,7 +95,8 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
final OfficeRepository officeRepository, final StaffRepositoryWrapper staffRepository, final NoteRepository noteRepository,
|
||||
final GroupLevelRepository groupLevelRepository, final GroupingTypesDataValidator fromApiJsonDeserializer,
|
||||
final LoanRepository loanRepository, final SavingsAccountRepository savingsRepository,
|
||||
final CodeValueRepositoryWrapper codeValueRepository, final CommandProcessingService commandProcessingService) {
|
||||
final CodeValueRepositoryWrapper codeValueRepository, final CommandProcessingService commandProcessingService,
|
||||
final CalendarInstanceRepository calendarInstanceRepository) {
|
||||
this.context = context;
|
||||
this.groupRepository = groupRepository;
|
||||
this.clientRepositoryWrapper = clientRepositoryWrapper;
|
||||
@@ -101,6 +109,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
this.savingsRepository = savingsRepository;
|
||||
this.codeValueRepository = codeValueRepository;
|
||||
this.commandProcessingService = commandProcessingService;
|
||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||
}
|
||||
|
||||
private CommandProcessingResult createGroupingType(final JsonCommand command, final GroupTypes groupingType, final Long centerId) {
|
||||
@@ -579,6 +588,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
final String errorMessage = "Group and child groups must have the same office.";
|
||||
throw new InvalidOfficeException("group", "attach.to.parent.group", errorMessage);
|
||||
}
|
||||
|
||||
childGroups.add(group);
|
||||
}
|
||||
}
|
||||
@@ -684,6 +694,60 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
.build();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult associateGroupsToCenter(final Long centerId, final JsonCommand command) {
|
||||
|
||||
this.fromApiJsonDeserializer.validateForAssociateGroups(command.json());
|
||||
|
||||
final Group centerForUpdate = this.groupRepository.findOneWithNotFoundDetection(centerId);
|
||||
final Set<Group> groupMembers = assembleSetOfChildGroups(centerForUpdate.officeId(), command);
|
||||
checkGroupMembersMeetingSyncWithCenterMeeting(centerId, groupMembers);
|
||||
|
||||
final Map<String, Object> actualChanges = new HashMap<>();
|
||||
final List<String> changes = centerForUpdate.associateGroups(groupMembers);
|
||||
if (!changes.isEmpty()) {
|
||||
actualChanges.put(GroupingTypesApiConstants.groupMembersParamName, changes);
|
||||
}
|
||||
|
||||
this.groupRepository.saveAndFlush(centerForUpdate);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withOfficeId(centerForUpdate.officeId()) //
|
||||
.withGroupId(centerForUpdate.getId()) //
|
||||
.withEntityId(centerForUpdate.getId()) //
|
||||
.with(actualChanges) //
|
||||
.build();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult disassociateGroupsToCenter(final Long centerId, final JsonCommand command) {
|
||||
this.fromApiJsonDeserializer.validateForDisassociateGroups(command.json());
|
||||
|
||||
final Group centerForUpdate = this.groupRepository.findOneWithNotFoundDetection(centerId);
|
||||
final Set<Group> groupMembers = assembleSetOfChildGroups(centerForUpdate.officeId(), command);
|
||||
|
||||
final Map<String, Object> actualChanges = new HashMap<>();
|
||||
|
||||
final List<String> changes = centerForUpdate.disassociateGroups(groupMembers);
|
||||
if (!changes.isEmpty()) {
|
||||
actualChanges.put(GroupingTypesApiConstants.clientMembersParamName, changes);
|
||||
}
|
||||
|
||||
this.groupRepository.saveAndFlush(centerForUpdate);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
.withOfficeId(centerForUpdate.officeId()) //
|
||||
.withGroupId(centerForUpdate.getId()) //
|
||||
.withEntityId(centerForUpdate.getId()) //
|
||||
.with(actualChanges) //
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
private void validateForJLGLoan(final Long groupId, final Set<Client> clientMembers) {
|
||||
for (final Client client : clientMembers) {
|
||||
@@ -720,4 +784,48 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
|
||||
}
|
||||
}
|
||||
|
||||
private void checkGroupMembersMeetingSyncWithCenterMeeting(final Long centerId, final Set<Group> groupMembers) {
|
||||
|
||||
/**
|
||||
* Get parent(center) calendar
|
||||
*/
|
||||
Calendar ceneterCalendar = null;
|
||||
final CalendarInstance parentCalendarInstance = this.calendarInstanceRepository.findByEntityIdAndEntityTypeIdAndCalendarTypeId(
|
||||
centerId, CalendarEntityType.CENTERS.getValue(), CalendarType.COLLECTION.getValue());
|
||||
if (parentCalendarInstance != null) {
|
||||
ceneterCalendar = parentCalendarInstance.getCalendar();
|
||||
}
|
||||
|
||||
for (final Group group : groupMembers) {
|
||||
/**
|
||||
* Get child(group) calendar
|
||||
*/
|
||||
Calendar groupCalendar = null;
|
||||
final CalendarInstance groupCalendarInstance = this.calendarInstanceRepository.findByEntityIdAndEntityTypeIdAndCalendarTypeId(
|
||||
group.getId(), CalendarEntityType.GROUPS.getValue(), CalendarType.COLLECTION.getValue());
|
||||
if (groupCalendarInstance != null) {
|
||||
groupCalendar = groupCalendarInstance.getCalendar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Group shouldn't have a meeting when no meeting attached for
|
||||
* center
|
||||
*/
|
||||
if (ceneterCalendar == null && groupCalendar != null) {
|
||||
throw new GeneralPlatformDomainRuleException(
|
||||
"error.msg.center.associating.group.not.allowed.with.meeting.attached.to.group", "Group with id " + group.getId()
|
||||
+ " is already associated with meeting", group.getId());
|
||||
}
|
||||
/**
|
||||
* Group meeting recurrence should match with center meeting
|
||||
* recurrence
|
||||
*/
|
||||
else if (ceneterCalendar != null && groupCalendar != null) {
|
||||
|
||||
if (!ceneterCalendar.getRecurrence().equalsIgnoreCase(groupCalendar.getRecurrence())) { throw new GeneralPlatformDomainRuleException(
|
||||
"error.msg.center.associating.group.not.allowed.with.different.meeting", "Group with id " + group.getId()
|
||||
+ " meeting recurrence doesnot matched with center meeting recurrence", group.getId()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -98,9 +98,9 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
||||
try {
|
||||
if (!loansIds.contains(accrualData.getLoanId())) {
|
||||
if (accrualData.getDueDateAsLocaldate().isAfter(tilldate)) {
|
||||
if (accruredTill == null) {
|
||||
//if (accruredTill == null) {
|
||||
accruredTill = accrualData.getAccruedTill();
|
||||
}
|
||||
//}
|
||||
addAccrualTillSpecificDate(tilldate, accrualData, accruredTill);
|
||||
} else {
|
||||
addAccrualAccounting(accrualData);
|
||||
|
||||
+2
-1
@@ -1395,7 +1395,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final StringBuilder sqlBuilder = new StringBuilder(400);
|
||||
sqlBuilder
|
||||
.append("loan.id as loanId ,if(loan.client_id is null,mg.office_id,mc.office_id) as officeId,")
|
||||
.append("loan.accrued_till as accruedTill, loan.repayment_period_frequency_enum as frequencyEnum, ")
|
||||
.append("ifnull(loan.accrued_till, ifnull(loan.interest_calculated_from_date, loan.disbursedon_date)) as accruedTill, ")
|
||||
.append("loan.repayment_period_frequency_enum as frequencyEnum, ")
|
||||
.append("loan.repay_every as repayEvery,")
|
||||
.append("(select sum(lc.amount) as dueamount from m_loan_charge lc where lc.loan_id = loan.id and lc.is_active = 1 and lc.waived = 0 and lc.is_penalty = 0 and lc.due_for_collection_as_of_date > ls.fromdate and lc.due_for_collection_as_of_date<= if(:tilldate < ls.duedate, :tilldate , ls.duedate)) as feedueIn,")
|
||||
.append("(select sum(lc.amount) as dueamount from m_loan_charge lc where lc.loan_id = loan.id and lc.is_active = 1 and lc.waived = 0 and lc.is_penalty = 1 and lc.due_for_collection_as_of_date > ls.fromdate and lc.due_for_collection_as_of_date<= if(:tilldate < ls.duedate, :tilldate , ls.duedate)) as penalitydueIn,")
|
||||
|
||||
+3
-1
@@ -668,7 +668,9 @@ public class LoanProduct extends AbstractPersistable<Long> {
|
||||
} else {
|
||||
this.productInterestRecalculationDetails = null;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (!isInterestRecalculationEnabledChanged && this.isInterestRecalculationEnabled()) {
|
||||
this.productInterestRecalculationDetails.update(command, actualChanges, localeAsInput);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user