diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java index c13f419ff..03d2522f6 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java @@ -258,7 +258,7 @@ public class CommandWrapper { public boolean isAccountNumberFormatResource() { return this.entityName.equals(AccountNumberFormatConstants.ENTITY_NAME.toUpperCase()); } - + public boolean isApprove() { return this.actionName.equalsIgnoreCase("APPROVE"); } @@ -1008,4 +1008,8 @@ public class CommandWrapper { public boolean isEnableOperation() { return this.actionName.equalsIgnoreCase("ENABLE"); } + + public boolean isEntityMappingResource() { + return this.entityName.equalsIgnoreCase("ENTITYMAPPING"); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java index 6fafeaf2e..c7997a2d1 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java @@ -1425,7 +1425,7 @@ public class CommandWrapperBuilder { this.href = "/groups/" + groupId + "?command=saveCollectionSheet"; return this; } - + public CommandWrapperBuilder saveIndividualCollectionSheet() { this.actionName = "SAVE"; this.entityName = "COLLECTIONSHEET"; @@ -2327,4 +2327,27 @@ public class CommandWrapperBuilder { return this; } + public CommandWrapperBuilder createMap(Long relId) { + this.actionName = "CREATE"; + this.entityName = "ENTITYMAPPING"; + this.entityId = relId; + this.href = "/entitytoentitymapping/" + relId; + return this; + } + + public CommandWrapperBuilder updateMap(Long mapId) { + this.actionName = "UPDATE"; + this.entityName = "ENTITYMAPPING"; + this.entityId = mapId; + this.href = "/entitytoentitymapping" + mapId; + return this; + } + + public CommandWrapperBuilder deleteMap(final Long mapId) { + this.actionName = "DELETE"; + this.entityName = "ENTITYMAPPING"; + this.entityId = mapId; + this.href = "/entitytoentitymapping/" + mapId; + return this; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java index 58d182c13..0a6784c94 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java @@ -910,7 +910,17 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer } else { throw new UnsupportedCommandException(wrapper.commandName()); } - } else { + } else if (wrapper.isEntityMappingResource()) { + if (wrapper.isCreate()) { + handler = this.applicationContext.getBean("createEntityToEntityMappingCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isUpdate()) { + handler = this.applicationContext.getBean("updateEntityToEntityMappingCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isDelete()) { + handler = this.applicationContext.getBean("deleteEntityToEntityMappingCommandHandler", NewCommandSourceHandler.class); + } else { + throw new UnsupportedCommandException(wrapper.commandName()); + } + }else { throw new UnsupportedCommandException(wrapper.commandName()); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/api/MifosEntityApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/api/MifosEntityApiResource.java new file mode 100644 index 000000000..201baf030 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/api/MifosEntityApiResource.java @@ -0,0 +1,156 @@ +/** + * 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.infrastructure.entityaccess.api; + +import java.util.Collection; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; + +import org.mifosplatform.commands.domain.CommandWrapper; +import org.mifosplatform.commands.service.CommandWrapperBuilder; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; +import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.mifosplatform.infrastructure.entityaccess.data.MifosEntityRelationData; +import org.mifosplatform.infrastructure.entityaccess.data.MifosEntityToEntityMappingData; +import org.mifosplatform.infrastructure.entityaccess.service.MifosEntityAccessReadService; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/entitytoentitymapping") +@Consumes({ MediaType.APPLICATION_JSON }) +@Produces({ MediaType.APPLICATION_JSON }) +@Component +@Scope("singleton") +public class MifosEntityApiResource { + + private final PlatformSecurityContext context; + private final MifosEntityAccessReadService readPlatformService; + private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final DefaultToApiJsonSerializer toApiJsonSerializerOfficeToLoanProducts; + private final ApiRequestParameterHelper apiRequestParameterHelper; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + public MifosEntityApiResource(final PlatformSecurityContext context, final MifosEntityAccessReadService readPlatformService, + final DefaultToApiJsonSerializer toApiJsonSerializer, + final DefaultToApiJsonSerializer toApiJsonSerializerOfficeToLoanProducts, + final ApiRequestParameterHelper apiRequestParameterHelper, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.readPlatformService = readPlatformService; + this.toApiJsonSerializer = toApiJsonSerializer; + this.apiRequestParameterHelper = apiRequestParameterHelper; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + this.toApiJsonSerializerOfficeToLoanProducts = toApiJsonSerializerOfficeToLoanProducts; + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveAll(@Context final UriInfo uriInfo) { + + this.context.authenticatedUser().validateHasReadPermission(MifosEntityApiResourceConstants.MIFOS_ENTITY_RESOURCE_NAME); + + final Collection entityMappings = this.readPlatformService.retrieveAllSupportedMappingTypes(); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, entityMappings, MifosEntityApiResourceConstants.RESPONSE_DATA_PARAMETERS); + } + + @GET + @Path("/{mapId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveOne(@PathParam("mapId") final Long mapId, @Context final UriInfo uriInfo) { + + this.context.authenticatedUser().validateHasReadPermission(MifosEntityApiResourceConstants.MIFOS_ENTITY_RESOURCE_NAME); + + final Collection entityToEntityMappings = this.readPlatformService.retrieveOneMapping(mapId); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializerOfficeToLoanProducts.serialize(settings, entityToEntityMappings, + MifosEntityApiResourceConstants.FETCH_ENTITY_TO_ENTITY_MAPPINGS); + } + + @GET + @Path("/{mapId}/{fromId}/{toId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String getEntityToEntityMappings(@PathParam("mapId") final Long mapId, @PathParam("fromId") final Long fromId, + @PathParam("toId") final Long toId, @Context final UriInfo uriInfo) { + + this.context.authenticatedUser().validateHasReadPermission(MifosEntityApiResourceConstants.MIFOS_ENTITY_RESOURCE_NAME); + + final Collection entityToEntityMappings = this.readPlatformService.retrieveEntityToEntityMappings( + mapId, fromId, toId); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializerOfficeToLoanProducts.serialize(settings, entityToEntityMappings, + MifosEntityApiResourceConstants.FETCH_ENTITY_TO_ENTITY_MAPPINGS); + } + + @POST + @Path("/{relId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String createMap(@PathParam("relId") final Long relId, final String apiRequestBodyAsJson) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder() // + .createMap(relId) // + .withJson(apiRequestBodyAsJson) // + .build(); // + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + + } + + @PUT + @Path("/{mapId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateMap(@PathParam("mapId") final Long mapId, final String apiRequestBodyAsJson) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder() // + .updateMap(mapId) // + .withJson(apiRequestBodyAsJson) // + .build(); // + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + + } + + @DELETE + @Path("{mapId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String delete(@PathParam("mapId") final Long mapId) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder() // + .deleteMap(mapId) // + .build(); // + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/api/MifosEntityApiResourceConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/api/MifosEntityApiResourceConstants.java new file mode 100644 index 000000000..9636fd4d9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/api/MifosEntityApiResourceConstants.java @@ -0,0 +1,41 @@ +/** + * 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.infrastructure.entityaccess.api; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class MifosEntityApiResourceConstants { + + public static final String MIFOS_ENTITY_RESOURCE_NAME = "MifosEntity"; + public static final String mappingTypes = "mappingTypes"; + public static final String mapId = "mapId"; + public static final String relId = "relId"; + public static final String fromEnityType = "fromId"; + public static final String toEntityType = "toId"; + public static final String startDate = "startDate"; + public static final String endDate = "endDate"; + public static final String LOCALE = "locale"; + public static final String DATE_FORMAT = "dateFormat"; + + public static final String OFFICE_ACCESS_TO_LOAN_PRODUCTS = " office_access_to_loan_products "; + public static final String OFFICE_ACCESS_TO_SAVINGS_PRODUCTS = " office_access_to_savings_products "; + public static final String OFFICE_ACCESS_TO_CHARGES_FEES = " office_access_to_fees/charges "; + public static final String ROLE_ACCESS_TO_LOAN_PRODUCTS = " role_access_to_loan_products "; + public static final String ROLE_ACCESS_TO_SAVINGS_PRODUCTS = " role_access_to_savings_products "; + + public static final Set RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList(mappingTypes)); + + public static final Set FETCH_ENTITY_TO_ENTITY_MAPPINGS = new HashSet<>(Arrays.asList(mapId,relId,fromEnityType, toEntityType)); + + public static final Set CREATE_ENTITY_MAPPING_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(fromEnityType, + toEntityType, startDate, LOCALE, DATE_FORMAT, endDate)); + + public static final Set UPDATE_ENTITY_MAPPING_REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(relId,fromEnityType, + toEntityType, startDate,LOCALE, DATE_FORMAT, endDate)); + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/data/MifosEntityDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/data/MifosEntityDataValidator.java new file mode 100644 index 000000000..173e005df --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/data/MifosEntityDataValidator.java @@ -0,0 +1,204 @@ +/** + * 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.infrastructure.entityaccess.data; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.mifosplatform.infrastructure.entityaccess.api.MifosEntityApiResourceConstants; +import org.mifosplatform.organisation.office.domain.OfficeRepositoryWrapper; +import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper; +import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct; +import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository; +import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException; +import org.mifosplatform.portfolio.savings.domain.SavingsProduct; +import org.mifosplatform.portfolio.savings.domain.SavingsProductRepository; +import org.mifosplatform.portfolio.savings.exception.SavingsProductNotFoundException; +import org.mifosplatform.useradministration.domain.Role; +import org.mifosplatform.useradministration.domain.RoleRepository; +import org.mifosplatform.useradministration.exception.RoleNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +@Component +public class MifosEntityDataValidator { + + private final FromJsonHelper fromApiJsonHelper; + private final OfficeRepositoryWrapper officeRepositoryWrapper; + private final LoanProductRepository loanProductRepository; + private final SavingsProductRepository savingsProductRepository; + private final ChargeRepositoryWrapper chargeRepositoryWrapper; + private final RoleRepository roleRepository; + + @Autowired + public MifosEntityDataValidator(final FromJsonHelper fromApiJsonHelper, final OfficeRepositoryWrapper officeRepositoryWrapper, + final LoanProductRepository loanProductRepository, final SavingsProductRepository savingsProductRepository, + final ChargeRepositoryWrapper chargeRepositoryWrapper, final RoleRepository roleRepository) { + this.fromApiJsonHelper = fromApiJsonHelper; + this.officeRepositoryWrapper = officeRepositoryWrapper; + this.loanProductRepository = loanProductRepository; + this.savingsProductRepository = savingsProductRepository; + this.chargeRepositoryWrapper = chargeRepositoryWrapper; + this.roleRepository = roleRepository; + } + + public void validateForCreate(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, + MifosEntityApiResourceConstants.CREATE_ENTITY_MAPPING_REQUEST_DATA_PARAMETERS); + final JsonElement element = this.fromApiJsonHelper.parse(json); + + final List dataValidationErrors = new ArrayList<>(); + + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) + .resource(MifosEntityApiResourceConstants.MIFOS_ENTITY_RESOURCE_NAME); + + if (this.fromApiJsonHelper.parameterExists(MifosEntityApiResourceConstants.fromEnityType, element)) { + final Long fromId = this.fromApiJsonHelper.extractLongNamed(MifosEntityApiResourceConstants.fromEnityType, element); + baseDataValidator.reset().parameter(MifosEntityApiResourceConstants.fromEnityType).value(fromId).notNull() + .integerGreaterThanZero(); + } + + if (this.fromApiJsonHelper.parameterExists(MifosEntityApiResourceConstants.toEntityType, element)) { + final Long toId = this.fromApiJsonHelper.extractLongNamed(MifosEntityApiResourceConstants.toEntityType, element); + baseDataValidator.reset().parameter(MifosEntityApiResourceConstants.toEntityType).value(toId).notNull() + .integerGreaterThanZero(); + } + + if (this.fromApiJsonHelper.parameterExists(MifosEntityApiResourceConstants.startDate, element)) { + final LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed(MifosEntityApiResourceConstants.startDate, element); + baseDataValidator.reset().parameter(MifosEntityApiResourceConstants.startDate).value(startDate); + } + + if (this.fromApiJsonHelper.parameterExists(MifosEntityApiResourceConstants.endDate, element)) { + final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed(MifosEntityApiResourceConstants.endDate, element); + baseDataValidator.reset().parameter(MifosEntityApiResourceConstants.endDate).value(endDate); + } + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + if (!dataValidationErrors.isEmpty()) { + // + throw new PlatformApiDataValidationException(dataValidationErrors); + } + } + + public void checkForEntity(String relId, Long fromId, Long toId) { + + switch (relId) { + case "1": + checkForOffice(fromId); + checkForLoanProducts(toId); + break; + case "2": + checkForOffice(fromId); + checkForSavingsProducts(toId); + break; + case "3": + checkForOffice(fromId); + checkForCharges(toId); + break; + case "4": + checkForRoles(fromId); + checkForLoanProducts(toId); + break; + case "5": + checkForRoles(fromId); + checkForSavingsProducts(toId); + break; + + } + + } + + public void checkForOffice(Long id) { + this.officeRepositoryWrapper.findOneWithNotFoundDetection(id); + } + + public void checkForLoanProducts(final Long id) { + final LoanProduct loanProduct = this.loanProductRepository.findOne(id); + if (loanProduct == null) { throw new LoanProductNotFoundException(id); } + } + + public void checkForSavingsProducts(final Long id) { + final SavingsProduct savingsProduct = this.savingsProductRepository.findOne(id); + if (savingsProduct == null) { throw new SavingsProductNotFoundException(id); } + } + + public void checkForCharges(final Long id) { + this.chargeRepositoryWrapper.findOneWithNotFoundDetection(id); + } + + public void checkForRoles(final Long id) { + final Role role = this.roleRepository.findOne(id); + if (role == null) { throw new RoleNotFoundException(id); } + } + + public void validateForUpdate(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, + MifosEntityApiResourceConstants.UPDATE_ENTITY_MAPPING_REQUEST_DATA_PARAMETERS); + final JsonElement element = this.fromApiJsonHelper.parse(json); + + final List dataValidationErrors = new ArrayList<>(); + + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) + .resource(MifosEntityApiResourceConstants.MIFOS_ENTITY_RESOURCE_NAME); + + boolean atLeastOneParameterPassedForUpdate = false; + if (this.fromApiJsonHelper.parameterExists(MifosEntityApiResourceConstants.fromEnityType, element)) { + atLeastOneParameterPassedForUpdate = true; + final String fromEnityType = this.fromApiJsonHelper.extractStringNamed(MifosEntityApiResourceConstants.fromEnityType, element); + baseDataValidator.reset().parameter(MifosEntityApiResourceConstants.fromEnityType).value(fromEnityType); + } + + if (this.fromApiJsonHelper.parameterExists(MifosEntityApiResourceConstants.fromEnityType, element)) { + atLeastOneParameterPassedForUpdate = true; + final String toEnityType = this.fromApiJsonHelper.extractStringNamed(MifosEntityApiResourceConstants.toEntityType, element); + baseDataValidator.reset().parameter(MifosEntityApiResourceConstants.fromEnityType).value(toEnityType); + } + + if (this.fromApiJsonHelper.parameterExists(MifosEntityApiResourceConstants.toEntityType, element)) { + atLeastOneParameterPassedForUpdate = true; + } + + if (this.fromApiJsonHelper.parameterExists(MifosEntityApiResourceConstants.startDate, element)) { + atLeastOneParameterPassedForUpdate = true; + } + + if (this.fromApiJsonHelper.parameterExists(MifosEntityApiResourceConstants.endDate, element)) { + atLeastOneParameterPassedForUpdate = true; + } + + if (!atLeastOneParameterPassedForUpdate) { + final Object forceError = null; + baseDataValidator.reset().anyOfNotNull(forceError); + } + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/data/MifosEntityRelationData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/data/MifosEntityRelationData.java new file mode 100644 index 000000000..aa02c88ea --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/data/MifosEntityRelationData.java @@ -0,0 +1,33 @@ +/** + * 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.infrastructure.entityaccess.data; + +import java.io.Serializable; + +public class MifosEntityRelationData implements Serializable { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private final Integer fromEntityType; + @SuppressWarnings("unused") + private final Integer toEntityType; + @SuppressWarnings("unused") + private final String mappingTypes; + + public MifosEntityRelationData(final Long id, final Integer fromEntityType, final Integer toEntityType, final String mappingTypes) { + this.id = id; + this.fromEntityType = fromEntityType; + this.toEntityType = toEntityType; + this.mappingTypes = mappingTypes; + } + + public static MifosEntityRelationData getMappingTypes(final Long id,final String mappingTypes) { + Integer fromEntityType = null; + final Integer toEntityType = null; + return new MifosEntityRelationData(id, fromEntityType, toEntityType, mappingTypes); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/data/MifosEntityToEntityMappingData.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/data/MifosEntityToEntityMappingData.java new file mode 100644 index 000000000..c32830634 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/data/MifosEntityToEntityMappingData.java @@ -0,0 +1,67 @@ +/** + * 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.infrastructure.entityaccess.data; + +import java.io.Serializable; +import java.util.Date; + +public class MifosEntityToEntityMappingData implements Serializable { + + @SuppressWarnings("unused") + private Long mapId; + + @SuppressWarnings("unused") + private Long relationId; + + @SuppressWarnings("unused") + private Long fromId; + + @SuppressWarnings("unused") + private Long toId; + + @SuppressWarnings("unused") + private Date startDate; + + @SuppressWarnings("unused") + private Date endDate; + + @SuppressWarnings("unused") + private final String fromEntity; + + @SuppressWarnings("unused") + private final String toEntity; + + private MifosEntityToEntityMappingData(final Long mapId, final Long relationId, final Long fromId, final Long toId, + final Date startDate, final Date endDate, final String fromEntity, final String toEntity) { + this.mapId = mapId; + this.relationId = relationId; + this.fromId = fromId; + this.toId = toId; + this.startDate = startDate; + this.endDate = endDate; + this.fromEntity = fromEntity; + this.toEntity = toEntity; + } + + public static MifosEntityToEntityMappingData getRelatedEntities(final Long mapId, final Long relationId, final Long fromId, + final Long toId, final Date startDate, final Date endDate ,final String fromEntity, final String toEntity) { + + + return new MifosEntityToEntityMappingData(mapId, relationId, fromId, toId, startDate, endDate, fromEntity, toEntity); + + } + + public static MifosEntityToEntityMappingData getRelatedEntities(final Long relationId, final Long fromId, final Long toId, + final Date startDate, final Date endDate) { + final Long mapId = null; + final String fromEntity = null; + final String toEntity = null; + + return new MifosEntityToEntityMappingData(mapId, relationId, fromId, toId, startDate, endDate, fromEntity, toEntity); + + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityRelation.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityRelation.java new file mode 100644 index 000000000..80aa5eced --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityRelation.java @@ -0,0 +1,100 @@ +/** + * 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.infrastructure.entityaccess.domain; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.Entity; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_entity_relation") +public class MifosEntityRelation extends AbstractPersistable { + + @OneToMany(cascade = CascadeType.ALL, mappedBy = "relationId", orphanRemoval = true) + private Set mifosEntityToEntityMapping = new HashSet<>(); + + @Column(name = "from_entity_type", nullable = false, length = 10) + private String fromEntityType; + + @Column(name = "to_entity_type", nullable = false, length = 10) + private String toEntityType; + + @Column(name = "code_name", nullable = false, length = 50) + private String codeName; + + /* private MifosEntityRelation(final String fromEntityType, final String toEntityType, final String codeName) { + this.fromEntityType = fromEntityType; + this.toEntityType = toEntityType; + this.codeName = codeName; + }*/ + + + public MifosEntityRelation() { + // TODO Auto-generated constructor stub + } + + + + public Set getMifosEntityToEntityMapping() { + return this.mifosEntityToEntityMapping; + } + + + + public void setMifosEntityToEntityMapping(Set mifosEntityToEntityMapping) { + this.mifosEntityToEntityMapping = mifosEntityToEntityMapping; + } + + + + public String getFromEntityType() { + return this.fromEntityType; + } + + + + public void setFromEntityType(String fromEntityType) { + this.fromEntityType = fromEntityType; + } + + + + public String getToEntityType() { + return this.toEntityType; + } + + + + public void setToEntityType(String toEntityType) { + this.toEntityType = toEntityType; + } + + + + public String getCodeName() { + return this.codeName; + } + + + + public void setCodeName(String codeName) { + this.codeName = codeName; + } + + + + + + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityRelationRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityRelationRepository.java new file mode 100644 index 000000000..c13f50a33 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityRelationRepository.java @@ -0,0 +1,13 @@ +/** + * 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.infrastructure.entityaccess.domain; + +import org.springframework.data.jpa.repository.JpaRepository; + + +public interface MifosEntityRelationRepository extends JpaRepository{ + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityRelationRepositoryWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityRelationRepositoryWrapper.java new file mode 100644 index 000000000..56418a351 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityRelationRepositoryWrapper.java @@ -0,0 +1,29 @@ +/** + * 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.infrastructure.entityaccess.domain; + +import org.mifosplatform.infrastructure.entityaccess.exception.MifosEntityAccessNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class MifosEntityRelationRepositoryWrapper { + + private final MifosEntityRelationRepository mifosEntityRelationRepository; + + @Autowired + private MifosEntityRelationRepositoryWrapper(final MifosEntityRelationRepository mifosEntityRelationRepository) { + this.mifosEntityRelationRepository = mifosEntityRelationRepository; + + } + + public MifosEntityRelation findOneWithNotFoundDetection(final Long id) { + final MifosEntityRelation mifosEntityRelation = this.mifosEntityRelationRepository.findOne(id); + if (mifosEntityRelation == null) { throw new MifosEntityAccessNotFoundException(id); } + return mifosEntityRelation; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityToEntityMapping.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityToEntityMapping.java new file mode 100644 index 000000000..c9f7ba03d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityToEntityMapping.java @@ -0,0 +1,124 @@ +/** + * 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.infrastructure.entityaccess.domain; + +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.entityaccess.api.MifosEntityApiResourceConstants; +import org.mifosplatform.infrastructure.entityaccess.exception.MifosEntityToEntityMappingDateException; +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_entity_to_entity_mapping", uniqueConstraints = { @UniqueConstraint(columnNames = { "rel_id", "from_id", "to_id" }) }) +public class MifosEntityToEntityMapping extends AbstractPersistable { + + @ManyToOne + @JoinColumn(name = "rel_id") + private MifosEntityRelation relationId; + + @Column(name = "from_id") + private Long fromId; + + @Column(name = "to_id") + private Long toId; + + @Column(name = "start_date", nullable = false) + @Temporal(TemporalType.DATE) + private Date startDate; + + @Column(name = "end_date", nullable = false) + @Temporal(TemporalType.DATE) + private Date endDate; + + private MifosEntityToEntityMapping(final MifosEntityRelation relationId, final Long fromId, final Long toId, final Date startDate, + final Date endDate) { + this.relationId = relationId; + this.fromId = fromId; + this.toId = toId; + this.startDate = startDate; + this.endDate = endDate; + + } + + public MifosEntityToEntityMapping() { + // + } + + public static MifosEntityToEntityMapping newMap(MifosEntityRelation relationId, Long fromId, Long toId, Date startDate, Date endDate) { + + return new MifosEntityToEntityMapping(relationId, fromId, toId, startDate, endDate); + + } + + public Map updateMap(final JsonCommand command) { + + final Map actualChanges = new LinkedHashMap<>(9); + + if (command.isChangeInLongParameterNamed(MifosEntityApiResourceConstants.fromEnityType, this.fromId)) { + final Long newValue = command.longValueOfParameterNamed(MifosEntityApiResourceConstants.fromEnityType); + actualChanges.put(MifosEntityApiResourceConstants.fromEnityType, newValue); + this.fromId = newValue; + } + + if (command.isChangeInLongParameterNamed(MifosEntityApiResourceConstants.toEntityType, this.toId)) { + final Long newValue = command.longValueOfParameterNamed(MifosEntityApiResourceConstants.toEntityType); + actualChanges.put(MifosEntityApiResourceConstants.toEntityType, newValue); + this.toId = newValue; + } + + if (command.isChangeInDateParameterNamed(MifosEntityApiResourceConstants.startDate, this.startDate)) { + final String valueAsInput = command.stringValueOfParameterNamed(MifosEntityApiResourceConstants.startDate); + actualChanges.put(MifosEntityApiResourceConstants.startDate, valueAsInput); + final Date startDate = command.DateValueOfParameterNamed(MifosEntityApiResourceConstants.startDate); + this.startDate = startDate; + } + + if (command.isChangeInDateParameterNamed(MifosEntityApiResourceConstants.endDate, this.endDate)) { + final String valueAsInput = command.stringValueOfParameterNamed(MifosEntityApiResourceConstants.endDate); + actualChanges.put(MifosEntityApiResourceConstants.endDate, valueAsInput); + final Date endDate = command.DateValueOfParameterNamed(MifosEntityApiResourceConstants.endDate); + this.endDate = endDate; + } + if (startDate != null && endDate != null) { + if (endDate.before(startDate)) { throw new MifosEntityToEntityMappingDateException(startDate.toString(), endDate.toString()); } + } + + return actualChanges; + + } + + public MifosEntityRelation getRelationId() { + return this.relationId; + } + + public void setRelationId(MifosEntityRelation relationId) { + this.relationId = relationId; + } + + /* + * public Date getStartDate() { Date startDate = null; if (this.startDate != + * null) { startDate = Date.fromDateFields(this.startDate); } return + * startDate; } + */ + + /* + * public Date getStartDate() { return (Date) ObjectUtils.defaultIfNull(new + * Date(this.startDate), null); } + */ + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityToEntityMappingRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityToEntityMappingRepository.java new file mode 100644 index 000000000..0068fd3af --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityToEntityMappingRepository.java @@ -0,0 +1,15 @@ +/** + * 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.infrastructure.entityaccess.domain; + +import org.springframework.data.jpa.repository.JpaRepository; + + +public interface MifosEntityToEntityMappingRepository extends JpaRepository{ + + + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityToEntityMappingRepositoryWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityToEntityMappingRepositoryWrapper.java new file mode 100644 index 000000000..568f51476 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/domain/MifosEntityToEntityMappingRepositoryWrapper.java @@ -0,0 +1,32 @@ +/** + * 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.infrastructure.entityaccess.domain; + +import org.mifosplatform.infrastructure.entityaccess.exception.MifosEntityAccessNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class MifosEntityToEntityMappingRepositoryWrapper { + + private final MifosEntityToEntityMappingRepository mifosEntityToEntityMappingRepository; + + @Autowired + public MifosEntityToEntityMappingRepositoryWrapper(final MifosEntityToEntityMappingRepository mifosEntityToEntityMappingRepository) { + this.mifosEntityToEntityMappingRepository = mifosEntityToEntityMappingRepository; + } + + public MifosEntityToEntityMapping findOneWithNotFoundDetection(final Long id) { + final MifosEntityToEntityMapping mifosEntityToEntityMapping = this.mifosEntityToEntityMappingRepository.findOne(id); + if (mifosEntityToEntityMapping == null) { throw new MifosEntityAccessNotFoundException(id); } + return mifosEntityToEntityMapping; + } + + public void delete(final MifosEntityToEntityMapping mapId) { + this.mifosEntityToEntityMappingRepository.delete(mapId); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/exception/MifosEntityAccessNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/exception/MifosEntityAccessNotFoundException.java index 3871df3d6..959023f35 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/exception/MifosEntityAccessNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/exception/MifosEntityAccessNotFoundException.java @@ -15,4 +15,5 @@ public class MifosEntityAccessNotFoundException extends AbstractPlatformResource public MifosEntityAccessNotFoundException(final Long id) { super("error.msg.entityaccess.id.invalid", "MifosEntityAccess with identifier " + id + " does not exist", id); } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/exception/MifosEntityToEntityMappingDateException.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/exception/MifosEntityToEntityMappingDateException.java new file mode 100644 index 000000000..9d9d1267c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/exception/MifosEntityToEntityMappingDateException.java @@ -0,0 +1,16 @@ +/** + * 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.infrastructure.entityaccess.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; + + +public class MifosEntityToEntityMappingDateException extends AbstractPlatformResourceNotFoundException { + + public MifosEntityToEntityMappingDateException(final String startDate,final String endDate) { + super("error.msg.invalid.endDate", "EndDate " + endDate + " cannot be before StartDate "+startDate); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/exception/MifosEntityToEntityMappingNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/exception/MifosEntityToEntityMappingNotFoundException.java new file mode 100644 index 000000000..c19879699 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/exception/MifosEntityToEntityMappingNotFoundException.java @@ -0,0 +1,15 @@ +/** + * 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.infrastructure.entityaccess.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; + +public class MifosEntityToEntityMappingNotFoundException extends AbstractPlatformResourceNotFoundException { + + public MifosEntityToEntityMappingNotFoundException(final String id) { + super("error.msg.entityaccess.id.invalid", "MifosEntityToEntityMapping with identifier " + id + " does not exist", id); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/handler/CreateEntityToEntityMappingCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/handler/CreateEntityToEntityMappingCommandHandler.java new file mode 100644 index 000000000..0de0919a3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/handler/CreateEntityToEntityMappingCommandHandler.java @@ -0,0 +1,33 @@ +/** + * 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.infrastructure.entityaccess.handler; + +import javax.transaction.Transactional; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.entityaccess.service.MifosEntityAccessWriteService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CreateEntityToEntityMappingCommandHandler implements NewCommandSourceHandler { + + private final MifosEntityAccessWriteService mifosEntityAccessWriteService; + + @Autowired + public CreateEntityToEntityMappingCommandHandler(final MifosEntityAccessWriteService mifosEntityAccessWriteService) { + this.mifosEntityAccessWriteService = mifosEntityAccessWriteService; + } + + @Override + @Transactional + public CommandProcessingResult processCommand(JsonCommand command) { + return this.mifosEntityAccessWriteService.createEntityToEntityMapping(command.entityId(),command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/handler/DeleteEntityToEntityMappingCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/handler/DeleteEntityToEntityMappingCommandHandler.java new file mode 100644 index 000000000..6afdb834d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/handler/DeleteEntityToEntityMappingCommandHandler.java @@ -0,0 +1,33 @@ +/** + * 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.infrastructure.entityaccess.handler; + +import javax.transaction.Transactional; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.entityaccess.service.MifosEntityAccessWriteService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DeleteEntityToEntityMappingCommandHandler implements NewCommandSourceHandler { + + private final MifosEntityAccessWriteService mifosEntityAccessWriteService; + + @Autowired + public DeleteEntityToEntityMappingCommandHandler(final MifosEntityAccessWriteService mifosEntityAccessWriteService) { + this.mifosEntityAccessWriteService = mifosEntityAccessWriteService; + } + + @Override + @Transactional + public CommandProcessingResult processCommand(JsonCommand command) { + return this.mifosEntityAccessWriteService.deleteEntityToEntityMapping(command.entityId()); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/handler/UpdateEntityToEntityMappingCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/handler/UpdateEntityToEntityMappingCommandHandler.java new file mode 100644 index 000000000..c6ce06579 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/handler/UpdateEntityToEntityMappingCommandHandler.java @@ -0,0 +1,33 @@ +/** + * 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.infrastructure.entityaccess.handler; + +import javax.transaction.Transactional; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.entityaccess.service.MifosEntityAccessWriteService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UpdateEntityToEntityMappingCommandHandler implements NewCommandSourceHandler { + + private final MifosEntityAccessWriteService mifosEntityAccessWriteService; + + @Autowired + public UpdateEntityToEntityMappingCommandHandler(final MifosEntityAccessWriteService mifosEntityAccessWriteService) { + this.mifosEntityAccessWriteService = mifosEntityAccessWriteService; + } + + @Override + @Transactional + public CommandProcessingResult processCommand(JsonCommand command) { + return this.mifosEntityAccessWriteService.updateEntityToEntityMapping(command.entityId(),command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessReadService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessReadService.java index 13b25cbfc..52ba72715 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessReadService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessReadService.java @@ -5,28 +5,32 @@ */ package org.mifosplatform.infrastructure.entityaccess.service; +import java.util.Collection; + import org.mifosplatform.infrastructure.entityaccess.data.MifosEntityAccessData; +import org.mifosplatform.infrastructure.entityaccess.data.MifosEntityRelationData; +import org.mifosplatform.infrastructure.entityaccess.data.MifosEntityToEntityMappingData; import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityAccessType; import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityType; -import java.util.Collection; - - public interface MifosEntityAccessReadService { - Collection retrieveEntityAccessFor (Long entityId, MifosEntityType type, - MifosEntityAccessType accessType, MifosEntityType secondType, - boolean includeAllOffices); - String getSQLQueryInClause_WithListOfIDsForEntityAccess (Long entityId, MifosEntityType firstEntityType, - MifosEntityAccessType accessType, MifosEntityType secondEntityType, - boolean includeAllOffices); - - String getSQLQueryInClauseIDList_ForLoanProductsForOffice (Long loanProductId, - boolean includeAllOffices); + Collection retrieveEntityAccessFor(Long entityId, MifosEntityType type, MifosEntityAccessType accessType, + MifosEntityType secondType, boolean includeAllOffices); - String getSQLQueryInClauseIDList_ForSavingsProductsForOffice( - Long savingsProductId, boolean includeAllOffices); + String getSQLQueryInClause_WithListOfIDsForEntityAccess(Long entityId, MifosEntityType firstEntityType, + MifosEntityAccessType accessType, MifosEntityType secondEntityType, boolean includeAllOffices); + + String getSQLQueryInClauseIDList_ForLoanProductsForOffice(Long loanProductId, boolean includeAllOffices); + + String getSQLQueryInClauseIDList_ForSavingsProductsForOffice(Long savingsProductId, boolean includeAllOffices); + + String getSQLQueryInClauseIDList_ForChargesForOffice(Long officeId, boolean includeAllOffices); + + Collection retrieveAllSupportedMappingTypes(); + + Collection retrieveOneMapping(Long mapId); + + Collection retrieveEntityToEntityMappings(Long mapId, Long fromoId, Long toId); - String getSQLQueryInClauseIDList_ForChargesForOffice(Long officeId, - boolean includeAllOffices); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessReadServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessReadServiceImpl.java index f49ce9be4..106755531 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessReadServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessReadServiceImpl.java @@ -5,10 +5,17 @@ */ package org.mifosplatform.infrastructure.entityaccess.service; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.Date; + import org.mifosplatform.infrastructure.core.service.RoutingDataSource; import org.mifosplatform.infrastructure.dataqueries.service.GenericDataServiceImpl; import org.mifosplatform.infrastructure.entityaccess.MifosEntityAccessConstants; import org.mifosplatform.infrastructure.entityaccess.data.MifosEntityAccessData; +import org.mifosplatform.infrastructure.entityaccess.data.MifosEntityRelationData; +import org.mifosplatform.infrastructure.entityaccess.data.MifosEntityToEntityMappingData; import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntity; import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityAccessType; import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityType; @@ -22,15 +29,11 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collection; - @Service public class MifosEntityAccessReadServiceImpl implements MifosEntityAccessReadService { - - private final PlatformSecurityContext context; - private final JdbcTemplate jdbcTemplate; + + private final PlatformSecurityContext context; + private final JdbcTemplate jdbcTemplate; private final static Logger logger = LoggerFactory.getLogger(GenericDataServiceImpl.class); @Autowired @@ -43,73 +46,73 @@ public class MifosEntityAccessReadServiceImpl implements MifosEntityAccessReadSe /* * (non-Javadoc) * @see org.mifosplatform.infrastructure.entityaccess.service.MifosEntityAccessReadService#getSQLQueryWithListOfIDsForEntityAccess - * (Long, - * org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityType, - * org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityAccessType, - * org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityType, - * boolean) + * (Long, + * org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityType, + * org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityAccessType, + * org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityType, + * boolean) * * This method returns the list of entity IDs as a comma separated list * Or null if there is no entity restrictions or if there */ @Override - public String getSQLQueryInClause_WithListOfIDsForEntityAccess ( - Long firstEntityId, - MifosEntityType firstEntityType, - MifosEntityAccessType accessType, - MifosEntityType secondEntityType, - boolean includeAllOffices) { - Collection accesslist = retrieveEntityAccessFor ( - firstEntityId, firstEntityType, accessType, secondEntityType, includeAllOffices); - String returnIdListStr = null; - StringBuffer accessListCSVStrBuf = null; - if ( (accesslist != null) && (accesslist.size() > 0) ) { - logger.debug("Found " + accesslist.size() + - " access type restrictions while getting entity access configuration for " + - firstEntityType.getType() + ":" + firstEntityId + - " with type " + accessType.toStr() + " against " + secondEntityType.getType() - ); - accessListCSVStrBuf = new StringBuffer (" "); - for (int i = 0; i < accesslist.size(); i++) { - MifosEntityAccessData accessData = (MifosEntityAccessData) accesslist.toArray()[i]; - if (accessData == null) { - throw new MifosEntityAccessConfigurationException(firstEntityId, firstEntityType, - accessType, secondEntityType); - } - if (accessData.getSecondEntity().getId() == 0) { // If there is any ID that zero, then allow access to all - accessListCSVStrBuf = null; - break; - } - if (i>0) { - accessListCSVStrBuf.append(','); - } - accessListCSVStrBuf.append(accessData.getSecondEntity().getId()); - } + public String getSQLQueryInClause_WithListOfIDsForEntityAccess ( + Long firstEntityId, + MifosEntityType firstEntityType, + MifosEntityAccessType accessType, + MifosEntityType secondEntityType, + boolean includeAllOffices) { + Collection accesslist = retrieveEntityAccessFor ( + firstEntityId, firstEntityType, accessType, secondEntityType, includeAllOffices); + String returnIdListStr = null; + StringBuffer accessListCSVStrBuf = null; + if ( (accesslist != null) && (accesslist.size() > 0) ) { + logger.debug("Found " + accesslist.size() + + " access type restrictions while getting entity access configuration for " + + firstEntityType.getType() + ":" + firstEntityId + + " with type " + accessType.toStr() + " against " + secondEntityType.getType() + ); + accessListCSVStrBuf = new StringBuffer (" "); + for (int i = 0; i < accesslist.size(); i++) { + MifosEntityAccessData accessData = (MifosEntityAccessData) accesslist.toArray()[i]; + if (accessData == null) { + throw new MifosEntityAccessConfigurationException(firstEntityId, firstEntityType, + accessType, secondEntityType); + } + if (accessData.getSecondEntity().getId() == 0) { // If there is any ID that zero, then allow access to all + accessListCSVStrBuf = null; + break; + } + if (i>0) { + accessListCSVStrBuf.append(','); + } + accessListCSVStrBuf.append(accessData.getSecondEntity().getId()); + } - } else { - logger.debug("Found zero access type restrictions while getting entity access configuration for " + - firstEntityType.getType() + ":" + firstEntityId + - " with type " + accessType.toStr() + " against " + secondEntityType.getType() - ); - accessListCSVStrBuf = new StringBuffer(); - accessListCSVStrBuf.append ("false"); // Append false so that no rows will be returned - } - if (accessListCSVStrBuf != null) { - returnIdListStr = accessListCSVStrBuf.toString(); - } - logger.debug("List of IDs applicable:" + returnIdListStr); - return returnIdListStr; + } else { + logger.debug("Found zero access type restrictions while getting entity access configuration for " + + firstEntityType.getType() + ":" + firstEntityId + + " with type " + accessType.toStr() + " against " + secondEntityType.getType() + ); + accessListCSVStrBuf = new StringBuffer(); + accessListCSVStrBuf.append ("false"); // Append false so that no rows will be returned + } + if (accessListCSVStrBuf != null) { + returnIdListStr = accessListCSVStrBuf.toString(); + } + logger.debug("List of IDs applicable:" + returnIdListStr); + return returnIdListStr; } - - @Override - public Collection retrieveEntityAccessFor( - Long firstEntityId, - MifosEntityType firstEntityType, - MifosEntityAccessType accessType, - MifosEntityType secondEntityType, - boolean includeAllSubOffices) { - final AppUser currentUser = this.context.authenticatedUser(); - + + @Override + public Collection retrieveEntityAccessFor( + Long firstEntityId, + MifosEntityType firstEntityType, + MifosEntityAccessType accessType, + MifosEntityType secondEntityType, + boolean includeAllSubOffices) { + final AppUser currentUser = this.context.authenticatedUser(); + final String hierarchy = currentUser.getOffice().getHierarchy(); String hierarchySearchString = null; if (includeAllSubOffices) { @@ -118,62 +121,62 @@ public class MifosEntityAccessReadServiceImpl implements MifosEntityAccessReadSe hierarchySearchString = hierarchy + "%"; } String sql = getSQLForRetriveEntityAccessFor(firstEntityType, - accessType, secondEntityType); + accessType, secondEntityType); Collection entityAccessData = null; MifosEntityAccessDataMapper mapper = new MifosEntityAccessDataMapper(); if (includeAllSubOffices && (firstEntityType.getTable().equals("m_office")) ) { - sql += " where firstentity.hierarchy like ? order by firstEntity.hierarchy"; - entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { firstEntityId, hierarchySearchString }); + sql += " where firstentity.hierarchy like ? order by firstEntity.hierarchy"; + entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { firstEntityId, hierarchySearchString }); } else { - entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { firstEntityId }); + entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { firstEntityId }); } return entityAccessData; - } - - private String getSQLForRetriveEntityAccessFor ( - MifosEntityType firstEntityType, - MifosEntityAccessType accessType, - MifosEntityType secondEntityType) { - StringBuffer str = new StringBuffer ("select eea.entity_id as entity_id, entity_type as entity_type, "); - str.append("access_type_code_value_id as access_id, cv.code_value as access_type_desc, c.code_name as code, "); - str.append("firstentity.id as first_entity_id, firstentity.name as entity_name, "); - str.append("otherentity.id as second_entity_id, otherentity.name as second_entity_name, "); - str.append("eea.second_entity_type as second_entity_type "); - str.append("from m_entity_to_entity_access eea "); - str.append("left join m_code_value cv on (cv.code_value = "); - str.append("'"); - str.append(accessType.toStr()); - str.append("' "); - str.append("and eea.access_type_code_value_id = cv.id) "); - str.append("left join m_code c on (c.code_name = '"); - str.append(MifosEntityAccessConstants.ENTITY_ACCESS_CODENAME); - str.append("' and cv.code_id = c.id) "); - str.append("left join "); - str.append(firstEntityType.getTable()); - str.append(" firstentity on (eea.entity_type = "); - str.append("'"); - str.append(firstEntityType.getType()); - str.append("'"); - str.append(" and eea.entity_id = firstentity.id) left join "); - str.append(secondEntityType.getTable()); - str.append(" otherentity on (eea.second_entity_type = "); - str.append("'"); - str.append(secondEntityType.getType()); - str.append("' "); - str.append("and eea.second_entity_id = otherentity.id) "); - str.append("where eea.access_type_code_value_id = cv.id "); - str.append("and eea.entity_id = ? "); - logger.debug(str.toString()); - return str.toString(); - } - - private static final class MifosEntityAccessDataMapper implements RowMapper { - @Override - public MifosEntityAccessData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - final String entityType = rs.getString("entity_type"); + } + + private String getSQLForRetriveEntityAccessFor ( + MifosEntityType firstEntityType, + MifosEntityAccessType accessType, + MifosEntityType secondEntityType) { + StringBuffer str = new StringBuffer ("select eea.entity_id as entity_id, entity_type as entity_type, "); + str.append("access_type_code_value_id as access_id, cv.code_value as access_type_desc, c.code_name as code, "); + str.append("firstentity.id as first_entity_id, firstentity.name as entity_name, "); + str.append("otherentity.id as second_entity_id, otherentity.name as second_entity_name, "); + str.append("eea.second_entity_type as second_entity_type "); + str.append("from m_entity_to_entity_access eea "); + str.append("left join m_code_value cv on (cv.code_value = "); + str.append("'"); + str.append(accessType.toStr()); + str.append("' "); + str.append("and eea.access_type_code_value_id = cv.id) "); + str.append("left join m_code c on (c.code_name = '"); + str.append(MifosEntityAccessConstants.ENTITY_ACCESS_CODENAME); + str.append("' and cv.code_id = c.id) "); + str.append("left join "); + str.append(firstEntityType.getTable()); + str.append(" firstentity on (eea.entity_type = "); + str.append("'"); + str.append(firstEntityType.getType()); + str.append("'"); + str.append(" and eea.entity_id = firstentity.id) left join "); + str.append(secondEntityType.getTable()); + str.append(" otherentity on (eea.second_entity_type = "); + str.append("'"); + str.append(secondEntityType.getType()); + str.append("' "); + str.append("and eea.second_entity_id = otherentity.id) "); + str.append("where eea.access_type_code_value_id = cv.id "); + str.append("and eea.entity_id = ? "); + logger.debug(str.toString()); + return str.toString(); + } + + private static final class MifosEntityAccessDataMapper implements RowMapper { + @Override + public MifosEntityAccessData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + final String entityType = rs.getString("entity_type"); final Long entityId = rs.getLong("entity_id"); final String entityName = rs.getString("entity_name"); final Long accessId = rs.getLong("access_id"); @@ -186,66 +189,207 @@ public class MifosEntityAccessReadServiceImpl implements MifosEntityAccessReadSe MifosEntity firstEntity = null; MifosEntityType etype = MifosEntityType.get(entityType); if (entityId != null && etype != null) { - firstEntity = new MifosEntity(entityId, etype); + firstEntity = new MifosEntity(entityId, etype); } MifosEntity secondEntity = null; MifosEntityType secondetype = MifosEntityType.get(secondEntityType); if (entityId != null && etype != null) { - secondEntity = new MifosEntity(secondEntityId, secondetype); + secondEntity = new MifosEntity(secondEntityId, secondetype); } MifosEntityAccessType accessType = null; if (accessTypeDesc != null) { - accessType = MifosEntityAccessType.get(accessTypeDesc); + accessType = MifosEntityAccessType.get(accessTypeDesc); } MifosEntityAccessData returnMifosEntityAccessData = null; if (firstEntity != null && secondEntity != null && accessType != null) { - returnMifosEntityAccessData = new MifosEntityAccessData(firstEntity, accessType, secondEntity); + returnMifosEntityAccessData = new MifosEntityAccessData(firstEntity, accessType, secondEntity); } return returnMifosEntityAccessData; - } - } + } + } - @Override - public String getSQLQueryInClauseIDList_ForLoanProductsForOffice( - Long officeId, boolean includeAllOffices) { - - MifosEntityType firstEntityType = MifosEntityType.OFFICE; - MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS; - MifosEntityType secondEntityType = MifosEntityType.LOAN_PRODUCT; + @Override + public String getSQLQueryInClauseIDList_ForLoanProductsForOffice( + Long officeId, boolean includeAllOffices) { + + MifosEntityType firstEntityType = MifosEntityType.OFFICE; + MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS; + MifosEntityType secondEntityType = MifosEntityType.LOAN_PRODUCT; - return getSQLQueryInClause_WithListOfIDsForEntityAccess ( - officeId, firstEntityType, accessType, - secondEntityType, includeAllOffices); - } + return getSQLQueryInClause_WithListOfIDsForEntityAccess ( + officeId, firstEntityType, accessType, + secondEntityType, includeAllOffices); + } - @Override - public String getSQLQueryInClauseIDList_ForSavingsProductsForOffice( - Long officeId, boolean includeAllOffices) { - - MifosEntityType firstEntityType = MifosEntityType.OFFICE; - MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_SAVINGS_PRODUCTS; - MifosEntityType secondEntityType = MifosEntityType.SAVINGS_PRODUCT; + @Override + public String getSQLQueryInClauseIDList_ForSavingsProductsForOffice( + Long officeId, boolean includeAllOffices) { + + MifosEntityType firstEntityType = MifosEntityType.OFFICE; + MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_SAVINGS_PRODUCTS; + MifosEntityType secondEntityType = MifosEntityType.SAVINGS_PRODUCT; - return getSQLQueryInClause_WithListOfIDsForEntityAccess ( - officeId, firstEntityType, accessType, - secondEntityType, includeAllOffices); - } - - @Override - public String getSQLQueryInClauseIDList_ForChargesForOffice( - Long officeId, boolean includeAllOffices) { - - MifosEntityType firstEntityType = MifosEntityType.OFFICE; - MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_CHARGES; - MifosEntityType secondEntityType = MifosEntityType.CHARGE; + return getSQLQueryInClause_WithListOfIDsForEntityAccess ( + officeId, firstEntityType, accessType, + secondEntityType, includeAllOffices); + } + + @Override + public String getSQLQueryInClauseIDList_ForChargesForOffice( + Long officeId, boolean includeAllOffices) { + + MifosEntityType firstEntityType = MifosEntityType.OFFICE; + MifosEntityAccessType accessType = MifosEntityAccessType.OFFICE_ACCESS_TO_CHARGES; + MifosEntityType secondEntityType = MifosEntityType.CHARGE; - return getSQLQueryInClause_WithListOfIDsForEntityAccess ( - officeId, firstEntityType, accessType, - secondEntityType, includeAllOffices); - } + return getSQLQueryInClause_WithListOfIDsForEntityAccess ( + officeId, firstEntityType, accessType, + secondEntityType, includeAllOffices); + } + @Override + public Collection retrieveAllSupportedMappingTypes() { + EntityRelationMapper entityMapper = new EntityRelationMapper(); + final String sql = entityMapper.schema(); + final Collection mapTypes = this.jdbcTemplate.query(sql, entityMapper, new Object[] {}); + return mapTypes; + } + private static final class EntityRelationMapper implements RowMapper { + + private final StringBuilder sqlBuilder = new StringBuilder("select id as id,code_name as mapping_Types from m_entity_relation "); + + public String schema() { + return this.sqlBuilder.toString(); + } + + @Override + public MifosEntityRelationData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + final Long mappingTypesId = rs.getLong("id"); + final String mappingTypes = rs.getString("mapping_Types"); + return MifosEntityRelationData.getMappingTypes(mappingTypesId, mappingTypes); + } + } + + @Override + public Collection retrieveEntityToEntityMappings(Long mapId, Long fromId, Long toId) { + + EntityToEntityMapper entityToEntityMapper = new EntityToEntityMapper(); + String sql = entityToEntityMapper.schema(); + final Collection mapTypes = this.jdbcTemplate.query(sql, entityToEntityMapper, new Object[] { + mapId, fromId, fromId, toId, toId }); + return mapTypes; + + } + + @Override + public Collection retrieveOneMapping(Long mapId) { + GetOneEntityMapper entityMapper = new GetOneEntityMapper(); + String sql = entityMapper.schema(); + final Collection mapTypes = this.jdbcTemplate.query(sql, entityMapper, new Object[] { mapId }); + return mapTypes; + } + + private static final class GetOneEntityMapper implements RowMapper { + + private final String schema; + + public GetOneEntityMapper() { + + StringBuffer str = new StringBuffer("select eem.rel_id as relId, "); + str.append("eem.from_id as fromId,eem.to_Id as toId,eem.start_date as startDate,eem.end_date as endDate "); + str.append("from m_entity_to_entity_mapping eem "); + str.append("where eem.id= ? "); + this.schema = str.toString(); + } + + public String schema() { + return this.schema; + } + + @Override + public MifosEntityToEntityMappingData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long relId = rs.getLong("relId"); + final Long fromId = rs.getLong("fromId"); + final Long toId = rs.getLong("toId"); + final Date startDate = rs.getDate("startDate"); + final Date endDate = rs.getDate("endDate"); + return MifosEntityToEntityMappingData.getRelatedEntities(relId, fromId, toId, startDate, endDate); + } + + } + + private static final class EntityToEntityMapper implements RowMapper { + + private final String schema; + + public EntityToEntityMapper() { + + StringBuffer str = new StringBuffer("select eem.id as mapId, "); + str.append("eem.rel_id as relId, "); + str.append("eem.from_id as from_id, "); + str.append("eem.to_id as to_id, "); + str.append("eem.start_date as startDate, "); + str.append("eem.end_date as endDate, "); + str.append("case er.code_name "); + str.append("when 'office_access_to_loan_products' then "); + str.append("o.name "); + str.append("when 'office_access_to_savings_products' then "); + str.append("o.name "); + str.append("when 'office_access_to_fees/charges' then "); + str.append("o.name "); + str.append("when 'role_access_to_loan_products' then "); + str.append("r.name "); + str.append("when 'role_access_to_savings_products' then "); + str.append("r.name "); + str.append("end as from_name, "); + str.append("case er.code_name "); + str.append("when 'office_access_to_loan_products' then "); + str.append("lp.name "); + str.append("when 'office_access_to_savings_products' then "); + str.append("sp.name "); + str.append("when 'office_access_to_fees/charges' then "); + str.append("charge.name "); + str.append("when 'role_access_to_loan_products' then "); + str.append("lp.name "); + str.append("when 'role_access_to_savings_products' then "); + str.append("sp.name "); + str.append("end as to_name, "); + str.append("er.code_name "); + str.append("from m_entity_to_entity_mapping eem "); + str.append("join m_entity_relation er on eem.rel_id = er.id "); + str.append("left join m_office o on er.from_entity_type = 1 and eem.from_id = o.id "); + str.append("left join m_role r on er.from_entity_type = 5 and eem.from_id = r.id "); + str.append("left join m_product_loan lp on er.to_entity_type = 2 and eem.to_id = lp.id "); + str.append("left join m_savings_product sp on er.to_entity_type = 3 and eem.to_id = sp.id "); + str.append("left join m_charge charge on er.to_entity_type = 4 and eem.to_id = charge.id "); + str.append("where "); + str.append("er.id = ? and "); + str.append("( ? = 0 or from_id = ? ) and "); + str.append("( ? = 0 or to_id = ? ) "); + + this.schema = str.toString(); + } + + public String schema() { + return this.schema; + } + + @Override + public MifosEntityToEntityMappingData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + final Long mapId = rs.getLong("mapId"); + final Long relId = rs.getLong("relId"); + final Long fromId = rs.getLong("from_id"); + final Long toId = rs.getLong("to_id"); + final String fromEntity = rs.getString("from_name"); + final String toEntity = rs.getString("to_name"); + final Date startDate = rs.getDate("startDate"); + final Date endDate = rs.getDate("endDate"); + return MifosEntityToEntityMappingData.getRelatedEntities(mapId, relId, fromId, toId, startDate, endDate, fromEntity, toEntity); + } + } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessWriteService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessWriteService.java index 0ae7123cd..06431519a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessWriteService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessWriteService.java @@ -11,20 +11,23 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; public interface MifosEntityAccessWriteService { - CommandProcessingResult createEntityAccess ( - final JsonCommand command); - - void addNewEntityAccess (final String entityType, final Long entityId, - final CodeValue accessType, - final String secondEntityType, final Long secondEntityId); + CommandProcessingResult createEntityAccess(final JsonCommand command); + + CommandProcessingResult createEntityToEntityMapping(final Long relId,final JsonCommand command); + + CommandProcessingResult updateEntityToEntityMapping(final Long mapId, final JsonCommand command); + + CommandProcessingResult deleteEntityToEntityMapping(final Long mapId); + + void addNewEntityAccess(final String entityType, final Long entityId, final CodeValue accessType, final String secondEntityType, + final Long secondEntityId); /* - CommandProcessingResult updateEntityAccess ( - final Long entityAccessId, final JsonCommand command); - - CommandProcessingResult removeEntityAccess ( - final String entityType, final Long entityId, - final Long accessType, - final String secondEntityType, final Long secondEntityId); - */ + * CommandProcessingResult updateEntityAccess ( final Long entityAccessId, + * final JsonCommand command); + * + * CommandProcessingResult removeEntityAccess ( final String entityType, + * final Long entityId, final Long accessType, final String + * secondEntityType, final Long secondEntityId); + */ } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessWriteServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessWriteServiceImpl.java index f4bd40626..6ba4518a2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessWriteServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/entityaccess/service/MifosEntityAccessWriteServiceImpl.java @@ -5,14 +5,25 @@ */ package org.mifosplatform.infrastructure.entityaccess.service; -import org.mifosplatform.infrastructure.core.api.JsonCommand; -import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; - +import java.util.Date; +import java.util.Map; import org.mifosplatform.infrastructure.codes.domain.CodeValue; 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.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.entityaccess.api.MifosEntityApiResourceConstants; +import org.mifosplatform.infrastructure.entityaccess.data.MifosEntityDataValidator; import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityAccess; import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityAccessRepository; +import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityRelation; +import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityRelationRepositoryWrapper; +import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityToEntityMapping; +import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityToEntityMappingRepository; +import org.mifosplatform.infrastructure.entityaccess.domain.MifosEntityToEntityMappingRepositoryWrapper; +import org.mifosplatform.infrastructure.entityaccess.exception.MifosEntityToEntityMappingDateException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -21,52 +32,145 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service -public class MifosEntityAccessWriteServiceImpl implements - MifosEntityAccessWriteService { +public class MifosEntityAccessWriteServiceImpl implements MifosEntityAccessWriteService { private final static Logger logger = LoggerFactory.getLogger(MifosEntityAccessWriteServiceImpl.class); private final CodeValueRepositoryWrapper codeValueRepositoryWrapper; private final MifosEntityAccessRepository entityAccessRepository; + private final MifosEntityRelationRepositoryWrapper mifosEntityRelationRepositoryWrapper; + private final MifosEntityToEntityMappingRepository mifosEntityToEntityMappingRepository; + private final MifosEntityToEntityMappingRepositoryWrapper mifosEntityToEntityMappingRepositoryWrapper; + private final MifosEntityDataValidator fromApiJsonDeserializer; @Autowired - public MifosEntityAccessWriteServiceImpl( - final MifosEntityAccessRepository entityAccessRepository, - final CodeValueRepositoryWrapper codeValueRepositoryWrapper) { - this.entityAccessRepository = entityAccessRepository; + public MifosEntityAccessWriteServiceImpl(final MifosEntityAccessRepository entityAccessRepository, + final CodeValueRepositoryWrapper codeValueRepositoryWrapper, + final MifosEntityRelationRepositoryWrapper mifosEntityRelationRepositoryWrapper, + final MifosEntityToEntityMappingRepository mifosEntityToEntityMappingRepository, + final MifosEntityToEntityMappingRepositoryWrapper mifosEntityToEntityMappingRepositoryWrapper, + MifosEntityDataValidator fromApiJsonDeserializer) { + this.entityAccessRepository = entityAccessRepository; this.codeValueRepositoryWrapper = codeValueRepositoryWrapper; + this.mifosEntityToEntityMappingRepository = mifosEntityToEntityMappingRepository; + this.fromApiJsonDeserializer = fromApiJsonDeserializer; + this.mifosEntityRelationRepositoryWrapper = mifosEntityRelationRepositoryWrapper; + this.mifosEntityToEntityMappingRepositoryWrapper = mifosEntityToEntityMappingRepositoryWrapper; } - @Override - public CommandProcessingResult createEntityAccess(JsonCommand command) { - // TODO Auto-generated method stub - return null; - } - - @Override - @Transactional - public void addNewEntityAccess (final String entityType, final Long entityId, - final CodeValue accessType, - final String secondEntityType, final Long secondEntityId) { - MifosEntityAccess entityAccess = MifosEntityAccess.createNew(entityType, entityId, - accessType, secondEntityType, secondEntityId); - entityAccessRepository.save(entityAccess); - } - - /* - @Override - public CommandProcessingResult updateEntityAccess(Long entityAccessId, - JsonCommand command) { - // TODO Auto-generated method stub - return null; - } + @Override + public CommandProcessingResult createEntityAccess(JsonCommand command) { + // TODO Auto-generated method stub + return null; + } - @Override - public CommandProcessingResult removeEntityAccess(String entityType, - Long entityId, Long accessType, String secondEntityType, - Long secondEntityId) { - // TODO Auto-generated method stub - return null; - } - */ + @Override + @Transactional + public void addNewEntityAccess(final String entityType, final Long entityId, final CodeValue accessType, final String secondEntityType, + final Long secondEntityId) { + MifosEntityAccess entityAccess = MifosEntityAccess.createNew(entityType, entityId, accessType, secondEntityType, secondEntityId); + entityAccessRepository.save(entityAccess); + } + + @Override + @Transactional + public CommandProcessingResult createEntityToEntityMapping(Long relId, JsonCommand command) { + + try { + + this.fromApiJsonDeserializer.validateForCreate(command.json()); + + final MifosEntityRelation mapId = this.mifosEntityRelationRepositoryWrapper.findOneWithNotFoundDetection(relId); + + final Long fromId = command.longValueOfParameterNamed(MifosEntityApiResourceConstants.fromEnityType); + final Long toId = command.longValueOfParameterNamed(MifosEntityApiResourceConstants.toEntityType); + final Date startDate = command.DateValueOfParameterNamed(MifosEntityApiResourceConstants.startDate); + final Date endDate = command.DateValueOfParameterNamed(MifosEntityApiResourceConstants.endDate); + + fromApiJsonDeserializer.checkForEntity(relId.toString(), fromId, toId); + if (startDate != null && endDate != null) { + if (endDate.before(startDate)) { throw new MifosEntityToEntityMappingDateException(startDate.toString(), endDate.toString()); } + } + + final MifosEntityToEntityMapping newMap = MifosEntityToEntityMapping.newMap(mapId, fromId, toId, startDate, endDate); + + this.mifosEntityToEntityMappingRepository.save(newMap); + + return new CommandProcessingResultBuilder().withEntityId(newMap.getId()).withCommandId(command.commandId()).build(); + } catch (final DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return CommandProcessingResult.empty(); + } + } + + @Override + @Transactional + public CommandProcessingResult updateEntityToEntityMapping(Long mapId, JsonCommand command) { + + try { + + this.fromApiJsonDeserializer.validateForUpdate(command.json()); + + final MifosEntityToEntityMapping mapForUpdate = this.mifosEntityToEntityMappingRepositoryWrapper + .findOneWithNotFoundDetection(mapId); + + String relId = mapForUpdate.getRelationId().getId().toString(); + final Long fromId = command.longValueOfParameterNamed(MifosEntityApiResourceConstants.fromEnityType); + final Long toId = command.longValueOfParameterNamed(MifosEntityApiResourceConstants.toEntityType); + fromApiJsonDeserializer.checkForEntity(relId, fromId, toId); + + final Map changes = mapForUpdate.updateMap(command); + + if (!changes.isEmpty()) { + this.mifosEntityToEntityMappingRepository.saveAndFlush(mapForUpdate); + } + return new CommandProcessingResultBuilder(). // + withEntityId(mapForUpdate.getId()).withCommandId(command.commandId()).build(); + } catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return CommandProcessingResult.empty(); + } + } + + @Transactional + @Override + public CommandProcessingResult deleteEntityToEntityMapping(Long mapId) { + // TODO Auto-generated method stub + + final MifosEntityToEntityMapping deleteMap = this.mifosEntityToEntityMappingRepositoryWrapper.findOneWithNotFoundDetection(mapId); + this.mifosEntityToEntityMappingRepository.delete(deleteMap); + + return new CommandProcessingResultBuilder(). // + withEntityId(deleteMap.getId()).build(); + + } + + private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { + + final Throwable realCause = dve.getMostSpecificCause(); + realCause.printStackTrace(); + if (realCause.getMessage().contains("rel_id_from_id_to_id")) { + final String fromId = command.stringValueOfParameterNamed(MifosEntityApiResourceConstants.fromEnityType); + final String toId = command.stringValueOfParameterNamed(MifosEntityApiResourceConstants.toEntityType); + throw new PlatformDataIntegrityException("error.msg.duplicate.entity.mapping", "EntityMapping from " + fromId + " to " + toId + + " already exist"); + } + + logAsErrorUnexpectedDataIntegrityException(dve); + throw new PlatformDataIntegrityException("error.msg.entity.mapping", "Unknown data integrity issue with resource."); + } + + private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { + logger.error(dve.getMessage(), dve); + } + + /* + * @Override public CommandProcessingResult updateEntityAccess(Long + * entityAccessId, JsonCommand command) { // TODO Auto-generated method stub + * return null; } + * + * @Override public CommandProcessingResult removeEntityAccess(String + * entityType, Long entityId, Long accessType, String secondEntityType, Long + * secondEntityId) { // TODO Auto-generated method stub return null; } + */ } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java index 0deeb0a10..cbe6cafc5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java @@ -94,12 +94,11 @@ public class ClientsApiResource { clientData = this.clientReadPlatformService.retrieveAllNarrations(ClientApiConstants.CLIENT_CLOSURE_REASON); } else if (is(commandParam, "acceptTransfer")) { clientData = this.clientReadPlatformService.retrieveAllNarrations(ClientApiConstants.CLIENT_CLOSURE_REASON); - }else if (is(commandParam, "reject")) { + } else if (is(commandParam, "reject")) { clientData = this.clientReadPlatformService.retrieveAllNarrations(ClientApiConstants.CLIENT_REJECT_REASON); - }else if (is(commandParam, "withdraw")) { + } else if (is(commandParam, "withdraw")) { clientData = this.clientReadPlatformService.retrieveAllNarrations(ClientApiConstants.CLIENT_WITHDRAW_REASON); - } - else { + } else { clientData = this.clientReadPlatformService.retrieveTemplate(officeId, staffInSelectedOfficeOnly); } @@ -144,8 +143,7 @@ public class ClientsApiResource { final ClientData templateData = this.clientReadPlatformService.retrieveTemplate(clientData.officeId(), staffInSelectedOfficeOnly); clientData = ClientData.templateOnTop(clientData, templateData); - Collection savingAccountOptions = this.savingsAccountReadPlatformService.retrieveForLookup( - clientId, null); + Collection savingAccountOptions = this.savingsAccountReadPlatformService.retrieveForLookup(clientId, null); if (savingAccountOptions != null && savingAccountOptions.size() > 0) { clientData = ClientData.templateWithSavingAccountOptions(clientData, savingAccountOptions); } @@ -243,21 +241,20 @@ public class ClientsApiResource { } else if (is(commandParam, "updateSavingsAccount")) { commandRequest = builder.updateClientSavingsAccount(clientId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - }else if (is(commandParam,"reject")){ - commandRequest = builder.rejectClient(clientId).build(); + } else if (is(commandParam, "reject")) { + commandRequest = builder.rejectClient(clientId).build(); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - }else if (is(commandParam,"withdraw")){ - commandRequest = builder.withdrawClient(clientId).build(); - result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - }else if (is(commandParam,"reactivate")){ - commandRequest = builder.reActivateClient(clientId).build(); - result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - } - + } else if (is(commandParam, "withdraw")) { + commandRequest = builder.withdrawClient(clientId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "reactivate")) { + commandRequest = builder.reActivateClient(clientId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } if (result == null) { throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "activate", "unassignStaff", "assignStaff", "close", "proposeTransfer", "withdrawTransfer", "acceptTransfer", "rejectTransfer", - "updateSavingsAccount","reject" ,"withdraw","reactivate"}); } + "updateSavingsAccount", "reject", "withdraw", "reactivate" }); } return this.toApiJsonSerializer.serialize(result); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index 401092b03..37e490530 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -1,4 +1,10 @@ /** + * 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/. + */ +/** + * 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/. diff --git a/mifosng-provider/src/main/resources/sql/migrations/core_db/V242__entitytoentitymappingrelation.sql b/mifosng-provider/src/main/resources/sql/migrations/core_db/V242__entitytoentitymappingrelation.sql new file mode 100644 index 000000000..7f4474a40 --- /dev/null +++ b/mifosng-provider/src/main/resources/sql/migrations/core_db/V242__entitytoentitymappingrelation.sql @@ -0,0 +1,38 @@ +CREATE TABLE `m_entity_relation` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `from_entity_type` INT(10) NOT NULL, + `to_entity_type` INT(10) NOT NULL, + `code_name` VARCHAR(50) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `from_entity_type_to_entity_type_code_name` (`from_entity_type`, `to_entity_type`, `code_name`) +) +COLLATE='utf8_general_ci' +ENGINE=InnoDB +AUTO_INCREMENT=1 +; + +CREATE TABLE `m_entity_to_entity_mapping` ( + `id` BIGINT(20) NOT NULL AUTO_INCREMENT, + `rel_id` BIGINT(20) NOT NULL DEFAULT '0', + `from_id` BIGINT(20) NOT NULL DEFAULT '0', + `to_id` BIGINT(20) UNSIGNED NOT NULL, + `start_date` DATE NULL DEFAULT NULL, + `end_date` DATE NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `rel_id_from_id_to_id` (`rel_id`, `from_id`, `to_id`), + CONSTRAINT `FK__rel_id_m_entity_relation_id` FOREIGN KEY (`rel_id`) REFERENCES `m_entity_relation` (`id`) +) +COLLATE='utf8_general_ci' +ENGINE=InnoDB +AUTO_INCREMENT=1 +; + +INSERT INTO `m_entity_relation` (`from_entity_type`, `to_entity_type`, `code_name`) VALUES (1, 2, 'office_access_to_loan_products'); +INSERT INTO `m_entity_relation` (`from_entity_type`, `to_entity_type`, `code_name`) VALUES (1, 3, 'office_access_to_savings_products'); +INSERT INTO `m_entity_relation` (`from_entity_type`, `to_entity_type`, `code_name`) VALUES (1, 4, 'office_access_to_fees/charges'); +INSERT INTO `m_entity_relation` (`from_entity_type`, `to_entity_type`, `code_name`) VALUES (5, 2, 'role_access_to_loan_products'); +INSERT INTO `m_entity_relation` (`from_entity_type`, `to_entity_type`, `code_name`) VALUES (5, 3, 'role_access_to_savings_products'); + +INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('infrastructure', 'CREATE_ENTITYMAPPING', 'ENTITYMAPPING', 'CREATE', 0); +INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('infrastructure', 'UPDATE_ENTITYMAPPING', 'ENTITYMAPPING', 'UPDATE', 0); +INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('infrastructure', 'DELETE_ENTITYMAPPING', 'ENTITYMAPPING', 'DELETE', 0); \ No newline at end of file