diff --git a/mifosng-db/patches/18-add_group_id_to_note_table.sql b/mifosng-db/patches/18-add_group_id_to_note_table.sql new file mode 100644 index 000000000..35cbe0747 --- /dev/null +++ b/mifosng-db/patches/18-add_group_id_to_note_table.sql @@ -0,0 +1,8 @@ +ALTER TABLE `m_note` + ADD COLUMN `group_id` BIGINT(20) NULL AFTER `client_id`, + ADD CONSTRAINT `FK_m_note_m_group` FOREIGN KEY (`group_id`) REFERENCES `m_group` (`id`); + +ALTER TABLE `m_note` + ALTER `client_id` DROP DEFAULT; +ALTER TABLE `m_note` + CHANGE COLUMN `client_id` `client_id` BIGINT(20) NULL AFTER `id`; \ No newline at end of file diff --git a/mifosng-db/patches/19-note_permissions.sql b/mifosng-db/patches/19-note_permissions.sql new file mode 100644 index 000000000..0fe02bcb2 --- /dev/null +++ b/mifosng-db/patches/19-note_permissions.sql @@ -0,0 +1,36 @@ +INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) +VALUES('portfolio', 'CREATE_LOANNOTE', 'LOANNOTE', 'CREATE', '0'), +('portfolio', 'READ_LOANNOTE', 'LOANNOTE', 'READ', '0'), +('portfolio', 'UPDATE_LOANNOTE', 'LOANNOTE', 'UPDATE', '0'), +('portfolio', 'DELETE_LOANNOTE', 'LOANNOTE', 'DELETE', '0'), +('portfolio', 'CREATE_LOANNOTE_CHECKER', 'LOANNOTE', 'CREATE', '0'), +('portfolio', 'UPDATE_LOANNOTE_CHECKER', 'LOANNOTE', 'UPDATE', '0'), +('portfolio', 'DELETE_LOANNOTE_CHECKER', 'LOANNOTE', 'DELETE', '0'), +('portfolio', 'CREATE_LOANTRANSACTIONNOTE', 'LOANTRANSACTIONNOTE', 'CREATE', '0'), +('portfolio', 'READ_LOANTRANSACTIONNOTE', 'LOANTRANSACTIONNOTE', 'READ', '0'), +('portfolio', 'UPDATE_LOANTRANSACTIONNOTE', 'LOANTRANSACTIONNOTE', 'UPDATE', '0'), +('portfolio', 'DELETE_LOANTRANSACTIONNOTE', 'LOANTRANSACTIONNOTE', 'DELETE', '0'), +('portfolio', 'CREATE_LOANTRANSACTIONNOTE_CHECKER', 'LOANTRANSACTIONNOTE', 'CREATE', '0'), +('portfolio', 'UPDATE_LOANTRANSACTIONNOTE_CHECKER', 'LOANTRANSACTIONNOTE', 'UPDATE', '0'), +('portfolio', 'DELETE_LOANTRANSACTIONNOTE_CHECKER', 'LOANTRANSACTIONNOTE', 'DELETE', '0'), +('portfolio', 'CREATE_DEPOSITNOTE', 'DEPOSITNOTE', 'CREATE', '0'), +('portfolio', 'READ_DEPOSITNOTE', 'DEPOSITNOTE', 'READ', '0'), +('portfolio', 'UPDATE_DEPOSITNOTE', 'DEPOSITNOTE', 'UPDATE', '0'), +('portfolio', 'DELETE_DEPOSITNOTE', 'DEPOSITNOTE', 'DELETE', '0'), +('portfolio', 'CREATE_DEPOSITNOTE_CHECKER', 'DEPOSITNOTE', 'CREATE', '0'), +('portfolio', 'UPDATE_DEPOSITNOTE_CHECKER', 'DEPOSITNOTE', 'UPDATE', '0'), +('portfolio', 'DELETE_DEPOSITNOTE_CHECKER', 'DEPOSITNOTE', 'DELETE', '0'), +('portfolio', 'CREATE_SAVINGNOTE', 'SAVINGNOTE', 'CREATE', '0'), +('portfolio', 'READ_SAVINGNOTE', 'SAVINGNOTE', 'READ', '0'), +('portfolio', 'UPDATE_SAVINGNOTE', 'SAVINGNOTE', 'UPDATE', '0'), +('portfolio', 'DELETE_SAVINGNOTE', 'SAVINGNOTE', 'DELETE', '0'), +('portfolio', 'CREATE_SAVINGNOTE_CHECKER', 'SAVINGNOTE', 'CREATE', '0'), +('portfolio', 'UPDATE_SAVINGNOTE_CHECKER', 'SAVINGNOTE', 'UPDATE', '0'), +('portfolio', 'DELETE_SAVINGNOTE_CHECKER', 'SAVINGNOTE', 'DELETE', '0'), +('portfolio', 'CREATE_GROUPNOTE', 'GROUPNOTE', 'CREATE', '0'), +('portfolio', 'READ_GROUPNOTE', 'GROUPNOTE', 'READ', '0'), +('portfolio', 'UPDATE_GROUPNOTE', 'GROUPNOTE', 'UPDATE', '0'), +('portfolio', 'DELETE_GROUPNOTE', 'GROUPNOTE', 'DELETE', '0'), +('portfolio', 'CREATE_GROUPNOTE_CHECKER', 'GROUPNOTE', 'CREATE', '0'), +('portfolio', 'UPDATE_GROUPNOTE_CHECKER', 'GROUPNOTE', 'UPDATE', '0'), +('portfolio', 'DELETE_GROUPNOTE_CHECKER', 'GROUPNOTE', 'DELETE', '0'); 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 a971c11fa..d22f72eae 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java @@ -448,5 +448,18 @@ public class CommandWrapper { public boolean isCalendarResource() { return this.entityName.equalsIgnoreCase("CALENDAR"); } + + public boolean isNoteResource() { + boolean isnoteResource = false; + if(this.entityName.equalsIgnoreCase("CLIENTNOTE") || + this.entityName.equalsIgnoreCase("LOANNOTE") || + this.entityName.equalsIgnoreCase("LOANTRANSACTIONNOTE") || + this.entityName.equalsIgnoreCase("DEPOSITNOTE") || + this.entityName.equalsIgnoreCase("SAVINGNOTE") || + this.entityName.equalsIgnoreCase("GROUPNOTE")){ + isnoteResource = true; + } + return isnoteResource; + } } \ 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 086ade266..8285f166c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java @@ -301,23 +301,6 @@ public class CommandWrapperBuilder { return this; } - public CommandWrapperBuilder createClientNote(final Long clientId) { - this.actionName = "CREATE"; - this.entityName = "CLIENTNOTE"; - this.clientId = clientId; - this.href = "/clients/" + clientId + "/notes/template"; - return this; - } - - public CommandWrapperBuilder updateClientNote(final Long clientId, final Long noteId) { - this.actionName = "UPDATE"; - this.entityName = "CLIENTNOTE"; - this.entityId = noteId; - this.clientId = clientId; - this.href = "/clients/" + clientId + "/notes"; - return this; - } - public CommandWrapperBuilder createClient() { this.actionName = "CREATE"; this.entityName = "CLIENT"; @@ -892,4 +875,33 @@ public class CommandWrapperBuilder { this.href = "/" + supportedEntityType + "/" + supportedEntityId + "/calendars/" + calendarId; return this; } + + public CommandWrapperBuilder createNote(final String entityName, final String resourceType, final Long resourceId) { + this.actionName = "CREATE"; + this.entityName = entityName;//Note supports multiple resources. Note Permissions are set for each resource. + this.supportedEntityType = resourceType; + this.supportedEntityId = resourceId; + this.href = "/" + resourceType + "/" + resourceId + "/notes/template"; + return this; + } + + public CommandWrapperBuilder updateNote(final String entityName, final String resourceType, final Long resourceId, final Long noteId) { + this.actionName = "UPDATE"; + this.entityName = entityName;//Note supports multiple resources. Note Permissions are set for each resource. + this.entityId = noteId; + this.supportedEntityType = resourceType; + this.supportedEntityId = resourceId; + this.href = "/" + resourceType + "/" + resourceId + "/notes"; + return this; + } + + public CommandWrapperBuilder deleteNote(final String entityName, final String resourceType, final Long resourceId, final Long noteId) { + this.actionName = "DELETE"; + this.entityName = entityName;//Note supports multiple resources. Note Permissions are set for each resource. + this.entityId = noteId; + this.supportedEntityType = resourceType; + this.supportedEntityId = resourceId; + this.href = "/" + resourceType + "/" + resourceId + "/calendars/" + noteId; + 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 763669bb0..ec951ebfe 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java @@ -125,11 +125,13 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer } else { throw new UnsupportedCommandException(wrapper.commandName()); } - } else if (wrapper.isClientNoteResource()) { + } else if (wrapper.isNoteResource()) { if (wrapper.isCreate()) { - handler = applicationContext.getBean("createClientNoteCommandHandler", NewCommandSourceHandler.class); + handler = applicationContext.getBean("createNoteCommandHandler", NewCommandSourceHandler.class); } else if (wrapper.isUpdate()) { - handler = applicationContext.getBean("updateClientNoteCommandHandler", NewCommandSourceHandler.class); + handler = applicationContext.getBean("updateNoteCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isDelete()) { + handler = applicationContext.getBean("deleteNoteCommandHandler", NewCommandSourceHandler.class); } else { throw new UnsupportedCommandException(wrapper.commandName()); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientNotesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientNotesApiResource.java deleted file mode 100644 index 2d5cc3b6a..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientNotesApiResource.java +++ /dev/null @@ -1,117 +0,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/. - */ -package org.mifosplatform.portfolio.client.api; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import javax.ws.rs.Consumes; -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.security.service.PlatformSecurityContext; -import org.mifosplatform.portfolio.client.data.NoteData; -import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Path("/clients/{clientId}/notes") -@Component -@Scope("singleton") -public class ClientNotesApiResource { - - private final Set NOTE_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "clientId", "loanId", "loanTransactionId", - "noteType", "note", "createdById", "createdByUsername", "createdOn", "updatedById", "updatedByUsername", "updatedOn")); - - private final PlatformSecurityContext context; - private final ClientReadPlatformService clientReadPlatformService; - private final DefaultToApiJsonSerializer toApiJsonSerializer; - private final ApiRequestParameterHelper apiRequestParameterHelper; - private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; - - @Autowired - public ClientNotesApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService, - final DefaultToApiJsonSerializer toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, - final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { - this.context = context; - this.clientReadPlatformService = readPlatformService; - this.toApiJsonSerializer = toApiJsonSerializer; - this.apiRequestParameterHelper = apiRequestParameterHelper; - this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; - } - - @GET - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveAllClientNotes(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission("CLIENTNOTE"); - - final Collection notes = this.clientReadPlatformService.retrieveAllClientNotes(clientId); - - final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, notes, NOTE_DATA_PARAMETERS); - } - - @POST - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String addNewClientNote(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) { - - final CommandWrapper commandRequest = new CommandWrapperBuilder().createClientNote(clientId).withJson(apiRequestBodyAsJson).build(); - - final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - - return this.toApiJsonSerializer.serialize(result); - } - - @GET - @Path("{noteId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId, - @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission("CLIENTNOTE"); - - final NoteData note = this.clientReadPlatformService.retrieveClientNote(clientId, noteId); - - final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, note, NOTE_DATA_PARAMETERS); - } - - @PUT - @Path("{noteId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId, - final String apiRequestBodyAsJson) { - - final CommandWrapper commandRequest = new CommandWrapperBuilder().updateClientNote(clientId, noteId).withJson(apiRequestBodyAsJson) - .build(); - - final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - - return this.toApiJsonSerializer.serialize(result); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/command/NoteCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/command/NoteCommand.java deleted file mode 100644 index 511d108aa..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/command/NoteCommand.java +++ /dev/null @@ -1,46 +0,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/. - */ -package org.mifosplatform.portfolio.client.command; - -/** - * Immutable command used for create or update of notes. - */ -public class NoteCommand { - - private final Long id; - private final Long clientId; - private final Long loanId; - private final Long loanTransactionId; - private final String note; - - public NoteCommand(final Long id, Long clientId, final String note) { - this.id = id; - this.clientId = clientId; - this.loanId = null; - this.loanTransactionId = null; - this.note = note; - } - - public Long getId() { - return id; - } - - public Long getClientId() { - return clientId; - } - - public Long getLoanId() { - return loanId; - } - - public Long getLoanTransactionId() { - return loanTransactionId; - } - - public String getNote() { - return note; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/NoteEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/NoteEnumerations.java deleted file mode 100644 index c71cc9776..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/NoteEnumerations.java +++ /dev/null @@ -1,41 +0,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/. - */ -package org.mifosplatform.portfolio.client.domain; - -import org.mifosplatform.infrastructure.core.data.EnumOptionData; -import org.mifosplatform.portfolio.client.domain.Note.NoteType; - -public class NoteEnumerations { - - public static EnumOptionData noteType(final Integer id) { - return noteType(Note.NoteType.parse(id)); - } - - public static EnumOptionData noteType(NoteType type) { - EnumOptionData optionData = null; - switch (type) { - case CLIENT: - optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Client note"); - break; - case LOAN: - optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Loan note"); - break; - case LOAN_TRANSACTION: - optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Loan transaction note"); - break; - case DEPOSIT: - optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Deposit transaction note"); - break; - case SAVING: - optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Saving transaction note"); - break; - default: - break; - - } - return optionData; - } -} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/NoteRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/NoteRepository.java deleted file mode 100644 index 4e5e8f0c7..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/NoteRepository.java +++ /dev/null @@ -1,18 +0,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/. - */ -package org.mifosplatform.portfolio.client.domain; - -import java.util.List; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; - -public interface NoteRepository extends JpaRepository, JpaSpecificationExecutor { - - List findByLoanId(Long id); - - List findByClientId(Long id); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/serialization/ClientNoteCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/serialization/ClientNoteCommandFromApiJsonDeserializer.java deleted file mode 100644 index 68dcf0c50..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/serialization/ClientNoteCommandFromApiJsonDeserializer.java +++ /dev/null @@ -1,59 +0,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/. - */ -package org.mifosplatform.portfolio.client.serialization; - -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang.StringUtils; -import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; -import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer; -import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer; -import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; -import org.mifosplatform.portfolio.client.command.ClientCommand; -import org.mifosplatform.portfolio.client.command.ClientNoteCommand; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; - -/** - * Implementation of {@link FromApiJsonDeserializer} for {@link ClientCommand} - * 's. - */ -@Component -public final class ClientNoteCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer { - - /** - * The parameters supported for this command. - */ - private final Set supportedParameters = new HashSet(Arrays.asList("note")); - - private final FromJsonHelper fromApiJsonHelper; - - @Autowired - public ClientNoteCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { - this.fromApiJsonHelper = fromApiJsonHelper; - } - - @Override - public ClientNoteCommand commandFromApiJson(final String json) { - - if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } - - final Type typeOfMap = new TypeToken>() {}.getType(); - fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); - - final JsonElement element = fromApiJsonHelper.parse(json); - final String note = fromApiJsonHelper.extractStringNamed("note", element); - - return new ClientNoteCommand(note); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java index eaf95c258..10fa5373c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java @@ -12,7 +12,6 @@ import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData; import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.data.ClientIdentifierData; import org.mifosplatform.portfolio.client.data.ClientLookup; -import org.mifosplatform.portfolio.client.data.NoteData; public interface ClientReadPlatformService { @@ -30,10 +29,6 @@ public interface ClientReadPlatformService { Collection retrieveClientLoanAccountsByLoanOfficerId(Long clientId, Long loanOfficerId); - Collection retrieveAllClientNotes(Long clientId); - - NoteData retrieveClientNote(Long clientId, Long noteId); - Collection retrieveClientIdentifiers(Long clientId); ClientIdentifierData retrieveClientIdentifier(Long clientId, Long clientIdentifierId); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java index 308aa002e..918db68d5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java @@ -12,9 +12,7 @@ import java.util.Collection; import java.util.List; import org.apache.commons.lang.StringUtils; -import org.joda.time.DateTime; import org.joda.time.LocalDate; -import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; @@ -25,14 +23,10 @@ import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData; import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.data.ClientIdentifierData; import org.mifosplatform.portfolio.client.data.ClientLookup; -import org.mifosplatform.portfolio.client.data.NoteData; -import org.mifosplatform.portfolio.client.domain.NoteEnumerations; import org.mifosplatform.portfolio.client.exception.ClientIdentifierNotFoundException; import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; -import org.mifosplatform.portfolio.client.exception.NoteNotFoundException; import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData; import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations; -import org.mifosplatform.useradministration.data.AppUserData; import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.service.AppUserReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; @@ -356,98 +350,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService } } - @Override - public NoteData retrieveClientNote(final Long clientId, final Long noteId) { - - try { - context.authenticatedUser(); - - // Check if client exists - retrieveIndividualClient(clientId); - - // FIXME - KW - use join on sql query to fetch user information for - // note - // rather than fetching users? - Collection allUsers = this.appUserReadPlatformService.retrieveAllUsers(); - - NoteMapper noteMapper = new NoteMapper(allUsers); - - String sql = "select " + noteMapper.schema() + " where n.client_id = ? and n.id = ?"; - - return this.jdbcTemplate.queryForObject(sql, noteMapper, new Object[] { clientId, noteId }); - } catch (EmptyResultDataAccessException e) { - throw new NoteNotFoundException(clientId); - } - } - - @Override - public Collection retrieveAllClientNotes(final Long clientId) { - - context.authenticatedUser(); - - // Check if client exists - retrieveIndividualClient(clientId); - - // FIXME - KW - use join on sql query to fetch user information for note - // rather than fetching users? - Collection allUsers = this.appUserReadPlatformService.retrieveAllUsers(); - - NoteMapper noteMapper = new NoteMapper(allUsers); - - String sql = "select " + noteMapper.schema() + " where n.client_id = ? order by n.created_date DESC"; - - return this.jdbcTemplate.query(sql, noteMapper, new Object[] { clientId }); - } - - private static final class NoteMapper implements RowMapper { - - private final Collection allUsers; - - public NoteMapper(final Collection allUsers) { - this.allUsers = allUsers; - } - - public String schema() { - return "n.id as id, n.client_id as clientId, n.loan_id as loanId, n.loan_transaction_id as transactionId, n.note_type_enum as noteTypeEnum, n.note as note, " - + "n.created_date as createdDate, n.createdby_id as createdById, n.lastmodified_date as lastModifiedDate, n.lastmodifiedby_id as lastModifiedById" - + " from m_note n"; - } - - @Override - public NoteData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - - Long id = JdbcSupport.getLong(rs, "id"); - Long clientId = JdbcSupport.getLong(rs, "clientId"); - Long loanId = JdbcSupport.getLong(rs, "loanId"); - Long transactionId = JdbcSupport.getLong(rs, "transactionId"); - Integer noteTypeId = JdbcSupport.getInteger(rs, "noteTypeEnum"); - EnumOptionData noteType = NoteEnumerations.noteType(noteTypeId); - String note = rs.getString("note"); - - DateTime createdDate = JdbcSupport.getDateTime(rs, "createdDate"); - Long createdById = JdbcSupport.getLong(rs, "createdById"); - String createdByUsername = findUserById(createdById, allUsers); - - DateTime lastModifiedDate = JdbcSupport.getDateTime(rs, "lastModifiedDate"); - Long lastModifiedById = JdbcSupport.getLong(rs, "lastModifiedById"); - String updatedByUsername = findUserById(createdById, allUsers); - - return new NoteData(id, clientId, loanId, transactionId, noteType, note, createdDate, createdById, createdByUsername, - lastModifiedDate, lastModifiedById, updatedByUsername); - } - - private String findUserById(final Long createdById, final Collection allUsers) { - String username = ""; - for (AppUserData appUserData : allUsers) { - if (appUserData.hasIdentifyOf(createdById)) { - username = appUserData.username(); - break; - } - } - return username; - } - } - + @Override public Collection retrieveClientIdentifiers(final Long clientId) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformService.java index 0c33d4afd..e09a45030 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformService.java @@ -29,10 +29,6 @@ public interface ClientWritePlatformService { @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_CLIENTIMAGE')") CommandProcessingResult deleteClientImage(Long clientId); - CommandProcessingResult addClientNote(Long clientId, JsonCommand command); - - CommandProcessingResult updateClientNote(Long clientId, Long noteId, JsonCommand command); - CommandProcessingResult addClientIdentifier(Long clientId, JsonCommand command); CommandProcessingResult updateClientIdentifier(Long clientId, Long clientIdentifierId, JsonCommand command); 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 f0ae7f8f0..a791139d3 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 @@ -26,22 +26,17 @@ import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.OfficeRepository; import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; -import org.mifosplatform.portfolio.client.command.ClientNoteCommand; import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientIdentifier; import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository; import org.mifosplatform.portfolio.client.domain.ClientRepository; -import org.mifosplatform.portfolio.client.domain.Note; -import org.mifosplatform.portfolio.client.domain.NoteRepository; import org.mifosplatform.portfolio.client.exception.ClientIdentifierNotFoundException; import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException; -import org.mifosplatform.portfolio.client.exception.NoteNotFoundException; import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromApiJsonDeserializer; -import org.mifosplatform.portfolio.client.serialization.ClientNoteCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.GroupRepository; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; @@ -62,19 +57,16 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP private final ClientIdentifierRepository clientIdentifierRepository; private final OfficeRepository officeRepository; private final GroupRepository groupRepository; - private final NoteRepository noteRepository; private final CodeValueRepositoryWrapper codeValueRepository; private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer; - private final ClientNoteCommandFromApiJsonDeserializer clientNoteFromApiJsonDeserializer; private final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer; private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory; @Autowired public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ClientRepository clientRepository, final ClientIdentifierRepository clientIdentifierRepository, final OfficeRepository officeRepository, - final NoteRepository noteRepository, final CodeValueRepositoryWrapper codeValueRepository, + final CodeValueRepositoryWrapper codeValueRepository, final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer, - final ClientNoteCommandFromApiJsonDeserializer clientNoteFromApiJsonDeserializer, final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final GroupRepository groupRepository) { @@ -82,10 +74,8 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP this.clientRepository = clientRepository; this.clientIdentifierRepository = clientIdentifierRepository; this.officeRepository = officeRepository; - this.noteRepository = noteRepository; this.codeValueRepository = codeValueRepository; this.fromApiJsonDeserializer = fromApiJsonDeserializer; - this.clientNoteFromApiJsonDeserializer = clientNoteFromApiJsonDeserializer; this.clientIdentifierCommandFromApiJsonDeserializer = clientIdentifierCommandFromApiJsonDeserializer; this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory; this.groupRepository = groupRepository; @@ -213,51 +203,6 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP } } - @Transactional - @Override - public CommandProcessingResult addClientNote(final Long clientId, final JsonCommand command) { - - context.authenticatedUser(); - - final ClientNoteCommand clientNoteCommand = this.clientNoteFromApiJsonDeserializer.commandFromApiJson(command.json()); - clientNoteCommand.validate(); - - final Client clientForUpdate = this.clientRepository.findOne(clientId); - if (clientForUpdate == null) { throw new ClientNotFoundException(clientId); } - - final Note note = Note.clientNoteFromJson(clientForUpdate, command); - - this.noteRepository.save(note); - - return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(clientForUpdate.getOffice().getId()) - .withClientId(clientId).withEntityId(note.getId()).build(); - } - - @Transactional - @Override - public CommandProcessingResult updateClientNote(final Long clientId, final Long noteId, final JsonCommand command) { - - context.authenticatedUser(); - - final ClientNoteCommand clientNoteCommand = this.clientNoteFromApiJsonDeserializer.commandFromApiJson(command.json()); - clientNoteCommand.validate(); - - final Note noteForUpdate = this.noteRepository.findOne(noteId); - if (noteForUpdate == null || noteForUpdate.isNotAgainstClientWithIdOf(clientId)) { throw new NoteNotFoundException(noteId, - clientId, "client"); } - - final Client client = this.clientRepository.findOne(clientId); - - final Map changes = noteForUpdate.update(command); - - if (!changes.isEmpty()) { - this.noteRepository.save(noteForUpdate); - } - - return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(client.getOffice().getId()) - .withClientId(clientId).withEntityId(noteId).with(changes).build(); - } - @Transactional @Override public CommandProcessingResult addClientIdentifier(final Long clientId, final JsonCommand command) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java index 8087d475e..3be66bb50 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/domain/LoanTransaction.java @@ -296,4 +296,10 @@ public final class LoanTransaction extends AbstractPersistable { return thisTransactionData; } + + + public Loan getLoan() { + return this.loan; + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 6c1c9667e..a4cf5bdc7 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -24,8 +24,6 @@ import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientRepository; -import org.mifosplatform.portfolio.client.domain.Note; -import org.mifosplatform.portfolio.client.domain.NoteRepository; import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; import org.mifosplatform.portfolio.fund.domain.Fund; import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; @@ -49,6 +47,8 @@ import org.mifosplatform.portfolio.loanproduct.domain.LoanProduct; import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRepository; import org.mifosplatform.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy; import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException; +import org.mifosplatform.portfolio.note.domain.Note; +import org.mifosplatform.portfolio.note.domain.NoteRepository; import org.mifosplatform.useradministration.domain.AppUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 5481d1b6f..8f2b2fc56 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -25,8 +25,6 @@ import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.portfolio.charge.domain.Charge; import org.mifosplatform.portfolio.charge.domain.ChargeRepositoryWrapper; import org.mifosplatform.portfolio.charge.exception.LoanChargeNotFoundException; -import org.mifosplatform.portfolio.client.domain.Note; -import org.mifosplatform.portfolio.client.domain.NoteRepository; import org.mifosplatform.portfolio.loanaccount.command.LoanUpdateCommand; import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine; import org.mifosplatform.portfolio.loanaccount.domain.Loan; @@ -46,6 +44,8 @@ import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFound import org.mifosplatform.portfolio.loanaccount.serialization.LoanEventApiJsonValidator; import org.mifosplatform.portfolio.loanaccount.serialization.LoanUpdateCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.loanproduct.exception.InvalidCurrencyException; +import org.mifosplatform.portfolio.note.domain.Note; +import org.mifosplatform.portfolio.note.domain.NoteRepository; import org.mifosplatform.useradministration.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/api/NotesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/api/NotesApiResource.java new file mode 100644 index 000000000..df8054c25 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/api/NotesApiResource.java @@ -0,0 +1,178 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.note.api; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +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.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.note.data.NoteData; +import org.mifosplatform.portfolio.note.domain.NoteType; +import org.mifosplatform.portfolio.note.service.NoteReadPlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/{resourceType}/{resourceId}/notes") +@Component +@Scope("singleton") +public class NotesApiResource { + + private final Set NOTE_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "clientId", "groupId", "loanId", + "loanTransactionId", "depositAccountId", "savingAccountId", "noteType", "note", "createdById", "createdByUsername", + "createdOn", "updatedById", "updatedByUsername", "updatedOn")); + + private final PlatformSecurityContext context; + private final NoteReadPlatformService readPlatformService; + private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final ApiRequestParameterHelper apiRequestParameterHelper; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + public NotesApiResource(final PlatformSecurityContext context, final NoteReadPlatformService readPlatformService, + final DefaultToApiJsonSerializer toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.context = context; + this.readPlatformService = readPlatformService; + this.toApiJsonSerializer = toApiJsonSerializer; + this.apiRequestParameterHelper = apiRequestParameterHelper; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveNotesByResource(@PathParam("resourceType") final String resourceType, + @PathParam("resourceId") final Long resourceId, @Context final UriInfo uriInfo) { + + NoteType noteType = NoteType.fromApiUrl(resourceType); + this.context.authenticatedUser().validateHasReadPermission(getResourceNameForPermissions(noteType)); + + final Integer noteTypeId = noteType.getValue(); + + final Collection notes = this.readPlatformService.retrieveNotesByResource(resourceId, noteTypeId); + + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, notes, this.NOTE_DATA_PARAMETERS); + } + + @GET + @Path("{noteId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveNote(@PathParam("resourceType") final String resourceType, @PathParam("resourceId") final Long resourceId, + @PathParam("noteId") final Long noteId, @Context final UriInfo uriInfo) { + + NoteType noteType = NoteType.fromApiUrl(resourceType); + this.context.authenticatedUser().validateHasReadPermission(getResourceNameForPermissions(noteType)); + + final Integer noteTypeId = noteType.getValue(); + + final NoteData note = this.readPlatformService.retrieveNote(noteId, resourceId, noteTypeId); + + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, note, this.NOTE_DATA_PARAMETERS); + } + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String addNewNote(@PathParam("resourceType") final String resourceType, @PathParam("resourceId") final Long resourceId, + final String apiRequestBodyAsJson) { + + NoteType noteType = NoteType.fromApiUrl(resourceType); + final String resourceNameForPermissions = getResourceNameForPermissions(noteType); + final CommandWrapper commandRequest = new CommandWrapperBuilder().createNote(resourceNameForPermissions, resourceType, resourceId) + .withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } + + @PUT + @Path("{noteId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String updateNote(@PathParam("resourceType") final String resourceType, @PathParam("resourceId") final Long resourceId, + @PathParam("noteId") final Long noteId, final String apiRequestBodyAsJson) { + + NoteType noteType = NoteType.fromApiUrl(resourceType); + final String resourceNameForPermissions = getResourceNameForPermissions(noteType); + + final CommandWrapper commandRequest = new CommandWrapperBuilder().updateNote(resourceNameForPermissions, resourceType, resourceId, noteId).withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } + + @DELETE + @Path("{noteId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String deleteNote(@PathParam("resourceType") final String resourceType, @PathParam("resourceId") final Long resourceId, + @PathParam("noteId") final Long noteId) { + + NoteType noteType = NoteType.fromApiUrl(resourceType); + final String resourceNameForPermissions = getResourceNameForPermissions(noteType); + + final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteNote(resourceNameForPermissions, resourceType, resourceId, noteId).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } + + private String getResourceNameForPermissions(NoteType type){ + String resourceNameForPermissions = "INVALIDNOTE"; + switch(type){ + case CLIENT: + resourceNameForPermissions = "CLIENTNOTE"; + break; + case LOAN: + resourceNameForPermissions = "LOANNOTE"; + break; + case LOAN_TRANSACTION: + resourceNameForPermissions = "LOANTRANSACTIONNOTE"; + break; + case DEPOSIT: + resourceNameForPermissions = "DEPOSITNOTE"; + break; + case SAVING: + resourceNameForPermissions = "SAVINGNOTE"; + break; + case GROUP: + resourceNameForPermissions = "GROUPNOTE"; + break; + + } + + return resourceNameForPermissions; + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/command/NoteCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/command/NoteCommand.java new file mode 100644 index 000000000..49916e6b3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/command/NoteCommand.java @@ -0,0 +1,20 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.note.command; + +/** + * Immutable command used for create or update of notes. + */ +public class NoteCommand { + + @SuppressWarnings("unused") + private final String note; + + public NoteCommand(final String note) { + this.note = note; + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/NoteData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/data/NoteData.java similarity index 68% rename from mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/NoteData.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/data/NoteData.java index 80e269186..f003631a4 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/NoteData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/data/NoteData.java @@ -3,13 +3,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.portfolio.client.data; +package org.mifosplatform.portfolio.note.data; import org.joda.time.DateTime; import org.mifosplatform.infrastructure.core.data.EnumOptionData; /** - * Immutable data object represent note or case information about a client, loan or loan transaction. + * Immutable data object represent note or case information about a client, loan + * or loan transaction. */ public class NoteData { @@ -18,10 +19,16 @@ public class NoteData { @SuppressWarnings("unused") private final Long clientId; @SuppressWarnings("unused") + private final Long groupId; + @SuppressWarnings("unused") private final Long loanId; @SuppressWarnings("unused") private final Long loanTransactionId; @SuppressWarnings("unused") + private final Long depositAccountId; + @SuppressWarnings("unused") + private final Long savingAccountId; + @SuppressWarnings("unused") private final EnumOptionData noteType; @SuppressWarnings("unused") private final String note; @@ -38,13 +45,17 @@ public class NoteData { @SuppressWarnings("unused") private final DateTime updatedOn; - public NoteData(final Long id, final Long clientId, final Long loanId, final Long transactionId, final EnumOptionData noteType, - final String note, final DateTime createdDate, final Long createdById, final String createdByUsername, - final DateTime lastModifiedDate, final Long lastModifiedById, final String updatedByUsername) { + public NoteData(final Long id, final Long clientId, final Long groupId, final Long loanId, final Long transactionId, + final Long depositAccountId, final Long savingAccountId, final EnumOptionData noteType, final String note, + final DateTime createdDate, final Long createdById, final String createdByUsername, final DateTime lastModifiedDate, + final Long lastModifiedById, final String updatedByUsername) { this.id = id; this.clientId = clientId; + this.groupId = groupId; this.loanId = loanId; this.loanTransactionId = transactionId; + this.depositAccountId = depositAccountId; + this.savingAccountId = savingAccountId; this.noteType = noteType; this.note = note; this.createdOn = createdDate; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Note.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/domain/Note.java similarity index 70% rename from mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Note.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/domain/Note.java index 41f4a885c..d7aa09835 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Note.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/domain/Note.java @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.portfolio.client.domain; +package org.mifosplatform.portfolio.note.domain; import java.util.LinkedHashMap; import java.util.Map; @@ -17,6 +17,8 @@ import javax.persistence.Table; import org.apache.commons.lang.StringUtils; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; +import org.mifosplatform.portfolio.client.domain.Client; +import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction; import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount; @@ -28,9 +30,14 @@ import org.mifosplatform.useradministration.domain.AppUser; public class Note extends AbstractAuditableCustom { @ManyToOne - @JoinColumn(name = "client_id", nullable = false) + @JoinColumn(name = "client_id", nullable = true) private final Client client; + @SuppressWarnings("unused") + @ManyToOne + @JoinColumn(name = "group_id", nullable = true) + private Group group; + @SuppressWarnings("unused") @ManyToOne @JoinColumn(name = "loan_id", nullable = true) @@ -46,55 +53,28 @@ public class Note extends AbstractAuditableCustom { @SuppressWarnings("unused") @Column(name = "note_type_enum") - private Integer noteTypeId; + private final Integer noteTypeId; @SuppressWarnings("unused") @ManyToOne @JoinColumn(name = "deposit_account_id", nullable = true) private DepositAccount depositAccount; - + @SuppressWarnings("unused") @ManyToOne @JoinColumn(name = "saving_account_id", nullable = true) private SavingAccount savingAccount; - public enum NoteType { - CLIENT(100, "noteType.client"), LOAN(200, "noteType.loan"), LOAN_TRANSACTION(300, "noteType.loan.transaction"), DEPOSIT(400, - "noteType.deposit"), SAVING(500,"noteType.saving"); - - private Integer value; - private String code; - - NoteType(final Integer value, final String code) { - this.value = value; - this.code = code; - } - - public Integer getValue() { - return value; - } - - public String getCode() { - return code; - } - - public static NoteType parse(Integer id) { - NoteType right = null; // Default - for (NoteType item : NoteType.values()) { - if (item.getValue().intValue() == id.intValue()) { - right = item; - break; - } - } - return right; - } - } - public static Note clientNoteFromJson(final Client client, final JsonCommand command) { final String note = command.stringValueOfParameterNamed("note"); return new Note(client, note); } + public static Note groupNoteFromJson(final Group group, final JsonCommand command) { + final String note = command.stringValueOfParameterNamed("note"); + return new Note(group, note); + } + public static Note loanNote(final Loan loan, final String note) { return new Note(loan, note); } @@ -103,24 +83,35 @@ public class Note extends AbstractAuditableCustom { return new Note(loan, loanTransaction, note); } - public static Note depositNote(final DepositAccount account, final String noteText) { - return new Note(account, noteText); + public static Note depositNote(final DepositAccount account, final String note) { + return new Note(account, note); } - private Note(Client client, String note) { + public static Note savingNote(final SavingAccount account, final String note) { + return new Note(account, note); + } + + private Note(final Client client, final String note) { this.client = client; this.note = note; this.noteTypeId = NoteType.CLIENT.getValue(); } - private Note(Loan loan, String note) { + private Note(final Group group, final String note) { + this.group = group; + this.note = note; + this.client = null; + this.noteTypeId = NoteType.GROUP.getValue(); + } + + private Note(final Loan loan, final String note) { this.loan = loan; this.client = loan.client(); this.note = note; this.noteTypeId = NoteType.LOAN.getValue(); } - private Note(Loan loan, LoanTransaction loanTransaction, String note) { + private Note(final Loan loan, final LoanTransaction loanTransaction, final String note) { this.loan = loan; this.loanTransaction = loanTransaction; this.client = loan.client(); @@ -130,6 +121,7 @@ public class Note extends AbstractAuditableCustom { protected Note() { this.client = null; + this.group = null; this.loan = null; this.loanTransaction = null; this.note = null; @@ -143,14 +135,14 @@ public class Note extends AbstractAuditableCustom { this.noteTypeId = NoteType.DEPOSIT.getValue(); } - public Note(SavingAccount account, String note) { - this.savingAccount = account; - this.client = account.getClient(); - this.note = note; - this.noteTypeId = NoteType.SAVING.getValue(); - } + public Note(final SavingAccount account, final String note) { + this.savingAccount = account; + this.client = account.getClient(); + this.note = note; + this.noteTypeId = NoteType.SAVING.getValue(); + } - public Map update(final JsonCommand command) { + public Map update(final JsonCommand command) { final Map actualChanges = new LinkedHashMap(7); final String noteParamName = "note"; @@ -162,11 +154,8 @@ public class Note extends AbstractAuditableCustom { return actualChanges; } - public boolean isNotAgainstClientWithIdOf(Long clientId) { + public boolean isNotAgainstClientWithIdOf(final Long clientId) { return !this.client.identifiedBy(clientId); } - - public static Note savingNote(final SavingAccount account, final String noteText) { - return new Note(account, noteText); - } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/domain/NoteRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/domain/NoteRepository.java new file mode 100644 index 000000000..9066b45cc --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/domain/NoteRepository.java @@ -0,0 +1,30 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.note.domain; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface NoteRepository extends JpaRepository, JpaSpecificationExecutor { + + List findByLoanId(Long id); + + List findByClientId(Long id); + + Note findByLoanIdAndId(Long loanId, Long id); + + Note findByClientIdAndId(Long clientId, Long id); + + Note findByGroupIdAndId(Long groupId, Long id); + + Note findByLoanTransactionIdAndId(Long loanTransactionId, Long id); + + Note findByDepositAccountIdAndId(Long depositAccountId, Long id); + + Note findBySavingAccountIdAndId(Long savingAccountId, Long id); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/domain/NoteType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/domain/NoteType.java new file mode 100644 index 000000000..f7016669c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/domain/NoteType.java @@ -0,0 +1,81 @@ +package org.mifosplatform.portfolio.note.domain; + +import java.util.HashMap; +import java.util.Map; + +public enum NoteType { + + CLIENT(100, "noteType.client", "clients"), LOAN(200, "noteType.loan", "loans"), LOAN_TRANSACTION(300, "noteType.loan.transaction", + "loanTransactions"), DEPOSIT(400, "noteType.deposit", "deposits"), SAVING(500, "noteType.saving", "savings"), GROUP(600, + "noteType.group", "groups"); + + private Integer value; + private String code; + private String apiUrl; + + NoteType(final Integer value, final String code, final String apiUrl) { + this.value = value; + this.code = code; + this.apiUrl = apiUrl; + } + + public Integer getValue() { + return this.value; + } + + public String getCode() { + return this.code; + } + + private static final Map intToEnumMap = new HashMap(); + private static int minValue; + private static int maxValue; + static { + int i = 0; + for (final NoteType type : NoteType.values()) { + if (i == 0) { + minValue = type.value; + } + intToEnumMap.put(type.value, type); + if (minValue >= type.value) { + minValue = type.value; + } + if (maxValue < type.value) { + maxValue = type.value; + } + i = i + 1; + } + } + + public static NoteType fromInt(final int i) { + final NoteType type = intToEnumMap.get(Integer.valueOf(i)); + return type; + } + + public static int getMinValue() { + return minValue; + } + + public static int getMaxValue() { + return maxValue; + } + + @Override + public String toString() { + return name().toString(); + } + + private static final Map apiUrlToEnumMap = new HashMap(); + + static { + for (final NoteType type : NoteType.values()) { + apiUrlToEnumMap.put(type.apiUrl, type); + } + } + + public static NoteType fromApiUrl(final String url) { + final NoteType type = apiUrlToEnumMap.get(url); + return type; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/exception/NoteNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/exception/NoteNotFoundException.java similarity index 72% rename from mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/exception/NoteNotFoundException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/exception/NoteNotFoundException.java index 5b314aefd..aae07d1af 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/exception/NoteNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/exception/NoteNotFoundException.java @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.portfolio.client.exception; +package org.mifosplatform.portfolio.note.exception; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; @@ -12,12 +12,13 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN */ public class NoteNotFoundException extends AbstractPlatformResourceNotFoundException { - public NoteNotFoundException(Long id) { + public NoteNotFoundException(final Long id) { super("error.msg.note.id.invalid", "Note with identifier " + id + " does not exist", id); } - public NoteNotFoundException(Long id, Long clientId, final String resource) { + public NoteNotFoundException(final Long id, final Long resourceId, final String resource) { super("error.msg." + resource + ".note.id.invalid", "Note with identifier " + id + " does not exist for " + resource - + " with identifier " + clientId, id, clientId); + + " with identifier " + resourceId, id, resourceId); } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/UpdateClientNoteCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/handler/CreateNoteCommandHandler.java similarity index 56% rename from mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/UpdateClientNoteCommandHandler.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/handler/CreateNoteCommandHandler.java index b35ada278..c1d70a4a9 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/UpdateClientNoteCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/handler/CreateNoteCommandHandler.java @@ -3,30 +3,30 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.portfolio.client.handler; +package org.mifosplatform.portfolio.note.handler; import org.mifosplatform.commands.handler.NewCommandSourceHandler; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.portfolio.client.service.ClientWritePlatformService; +import org.mifosplatform.portfolio.note.service.NoteWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service -public class UpdateClientNoteCommandHandler implements NewCommandSourceHandler { +public class CreateNoteCommandHandler implements NewCommandSourceHandler { - private final ClientWritePlatformService clientWritePlatformService; + private final NoteWritePlatformService writePlatformService; @Autowired - public UpdateClientNoteCommandHandler(final ClientWritePlatformService clientWritePlatformService) { - this.clientWritePlatformService = clientWritePlatformService; + public CreateNoteCommandHandler(final NoteWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; } @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - - return this.clientWritePlatformService.updateClientNote(command.getClientId(), command.entityId(), command); + return this.writePlatformService.createNote(command); } -} \ No newline at end of file + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/CreateClientNoteCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/handler/DeleteNoteCommandHandler.java similarity index 57% rename from mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/CreateClientNoteCommandHandler.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/handler/DeleteNoteCommandHandler.java index f2bee0d1f..3662391f4 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/handler/CreateClientNoteCommandHandler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/handler/DeleteNoteCommandHandler.java @@ -3,30 +3,29 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -package org.mifosplatform.portfolio.client.handler; +package org.mifosplatform.portfolio.note.handler; import org.mifosplatform.commands.handler.NewCommandSourceHandler; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.portfolio.client.service.ClientWritePlatformService; +import org.mifosplatform.portfolio.note.service.NoteWritePlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service -public class CreateClientNoteCommandHandler implements NewCommandSourceHandler { +public class DeleteNoteCommandHandler implements NewCommandSourceHandler { - private final ClientWritePlatformService clientWritePlatformService; + private final NoteWritePlatformService writePlatformService; @Autowired - public CreateClientNoteCommandHandler(final ClientWritePlatformService clientWritePlatformService) { - this.clientWritePlatformService = clientWritePlatformService; + public DeleteNoteCommandHandler(final NoteWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; } @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - - return this.clientWritePlatformService.addClientNote(command.getClientId(), command); + return this.writePlatformService.deleteNote(command); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/handler/UpdateNoteCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/handler/UpdateNoteCommandHandler.java new file mode 100644 index 000000000..14e9061e9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/handler/UpdateNoteCommandHandler.java @@ -0,0 +1,28 @@ +package org.mifosplatform.portfolio.note.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.note.service.NoteWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class UpdateNoteCommandHandler implements NewCommandSourceHandler { + + private final NoteWritePlatformService writePlatformService; + + @Autowired + public UpdateNoteCommandHandler(final NoteWritePlatformService noteWritePlatformService) { + this.writePlatformService = noteWritePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.writePlatformService.updateNote(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/serialization/NoteCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/serialization/NoteCommandFromApiJsonDeserializer.java new file mode 100644 index 000000000..ceab45a88 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/serialization/NoteCommandFromApiJsonDeserializer.java @@ -0,0 +1,82 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.note.serialization; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +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.AbstractFromApiJsonDeserializer; +import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.mifosplatform.portfolio.note.command.NoteCommand; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +/** + * Implementation of {@link FromApiJsonDeserializer} for {@link NoteCommand} + * 's. + */ +@Component +public final class NoteCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer { + + /** + * The parameters supported for this command. + */ + private final Set supportedParameters = new HashSet(Arrays.asList("note")); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public NoteCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + @Override + public NoteCommand commandFromApiJson(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters); + + final JsonElement element = this.fromApiJsonHelper.parse(json); + final String note = this.fromApiJsonHelper.extractStringNamed("note", element); + + return new NoteCommand(note); + } + + public void validateNote(final String json) { + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters); + final JsonElement element = this.fromApiJsonHelper.parse(json); + + final List dataValidationErrors = new ArrayList(); + + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("note"); + + final String note = this.fromApiJsonHelper.extractStringNamed("note", element); + baseDataValidator.reset().parameter("note").value(note).notBlank().notExceedingLengthOf(1000); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteEnumerations.java new file mode 100644 index 000000000..5d05ff7a9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteEnumerations.java @@ -0,0 +1,45 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.note.service; + +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.note.domain.NoteType; + +public class NoteEnumerations { + + public static EnumOptionData noteType(final Integer id) { + return noteType(NoteType.fromInt(id)); + } + + public static EnumOptionData noteType(final NoteType type) { + EnumOptionData optionData = null; + switch (type) { + case CLIENT: + optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Client note"); + break; + case LOAN: + optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Loan note"); + break; + case LOAN_TRANSACTION: + optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Loan transaction note"); + break; + case DEPOSIT: + optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Deposit transaction note"); + break; + case SAVING: + optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Saving transaction note"); + break; + case GROUP: + optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), "Group note"); + break; + default: + break; + + } + return optionData; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteReadPlatformService.java new file mode 100644 index 000000000..dbef0fe79 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteReadPlatformService.java @@ -0,0 +1,17 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.note.service; + +import java.util.Collection; + +import org.mifosplatform.portfolio.note.data.NoteData; + +public interface NoteReadPlatformService { + + NoteData retrieveNote(final Long noteId, Long resourceId, Integer noteTypeId); + + Collection retrieveNotesByResource(final Long resourceId, final Integer noteTypeId); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteReadPlatformServiceImpl.java new file mode 100644 index 000000000..ffedcf599 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteReadPlatformServiceImpl.java @@ -0,0 +1,120 @@ +package org.mifosplatform.portfolio.note.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.DateTime; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.domain.JdbcSupport; +import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; +import org.mifosplatform.portfolio.note.data.NoteData; +import org.mifosplatform.portfolio.note.domain.NoteType; +import org.mifosplatform.portfolio.note.exception.NoteNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class NoteReadPlatformServiceImpl implements NoteReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public NoteReadPlatformServiceImpl(final TenantAwareRoutingDataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + private static final class NoteMapper implements RowMapper { + + public String schema() { + return " select n.id as id, n.client_id as clientId, n.group_id as groupId, n.loan_id as loanId, n.loan_transaction_id as transactionId, n.deposit_account_id as depositAccountId, " + + " n.saving_account_id as savingAccountId, n.note_type_enum as noteTypeEnum, n.note as note, n.created_date as createdDate, n.createdby_id as createdById, " + + " cb.username as createdBy, n.lastmodified_date as lastModifiedDate, n.lastmodifiedby_id as lastModifiedById, mb.username as modifiedBy " + + " from m_note n left join m_appuser cb on cb.id=n.createdby_id left join m_appuser mb on mb.id=n.lastmodifiedby_id "; + } + + @Override + public NoteData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = JdbcSupport.getLong(rs, "id"); + final Long clientId = JdbcSupport.getLong(rs, "clientId"); + final Long groupId = JdbcSupport.getLong(rs, "groupId"); + final Long loanId = JdbcSupport.getLong(rs, "loanId"); + final Long transactionId = JdbcSupport.getLong(rs, "transactionId"); + final Long depositAccountId = JdbcSupport.getLong(rs, "depositAccountId"); + final Long savingAccountId = JdbcSupport.getLong(rs, "savingAccountId"); + final Integer noteTypeId = JdbcSupport.getInteger(rs, "noteTypeEnum"); + final EnumOptionData noteType = NoteEnumerations.noteType(noteTypeId); + final String note = rs.getString("note"); + final DateTime createdDate = JdbcSupport.getDateTime(rs, "createdDate"); + final Long createdById = JdbcSupport.getLong(rs, "createdById"); + final DateTime lastModifiedDate = JdbcSupport.getDateTime(rs, "lastModifiedDate"); + final Long lastModifiedById = JdbcSupport.getLong(rs, "lastModifiedById"); + final String createdByUsername = rs.getString("createdBy"); + final String updatedByUsername = rs.getString("modifiedBy"); + return new NoteData(id, clientId, groupId, loanId, transactionId, depositAccountId, savingAccountId, noteType, note, + createdDate, createdById, createdByUsername, lastModifiedDate, lastModifiedById, updatedByUsername); + } + } + + @Override + public NoteData retrieveNote(final Long noteId, final Long resourceId, final Integer noteTypeId) { + final NoteType noteType = NoteType.fromInt(noteTypeId); + try { + final NoteMapper rm = new NoteMapper(); + String conditionSql = getResourceCondition(noteType); + if (StringUtils.isNotBlank(conditionSql)) { + conditionSql = " and " + conditionSql; + } + + final String sql = rm.schema() + " where n.id = ? " + conditionSql + " order by n.created_date DESC"; + + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { noteId, resourceId }); + } catch (final EmptyResultDataAccessException e) { + throw new NoteNotFoundException(noteId, resourceId, noteType.name().toLowerCase()); + } + } + + @Override + public Collection retrieveNotesByResource(final Long resourceId, final Integer noteTypeId) { + final NoteType noteType = NoteType.fromInt(noteTypeId); + final NoteMapper rm = new NoteMapper(); + String conditionSql = getResourceCondition(noteType); + + final String sql = rm.schema() + " where " + conditionSql + " order by n.created_date DESC"; + + return this.jdbcTemplate.query(sql, rm, new Object[] { resourceId }); + } + + public static String getResourceCondition(final NoteType noteType) { + String conditionSql = ""; + switch (noteType) { + case CLIENT: + conditionSql = " n.client_id = ? "; + break; + case LOAN: + conditionSql = " n.loan_id = ? "; + break; + case LOAN_TRANSACTION: + conditionSql = " n.loan_transaction_id = ? "; + break; + case DEPOSIT: + conditionSql = " n.deposit_account_id = ? "; + break; + case SAVING: + conditionSql = " n.saving_account_id = ? "; + break; + case GROUP: + conditionSql = " n.group_id = ? "; + break; + default: + break; + } + + return conditionSql; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteWritePlatformService.java new file mode 100644 index 000000000..745671b45 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteWritePlatformService.java @@ -0,0 +1,13 @@ +package org.mifosplatform.portfolio.note.service; + +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; + +public interface NoteWritePlatformService { + + CommandProcessingResult createNote(JsonCommand command); + + CommandProcessingResult updateNote(JsonCommand command); + + CommandProcessingResult deleteNote(JsonCommand command); +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..167158a2f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,198 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.note.service; + +import java.util.Map; + +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; +import org.mifosplatform.portfolio.client.domain.Client; +import org.mifosplatform.portfolio.client.domain.ClientRepository; +import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; +import org.mifosplatform.portfolio.group.domain.Group; +import org.mifosplatform.portfolio.group.domain.GroupRepository; +import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; +import org.mifosplatform.portfolio.loanaccount.domain.Loan; +import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository; +import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction; +import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository; +import org.mifosplatform.portfolio.loanaccount.exception.LoanNotFoundException; +import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFoundException; +import org.mifosplatform.portfolio.note.domain.Note; +import org.mifosplatform.portfolio.note.domain.NoteRepository; +import org.mifosplatform.portfolio.note.domain.NoteType; +import org.mifosplatform.portfolio.note.exception.NoteNotFoundException; +import org.mifosplatform.portfolio.note.serialization.NoteCommandFromApiJsonDeserializer; +import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount; +import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccountRepository; +import org.mifosplatform.portfolio.savingsaccount.exception.SavingAccountNotFoundException; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccount; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountRepository; +import org.mifosplatform.portfolio.savingsdepositaccount.exception.DepositAccountNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatformService { + + private final NoteRepository noteRepository; + private final ClientRepository clientRepository; + private final GroupRepository groupRepository; + private final DepositAccountRepository depositAccountRepository; + private final SavingAccountRepository savingAccountRepository; + private final LoanRepository loanRepository; + private final LoanTransactionRepository loanTransactionRepository; + private final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer; + + @Autowired + public NoteWritePlatformServiceJpaRepositoryImpl(final NoteRepository noteRepository, final ClientRepository clientRepository, + final GroupRepository groupRepository, final DepositAccountRepository depositAccountRepository, + final SavingAccountRepository savingAccountRepository, final LoanRepository loanRepository, + final LoanTransactionRepository loanTransactionRepository, final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer) { + this.noteRepository = noteRepository; + this.clientRepository = clientRepository; + this.groupRepository = groupRepository; + this.depositAccountRepository = depositAccountRepository; + this.savingAccountRepository = savingAccountRepository; + this.loanRepository = loanRepository; + this.loanTransactionRepository = loanTransactionRepository; + this.fromApiJsonDeserializer = fromApiJsonDeserializer; + } + + @Override + public CommandProcessingResult createNote(final JsonCommand command) { + + this.fromApiJsonDeserializer.validateNote(command.json()); + + final Note newNote = getNewNote(command); + + this.noteRepository.save(newNote); + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(newNote.getId()) // + .build(); + + } + + @Override + public CommandProcessingResult updateNote(final JsonCommand command) { + + this.fromApiJsonDeserializer.validateNote(command.json()); + + final Note noteForUpdate = getNoteForUpdate(command); + + final Map changes = noteForUpdate.update(command); + + if (!changes.isEmpty()) { + this.noteRepository.saveAndFlush(noteForUpdate); + } + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(noteForUpdate.getId()) // + .with(changes) // + .build(); + } + + @Override + public CommandProcessingResult deleteNote(JsonCommand command) { + + final Note noteForDelete = getNoteForUpdate(command); + + this.noteRepository.delete(noteForDelete); + return new CommandProcessingResultBuilder() // + .withCommandId(null) // + .withEntityId(command.entityId()) // + .build(); + } + + private Note getNewNote(final JsonCommand command) { + final String resourceUrl = command.getSupportedEntityType(); + final Long resourceId = command.getSupportedEntityId(); + final NoteType type = NoteType.fromApiUrl(resourceUrl); + Note newNote = null; + final String note = command.stringValueOfParameterNamed("note"); + switch (type) { + case CLIENT: { + final Client client = this.clientRepository.findOne(resourceId); + if (client == null) { throw new ClientNotFoundException(resourceId); } + newNote = Note.clientNoteFromJson(client, command); + } + break; + case DEPOSIT: { + final DepositAccount depositAccount = this.depositAccountRepository.findOne(resourceId); + if (depositAccount == null) { throw new DepositAccountNotFoundException(resourceId); } + newNote = Note.depositNote(depositAccount, note); + } + break; + case GROUP: { + final Group group = this.groupRepository.findOne(resourceId); + if (group == null) { throw new GroupNotFoundException(resourceId); } + newNote = Note.groupNoteFromJson(group, command); + } + break; + case LOAN: { + final Loan loan = this.loanRepository.findOne(resourceId); + if (loan == null) { throw new LoanNotFoundException(resourceId); } + newNote = Note.loanNote(loan, note); + } + break; + case LOAN_TRANSACTION: { + final LoanTransaction loanTransaction = this.loanTransactionRepository.findOne(resourceId); + if (loanTransaction == null) { throw new LoanTransactionNotFoundException(resourceId); } + final Loan loan = loanTransaction.getLoan(); + newNote = Note.loanTransactionNote(loan, loanTransaction, note); + } + break; + case SAVING: { + final SavingAccount savingAccount = this.savingAccountRepository.findOne(resourceId); + if (savingAccount == null) { throw new SavingAccountNotFoundException(resourceId); } + newNote = Note.savingNote(savingAccount, note); + } + break; + } + + return newNote; + } + + private Note getNoteForUpdate(final JsonCommand command) { + final String resourceUrl = command.getSupportedEntityType(); + final Long resourceId = command.getSupportedEntityId(); + final Long noteId = command.entityId(); + final NoteType type = NoteType.fromApiUrl(resourceUrl); + Note noteForUpdate = null; + switch (type) { + case CLIENT: { + noteForUpdate = this.noteRepository.findByClientIdAndId(resourceId, noteId); + } + break; + case DEPOSIT: { + noteForUpdate = this.noteRepository.findByDepositAccountIdAndId(resourceId, noteId); + } + break; + case GROUP: { + noteForUpdate = this.noteRepository.findByGroupIdAndId(resourceId, noteId); + } + break; + case LOAN: { + noteForUpdate = this.noteRepository.findByLoanIdAndId(resourceId, noteId); + } + break; + case LOAN_TRANSACTION: { + noteForUpdate = this.noteRepository.findByLoanTransactionIdAndId(resourceId, noteId); + } + break; + case SAVING: { + noteForUpdate = this.noteRepository.findBySavingAccountIdAndId(resourceId, noteId); + } + break; + } + if (noteForUpdate == null) { throw new NoteNotFoundException(noteId, resourceId, type.name().toLowerCase()); } + return noteForUpdate; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java index f46cc2461..c78563d48 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java @@ -18,8 +18,8 @@ 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.security.service.PlatformSecurityContext; -import org.mifosplatform.portfolio.client.domain.Note; -import org.mifosplatform.portfolio.client.domain.NoteRepository; +import org.mifosplatform.portfolio.note.domain.Note; +import org.mifosplatform.portfolio.note.domain.NoteRepository; import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup; import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount; import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccountRepository; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java index 40479f4af..05df1130f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java @@ -21,8 +21,8 @@ import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityExce import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.domain.Money; -import org.mifosplatform.portfolio.client.domain.Note; -import org.mifosplatform.portfolio.client.domain.NoteRepository; +import org.mifosplatform.portfolio.note.domain.Note; +import org.mifosplatform.portfolio.note.domain.NoteRepository; import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountsForLookup; import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccount; import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountRepository;