MIFOSX-97: move maker checker to cleaner implementatin on handlers with change detection on updates.

This commit is contained in:
Keith Woodlock
2012-12-12 14:00:05 +00:00
parent 3a73d9aacd
commit 892afd409d
165 changed files with 5043 additions and 6059 deletions
@@ -0,0 +1,21 @@
drop table if exists `m_portfolio_command_source`;
CREATE TABLE `m_portfolio_command_source` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`permission_code` varchar(50) NOT NULL,
`api_operation` varchar(30) NOT NULL,
`api_resource` varchar(100) NOT NULL,
`resource_id` bigint(20) DEFAULT NULL,
`api_subresource` varchar(100) DEFAULT NULL,
`subresource_id` bigint(20) DEFAULT NULL,
`command_as_json` text NOT NULL,
`maker_id` bigint(20) NOT NULL,
`made_on_date` datetime NOT NULL,
`checker_id` bigint(20) DEFAULT NULL,
`checked_on_date` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_m_maker_m_appuser` (`maker_id`),
KEY `FK_m_checker_m_appuser` (`checker_id`),
CONSTRAINT `FK_m_checker_m_appuser` FOREIGN KEY (`checker_id`) REFERENCES `m_appuser` (`id`),
CONSTRAINT `FK_m_maker_m_appuser` FOREIGN KEY (`maker_id`) REFERENCES `m_appuser` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -16,6 +16,9 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.audit.data.AuditData;
import org.mifosplatform.audit.data.AuditSearchData;
import org.mifosplatform.audit.service.AuditReadPlatformService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
@@ -30,128 +33,103 @@ import org.springframework.stereotype.Component;
@Scope("singleton")
public class AuditApiResource {
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "apiOperation", "resource", "resourceId",
"maker", "madeOnDate", "checker", "checkedOnDate",
"commandAsJson"));
private final String resourceNameForPermissions = "AUDIT";
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "apiOperation", "resource", "resourceId",
"maker", "madeOnDate", "checker", "checkedOnDate", "commandAsJson"));
private final PlatformSecurityContext context;
private final AuditReadPlatformService auditReadPlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer;
private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
private final String resourceNameForPermissions = "AUDIT";
@Autowired
public AuditApiResource(
final PlatformSecurityContext context,
final AuditReadPlatformService auditReadPlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper,
final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer,
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate) {
this.context = context;
this.auditReadPlatformService = auditReadPlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.toApiJsonSerializer = toApiJsonSerializer;
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
}
private final PlatformSecurityContext context;
private final AuditReadPlatformService auditReadPlatformService;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer;
private final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate;
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditEntries(@Context final UriInfo uriInfo,
@QueryParam("apiOperation") final String apiOperation,
@QueryParam("resource") final String resource,
@QueryParam("resourceId") final Long resourceId,
@QueryParam("makerId") final Long makerId,
@QueryParam("checkerId") final Long checkerId) {
@Autowired
public AuditApiResource(final PlatformSecurityContext context, final AuditReadPlatformService auditReadPlatformService,
final ApiRequestParameterHelper apiRequestParameterHelper, final DefaultToApiJsonSerializer<AuditData> toApiJsonSerializer,
final DefaultToApiJsonSerializer<AuditSearchData> toApiJsonSerializerSearchTemplate) {
this.context = context;
this.auditReadPlatformService = auditReadPlatformService;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.toApiJsonSerializer = toApiJsonSerializer;
this.toApiJsonSerializerSearchTemplate = toApiJsonSerializerSearchTemplate;
}
context.authenticatedUser().validateHasReadPermission(
resourceNameForPermissions);
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditEntries(@Context final UriInfo uriInfo, @QueryParam("apiOperation") final String apiOperation,
@QueryParam("resource") final String resource, @QueryParam("resourceId") final Long resourceId,
@QueryParam("makerId") final Long makerId, @QueryParam("checkerId") final Long checkerId) {
final String extraCriteria = getExtraCriteria(apiOperation, resource,
resourceId, makerId, checkerId);
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper
.process(uriInfo.getQueryParameters());
final String extraCriteria = getExtraCriteria(apiOperation, resource, resourceId, makerId, checkerId);
final Collection<AuditData> auditEntries = this.auditReadPlatformService
.retrieveAuditEntries(extraCriteria, settings.isIncludeJson());
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, auditEntries,
RESPONSE_DATA_PARAMETERS);
}
final Collection<AuditData> auditEntries = this.auditReadPlatformService.retrieveAuditEntries(extraCriteria,
settings.isIncludeJson());
@GET
@Path("{auditId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditEntry(@PathParam("auditId") final Long auditId,
@Context final UriInfo uriInfo) {
return this.toApiJsonSerializer.serialize(settings, auditEntries, RESPONSE_DATA_PARAMETERS);
}
context.authenticatedUser().validateHasReadPermission(
resourceNameForPermissions);
@GET
@Path("{auditId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditEntry(@PathParam("auditId") final Long auditId, @Context final UriInfo uriInfo) {
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper
.process(uriInfo.getQueryParameters());
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
final AuditData auditEntry = this.auditReadPlatformService
.retrieveAuditEntry(auditId);
final AuditData auditEntry = this.auditReadPlatformService.retrieveAuditEntry(auditId);
return this.toApiJsonSerializer.serialize(settings, auditEntry,
RESPONSE_DATA_PARAMETERS);
}
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, auditEntry, RESPONSE_DATA_PARAMETERS);
}
@GET
@Path("/searchtemplate")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) {
@GET
@Path("/searchtemplate")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditSearchTemplate(@Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(
resourceNameForPermissions);
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper
.process(uriInfo.getQueryParameters());
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
final AuditSearchData auditSearchData = this.auditReadPlatformService
.retrieveSearchTemplate();
final AuditSearchData auditSearchData = this.auditReadPlatformService.retrieveSearchTemplate();
final Set<String> RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet<String>(
Arrays.asList("appUsers", "apiOperations", "resources"));
final Set<String> RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE = new HashSet<String>(Arrays.asList("appUsers", "apiOperations",
"resources"));
return this.toApiJsonSerializerSearchTemplate.serialize(settings, auditSearchData,
RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
}
return this.toApiJsonSerializerSearchTemplate.serialize(settings, auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
}
private String getExtraCriteria(String apiOperation, String resource,
Long resourceId, Long makerId, Long checkerId) {
private String getExtraCriteria(final String apiOperation, final String resource, final Long resourceId, final Long makerId, final Long checkerId) {
String extraCriteria = "";
String extraCriteria = "";
if (apiOperation != null) {
extraCriteria += " and aud.api_operation = "
+ ApiParameterHelper.sqlEncodeString(apiOperation);
}
if (resource != null) {
extraCriteria += " and aud.api_resource = "
+ ApiParameterHelper.sqlEncodeString(resource);
}
if (resourceId != null) {
extraCriteria += " and aud.resource_id = " + resourceId;
}
if (makerId != null) {
extraCriteria += " and aud.maker_id = " + makerId;
}
if (checkerId != null) {
extraCriteria += " and aud.checker_id = " + checkerId;
}
if (apiOperation != null) {
extraCriteria += " and aud.api_operation = " + ApiParameterHelper.sqlEncodeString(apiOperation);
}
if (resource != null) {
extraCriteria += " and aud.api_resource = " + ApiParameterHelper.sqlEncodeString(resource);
}
if (resourceId != null) {
extraCriteria += " and aud.resource_id = " + resourceId;
}
if (makerId != null) {
extraCriteria += " and aud.maker_id = " + makerId;
}
if (checkerId != null) {
extraCriteria += " and aud.checker_id = " + checkerId;
}
if (StringUtils.isNotBlank(extraCriteria)) {
extraCriteria = extraCriteria.substring(4);
}
return extraCriteria;
}
if (StringUtils.isNotBlank(extraCriteria)) {
extraCriteria = extraCriteria.substring(4);
}
return extraCriteria;
}
}
@@ -1,14 +0,0 @@
package org.mifosplatform.audit.api;
import java.util.Collection;
public interface AuditReadPlatformService {
Collection<AuditData> retrieveAuditEntries(String extraCriteria,
boolean includeJson);
AuditData retrieveAuditEntry(Long auditId);
AuditSearchData retrieveSearchTemplate();
}
@@ -1,157 +0,0 @@
package org.mifosplatform.audit.api;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.useradministration.data.AppUserLookup;
import org.mifosplatform.useradministration.service.AppUserReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
private final AppUserReadPlatformService appUserReadPlatformService;
@Autowired
public AuditReadPlatformServiceImpl(final PlatformSecurityContext context,
final TenantAwareRoutingDataSource dataSource,
final AppUserReadPlatformService appUserReadPlatformService) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.appUserReadPlatformService = appUserReadPlatformService;
}
private static final class AuditMapper implements RowMapper<AuditData> {
public String schema(boolean includeJson) {
String commandAsJsonString = "";
if (includeJson)
commandAsJsonString = ", aud.command_as_json as commandAsJson ";
return " aud.id as id, aud.api_operation as apiOperation, aud.api_resource as resource, aud.resource_id as resourceId,"
+ " mk.username as maker, aud.made_on_date as madeOnDate, ck.username as checker, aud.checked_on_date as checkedOnDate"
+ commandAsJsonString
+ " from m_portfolio_command_source aud "
+ " left join m_appuser mk on mk.id = aud.maker_id"
+ " left join m_appuser ck on ck.id = aud.checker_id";
}
@Override
public AuditData mapRow(final ResultSet rs,
@SuppressWarnings("unused") final int rowNum)
throws SQLException {
final Long id = rs.getLong("id");
final String apiOperation = rs.getString("apiOperation");
final String resource = rs.getString("resource");
final Long resourceId = JdbcSupport.getLong(rs, "resourceId");
final String maker = rs.getString("maker");
final LocalDate madeOnDate = JdbcSupport.getLocalDate(rs,
"madeOnDate");
final String checker = rs.getString("checker");
final LocalDate checkedOnDate = JdbcSupport.getLocalDate(rs,
"checkedOnDate");
String commandAsJson;
// commandAsJson might not be on the select list of columns
try {
commandAsJson = rs.getString("commandAsJson");
} catch (SQLException e) {
commandAsJson = null;
}
return new AuditData(id, apiOperation, resource, resourceId, maker,
madeOnDate, checker, checkedOnDate, commandAsJson);
}
}
@Override
public Collection<AuditData> retrieveAuditEntries(String extraCriteria,
boolean includeJson) {
context.authenticatedUser();
final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(includeJson);
if (StringUtils.isNotBlank(extraCriteria))
sql += " where (" + extraCriteria + ")";
sql += " order by aud.id DESC";
return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
@Override
public AuditData retrieveAuditEntry(Long auditId) {
context.authenticatedUser();
final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(true);
sql += " where aud.id = " + auditId;
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {});
}
@Override
public AuditSearchData retrieveSearchTemplate() {
Collection<AppUserLookup> appUsers = appUserReadPlatformService
.retrieveSearchTemplate();
ApiOperationsMapper mapper = new ApiOperationsMapper();
List<String> apiOperations = this.jdbcTemplate.query(mapper.schema(),
mapper, new Object[] {});
ApiResourcesMapper mapper2 = new ApiResourcesMapper();
List<String> resources = this.jdbcTemplate.query(mapper2.schema(),
mapper2, new Object[] {});
return new AuditSearchData(appUsers, apiOperations, resources);
}
private static final class ApiOperationsMapper implements RowMapper<String> {
@Override
public String mapRow(final ResultSet rs,
@SuppressWarnings("unused") final int rowNum)
throws SQLException {
return rs.getString("apiOperation");
}
public String schema() {
return " SELECT distinct(action_name) as apiOperation FROM m_permission "
+ " where action_name is not null and action_name <> 'READ' "
+ " order by if(action_name in ('CREATE', 'DELETE', 'UPDATE'), action_name, 'ZZZ'), action_name";
}
}
private static final class ApiResourcesMapper implements RowMapper<String> {
@Override
public String mapRow(final ResultSet rs,
@SuppressWarnings("unused") final int rowNum)
throws SQLException {
return rs.getString("resource");
}
public String schema() {
return " select distinct(api_resource) as resource from m_portfolio_command_source order by api_resource";
}
}
}
@@ -1,26 +0,0 @@
package org.mifosplatform.audit.api;
import java.util.Collection;
import java.util.List;
import org.mifosplatform.useradministration.data.AppUserLookup;
/**
* Immutable data object representing client data.
*/
final public class AuditSearchData {
@SuppressWarnings("unused")
private final Collection<AppUserLookup> appUsers;
@SuppressWarnings("unused")
private final List<String> apiOperations;
@SuppressWarnings("unused")
private final List<String> resources;
public AuditSearchData(final Collection<AppUserLookup> appUsers,
final List<String> apiOperations, final List<String> resources) {
this.appUsers = appUsers;
this.apiOperations = apiOperations;
this.resources = resources;
}
}
@@ -1,11 +1,11 @@
package org.mifosplatform.audit.api;
package org.mifosplatform.audit.data;
import org.joda.time.LocalDate;
/**
* Immutable data object representing client data.
*/
final public class AuditData {
public final class AuditData {
@SuppressWarnings("unused")
private final Long id;
@@ -0,0 +1,25 @@
package org.mifosplatform.audit.data;
import java.util.Collection;
import java.util.List;
import org.mifosplatform.useradministration.data.AppUserLookup;
/**
* Immutable data object representing client data.
*/
public final class AuditSearchData {
@SuppressWarnings("unused")
private final Collection<AppUserLookup> appUsers;
@SuppressWarnings("unused")
private final List<String> apiOperations;
@SuppressWarnings("unused")
private final List<String> resources;
public AuditSearchData(final Collection<AppUserLookup> appUsers, final List<String> apiOperations, final List<String> resources) {
this.appUsers = appUsers;
this.apiOperations = apiOperations;
this.resources = resources;
}
}
@@ -0,0 +1,16 @@
package org.mifosplatform.audit.service;
import java.util.Collection;
import org.mifosplatform.audit.data.AuditData;
import org.mifosplatform.audit.data.AuditSearchData;
public interface AuditReadPlatformService {
Collection<AuditData> retrieveAuditEntries(String extraCriteria, boolean includeJson);
AuditData retrieveAuditEntry(Long auditId);
AuditSearchData retrieveSearchTemplate();
}
@@ -0,0 +1,138 @@
package org.mifosplatform.audit.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.audit.data.AuditData;
import org.mifosplatform.audit.data.AuditSearchData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.useradministration.data.AppUserLookup;
import org.mifosplatform.useradministration.service.AppUserReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context;
private final AppUserReadPlatformService appUserReadPlatformService;
@Autowired
public AuditReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
final AppUserReadPlatformService appUserReadPlatformService) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.appUserReadPlatformService = appUserReadPlatformService;
}
private static final class AuditMapper implements RowMapper<AuditData> {
public String schema(boolean includeJson) {
String commandAsJsonString = "";
if (includeJson) commandAsJsonString = ", aud.command_as_json as commandAsJson ";
return " aud.id as id, aud.api_operation as apiOperation, aud.api_resource as resource, aud.resource_id as resourceId,"
+ " mk.username as maker, aud.made_on_date as madeOnDate, ck.username as checker, aud.checked_on_date as checkedOnDate"
+ commandAsJsonString + " from m_portfolio_command_source aud " + " left join m_appuser mk on mk.id = aud.maker_id"
+ " left join m_appuser ck on ck.id = aud.checker_id";
}
@Override
public AuditData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long id = rs.getLong("id");
final String apiOperation = rs.getString("apiOperation");
final String resource = rs.getString("resource");
final Long resourceId = JdbcSupport.getLong(rs, "resourceId");
final String maker = rs.getString("maker");
final LocalDate madeOnDate = JdbcSupport.getLocalDate(rs, "madeOnDate");
final String checker = rs.getString("checker");
final LocalDate checkedOnDate = JdbcSupport.getLocalDate(rs, "checkedOnDate");
String commandAsJson;
// commandAsJson might not be on the select list of columns
try {
commandAsJson = rs.getString("commandAsJson");
} catch (SQLException e) {
commandAsJson = null;
}
return new AuditData(id, apiOperation, resource, resourceId, maker, madeOnDate, checker, checkedOnDate, commandAsJson);
}
}
@Override
public Collection<AuditData> retrieveAuditEntries(String extraCriteria, boolean includeJson) {
context.authenticatedUser();
final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(includeJson);
if (StringUtils.isNotBlank(extraCriteria)) sql += " where (" + extraCriteria + ")";
sql += " order by aud.id DESC";
return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
@Override
public AuditData retrieveAuditEntry(Long auditId) {
context.authenticatedUser();
final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(true);
sql += " where aud.id = " + auditId;
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {});
}
@Override
public AuditSearchData retrieveSearchTemplate() {
Collection<AppUserLookup> appUsers = appUserReadPlatformService.retrieveSearchTemplate();
ApiOperationsMapper mapper = new ApiOperationsMapper();
List<String> apiOperations = this.jdbcTemplate.query(mapper.schema(), mapper, new Object[] {});
ApiResourcesMapper mapper2 = new ApiResourcesMapper();
List<String> resources = this.jdbcTemplate.query(mapper2.schema(), mapper2, new Object[] {});
return new AuditSearchData(appUsers, apiOperations, resources);
}
private static final class ApiOperationsMapper implements RowMapper<String> {
@Override
public String mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
return rs.getString("apiOperation");
}
public String schema() {
return " SELECT distinct(action_name) as apiOperation FROM m_permission "
+ " where action_name is not null and action_name <> 'READ' "
+ " order by if(action_name in ('CREATE', 'DELETE', 'UPDATE'), action_name, 'ZZZ'), action_name";
}
}
private static final class ApiResourcesMapper implements RowMapper<String> {
@Override
public String mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
return rs.getString("resource");
}
public String schema() {
return " select distinct(api_resource) as resource from m_portfolio_command_source order by api_resource";
}
}
}
@@ -98,6 +98,6 @@ public class CommandsApiResource {
final Long id = this.writePlatformService.deleteEntry(commandId);
return this.toApiJsonSerializer.serialize(EntityIdentifier.makerChecker(id));
return this.toApiJsonSerializer.serialize(EntityIdentifier.commandOnlyResult(id));
}
}
@@ -11,7 +11,8 @@ import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.joda.time.DateTime;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.data.jpa.domain.AbstractPersistable;
@@ -19,24 +20,35 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
@Table(name = "m_portfolio_command_source")
public class CommandSource extends AbstractPersistable<Long> {
@Column(name = "api_operation", length = 20)
@Column(name = "permission_code", length = 50)
private String permissionCode;
@Column(name = "api_operation", length = 30)
private String apiOperation;
@Column(name = "api_resource", length = 20)
@Column(name = "api_resource", length = 100)
private String resource;
@Column(name = "resource_id")
private Long resourceId;
@Column(name = "api_subresource", length = 100)
private String subResource;
@Column(name = "subresource_id")
private Long subResourceId;
@Column(name = "command_as_json", length = 1000)
private String commandAsJson;
@SuppressWarnings("unused")
@ManyToOne
@JoinColumn(name = "maker_id", nullable = false)
private AppUser maker;
@SuppressWarnings("unused")
@Column(name = "made_on_date", nullable = false)
@Temporal(TemporalType.DATE)
@Temporal(TemporalType.TIMESTAMP)
private Date madeOnDate;
@SuppressWarnings("unused")
@@ -46,37 +58,33 @@ public class CommandSource extends AbstractPersistable<Long> {
@SuppressWarnings("unused")
@Column(name = "checked_on_date", nullable = false)
@Temporal(TemporalType.DATE)
@Temporal(TemporalType.TIMESTAMP)
private Date checkedOnDate;
public static CommandSource createdBy(final String apiOperation, final String resource, final Long resourceId,
final String commandSerializedAsJson, final AppUser maker, final LocalDate madeOnDate) {
return new CommandSource(apiOperation, resource, resourceId, commandSerializedAsJson, maker, madeOnDate);
public static CommandSource fullEntryFrom(final CommandWrapper wrapper, final JsonCommand command, final AppUser maker) {
return new CommandSource(wrapper.taskPermissionName(), wrapper.operation(), wrapper.resourceName(), command.resourceId(),
wrapper.subResourceName(), command.subResourceId(), command.json(), maker, DateTime.now());
}
protected CommandSource() {
//
}
private CommandSource(final String apiOperation, final String resource, final Long resourceId, final String commandSerializedAsJson, final AppUser maker,
final LocalDate madeOnDate) {
private CommandSource(final String permissionCode, final String apiOperation, final String resource, final Long resourceId,
final String subResource, final Long subResourceId, final String commandSerializedAsJson, final AppUser maker,
final DateTime madeOnDateTime) {
this.permissionCode = permissionCode;
this.apiOperation = StringUtils.defaultIfEmpty(apiOperation, null);
this.resource = StringUtils.defaultIfEmpty(resource, null);
this.resourceId = resourceId;
this.subResource = StringUtils.defaultIfEmpty(subResource, null);
this.subResourceId = subResourceId;
this.commandAsJson = commandSerializedAsJson;
this.maker = maker;
this.madeOnDate = madeOnDate.toDate();
this.madeOnDate = madeOnDateTime.toDate();
}
public CommandSource copy() {
LocalDate madeOnLocalDate = null;
if (this.madeOnDate != null) {
madeOnLocalDate = new LocalDate(this.madeOnDate);
}
return new CommandSource(this.apiOperation, this.resource, this.resourceId, this.commandAsJson, this.maker, madeOnLocalDate);
}
public void markAsChecked(final AppUser checker, final LocalDate checkedOnDate) {
public void markAsChecked(final AppUser checker, final DateTime checkedOnDate) {
this.checker = checker;
this.checkedOnDate = checkedOnDate.toDate();
}
@@ -85,6 +93,10 @@ public class CommandSource extends AbstractPersistable<Long> {
this.resourceId = resourceId;
}
public void updateSubResourceId(final Long subResourceId) {
this.subResourceId = subResourceId;
}
public void updateJsonTo(final String json) {
this.commandAsJson = json;
}
@@ -92,7 +104,7 @@ public class CommandSource extends AbstractPersistable<Long> {
public Long resourceId() {
return this.resourceId;
}
public boolean hasJson() {
return StringUtils.isNotBlank(this.commandAsJson);
}
@@ -113,81 +125,23 @@ public class CommandSource extends AbstractPersistable<Long> {
return this.apiOperation;
}
public boolean isCreate() {
return this.apiOperation.equalsIgnoreCase("CREATE");
public String getPermissionCode() {
return this.permissionCode;
}
public boolean isUpdate() {
// permissions resource has special update which involves no resource.
return (isPermissionResource() && isUpdateOperation()) || (isCurrencyResource() && isUpdateOperation())
|| (isUpdateOperation() && this.resourceId != null);
public String getResource() {
return this.resource;
}
private boolean isUpdateOperation() {
return this.apiOperation.equalsIgnoreCase("UPDATE");
public Long getResourceId() {
return this.resourceId;
}
public boolean isDelete() {
return this.apiOperation.equalsIgnoreCase("DELETE") && this.resourceId != null;
public String getSubResource() {
return this.subResource;
}
public boolean isUpdateRolePermissions() {
return this.apiOperation.equalsIgnoreCase("UPDATEPERMISSIONS") && this.resourceId != null;
}
public boolean isPermissionResource() {
return this.resource.equalsIgnoreCase("PERMISSIONS");
}
public boolean isRoleResource() {
return this.resource.equalsIgnoreCase("ROLES");
}
public boolean isUserResource() {
return this.resource.equalsIgnoreCase("USERS");
}
public boolean isCurrencyResource() {
return this.resource.equalsIgnoreCase("CURRENCIES");
}
public boolean isCodeResource() {
return this.resource.equalsIgnoreCase("CODES");
}
public boolean isStaffResource() {
return this.resource.equalsIgnoreCase("STAFF");
}
public boolean isFundResource() {
return this.resource.equalsIgnoreCase("FUNDS");
}
public boolean isOfficeResource() {
return this.resource.equalsIgnoreCase("OFFICES");
}
public boolean isOfficeTransactionResource() {
return this.resource.equalsIgnoreCase("OFFICETRANSACTIONS");
}
public boolean isChargeDefinitionResource() {
return this.resource.equalsIgnoreCase("CHARGES");
}
public boolean isLoanProductResource() {
return this.resource.equalsIgnoreCase("LOANPRODUCTS");
}
public boolean isClientResource() {
return this.resource.equalsIgnoreCase("CLIENTS");
}
public boolean isClientIdentifierResource() {
return this.resource.toUpperCase().startsWith("CLIENTS") && this.resource.toUpperCase().endsWith("IDENTIFIERS");
}
public boolean isClientNoteResource() {
return this.resource.toUpperCase().startsWith("CLIENTS") && this.resource.toUpperCase().endsWith("NOTES");
public Long getSubResourceId() {
return this.subResourceId;
}
}
@@ -3,8 +3,6 @@ package org.mifosplatform.commands.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface CommandSourceRepository extends
JpaRepository<CommandSource, Long>,
JpaSpecificationExecutor<CommandSource> {
// no added behaviour
public interface CommandSourceRepository extends JpaRepository<CommandSource, Long>, JpaSpecificationExecutor<CommandSource> {
// no added behaviour
}
@@ -0,0 +1,156 @@
package org.mifosplatform.commands.domain;
public class CommandWrapper {
private final Long commandId;
private final String apiOperation;
private final String resource;
private final Long resourceId;
private final String taskPermissionName;
private final String subResource;
private final Long subResourceId;
public static CommandWrapper wrap(final String taskPermissionName, final String apiOperation, final String resource,
final Long resourceId) {
return new CommandWrapper(null, taskPermissionName, apiOperation, resource, resourceId, null, null);
}
public static CommandWrapper wrap(final String taskPermissionName, final String apiOperation, final String resource,
final Long resourceId, final String subResource, final Long subRescourceId) {
return new CommandWrapper(null, taskPermissionName, apiOperation, resource, resourceId, subResource, subRescourceId);
}
public static CommandWrapper fromExistingCommand(final Long commandId, final String taskPermissionName, final String apiOperation, final String resource,
final Long resourceId, final String subResource, final Long subRescourceId) {
return new CommandWrapper(commandId, taskPermissionName, apiOperation, resource, resourceId, subResource, subRescourceId);
}
private CommandWrapper(final Long commandId, final String taskPermissionName, final String apiOperation, final String resource,
final Long resourceId, final String subResource, final Long subResourceId) {
this.commandId = commandId;
this.taskPermissionName = taskPermissionName;
this.apiOperation = apiOperation;
this.resource = resource;
this.resourceId = resourceId;
this.subResource = subResource;
this.subResourceId = subResourceId;
}
public String commandName() {
return this.apiOperation + '-' + this.resource;
}
public Long commandId() {
return this.commandId;
}
public Long resourceId() {
return this.resourceId;
}
public String resourceName() {
return this.resource;
}
public Long subResourceId() {
return this.subResourceId;
}
public String subResourceName() {
return this.subResource;
}
public String taskPermissionName() {
return this.taskPermissionName;
}
public String operation() {
return this.apiOperation;
}
public boolean isCreate() {
return this.apiOperation.equalsIgnoreCase("CREATE");
}
public boolean isUpdate() {
// permissions resource has special update which involves no resource.
return (isPermissionResource() && isUpdateOperation()) || (isCurrencyResource() && isUpdateOperation())
|| (isUpdateOperation() && this.resourceId != null);
}
private boolean isUpdateOperation() {
return this.apiOperation.equalsIgnoreCase("UPDATE");
}
public boolean isDelete() {
return this.apiOperation.equalsIgnoreCase("DELETE") && this.resourceId != null;
}
public boolean isUpdateRolePermissions() {
return this.apiOperation.equalsIgnoreCase("UPDATEPERMISSIONS") && this.resourceId != null;
}
public boolean isPermissionResource() {
return this.resource.equalsIgnoreCase("PERMISSIONS");
}
public boolean isRoleResource() {
return this.resource.equalsIgnoreCase("ROLES");
}
public boolean isUserResource() {
return this.resource.equalsIgnoreCase("USERS");
}
public boolean isCurrencyResource() {
return this.resource.equalsIgnoreCase("CURRENCIES");
}
public boolean isCodeResource() {
return this.resource.equalsIgnoreCase("CODES");
}
public boolean isStaffResource() {
return this.resource.equalsIgnoreCase("STAFF");
}
public boolean isFundResource() {
return this.resource.equalsIgnoreCase("FUNDS");
}
public boolean isOfficeResource() {
return this.resource.equalsIgnoreCase("OFFICES");
}
public boolean isOfficeTransactionResource() {
return this.resource.equalsIgnoreCase("OFFICETRANSACTIONS");
}
public boolean isChargeDefinitionResource() {
return this.resource.equalsIgnoreCase("CHARGES");
}
public boolean isLoanProductResource() {
return this.resource.equalsIgnoreCase("LOANPRODUCTS");
}
public boolean isClientResource() {
return this.resource.equalsIgnoreCase("CLIENTS");
}
public boolean isClientIdentifierResource() {
return isClientResource() && isIdentifiersSubResource();
}
public boolean isClientNoteResource() {
return isClientResource() && isNotesSubResource();
}
public boolean isNotesSubResource() {
return "NOTES".equalsIgnoreCase(this.subResource);
}
public boolean isIdentifiersSubResource() {
return "IDENTIFIERS".equalsIgnoreCase(this.subResource);
}
}
@@ -1,109 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand;
import org.mifosplatform.portfolio.charge.serialization.ChargeCommandFromCommandJsonDeserializer;
import org.mifosplatform.portfolio.charge.service.ChargeWritePlatformService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ChargeDefinitionCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChargeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final ChargeWritePlatformService writePlatformService;
@Autowired
public ChargeDefinitionCommandHandler(final PlatformSecurityContext context,
final ChargeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final ChargeWritePlatformService writePlatformService) {
this.context = context;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
CommandSource commandSourceResult = commandSource.copy();
final Long resourceId = commandSource.resourceId();
final ChargeDefinitionCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
commandSourceResult.json());
if (commandSource.isCreate()) {
try {
Long newResourceId = this.writePlatformService.createCharge(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(newResourceId);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
this.writePlatformService.updateCharge(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) {
try {
this.writePlatformService.deleteCharge(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
}
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
Long resourceId = commandSourceResult.resourceId();
final ChargeDefinitionCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"CREATE_CHARGE_MAKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_CHARGE_MAKER", allowedPermissions);
resourceId = this.writePlatformService.createCharge(command);
commandSourceResult.updateResourceId(resourceId);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"UPDATE_CHARGE_MAKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CHARGE_MAKER", allowedPermissions);
this.writePlatformService.updateCharge(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"DELETE_CHARGE_MAKER");
context.authenticatedUser().validateHasPermissionTo("DELETE_CHARGE_MAKER", allowedPermissions);
this.writePlatformService.deleteCharge(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
}
return commandSourceResult;
}
}
@@ -1,117 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
@Service
public class ClientCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ClientWritePlatformService clientWritePlatformService;
private final FromJsonHelper fromApiJsonHelper;
private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer;
@Autowired
public ClientCommandHandler(final PlatformSecurityContext context, final FromJsonHelper fromApiJsonHelper,
final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer,
final ClientWritePlatformService clientWritePlatformService) {
this.context = context;
this.fromApiJsonHelper = fromApiJsonHelper;
this.toApiJsonSerializer = toApiJsonSerializer;
this.clientWritePlatformService = clientWritePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSource.json());
final JsonCommand command = JsonCommand.from(commandSource.json(), parsedCommand, this.fromApiJsonHelper);
CommandSource commandSourceResult = commandSource.copy();
if (commandSource.isCreate()) {
try {
Long newResourceId = this.clientWritePlatformService.createClient(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(newResourceId);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(commandSource.resourceId(), command);
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) {
try {
this.clientWritePlatformService.deleteClient(commandSource.resourceId(), command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
}
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
final JsonElement parsedCommand = fromApiJsonHelper.parse(commandSourceResult.json());
final JsonCommand command = JsonCommand.withMakerCheckerApproval(commandSourceResult.json(), parsedCommand, fromApiJsonHelper);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"CREATE_CLIENT_CHECKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENT_CHECKER", allowedPermissions);
Long resourceId = this.clientWritePlatformService.createClient(command);
commandSourceResult.updateResourceId(resourceId);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"UPDATE_CLIENT_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT_CHECKER", allowedPermissions);
EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(commandSourceResult.resourceId(), command);
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"DELETE_CLIENT_CHECKER");
context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENT_CHECKER", allowedPermissions);
this.clientWritePlatformService.deleteClient(commandSourceResult.resourceId(), command);
commandSourceResult.markAsChecked(checker, new LocalDate());
}
return commandSourceResult;
}
}
@@ -1,103 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand;
import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromCommandJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ClientIdentifierCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ClientWritePlatformService clientWritePlatformService;
private final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
@Autowired
public ClientIdentifierCommandHandler(final PlatformSecurityContext context,
final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final ClientWritePlatformService clientWritePlatformService) {
this.context = context;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.clientWritePlatformService = clientWritePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final ClientIdentifierCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(commandSource.resourceId(),
commandSource.json());
CommandSource commandSourceResult = commandSource.copy();
if (commandSource.isCreate()) {
try {
Long newResourceId = this.clientWritePlatformService.addClientIdentifier(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(newResourceId);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
this.clientWritePlatformService.updateClientIdentifier(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) {
try {
this.clientWritePlatformService.deleteClientIdentifier(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
}
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
final ClientIdentifierCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSourceResult.resourceId(), commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"CREATE_CLIENTIDENTIFIER_CHECKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENTIDENTIFIER_CHECKER", allowedPermissions);
Long resourceId = this.clientWritePlatformService.addClientIdentifier(command);
commandSourceResult.updateResourceId(resourceId);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"UPDATE_CLIENTIDENTIFIER_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENTIDENTIFIER_CHECKER", allowedPermissions);
this.clientWritePlatformService.updateClientIdentifier(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"DELETE_CLIENTIDENTIFIER_CHECKER");
context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENTIDENTIFIER_CHECKER", allowedPermissions);
this.clientWritePlatformService.deleteClientIdentifier(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
}
return commandSourceResult;
}
}
@@ -1,91 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.command.ClientNoteCommand;
import org.mifosplatform.portfolio.client.serialization.ClientNoteCommandFromCommandJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ClientNoteCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ClientWritePlatformService clientWritePlatformService;
private final ClientNoteCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
@Autowired
public ClientNoteCommandHandler(final PlatformSecurityContext context,
final ClientNoteCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final ClientWritePlatformService clientWritePlatformService) {
this.context = context;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.clientWritePlatformService = clientWritePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final ClientNoteCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(commandSource.resourceId(),
commandSource.json());
CommandSource commandSourceResult = commandSource.copy();
if (commandSource.isCreate()) {
try {
EntityIdentifier result = this.clientWritePlatformService.addClientNote(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(result.getEntityId());
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
this.clientWritePlatformService.updateNote(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
final ClientNoteCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(commandSourceResult.resourceId(),
commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"CREATE_CLIENTNOTE_CHECKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENTNOTE_CHECKER", allowedPermissions);
EntityIdentifier result = this.clientWritePlatformService.addClientNote(command);
commandSourceResult.updateResourceId(result.getEntityId());
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"UPDATE_CLIENTNOTE_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENTNOTE_CHECKER", allowedPermissions);
this.clientWritePlatformService.updateNote(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
return commandSourceResult;
}
}
@@ -1,119 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.infrastructure.codes.service.CodeWritePlatformService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
@Service
public class CodeCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final FromJsonHelper fromApiJsonHelper;
private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer;
private final CodeWritePlatformService writePlatformService;
@Autowired
public CodeCommandHandler(final PlatformSecurityContext context,
final FromJsonHelper fromApiJsonHelper,
final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer,
final CodeWritePlatformService writePlatformService) {
this.context = context;
this.fromApiJsonHelper = fromApiJsonHelper;
this.toApiJsonSerializer = toApiJsonSerializer;
this.writePlatformService = writePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final Long resourceId = commandSource.resourceId();
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSource.json());
final JsonCommand command = JsonCommand.from(commandSource.json(), parsedCommand, this.fromApiJsonHelper);
CommandSource commandSourceResult = commandSource.copy();
if (commandSource.isCreate()) {
try {
Long newResourceId = this.writePlatformService.createCode(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(newResourceId);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
EntityIdentifier result = this.writePlatformService.updateCode(resourceId, command);
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) {
try {
this.writePlatformService.deleteCode(resourceId, command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
}
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
Long resourceId = commandSourceResult.resourceId();
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSourceResult.json());
final JsonCommand command = JsonCommand.withMakerCheckerApproval(commandSourceResult.json(), parsedCommand, this.fromApiJsonHelper);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "CREATE_CODE_MAKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_CODE_MAKER", allowedPermissions);
resourceId = this.writePlatformService.createCode(command);
commandSourceResult.updateResourceId(resourceId);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "UPDATE_CODE_MAKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CODE_MAKER", allowedPermissions);
EntityIdentifier result = this.writePlatformService.updateCode(resourceId, command);
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "DELETE_CODE_MAKER");
context.authenticatedUser().validateHasPermissionTo("DELETE_CODE_MAKER", allowedPermissions);
this.writePlatformService.deleteCode(resourceId, command);
commandSourceResult.markAsChecked(checker, new LocalDate());
}
return commandSourceResult;
}
}
@@ -1,19 +0,0 @@
package org.mifosplatform.commands.handler;
import org.mifosplatform.commands.domain.CommandSource;
public interface CommandSourceHandler {
/*
* Used when users with 'create' capability create a command. If
* 'maker-checker' is not enabled for this specific command then the
* 'creator' is also marked 'as the checker' and command automatically is
* processed and changes state of system.
*/
CommandSource handleCommandWithSupportForRollback(CommandSource commandSource);
/*
* Used when users with 'checker' capability approve a command.
*/
CommandSource handleCommandForCheckerApproval(CommandSource commandSourceResult);
}
@@ -1,140 +0,0 @@
package org.mifosplatform.commands.handler;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* A class to delegate handling of commands to appropriate handler.
*/
@Service
public class CommandSourceHandlerDelegator {
private final PlatformSecurityContext context;
private final ClientCommandHandler clientCommandHandler;
private final RoleCommandHandler roleCommandHandler;
private final PermissionsCommandHandler permissionCommandHandler;
private final UserCommandHandler userCommandHandler;
private final CodeCommandHandler codeCommandHandler;
private final StaffCommandHandler staffCommandHandler;
private final FundCommandHandler fundCommandHandler;
private final OfficeCommandHandler officeCommandHandler;
private final OfficeTransactionCommandHandler officeTransactionCommandHandler;
private final CurrencyCommandHandler currencyCommandHandler;
private final ChargeDefinitionCommandHandler chargeDefinitionCommandHandler;
private final LoanProductCommandHandler loanProductCommandHandler;
private final ClientIdentifierCommandHandler clientIdentifierCommandHandler;
private final ClientNoteCommandHandler clientNoteCommandHandler;
@Autowired
public CommandSourceHandlerDelegator(final PlatformSecurityContext context,
final ClientCommandHandler clientCommandHandler,
final ClientIdentifierCommandHandler clientIdentifierCommandHandler,
final ClientNoteCommandHandler clientNoteCommandHandler,
final RoleCommandHandler roleCommandHandler,
final PermissionsCommandHandler permissionCommandHandler,
final UserCommandHandler userCommandHandler,
final CodeCommandHandler codeCommandHandler,
final StaffCommandHandler staffCommandHandler,
final FundCommandHandler fundCommandHandler,
final OfficeCommandHandler officeCommandHandler,
final OfficeTransactionCommandHandler officeTransactionCommandHandler,
final CurrencyCommandHandler currencyCommandHandler,
final ChargeDefinitionCommandHandler chargeDefinitionCommandHandler,
final LoanProductCommandHandler loanProductCommandHandler) {
this.context = context;
this.clientCommandHandler = clientCommandHandler;
this.clientIdentifierCommandHandler = clientIdentifierCommandHandler;
this.clientNoteCommandHandler = clientNoteCommandHandler;
this.roleCommandHandler = roleCommandHandler;
this.permissionCommandHandler = permissionCommandHandler;
this.userCommandHandler = userCommandHandler;
this.codeCommandHandler = codeCommandHandler;
this.staffCommandHandler = staffCommandHandler;
this.fundCommandHandler = fundCommandHandler;
this.officeCommandHandler = officeCommandHandler;
this.officeTransactionCommandHandler = officeTransactionCommandHandler;
this.currencyCommandHandler = currencyCommandHandler;
this.chargeDefinitionCommandHandler = chargeDefinitionCommandHandler;
this.loanProductCommandHandler = loanProductCommandHandler;
}
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
context.authenticatedUser();
CommandSource commandSourceResult = null;
if (commandSource.isClientResource()) {
commandSourceResult = clientCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isClientIdentifierResource()) {
commandSourceResult = clientIdentifierCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isClientNoteResource()) {
commandSourceResult = clientNoteCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isRoleResource()) {
commandSourceResult = roleCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isPermissionResource()) {
commandSourceResult = permissionCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isUserResource()) {
commandSourceResult = userCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isCodeResource()) {
commandSourceResult = codeCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isStaffResource()) {
commandSourceResult = staffCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isFundResource()) {
commandSourceResult = fundCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isOfficeResource()) {
commandSourceResult = officeCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isOfficeTransactionResource()) {
commandSourceResult = officeTransactionCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isCurrencyResource()) {
commandSourceResult = currencyCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isChargeDefinitionResource()) {
commandSourceResult = chargeDefinitionCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else if (commandSource.isLoanProductResource()) {
commandSourceResult = loanProductCommandHandler.handleCommandWithSupportForRollback(commandSource);
} else {
throw new UnsupportedCommandException(commandSource.commandName());
}
return commandSourceResult;
}
public CommandSource handleCommandForCheckerApproval(final CommandSource existingCommandSource) {
CommandSource commandSourceResult = null;
if (existingCommandSource.isClientResource()) {
commandSourceResult = clientCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isClientIdentifierResource()) {
commandSourceResult = clientIdentifierCommandHandler.handleCommandWithSupportForRollback(existingCommandSource);
} else if (existingCommandSource.isClientNoteResource()) {
commandSourceResult = clientNoteCommandHandler.handleCommandWithSupportForRollback(existingCommandSource);
} else if (existingCommandSource.isRoleResource()) {
commandSourceResult = roleCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isPermissionResource()) {
commandSourceResult = permissionCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isUserResource()) {
commandSourceResult = userCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isCodeResource()) {
commandSourceResult = codeCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isStaffResource()) {
commandSourceResult = staffCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isFundResource()) {
commandSourceResult = fundCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isOfficeResource()) {
commandSourceResult = officeCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isOfficeTransactionResource()) {
commandSourceResult = officeTransactionCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isCurrencyResource()) {
commandSourceResult = currencyCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isChargeDefinitionResource()) {
commandSourceResult = chargeDefinitionCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else if (existingCommandSource.isLoanProductResource()) {
commandSourceResult = loanProductCommandHandler.handleCommandForCheckerApproval(existingCommandSource);
} else {
throw new UnsupportedCommandException(existingCommandSource.commandName());
}
return commandSourceResult;
}
}
@@ -1,78 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.command.CurrencyCommand;
import org.mifosplatform.organisation.monetary.serialization.CurrencyCommandFromCommandJsonDeserializer;
import org.mifosplatform.organisation.monetary.service.CurrencyWritePlatformService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CurrencyCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final CurrencyCommandFromCommandJsonDeserializer fromApiJsonDeserializer;
private final CurrencyWritePlatformService writePlatformService;
@Autowired
public CurrencyCommandHandler(final PlatformSecurityContext context,
final CurrencyCommandFromCommandJsonDeserializer fromApiJsonDeserializer,
final CurrencyWritePlatformService writePlatformService) {
this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
CommandSource commandSourceResult = commandSource.copy();
if (commandSource.isCreate()) {
throw new UnsupportedCommandException(commandSource.commandName());
} else if (commandSource.isUpdate()) {
try {
final CurrencyCommand command = this.fromApiJsonDeserializer.commandFromCommandJson(commandSource.json());
this.writePlatformService.updateAllowedCurrencies(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
final CurrencyCommand command = this.fromApiJsonDeserializer.commandFromCommandJson(commandSourceResult.resourceId(),
commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
throw new UnsupportedCommandException(commandSourceResult.commandName());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"UPDATE_CURRENCY_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CURRENCY_CHECKER", allowedPermissions);
this.writePlatformService.updateAllowedCurrencies(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
return commandSourceResult;
}
}
@@ -1,94 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.portfolio.fund.command.FundCommand;
import org.mifosplatform.portfolio.fund.serialization.FundCommandFromCommandJsonDeserializer;
import org.mifosplatform.portfolio.fund.service.FundWritePlatformService;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class FundCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final FundCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final FundWritePlatformService writePlatformService;
@Autowired
public FundCommandHandler(final PlatformSecurityContext context,
final FundCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final FundWritePlatformService writePlatformService) {
this.context = context;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final Long resourceId = commandSource.resourceId();
final FundCommand command = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, commandSource.json());
CommandSource commandSourceResult = commandSource.copy();
Long newResourceId = null;
if (commandSource.isCreate()) {
try {
newResourceId = this.writePlatformService.createFund(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(newResourceId);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
this.writePlatformService.updateFund(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
Long resourceId = commandSourceResult.resourceId();
final FundCommand command = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"CREATE_FUND_CHECKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_FUND_CHECKER", allowedPermissions);
resourceId = this.writePlatformService.createFund(command);
commandSourceResult.updateResourceId(resourceId);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"UPDATE_FUND_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_FUND_CHECKER", allowedPermissions);
resourceId = this.writePlatformService.updateFund(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
return commandSourceResult;
}
}
@@ -1,95 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.portfolio.loanproduct.command.LoanProductCommand;
import org.mifosplatform.portfolio.loanproduct.serialization.LoanProductCommandFromCommandJsonDeserializer;
import org.mifosplatform.portfolio.loanproduct.service.LoanProductWritePlatformService;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class LoanProductCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final LoanProductCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final LoanProductWritePlatformService writePlatformService;
@Autowired
public LoanProductCommandHandler(final PlatformSecurityContext context,
final LoanProductCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final LoanProductWritePlatformService writePlatformService) {
this.context = context;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final Long resourceId = commandSource.resourceId();
final LoanProductCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId, commandSource.json());
CommandSource commandSourceResult = commandSource.copy();
if (commandSource.isCreate()) {
try {
EntityIdentifier result = this.writePlatformService.createLoanProduct(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(result.getEntityId());
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
this.writePlatformService.updateLoanProduct(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
Long resourceId = commandSourceResult.resourceId();
final LoanProductCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"CREATE_LOANPRODUCT_MAKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_LOANPRODUCT_MAKER", allowedPermissions);
EntityIdentifier result = this.writePlatformService.createLoanProduct(command);
commandSourceResult.updateResourceId(result.getEntityId());
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"UPDATE_LOANPRODUCT_MAKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_LOANPRODUCT_MAKER", allowedPermissions);
this.writePlatformService.updateLoanProduct(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
return commandSourceResult;
}
}
@@ -0,0 +1,9 @@
package org.mifosplatform.commands.handler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface NewCommandSourceHandler {
EntityIdentifier processCommand(JsonCommand command);
}
@@ -1,95 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.command.OfficeCommand;
import org.mifosplatform.organisation.office.serialization.OfficeCommandFromCommandJsonDeserializer;
import org.mifosplatform.organisation.office.service.OfficeWritePlatformService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OfficeCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final OfficeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final OfficeWritePlatformService writePlatformService;
@Autowired
public OfficeCommandHandler(final PlatformSecurityContext context,
final OfficeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final OfficeWritePlatformService writePlatformService) {
this.context = context;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final Long resourceId = commandSource.resourceId();
final OfficeCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId, commandSource.json());
CommandSource commandSourceResult = commandSource.copy();
Long newResourceId = null;
if (commandSource.isCreate()) {
try {
newResourceId = this.writePlatformService.createOffice(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(newResourceId);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
this.writePlatformService.updateOffice(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
Long resourceId = commandSourceResult.resourceId();
final OfficeCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"CREATE_OFFICE_CHECKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_OFFICE_CHECKER", allowedPermissions);
resourceId = this.writePlatformService.createOffice(command);
commandSourceResult.updateResourceId(resourceId);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"UPDATE_OFFICE_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_OFFICE_CHECKER", allowedPermissions);
resourceId = this.writePlatformService.updateOffice(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
return commandSourceResult;
}
}
@@ -1,84 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.command.BranchMoneyTransferCommand;
import org.mifosplatform.organisation.office.serialization.BranchMoneyTransferCommandFromCommandJsonDeserializer;
import org.mifosplatform.organisation.office.service.OfficeWritePlatformService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OfficeTransactionCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final BranchMoneyTransferCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final OfficeWritePlatformService writePlatformService;
@Autowired
public OfficeTransactionCommandHandler(final PlatformSecurityContext context,
final BranchMoneyTransferCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final OfficeWritePlatformService writePlatformService) {
this.context = context;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
Long resourceId = commandSource.resourceId();
final BranchMoneyTransferCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
commandSource.json());
CommandSource commandSourceResult = commandSource.copy();
Long newResourceId = null;
if (commandSource.isCreate()) {
try {
newResourceId = this.writePlatformService.externalBranchMoneyTransfer(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(newResourceId);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
throw new UnsupportedCommandException(commandSource.commandName());
} else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
Long resourceId = commandSourceResult.resourceId();
final BranchMoneyTransferCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"CREATE_OFFICETRANSACTION_CHECKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_OFFICETRANSACTION_CHECKER", allowedPermissions);
resourceId = this.writePlatformService.externalBranchMoneyTransfer(command);
commandSourceResult.updateResourceId(resourceId);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
throw new UnsupportedCommandException(commandSourceResult.commandName());
} else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
return commandSourceResult;
}
}
@@ -1,95 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.mifosplatform.useradministration.service.PermissionWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
@Service
public class PermissionsCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final FromJsonHelper fromApiJsonHelper;
private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer;
private final PermissionWritePlatformService permissionWritePlatformService;
@Autowired
public PermissionsCommandHandler(final PlatformSecurityContext context,
final FromJsonHelper fromApiJsonHelper,
final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer,
final PermissionWritePlatformService permissionWritePlatformService) {
this.context = context;
this.fromApiJsonHelper = fromApiJsonHelper;
this.toApiJsonSerializer = toApiJsonSerializer;
this.permissionWritePlatformService = permissionWritePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSource.json());
final JsonCommand command = JsonCommand.from(commandSource.json(), parsedCommand, this.fromApiJsonHelper);
CommandSource commandSourceResult = commandSource.copy();
if (commandSource.isUpdate()) {
try {
EntityIdentifier result = this.permissionWritePlatformService.updateMakerCheckerPermissions(command);
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else {
throw new UnsupportedCommandException(commandSource.commandName());
}
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSourceResult.json());
final JsonCommand command = JsonCommand.withMakerCheckerApproval(commandSourceResult.json(), parsedCommand, this.fromApiJsonHelper);
if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER",
"UPDATE_PERMISSION_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_PERMISSION_CHECKER", allowedPermissions);
EntityIdentifier result = this.permissionWritePlatformService.updateMakerCheckerPermissions(command);
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else {
throw new UnsupportedCommandException(commandSourceResult.commandName());
}
return commandSourceResult;
}
}
@@ -1,129 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.mifosplatform.useradministration.service.RoleWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
@Service
public class RoleCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final RoleWritePlatformService writePlatformService;
private final FromJsonHelper fromApiJsonHelper;
private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer;
@Autowired
public RoleCommandHandler(final PlatformSecurityContext context,
final FromJsonHelper fromApiJsonHelper,
final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer,
final RoleWritePlatformService writePlatformService) {
this.context = context;
this.fromApiJsonHelper = fromApiJsonHelper;
this.toApiJsonSerializer = toApiJsonSerializer;
this.writePlatformService = writePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
CommandSource commandSourceResult = commandSource.copy();
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSource.json());
final JsonCommand command = JsonCommand.from(commandSource.json(), parsedCommand, this.fromApiJsonHelper);
final Long resourceId = commandSource.resourceId();
if (commandSource.isCreate()) {
try {
final Long newResourceId = this.writePlatformService.createRole(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(newResourceId);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
final EntityIdentifier result = this.writePlatformService.updateRole(resourceId, command);
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdateRolePermissions()) {
try {
final EntityIdentifier result = this.writePlatformService.updateRolePermissions(resourceId, command);
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSourceResult.json());
final JsonCommand command = JsonCommand.withMakerCheckerApproval(commandSourceResult.json(), parsedCommand, this.fromApiJsonHelper);
final Long resourceId = commandSourceResult.resourceId();
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "CREATE_ROLE_CHECKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_ROLE_CHECKER", allowedPermissions);
final Long newResourceId = this.writePlatformService.createRole(command);
commandSourceResult.updateResourceId(newResourceId);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER", "UPDATE_ROLE_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_ROLE_CHECKER", allowedPermissions);
final EntityIdentifier result = this.writePlatformService.updateRole(resourceId, command);
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdateRolePermissions()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER",
"PERMISSIONS_ROLE_CHECKER");
context.authenticatedUser().validateHasPermissionTo("PERMISSIONS_ROLE_CHECKER", allowedPermissions);
EntityIdentifier result = this.writePlatformService.updateRolePermissions(resourceId, command);
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
return commandSourceResult;
}
}
@@ -1,92 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.staff.command.StaffCommand;
import org.mifosplatform.organisation.staff.serialization.StaffCommandFromCommandJsonDeserializer;
import org.mifosplatform.organisation.staff.service.StaffWritePlatformService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class StaffCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final StaffWritePlatformService writePlatformService;
@Autowired
public StaffCommandHandler(final PlatformSecurityContext context,
final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final StaffWritePlatformService writePlatformService) {
this.context = context;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final Long resourceId = commandSource.resourceId();
final StaffCommand command = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, commandSource.json());
CommandSource commandSourceResult = commandSource.copy();
Long newResourceId = null;
if (commandSource.isCreate()) {
try {
newResourceId = this.writePlatformService.createStaff(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(newResourceId);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
this.writePlatformService.updateStaff(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
Long resourceId = commandSourceResult.resourceId();
final StaffCommand command = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"CREATE_STAFF_CHECKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_STAFF_CHECKER", allowedPermissions);
resourceId = this.writePlatformService.createStaff(command);
commandSourceResult.updateResourceId(resourceId);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"UPDATE_STAFF_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_STAFF_CHECKER", allowedPermissions);
resourceId = this.writePlatformService.updateStaff(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
return commandSourceResult;
}
}
@@ -1,131 +0,0 @@
package org.mifosplatform.commands.handler;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.mifosplatform.useradministration.service.AppUserWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
@Service
public class UserCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final FromJsonHelper fromApiJsonHelper;
private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer;
private final AppUserWritePlatformService writePlatformService;
@Autowired
public UserCommandHandler(final PlatformSecurityContext context, final FromJsonHelper fromApiJsonHelper,
final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer,
final AppUserWritePlatformService writePlatformService) {
this.context = context;
this.fromApiJsonHelper = fromApiJsonHelper;
this.toApiJsonSerializer = toApiJsonSerializer;
this.writePlatformService = writePlatformService;
}
@Override
public CommandSource handleCommandWithSupportForRollback(final CommandSource commandSource) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final Long resourceId = commandSource.resourceId();
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSource.json());
final JsonCommand command = JsonCommand.from(commandSource.json(), parsedCommand, this.fromApiJsonHelper);
CommandSource commandSourceResult = commandSource.copy();
if (commandSource.isCreate()) {
try {
final Long newResourceId = this.writePlatformService.createUser(command);
commandSourceResult.markAsChecked(maker, asToday);
commandSourceResult.updateResourceId(newResourceId);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isUpdate()) {
try {
EntityIdentifier result = null;
if (maker.hasIdOf(resourceId)) {
result = this.writePlatformService.updateUsersOwnAccountDetails(resourceId, command);
} else {
result = this.writePlatformService.updateUser(resourceId, command);
}
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) {
try {
this.writePlatformService.deleteUser(resourceId, command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
}
return commandSourceResult;
}
@Override
public CommandSource handleCommandForCheckerApproval(final CommandSource commandSourceResult) {
final AppUser checker = context.authenticatedUser();
final Long resourceId = commandSourceResult.resourceId();
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSourceResult.json());
final JsonCommand command = JsonCommand.withMakerCheckerApproval(commandSourceResult.json(), parsedCommand, this.fromApiJsonHelper);
if (commandSourceResult.isUserResource()) {
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER",
"CREATE_USER_MAKER");
context.authenticatedUser().validateHasPermissionTo("CREATE_USER_MAKER", allowedPermissions);
final Long newResourceId = this.writePlatformService.createUser(command);
commandSourceResult.updateResourceId(newResourceId);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isUpdate()) {
EntityIdentifier result = null;
if (checker.hasIdOf(resourceId)) {
result = this.writePlatformService.updateUsersOwnAccountDetails(resourceId, command);
} else {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER",
"UPDATE_USER_MAKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_USER_MAKER", allowedPermissions);
result = this.writePlatformService.updateUser(resourceId, command);
}
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "USER_ADMINISTRATION_SUPER_USER",
"DELETE_USER_MAKER");
context.authenticatedUser().validateHasPermissionTo("DELETE_USER_MAKER", allowedPermissions);
this.writePlatformService.deleteUser(resourceId, command);
commandSourceResult.markAsChecked(checker, new LocalDate());
}
}
return commandSourceResult;
}
}
@@ -0,0 +1,13 @@
package org.mifosplatform.commands.service;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface CommandProcessingService {
EntityIdentifier processAndLogCommand(CommandWrapper wrapper, JsonCommand command, boolean isApprovedByChecker);
EntityIdentifier logCommand(CommandWrapper wrapper, JsonCommand command);
}
@@ -4,7 +4,10 @@ import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface PortfolioCommandSourceWritePlatformService {
EntityIdentifier logCommandSource(String apiOperation, String resource, Long resourceId, String commandSerializedAsJson);
EntityIdentifier logCommandSource(String taskPermissionName, String apiOperation, String resource, Long resourceId, String subResource,
Long subRescourceId, String json);
EntityIdentifier logCommandSource(String taskPermissionName, String apiOperation, String resource, Long resourceId, String json);
EntityIdentifier approveEntry(Long id);
@@ -1,62 +1,107 @@
package org.mifosplatform.commands.service;
import org.joda.time.LocalDate;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.domain.CommandSourceRepository;
import org.mifosplatform.commands.handler.CommandSourceHandlerDelegator;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.useradministration.domain.AppUser;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.google.gson.JsonElement;
@Service
public class PortfolioCommandSourceWritePlatformServiceImpl implements PortfolioCommandSourceWritePlatformService {
private final PlatformSecurityContext context;
private final CommandSourceRepository commandSourceRepository;
private final CommandSourceHandlerDelegator commandSourceHandlerDelegator;
private final FromJsonHelper fromApiJsonHelper;
private final CommandProcessingService processAndLogCommandService;
@Autowired
public PortfolioCommandSourceWritePlatformServiceImpl(final PlatformSecurityContext context,
final CommandSourceRepository makerCheckerRepository, final CommandSourceHandlerDelegator commandSourceHandlerDelegator) {
final CommandSourceRepository commandSourceRepository, final FromJsonHelper fromApiJsonHelper,
final CommandProcessingService processAndLogCommandService) {
this.context = context;
this.commandSourceRepository = makerCheckerRepository;
this.commandSourceHandlerDelegator = commandSourceHandlerDelegator;
this.commandSourceRepository = commandSourceRepository;
this.fromApiJsonHelper = fromApiJsonHelper;
this.processAndLogCommandService = processAndLogCommandService;
}
// NOT TRANSACTIONAL BY DESIGN FOR NOW
@Override
public EntityIdentifier logCommandSource(final String apiOperation, final String resource, final Long resourceId,
final String commandSerializedAsJson) {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final CommandSource commandSourceInput = CommandSource.createdBy(apiOperation, resource, resourceId, commandSerializedAsJson, maker, asToday);
final CommandSource commandSourceResult = this.commandSourceHandlerDelegator.handleCommandWithSupportForRollback(commandSourceInput);
public EntityIdentifier logCommandSource(final String taskPermissionName, final String apiOperation, final String resource,
final Long resourceId, final String subResource, final Long subRescourceId, final String json) {
if (commandSourceResult.hasJson()) {
commandSourceRepository.save(commandSourceResult);
context.authenticatedUser().validateHasPermissionTo(taskPermissionName);
final CommandWrapper wrapper = CommandWrapper.wrap(taskPermissionName, apiOperation, resource, resourceId, subResource, subRescourceId);
EntityIdentifier result = null;
try {
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, resourceId, subRescourceId);
final boolean isApprovedByChecker = false;
result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
final String jsonToUse = StringUtils.defaultIfEmpty(e.getJsonOfChangesOnly(), json);
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonToUse);
final JsonCommand command = JsonCommand.from(jsonToUse, parsedCommand, this.fromApiJsonHelper, resourceId, subRescourceId);
result = this.processAndLogCommandService.logCommand(wrapper, command);
}
return EntityIdentifier.makerChecker(commandSourceResult.resourceId(), commandSourceResult.getId());
return result;
}
@Transactional
@Override
public EntityIdentifier approveEntry(final Long id) {
public EntityIdentifier logCommandSource(final String taskPermissionName, final String apiOperation, final String resource,
final Long resourceId, final String json) {
context.authenticatedUser();
context.authenticatedUser().validateHasPermissionTo(taskPermissionName);
final CommandSource commandSourceInput = this.commandSourceRepository.findOne(id);
final CommandSource commandSourceResult = this.commandSourceHandlerDelegator.handleCommandForCheckerApproval(commandSourceInput);
if (commandSourceResult.hasJson()) {
commandSourceRepository.save(commandSourceResult);
final CommandWrapper wrapper = CommandWrapper.wrap(taskPermissionName, apiOperation, resource, resourceId);
EntityIdentifier result = null;
try {
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json);
final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, resourceId, null);
final boolean isApprovedByChecker = false;
result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
final String jsonToUse = StringUtils.defaultIfEmpty(e.getJsonOfChangesOnly(), json);
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonToUse);
final JsonCommand command = JsonCommand.from(jsonToUse, parsedCommand, this.fromApiJsonHelper, resourceId, null);
result = this.processAndLogCommandService.logCommand(wrapper, command);
}
return EntityIdentifier.makerChecker(commandSourceResult.resourceId(), commandSourceResult.getId());
return result;
}
@Override
public EntityIdentifier approveEntry(final Long commandId) {
final CommandSource commandSourceInput = this.commandSourceRepository.findOne(commandId);
context.authenticatedUser().validateHasCheckerPermissionTo(commandSourceInput.getPermissionCode());
final CommandWrapper wrapper = CommandWrapper.fromExistingCommand(commandId, commandSourceInput.getPermissionCode(), commandSourceInput.operation(),
commandSourceInput.resourceName(), commandSourceInput.resourceId(), commandSourceInput.getSubResource(), commandSourceInput.getSubResourceId());
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSourceInput.json());
final JsonCommand command = JsonCommand.fromExistingCommand(commandId, commandSourceInput.json(), parsedCommand, this.fromApiJsonHelper, commandSourceInput.resourceId(), commandSourceInput.getSubResourceId());
final boolean makerCheckerApproval = true;
return this.processAndLogCommandService.processAndLogCommand(wrapper, command, makerCheckerApproval);
}
@Transactional
@@ -0,0 +1,218 @@
package org.mifosplatform.commands.service;
import java.util.Map;
import org.joda.time.DateTime;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.domain.CommandSourceRepository;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.service.ConfigurationDomainService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class SynchronousCommandProcessingService implements CommandProcessingService {
private PlatformSecurityContext context;
private final ApplicationContext applicationContext;
private final ToApiJsonSerializer<Map<String, Object>> toApiJsonSerializer;
private CommandSourceRepository commandSourceRepository;
private final ConfigurationDomainService configurationDomainService;
@Autowired
public SynchronousCommandProcessingService(final PlatformSecurityContext context, final ApplicationContext applicationContext,
final ToApiJsonSerializer<Map<String, Object>> toApiJsonSerializer, final CommandSourceRepository commandSourceRepository,
final ConfigurationDomainService configurationDomainService) {
this.context = context;
this.context = context;
this.applicationContext = applicationContext;
this.toApiJsonSerializer = toApiJsonSerializer;
this.commandSourceRepository = commandSourceRepository;
this.commandSourceRepository = commandSourceRepository;
this.configurationDomainService = configurationDomainService;
}
@Transactional
@Override
public EntityIdentifier processAndLogCommand(final CommandWrapper wrapper, final JsonCommand command, final boolean isApprovedByChecker) {
final NewCommandSourceHandler handler = findCommandHandler(wrapper);
final EntityIdentifier result = handler.processCommand(command);
final AppUser maker = context.authenticatedUser();
CommandSource commandSourceResult = null;
if (command.commandId() != null) {
commandSourceResult = this.commandSourceRepository.findOne(command.commandId());
commandSourceResult.markAsChecked(maker, DateTime.now());
} else {
commandSourceResult = CommandSource.fullEntryFrom(wrapper, command, maker);
}
commandSourceResult.updateResourceId(result.resourceId());
commandSourceResult.updateSubResourceId(result.subResourceId());
String changesOnlyJson = null;
if (result.hasChanges()) {
changesOnlyJson = this.toApiJsonSerializer.serializeResult(result.getChanges());
commandSourceResult.updateJsonTo(changesOnlyJson);
}
if (!result.hasChanges() && wrapper.isUpdate()) {
commandSourceResult.updateJsonTo(null);
}
if (commandSourceResult.hasJson()) {
commandSourceRepository.save(commandSourceResult);
}
if (this.configurationDomainService.isMakerCheckerEnabledForTask(wrapper.taskPermissionName()) && !isApprovedByChecker) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(changesOnlyJson); }
return result;
}
@Transactional
@Override
public EntityIdentifier logCommand(final CommandWrapper wrapper, final JsonCommand command) {
final AppUser maker = context.authenticatedUser();
final CommandSource commandSourceResult = CommandSource.fullEntryFrom(wrapper, command, maker);
if (commandSourceResult.hasJson()) {
commandSourceRepository.save(commandSourceResult);
}
return EntityIdentifier.resourceResult(commandSourceResult.resourceId(), commandSourceResult.getId());
}
private NewCommandSourceHandler findCommandHandler(final CommandWrapper wrapper) {
NewCommandSourceHandler handler = null;
if (wrapper.isClientNoteResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createClientNoteCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateClientNoteCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isClientIdentifierResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createClientIdentifierCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateClientIdentifierCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = applicationContext.getBean("deleteClientIdentifierCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isClientResource() && !wrapper.isNotesSubResource() && !wrapper.isIdentifiersSubResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createClientCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateClientCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = applicationContext.getBean("deleteClientCommandHandler", NewCommandSourceHandler.class);
}
// end of client
} else if (wrapper.isUpdateRolePermissions()) {
handler = applicationContext.getBean("updateRolePermissionsCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isPermissionResource()) {
handler = applicationContext.getBean("updateMakerCheckerPermissionsCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isRoleResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createRoleCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateRoleCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isUserResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createUserCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateUserCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = applicationContext.getBean("deleteUserCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isStaffResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createStaffCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateStaffCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isCodeResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createCodeCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateCodeCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = applicationContext.getBean("deleteCodeCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isCurrencyResource()) {
handler = applicationContext.getBean("updateCurrencyCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isFundResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createFundCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateFundCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isOfficeResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createOfficeCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateOfficeCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isOfficeTransactionResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createOfficeTransactionCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isChargeDefinitionResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createChargeDefinitionCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateChargeDefinitionCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = applicationContext.getBean("deleteChargeDefinitionCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isLoanProductResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createLoanProductCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateLoanProductCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
return handler;
}
}
@@ -3,7 +3,6 @@ package org.mifosplatform.infrastructure.codes.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ws.rs.Consumes;
@@ -76,10 +75,7 @@ public class CodesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createCode(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "CREATE_CODE");
context.authenticatedUser().validateHasPermissionTo("CREATE_CODE", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "codes", null,
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CODE", "CREATE", "codes", null,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -103,10 +99,7 @@ public class CodesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateCode(@PathParam("codeId") final Long codeId, final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "UPDATE_CODE");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CODE", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "codes", codeId,
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CODE", "UPDATE", "codes", codeId,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -118,10 +111,8 @@ public class CodesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String deleteCodeApplication(@PathParam("codeId") final Long codeId) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "DELETE_CODE");
context.authenticatedUser().validateHasPermissionTo("DELETE_CODE", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "codes", codeId, "{}");
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CODE", "DELETE", "codes", codeId,
"{}");
return this.toApiJsonSerializer.serialize(result);
}
@@ -0,0 +1,27 @@
package org.mifosplatform.infrastructure.codes.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.codes.service.CodeWritePlatformService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CreateCodeCommandHandler implements NewCommandSourceHandler {
private final CodeWritePlatformService writePlatformService;
@Autowired
public CreateCodeCommandHandler(final CodeWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.writePlatformService.createCode(command);
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.infrastructure.codes.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.codes.service.CodeWritePlatformService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class DeleteCodeCommandHandler implements NewCommandSourceHandler {
private final CodeWritePlatformService writePlatformService;
@Autowired
public DeleteCodeCommandHandler(final CodeWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.writePlatformService.deleteCode(command.resourceId());
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.infrastructure.codes.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.codes.service.CodeWritePlatformService;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UpdateCodeCommandHandler implements NewCommandSourceHandler {
private final CodeWritePlatformService writePlatformService;
@Autowired
public UpdateCodeCommandHandler(final CodeWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.writePlatformService.updateCode(command.resourceId(), command);
}
}
@@ -6,9 +6,10 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.codes.command.CodeCommand;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.springframework.beans.factory.annotation.Autowired;
@@ -30,16 +31,16 @@ public final class CodeCommandFromApiJsonDeserializer extends AbstractFromApiJso
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public CodeCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, final CommandSerializer commandSerializerService) {
super(commandSerializerService);
public CodeCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
@Override
public CodeCommand commandFromApiJson(@SuppressWarnings("unused") final Long codeId, final String json) {
public CodeCommand commandFromApiJson(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final JsonElement element = fromApiJsonHelper.parse(json);
@@ -5,9 +5,9 @@ import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface CodeWritePlatformService {
Long createCode(JsonCommand command);
EntityIdentifier createCode(JsonCommand command);
EntityIdentifier updateCode(Long codeId, JsonCommand command);
EntityIdentifier deleteCode(Long codeId, JsonCommand command);
EntityIdentifier deleteCode(Long codeId);
}
@@ -12,8 +12,6 @@ import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.service.ConfigurationDomainService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -28,37 +26,32 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
private final PlatformSecurityContext context;
private final CodeRepository codeRepository;
private final ConfigurationDomainService configurationDomainService;
private final CodeCommandFromApiJsonDeserializer fromApiJsonDeserializer;
@Autowired
public CodeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final CodeRepository codeRepository,
final ConfigurationDomainService configurationDomainService,
final CodeCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
this.context = context;
this.codeRepository = codeRepository;
this.configurationDomainService = configurationDomainService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
}
@Transactional
@Override
public Long createCode(final JsonCommand command) {
public EntityIdentifier createCode(final JsonCommand command) {
try {
context.authenticatedUser();
final CodeCommand codeCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
codeCommand.validateForCreate();
final Code code = Code.fromJson(command);
this.codeRepository.save(code);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_CODE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return code.getId();
return EntityIdentifier.resourceResult(code.getId(), null);
} catch (DataIntegrityViolationException dve) {
return Long.valueOf(-1);
return EntityIdentifier.empty();
}
}
@@ -78,8 +71,6 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
this.codeRepository.save(code);
}
if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_CODE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return EntityIdentifier.withChanges(codeId, changes);
} catch (DataIntegrityViolationException dve) {
handleCodeDataIntegrityIssues(command, dve);
@@ -89,19 +80,15 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
@Transactional
@Override
public EntityIdentifier deleteCode(final Long codeId, final JsonCommand command) {
public EntityIdentifier deleteCode(final Long codeId) {
context.authenticatedUser();
final Code code = retrieveCodeBy(codeId);
if (code.isSystemDefined()) {
throw new SystemDefinedCodeCannotBeChangedException();
}
if (code.isSystemDefined()) { throw new SystemDefinedCodeCannotBeChangedException(); }
this.codeRepository.delete(code);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("DELETE_CODE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return new EntityIdentifier(code.getId());
}
@@ -110,17 +97,17 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
if (code == null) { throw new CodeNotFoundException(codeId.toString()); }
return code;
}
/*
* Guaranteed to throw an exception no matter what the data integrity issue
* is.
*/
private void handleCodeDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("code_name_org")) {
if (realCause.getMessage().contains("code_name_org")) {
final String name = command.stringValueOfParameterNamed("name");
throw new PlatformDataIntegrityException("error.msg.code.duplicate.name",
"A code with name '" + name + "' already exists"); }
throw new PlatformDataIntegrityException("error.msg.code.duplicate.name", "A code with name '" + name + "' already exists");
}
logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue",
@@ -1,9 +1,11 @@
package org.mifosplatform.infrastructure.core.api;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Map;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
@@ -23,36 +25,49 @@ import com.google.gson.reflect.TypeToken;
public final class JsonCommand {
private final String jsonCommand;
private final transient boolean approvedByChecker;
private final JsonElement parsedCommand;
private final FromJsonHelper fromApiJsonHelper;
private final Long commandId;
private final Long resourceId;
private final Long subResourceId;
public static JsonCommand from(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper) {
return new JsonCommand(jsonCommand, parsedCommand, fromApiJsonHelper, false);
public static JsonCommand from(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
final Long resourceId, final Long subResourceId) {
return new JsonCommand(null, jsonCommand, parsedCommand, fromApiJsonHelper, resourceId, subResourceId);
}
public static JsonCommand fromExistingCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
final Long resourceId, final Long subResourceId) {
return new JsonCommand(commandId, jsonCommand, parsedCommand, fromApiJsonHelper, resourceId, subResourceId);
}
public static JsonCommand withMakerCheckerApproval(final String jsonCommand, final JsonElement parsedCommand,
final FromJsonHelper fromApiJsonHelper) {
return new JsonCommand(jsonCommand, parsedCommand, fromApiJsonHelper, true);
}
public JsonCommand(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
final boolean approvedByChecker) {
public JsonCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper,
final Long resourceId, final Long subResourceId) {
this.commandId = commandId;
this.jsonCommand = jsonCommand;
this.parsedCommand = parsedCommand;
this.fromApiJsonHelper = fromApiJsonHelper;
this.approvedByChecker = approvedByChecker;
this.resourceId = resourceId;
this.subResourceId = subResourceId;
}
public String json() {
return this.jsonCommand;
}
public boolean isApprovedByChecker() {
return this.approvedByChecker;
public Long commandId() {
return this.commandId;
}
public Long resourceId() {
return this.resourceId;
}
public Long subResourceId() {
return this.subResourceId;
}
private boolean differenceExists(LocalDate baseValue, LocalDate workingCopyValue) {
private boolean differenceExists(final LocalDate baseValue, final LocalDate workingCopyValue) {
boolean differenceExists = false;
if (baseValue != null) {
@@ -82,7 +97,31 @@ public final class JsonCommand {
return !Arrays.equals(baseValue, workingCopyValue);
}
private boolean differenceExists(final Long baseValue, final Long workingCopyValue) {
private boolean differenceExists(final Number baseValue, final Number workingCopyValue) {
boolean differenceExists = false;
if (baseValue != null) {
differenceExists = !baseValue.equals(workingCopyValue);
} else {
differenceExists = workingCopyValue != null;
}
return differenceExists;
}
private boolean differenceExists(final BigDecimal baseValue, final BigDecimal workingCopyValue) {
boolean differenceExists = false;
if (baseValue != null) {
differenceExists = baseValue.compareTo(workingCopyValue) != 0;
} else {
differenceExists = workingCopyValue != null;
}
return differenceExists;
}
private boolean differenceExists(final Boolean baseValue, final Boolean workingCopyValue) {
boolean differenceExists = false;
if (baseValue != null) {
@@ -97,7 +136,7 @@ public final class JsonCommand {
private boolean parameterExists(final String parameterName) {
return this.fromApiJsonHelper.parameterExists(parameterName, parsedCommand);
}
public boolean hasParameter(final String parameterName) {
return parameterExists(parameterName);
}
@@ -160,6 +199,56 @@ public final class JsonCommand {
return StringUtils.defaultIfEmpty(value, "");
}
public boolean isChangeInBigDecimalParameterNamed(final String parameterName, final BigDecimal existingValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
final BigDecimal workingValue = bigDecimalValueOfParameterNamed(parameterName);
isChanged = differenceExists(existingValue, workingValue);
}
return isChanged;
}
public BigDecimal bigDecimalValueOfParameterNamed(final String parameterName) {
return this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(parameterName, parsedCommand);
}
public boolean isChangeInIntegerParameterNamed(final String parameterName, final Integer existingValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
final Integer workingValue = integerValueOfParameterNamed(parameterName);
isChanged = differenceExists(existingValue, workingValue);
}
return isChanged;
}
public Integer integerValueOfParameterNamed(final String parameterName) {
return this.fromApiJsonHelper.extractIntegerWithLocaleNamed(parameterName, parsedCommand);
}
public boolean isChangeInBooleanParameterNamed(final String parameterName, final Boolean existingValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
final Boolean workingValue = booleanObjectValueOfParameterNamed(parameterName);
isChanged = differenceExists(existingValue, workingValue);
}
return isChanged;
}
/**
* Returns {@link Boolean} that could possibly be null.
*/
public Boolean booleanObjectValueOfParameterNamed(final String parameterName) {
return this.fromApiJsonHelper.extractBooleanNamed(parameterName, parsedCommand);
}
/**
* always returns true or false
*/
public boolean booleanPrimitiveValueOfParameterNamed(final String parameterName) {
final Boolean value = this.fromApiJsonHelper.extractBooleanNamed(parameterName, parsedCommand);
return (Boolean) ObjectUtils.defaultIfNull(value, Boolean.FALSE);
}
public boolean isChangeInArrayParameterNamed(final String parameterName, final String[] existingValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
@@ -173,7 +262,8 @@ public final class JsonCommand {
return this.fromApiJsonHelper.extractArrayNamed(parameterName, parsedCommand);
}
public boolean isChangeInPasswordParameterNamed(final String parameterName, final String existingValue, final PlatformPasswordEncoder platformPasswordEncoder, final Long saltValue) {
public boolean isChangeInPasswordParameterNamed(final String parameterName, final String existingValue,
final PlatformPasswordEncoder platformPasswordEncoder, final Long saltValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
final String workingValue = passwordValueOfParameterNamed(parameterName, platformPasswordEncoder, saltValue);
@@ -181,10 +271,11 @@ public final class JsonCommand {
}
return isChanged;
}
public String passwordValueOfParameterNamed(final String parameterName, final PlatformPasswordEncoder platformPasswordEncoder, final Long saltValue) {
public String passwordValueOfParameterNamed(final String parameterName, final PlatformPasswordEncoder platformPasswordEncoder,
final Long saltValue) {
final String passwordPlainText = stringValueOfParameterNamed(parameterName);
final PlatformUser dummyPlatformUser = new BasicPasswordEncodablePlatformUser(saltValue, "", passwordPlainText);
return platformPasswordEncoder.encode(dummyPlatformUser);
}
@@ -134,7 +134,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
@Override
public ClientData convertInternalJsonFormatToClientDataChange(final Long resourceIdentifier, final String json) {
final ClientCommand command = this.clientCommandFromApiJsonDeserializer.commandFromApiJson(resourceIdentifier, json);
final ClientCommand command = this.clientCommandFromApiJsonDeserializer.commandFromApiJson(json);
return ClientData.dataChangeInstance(resourceIdentifier, command.getOfficeId(), command.getExternalId(), command.getFirstname(),
command.getLastname(), command.getClientOrBusinessName(), command.getJoiningDate());
@@ -5,55 +5,71 @@ import java.util.Map;
/**
* Represents the successful result of an REST API call.
*
* FIXME - KW - Rename to CommandProcessingResult - make immutable
*/
public class EntityIdentifier {
private Long entityId;
// TODO - Rename variable to commandId or taskId or something that shows
// this is the id of a command in a table/queue for processing.
@SuppressWarnings("unused")
private Long makerCheckerId;
private Long commandId;
private Long resourceId;
private Long subResourceId;
private Map<String, Object> changes;
public static EntityIdentifier makerChecker(final Long makerCheckerId) {
return new EntityIdentifier(null, makerCheckerId, null);
public static EntityIdentifier commandOnlyResult(final Long commandId) {
return new EntityIdentifier(null, null, commandId, null);
}
public static EntityIdentifier makerChecker(final Long resourceId, final Long makerCheckerId) {
return new EntityIdentifier(resourceId, makerCheckerId, null);
public static EntityIdentifier resourceResult(final Long resourceId, final Long commandId) {
return new EntityIdentifier(resourceId, null, commandId, null);
}
public static EntityIdentifier resourceResult(final Long resourceId, final Long commandId, final Map<String, Object> changes) {
return new EntityIdentifier(resourceId, null, commandId, changes);
}
public static EntityIdentifier subResourceResult(final Long resourceId, final Long subResourceId, final Long commandId) {
return new EntityIdentifier(resourceId, subResourceId, commandId, null);
}
public static EntityIdentifier subResourceResult(final Long resourceId, final Long subResourceId, final Long commandId, final Map<String, Object> changes) {
return new EntityIdentifier(resourceId, subResourceId, commandId, changes);
}
public static EntityIdentifier withChanges(final Long resourceId, final Map<String, Object> changes) {
return new EntityIdentifier(resourceId, null, changes);
}
public static EntityIdentifier empty() {
return new EntityIdentifier(Long.valueOf(-1), null, null);
return new EntityIdentifier(resourceId, null, null, changes);
}
public EntityIdentifier() {
public static EntityIdentifier empty() {
return new EntityIdentifier(Long.valueOf(-1), Long.valueOf(-1), Long.valueOf(-1), null);
}
protected EntityIdentifier() {
//
}
public EntityIdentifier(final Long entityId) {
this.entityId = entityId;
this.resourceId = entityId;
this.changes = new HashMap<String, Object>();
}
private EntityIdentifier(final Long entityId, final Long makerCheckerId, final Map<String, Object> changesOnly) {
this.entityId = entityId;
this.makerCheckerId = makerCheckerId;
private EntityIdentifier(final Long resourceId, final Long subResourceId, final Long commandId, final Map<String, Object> changesOnly) {
this.resourceId = resourceId;
this.subResourceId = subResourceId;
this.commandId = commandId;
this.changes = changesOnly;
}
public Long getEntityId() {
return this.entityId;
public Long commandId() {
return this.commandId;
}
public void setEntityId(final Long entityId) {
this.entityId = entityId;
public Long resourceId() {
return this.resourceId;
}
public Long subResourceId() {
return this.subResourceId;
}
public Map<String, Object> getChanges() {
@@ -63,4 +79,9 @@ public class EntityIdentifier {
}
return checkIfEmpty;
}
}
public boolean hasChanges() {
final boolean noChanges = this.changes == null || this.changes.isEmpty();
return !noChanges;
}
}
@@ -6,29 +6,6 @@ package org.mifosplatform.infrastructure.core.serialization;
*/
public abstract class AbstractFromApiJsonDeserializer<T> implements FromApiJsonDeserializer<T> {
private final CommandSerializer commandSerializerService;
public AbstractFromApiJsonDeserializer(final CommandSerializer commandSerializerService) {
this.commandSerializerService = commandSerializerService;
}
@Override
public T commandFromApiJson(final String json) {
return commandFromApiJson(null, json);
}
@Override
public abstract T commandFromApiJson(final Long resourceId, final String json);
@Override
public String serializedCommandJsonFromApiJson(final String json) {
final T command = commandFromApiJson(json);
return this.commandSerializerService.serializeCommandToJson(command);
}
@Override
public String serializedCommandJsonFromApiJson(final Long resourceId, final String json) {
final T command = commandFromApiJson(resourceId, json);
return this.commandSerializerService.serializeCommandToJson(command);
}
public abstract T commandFromApiJson(final String json);
}
@@ -0,0 +1,39 @@
package org.mifosplatform.infrastructure.core.serialization;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JodaDateTimeAdapter;
import org.mifosplatform.infrastructure.core.api.JodaLocalDateAdapter;
import org.springframework.stereotype.Component;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
* <p>A google gson implementation of {@link ExcludeNothingJsonSerializer} contract.</p>
*
* <p>It serializes all fields of any Java {@link Object} passed to it.</p>
*/
@Component
public final class CommandProcessingResultJsonSerializer {
private final Gson gson;
public CommandProcessingResultJsonSerializer() {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter());
builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter());
builder.serializeNulls();
this.gson = builder.create();
}
public String serialize(final Object result) {
String returnedResult = null;
final String serializedResult = this.gson.toJson(result);
if (!"null".equalsIgnoreCase(serializedResult)) {
returnedResult = serializedResult;
}
return returnedResult;
}
}
@@ -17,17 +17,25 @@ public final class DefaultToApiJsonSerializer<T> implements ToApiJsonSerializer<
private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOff;
private final ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOn;
private final CommandProcessingResultJsonSerializer commandProcessingResultSerializer;
private final GoogleGsonSerializerHelper helper;
@Autowired
public DefaultToApiJsonSerializer(
final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOff,
final ExcludeNothingWithPrettyPrintingOnJsonSerializerGoogleGson excludeNothingWithPrettyPrintingOn,
final CommandProcessingResultJsonSerializer commandProcessingResultSerializer,
final GoogleGsonSerializerHelper helper) {
this.excludeNothingWithPrettyPrintingOff = excludeNothingWithPrettyPrintingOff;
this.excludeNothingWithPrettyPrintingOn = excludeNothingWithPrettyPrintingOn;
this.commandProcessingResultSerializer = commandProcessingResultSerializer;
this.helper = helper;
}
@Override
public String serializeResult(final Object object) {
return this.commandProcessingResultSerializer.serialize(object);
}
@Override
public String serialize(final Object object) {
@@ -6,10 +6,4 @@ package org.mifosplatform.infrastructure.core.serialization;
public interface FromApiJsonDeserializer<T> {
T commandFromApiJson(final String json);
T commandFromApiJson(final Long resourceId, final String json);
String serializedCommandJsonFromApiJson(final String json);
String serializedCommandJsonFromApiJson(final Long resourceId, final String json);
}
@@ -86,6 +86,10 @@ public class FromJsonHelper {
public String[] extractArrayNamed(final String parameterName, final JsonElement element, final Set<String> parametersPassedInRequest) {
return helperDelegator.extractArrayNamed(parameterName, element, parametersPassedInRequest);
}
public Boolean extractBooleanNamed(final String parameterName, final JsonElement element) {
return helperDelegator.extractBooleanNamed(parameterName, element, new HashSet<String>());
}
public Boolean extractBooleanNamed(final String parameterName, final JsonElement element, final Set<String> parametersPassedInRequest) {
return helperDelegator.extractBooleanNamed(parameterName, element, parametersPassedInRequest);
@@ -105,6 +109,10 @@ public class FromJsonHelper {
return helperDelegator.extractLocalDateAsArrayNamed(parameterName, element, parametersPassedInRequest);
}
public BigDecimal extractBigDecimalWithLocaleNamed(final String parameterName, final JsonElement element) {
return helperDelegator.extractBigDecimalWithLocaleNamed(parameterName, element, new HashSet<String>());
}
public BigDecimal extractBigDecimalWithLocaleNamed(final String parameterName, final JsonElement element,
final Set<String> parametersPassedInRequest) {
return helperDelegator.extractBigDecimalWithLocaleNamed(parameterName, element, parametersPassedInRequest);
@@ -115,6 +123,10 @@ public class FromJsonHelper {
return helperDelegator.extractBigDecimalNamed(parameterName, element.getAsJsonObject(), Locale.US, parametersPassedInRequest);
}
public Integer extractIntegerWithLocaleNamed(final String parameterName, final JsonElement element) {
return helperDelegator.extractIntegerWithLocaleNamed(parameterName, element.getAsJsonObject(), new HashSet<String>());
}
public Integer extractIntegerWithLocaleNamed(final String parameterName, final JsonElement element,
final Set<String> parametersPassedInRequest) {
return helperDelegator.extractIntegerWithLocaleNamed(parameterName, element.getAsJsonObject(), parametersPassedInRequest);
@@ -6,6 +6,8 @@ import java.util.Set;
public interface ToApiJsonSerializer<T> {
String serialize(final Object object);
String serializeResult(final Object object);
String serialize(final ApiRequestJsonSerializationSettings settings, Collection<T> collection, Set<String> supportedResponseParameters);
@@ -77,8 +77,7 @@ public class DataTableApiResource {
this.readWriteNonCoreDataService.registerDatatable(datatable, apptable);
EntityIdentifier entityIdentifier = new EntityIdentifier();
return Response.ok().entity(entityIdentifier).build();
return Response.ok().entity(EntityIdentifier.empty()).build();
}
@POST
@@ -89,8 +88,7 @@ public class DataTableApiResource {
this.readWriteNonCoreDataService.deregisterDatatable(datatable);
EntityIdentifier entityIdentifier = new EntityIdentifier();
return Response.ok().entity(entityIdentifier).build();
return Response.ok().entity(EntityIdentifier.empty()).build();
}
@GET
@@ -2,7 +2,6 @@ package org.mifosplatform.organisation.monetary.api;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ws.rs.Consumes;
@@ -21,7 +20,6 @@ import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSeriali
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.data.ConfigurationData;
import org.mifosplatform.organisation.monetary.serialization.CurrencyCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.monetary.service.OrganisationCurrencyReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
@@ -38,20 +36,17 @@ public class CurrenciesApiResource {
private final PlatformSecurityContext context;
private final OrganisationCurrencyReadPlatformService readPlatformService;
private final CurrencyCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<ConfigurationData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired
public CurrenciesApiResource(final PlatformSecurityContext context, final OrganisationCurrencyReadPlatformService readPlatformService,
final CurrencyCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<ConfigurationData> toApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.readPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -75,13 +70,8 @@ public class CurrenciesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateCurrencies(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_CURRENCY");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CURRENCY", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "currencies", null,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CURRENCY", "UPDATE", "currencies",
null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -5,16 +5,18 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
/**
* Immutable command for updating allowed currencies.
*/
public class CurrencyCommand {
private String[] currencies;
private final transient boolean makerCheckerApproval;
public CurrencyCommand(final boolean makerCheckerApproval, final String[] currencies) {
this.makerCheckerApproval = makerCheckerApproval;
public CurrencyCommand(final String[] currencies) {
final List<String> listOfCurrencyCodes = new ArrayList<String>(Arrays.asList(currencies));
Collections.sort(listOfCurrencyCodes);
this.currencies = listOfCurrencyCodes.toArray(new String[listOfCurrencyCodes.size()]);
@@ -23,8 +25,14 @@ public class CurrencyCommand {
public String[] getCurrencies() {
return currencies;
}
public boolean isApprovedByChecker() {
return this.makerCheckerApproval;
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("currencies");
baseDataValidator.reset().parameter("currencies").value(this.currencies).arrayNotEmpty();
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.organisation.monetary.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.organisation.monetary.service.CurrencyWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UpdateCurrencyCommandHandler implements NewCommandSourceHandler {
private final CurrencyWritePlatformService writePlatformService;
@Autowired
public UpdateCurrencyCommandHandler(final CurrencyWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.writePlatformService.updateAllowedCurrencies(command);
}
}
@@ -6,13 +6,16 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
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.organisation.monetary.command.CurrencyCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
/**
@@ -20,7 +23,7 @@ import com.google.gson.reflect.TypeToken;
* 's.
*/
@Component
public final class CurrencyCommandFromApiJsonDeserializer implements FromApiJsonDeserializer<CurrencyCommand> {
public final class CurrencyCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<CurrencyCommand> {
/**
* The parameters supported for this command.
@@ -28,42 +31,22 @@ public final class CurrencyCommandFromApiJsonDeserializer implements FromApiJson
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("currencies"));
private final FromJsonHelper fromApiJsonHelper;
private final CurrencyCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final CommandSerializer commandSerializerService;
@Autowired
public CurrencyCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper,
final CurrencyCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final CommandSerializer commandSerializerService) {
public CurrencyCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.commandSerializerService = commandSerializerService;
}
@Override
public CurrencyCommand commandFromApiJson(final String json) {
return commandFromApiJson(null, json);
}
@Override
public CurrencyCommand commandFromApiJson(final Long resourceId, final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
return this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId, json);
}
@Override
public String serializedCommandJsonFromApiJson(final String json) {
final CurrencyCommand command = commandFromApiJson(json);
return this.commandSerializerService.serializeCommandToJson(command);
}
@Override
public String serializedCommandJsonFromApiJson(final Long roleId, final String json) {
final CurrencyCommand command = commandFromApiJson(roleId, json);
return this.commandSerializerService.serializeCommandToJson(command);
final JsonElement element = fromApiJsonHelper.parse(json);
final String[] currencies = fromApiJsonHelper.extractArrayNamed("currencies", element);
return new CurrencyCommand(currencies);
}
}
@@ -1,47 +0,0 @@
package org.mifosplatform.organisation.monetary.serialization;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.FromCommandJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.monetary.command.CurrencyCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
@Component
public final class CurrencyCommandFromCommandJsonDeserializer implements FromCommandJsonDeserializer<CurrencyCommand> {
private final FromJsonHelper fromJsonHelper;
@Autowired
public CurrencyCommandFromCommandJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromJsonHelper = fromApiJsonHelper;
}
@Override
public CurrencyCommand commandFromCommandJson(final String commandAsJson) {
return commandFromCommandJson(null, commandAsJson);
}
@Override
public CurrencyCommand commandFromCommandJson(final Long resourceId, final String commandAsJson) {
return commandFromCommandJson(resourceId, commandAsJson, false);
}
@Override
public CurrencyCommand commandFromCommandJson(@SuppressWarnings("unused") final Long resourceId, final String commandAsJson,
final boolean makerCheckerApproval) {
if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); }
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromJsonHelper.parse(commandAsJson);
final String[] currencies = fromJsonHelper.extractArrayNamed("currencies", element, parametersPassedInRequest);
return new CurrencyCommand(makerCheckerApproval, currencies);
}
}
@@ -1,5 +1,6 @@
package org.mifosplatform.organisation.monetary.service;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.useradministration.domain.Permission;
import org.mifosplatform.useradministration.domain.PermissionRepository;
import org.mifosplatform.useradministration.exception.PermissionNotFoundException;
@@ -10,7 +11,7 @@ import org.springframework.stereotype.Service;
public class ConfigurationDomainServiceJpa implements ConfigurationDomainService {
private final PermissionRepository permissionRepository;
/*
* hard code to false to disable maker checker across the board.
*/
@@ -20,14 +21,14 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
public ConfigurationDomainServiceJpa(final PermissionRepository permissionRepository) {
this.permissionRepository = permissionRepository;
}
@Override
public boolean isMakerCheckerEnabledForTask(final String taskPermissionCode) {
if (StringUtils.isBlank(taskPermissionCode)) { throw new PermissionNotFoundException(taskPermissionCode); }
final Permission thisTask = this.permissionRepository.findOneByCode(taskPermissionCode);
if (thisTask == null) {
throw new PermissionNotFoundException(taskPermissionCode);
}
if (thisTask == null) { throw new PermissionNotFoundException(taskPermissionCode); }
return thisTask.hasMakerCheckerEnabled() && this.makerCheckerGloablConfigurationEnabled;
}
}
@@ -1,9 +1,10 @@
package org.mifosplatform.organisation.monetary.service;
import org.mifosplatform.organisation.monetary.command.CurrencyCommand;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface CurrencyWritePlatformService {
void updateAllowedCurrencies(CurrencyCommand command);
EntityIdentifier updateAllowedCurrencies(JsonCommand command);
}
@@ -2,19 +2,21 @@ package org.mifosplatform.organisation.monetary.service;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.command.CurrencyCommand;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepository;
import org.mifosplatform.organisation.monetary.exception.CurrencyNotFoundException;
import org.mifosplatform.organisation.monetary.serialization.CurrencyCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.office.domain.OrganisationCurrency;
import org.mifosplatform.organisation.office.domain.OrganisationCurrencyRepository;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -25,54 +27,48 @@ public class CurrencyWritePlatformServiceJpaRepositoryImpl implements CurrencyWr
private final PlatformSecurityContext context;
private final ApplicationCurrencyRepository applicationCurrencyRepository;
private final OrganisationCurrencyRepository organisationCurrencyRepository;
private final ConfigurationDomainService configurationDomainService;
private final CurrencyCommandFromApiJsonDeserializer fromApiJsonDeserializer;
@Autowired
public CurrencyWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final CurrencyCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final ApplicationCurrencyRepository applicationCurrencyRepository,
final OrganisationCurrencyRepository organisationCurrencyRepository, final ConfigurationDomainService configurationDomainService) {
final OrganisationCurrencyRepository organisationCurrencyRepository) {
this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.applicationCurrencyRepository = applicationCurrencyRepository;
this.organisationCurrencyRepository = organisationCurrencyRepository;
this.configurationDomainService = configurationDomainService;
}
@Transactional
@Override
public void updateAllowedCurrencies(final CurrencyCommand command) {
public EntityIdentifier updateAllowedCurrencies(final JsonCommand command) {
context.authenticatedUser();
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("configuration");
final CurrencyCommand currencyCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
currencyCommand.validateForUpdate();
baseDataValidator.reset().parameter("currencies").value(command.getCurrencies()).arrayNotEmpty();
final Map<String, Object> changes = new LinkedHashMap<String, Object>();
final List<String> allowedCurrencyCodes = new ArrayList<String>();
final Set<OrganisationCurrency> allowedCurrencies = new HashSet<OrganisationCurrency>();
for (final String currencyCode : currencyCommand.getCurrencies()) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
final ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(currencyCode);
if (currency == null) { throw new CurrencyNotFoundException(currencyCode); }
Set<OrganisationCurrency> allowedCurrencies = new HashSet<OrganisationCurrency>();
final OrganisationCurrency allowedCurrency = new OrganisationCurrency(currency.getCode(), currency.getName(),
currency.getDecimalPlaces(), currency.getNameCode(), currency.getDisplaySymbol());
for (String currencyCode : command.getCurrencies()) {
ApplicationCurrency currency = this.applicationCurrencyRepository.findOneByCode(currencyCode);
if (currency == null) {
baseDataValidator.reset().parameter("currencies").value(command.getCurrencies())
.inValidValue("currency.code", currencyCode);
} else {
OrganisationCurrency allowedCurrency = new OrganisationCurrency(currency.getCode(), currency.getName(),
currency.getDecimalPlaces(), currency.getNameCode(), currency.getDisplaySymbol());
allowedCurrencies.add(allowedCurrency);
}
allowedCurrencyCodes.add(currencyCode);
allowedCurrencies.add(allowedCurrency);
}
changes.put("currencies", allowedCurrencyCodes.toArray(new String[allowedCurrencyCodes.size()]));
this.organisationCurrencyRepository.deleteAll();
this.organisationCurrencyRepository.save(allowedCurrencies);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_CURRENCY") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
return EntityIdentifier.withChanges(null, changes);
}
}
@@ -3,7 +3,6 @@ package org.mifosplatform.organisation.office.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ws.rs.Consumes;
@@ -22,7 +21,6 @@ import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSeriali
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeTransactionData;
import org.mifosplatform.organisation.office.serialization.BranchMoneyTransferCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
@@ -38,24 +36,20 @@ public class OfficeTransactionsApiResource {
"allowedOffices", "currencyOptions"));
private final String resourceNameForReadPermissions = "OFFICE";
private final String resourceNameForPermissions = "OFFICETRANSACTION";
private final PlatformSecurityContext context;
private final OfficeReadPlatformService readPlatformService;
private final BranchMoneyTransferCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<OfficeTransactionData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired
public OfficeTransactionsApiResource(final PlatformSecurityContext context, final OfficeReadPlatformService readPlatformService,
final BranchMoneyTransferCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<OfficeTransactionData> toApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.readPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -93,19 +87,8 @@ public class OfficeTransactionsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String transferMoneyFrom(final String apiRequestBodyAsJson) {
// TODO - complete permissions for office transactions when more
// functionality add or it is replaced by simple accounting equivalent
// (JPW)
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"CREATE_OFFICETRANSACTION");
context.authenticatedUser().validateHasPermissionTo("CREATE_OFFICETRANSACTION", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "officetransactions", null,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_OFFICETRANSACTION", "CREATE",
"officetransactions", null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -27,7 +27,6 @@ import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSeria
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.office.data.OfficeLookup;
import org.mifosplatform.organisation.office.serialization.OfficeCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
@@ -48,19 +47,16 @@ public class OfficesApiResource {
private final PlatformSecurityContext context;
private final OfficeReadPlatformService readPlatformService;
private final OfficeCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<OfficeData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired
public OfficesApiResource(final PlatformSecurityContext context, final OfficeReadPlatformService readPlatformService,
final OfficeCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<OfficeData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.readPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -101,13 +97,8 @@ public class OfficesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createOffice(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_OFFICE");
context.authenticatedUser().validateHasPermissionTo("CREATE_OFFICE", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "offices", null,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_OFFICE", "CREATE", "offices",
null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -137,13 +128,8 @@ public class OfficesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateOffice(@PathParam("officeId") final Long officeId, final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_OFFICE");
context.authenticatedUser().validateHasPermissionTo("UPDATE_OFFICE", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "offices", officeId,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_OFFICE", "UPDATE", "offices",
officeId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -3,7 +3,6 @@ package org.mifosplatform.organisation.office.command;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
@@ -22,14 +21,8 @@ public class BranchMoneyTransferCommand {
private final BigDecimal transactionAmount;
private final String description;
private final transient Set<String> parametersPassedInRequest;
private final transient boolean makerCheckerApproval;
public BranchMoneyTransferCommand(final Set<String> parametersPassedInRequest, final boolean makerCheckerApproval,
final Long fromOfficeId, final Long toOfficeId, final LocalDate transactionDate, final String currencyCode,
final BigDecimal transactionAmount, final String description) {
this.parametersPassedInRequest = parametersPassedInRequest;
this.makerCheckerApproval = makerCheckerApproval;
public BranchMoneyTransferCommand(final Long fromOfficeId, final Long toOfficeId, final LocalDate transactionDate,
final String currencyCode, final BigDecimal transactionAmount, final String description) {
this.fromOfficeId = fromOfficeId;
this.toOfficeId = toOfficeId;
this.transactionDate = transactionDate;
@@ -62,14 +55,6 @@ public class BranchMoneyTransferCommand {
return description;
}
public boolean isFromOfficeIdChanged() {
return this.parametersPassedInRequest.contains("fromOfficeId");
}
public boolean isApprovedByChecker() {
return this.makerCheckerApproval;
}
public void validateBranchTransfer() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -2,7 +2,6 @@ package org.mifosplatform.organisation.office.command;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
@@ -14,31 +13,18 @@ import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidation
*/
public class OfficeCommand {
private final String name;
private final String externalId;
private final LocalDate openingDate;
private final Long parentId;
private final transient Set<String> modifiedParameters;
private final transient boolean makerCheckerApproval;
private final transient Long id;
public OfficeCommand(final Set<String> modifiedParameters, final boolean makerCheckerApproval, final Long id, final String officeName,
final String externalId, final Long parentId, final LocalDate openingDate) {
this.modifiedParameters = modifiedParameters;
this.makerCheckerApproval = makerCheckerApproval;
this.id = id;
public OfficeCommand(final String officeName, final String externalId, final Long parentId, final LocalDate openingDate) {
this.name = officeName;
this.externalId = externalId;
this.parentId = parentId;
this.openingDate = openingDate;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
@@ -55,26 +41,6 @@ public class OfficeCommand {
return parentId;
}
public boolean isNameChanged() {
return this.modifiedParameters.contains("name");
}
public boolean isExternalIdChanged() {
return this.modifiedParameters.contains("externalId");
}
public boolean isOpeningDateChanged() {
return this.modifiedParameters.contains("openingDate");
}
public boolean isParentChanged() {
return this.modifiedParameters.contains("parentId");
}
public boolean isApprovedByChecker() {
return this.makerCheckerApproval;
}
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -94,7 +60,6 @@ public class OfficeCommand {
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("office");
baseDataValidator.reset().parameter("id").value(this.id).notNull();
baseDataValidator.reset().parameter("name").value(this.name).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("openingDate").value(this.openingDate).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("externalId").value(this.externalId).ignoreIfNull().notExceedingLengthOf(100);
@@ -103,6 +68,6 @@ public class OfficeCommand {
baseDataValidator.reset().anyOfNotNull(this.name, this.openingDate, this.externalId, this.parentId);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -1,8 +1,10 @@
package org.mifosplatform.organisation.office.domain;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -17,17 +19,15 @@ import javax.persistence.UniqueConstraint;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.organisation.office.command.OfficeCommand;
import org.mifosplatform.organisation.office.exception.CannotUpdateOfficeWithParentOfficeSameAsSelf;
import org.mifosplatform.organisation.office.exception.RootOfficeParentCannotBeUpdated;
import org.mifosplatform.useradministration.domain.AppUser;
@Entity
@Table(name = "m_office", uniqueConstraints={
@UniqueConstraint(columnNames = {"name"}, name="name_org"),
@UniqueConstraint(columnNames = {"external_id"}, name="externalid_org")
})
@Table(name = "m_office", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "name_org"),
@UniqueConstraint(columnNames = { "external_id" }, name = "externalid_org") })
public class Office extends AbstractAuditableCustom<AppUser, Long> {
@OneToMany(fetch = FetchType.EAGER)
@@ -36,30 +36,32 @@ public class Office extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Office parent;
private Office parent;
@Column(name = "name", nullable = false, length=100)
private String name;
@Column(name = "hierarchy", nullable = false, length=50)
private String hierarchy;
@Column(name = "name", nullable = false, length = 100)
private String name;
@SuppressWarnings("unused")
@Column(name = "opening_date", nullable = false)
@Column(name = "hierarchy", nullable = false, length = 50)
private String hierarchy;
@Column(name = "opening_date", nullable = false)
@Temporal(TemporalType.DATE)
private Date openingDate;
private Date openingDate;
@SuppressWarnings("unused")
@Column(name = "external_id", length=100)
private String externalId;
@Column(name = "external_id", length = 100)
private String externalId;
public static Office headOffice(final String name, final LocalDate openingDate, final String externalId) {
return new Office(null, name, openingDate, externalId);
}
public static Office createNew(final Office parent, final String name, final LocalDate openingDate, final String externalId) {
return new Office(parent, name, openingDate, externalId);
}
public static Office fromJson(final Office parentOffice, final JsonCommand command) {
final String name = command.stringValueOfParameterNamed("name");
final LocalDate openingDate = command.localDateValueOfParameterNamed("openingDate");
final String externalId = command.stringValueOfParameterNamed("externalId");
return new Office(parentOffice, name, openingDate, externalId);
}
protected Office() {
this.openingDate = null;
@@ -73,113 +75,139 @@ public class Office extends AbstractAuditableCustom<AppUser, Long> {
this.openingDate = openingDate.toDateMidnight().toDate();
if (parent != null) {
this.parent.addChild(this);
}
if (StringUtils.isNotBlank(name)) {
this.name = name.trim();
} else {
this.name = null;
}
if (StringUtils.isNotBlank(externalId)) {
this.externalId = externalId.trim();
} else {
this.externalId = null;
}
if (StringUtils.isNotBlank(name)) {
this.name = name.trim();
} else {
this.name = null;
}
if (StringUtils.isNotBlank(externalId)) {
this.externalId = externalId.trim();
} else {
this.externalId = null;
}
}
private void addChild(final Office office) {
private void addChild(final Office office) {
this.children.add(office);
}
public void update(final OfficeCommand command) {
if (command.isNameChanged()) {
this.name = StringUtils.defaultIfEmpty(command.getName(), null);
}
if (command.isExternalIdChanged()) {
this.externalId = StringUtils.defaultIfEmpty(command.getExternalId(), null);
}
if (command.isOpeningDateChanged()) {
if (command.getOpeningDate() != null) {
this.openingDate = command.getOpeningDate().toDate();
} else {
this.openingDate = null;
}
}
}
public void update(final Office newParent) {
if (this.parent == null) {
throw new RootOfficeParentCannotBeUpdated();
}
if (this.identifiedBy(newParent.getId())) {
throw new CannotUpdateOfficeWithParentOfficeSameAsSelf(this.getId(), newParent.getId());
}
this.parent = newParent;
generateHierarchy();
}
public boolean identifiedBy(final Long id) {
return getId().equals(id);
}
public Map<String, Object> update(final JsonCommand command) {
public void generateHierarchy() {
if (parent != null) {
this.hierarchy = this.parent.hierarchyOf(this.getId());
} else {
this.hierarchy = ".";
}
}
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7);
private String hierarchyOf(Long id) {
return this.hierarchy + id.toString() + ".";
}
public String getName() {
return this.name;
final String dateFormatAsInput = command.dateFormat();
final String localeAsInput = command.locale();
final String parentIdParamName = "parentId";
if (command.isChangeInLongParameterNamed(parentIdParamName, this.parent.getId())) {
final Long newValue = command.longValueOfParameterNamed(parentIdParamName);
actualChanges.put(parentIdParamName, newValue);
}
final String openingDateParamName = "openingDate";
if (command.isChangeInLocalDateParameterNamed(openingDateParamName, getOpeningLocalDate())) {
final String valueAsInput = command.stringValueOfParameterNamed(openingDateParamName);
actualChanges.put(openingDateParamName, valueAsInput);
actualChanges.put("dateFormat", dateFormatAsInput);
actualChanges.put("locale", localeAsInput);
final LocalDate newValue = command.localDateValueOfParameterNamed(openingDateParamName);
this.openingDate = newValue.toDate();
}
final String nameParamName = "name";
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
final String newValue = command.stringValueOfParameterNamed(nameParamName);
actualChanges.put(nameParamName, newValue);
this.name = newValue;
}
final String externalIdParamName = "externalId";
if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) {
final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
actualChanges.put(externalIdParamName, newValue);
this.externalId = StringUtils.defaultIfEmpty(newValue, null);
}
return actualChanges;
}
public String getHierarchy() {
return hierarchy;
}
private LocalDate getOpeningLocalDate() {
LocalDate openingLocalDate = null;
if (this.openingDate != null) {
openingLocalDate = LocalDate.fromDateFields(this.openingDate);
}
return openingLocalDate;
}
public boolean hasParentOf(final Office office) {
boolean isParent = false;
if (this.parent != null) {
isParent = this.parent.equals(office);
}
return isParent;
}
public boolean doesNotHaveAnOfficeInHierarchyWithId(Long officeId) {
return !this.hasAnOfficeInHierarchyWithId(officeId);
}
private boolean hasAnOfficeInHierarchyWithId(Long officeId) {
boolean match = false;
if (identifiedBy(officeId)) {
match = true;
}
if (!match) {
for (Office child : this.children) {
boolean result = child.hasAnOfficeInHierarchyWithId(officeId);
if (result) {
match = result;
break;
}
}
}
return match;
}
public void update(final Office newParent) {
if (this.parent == null) { throw new RootOfficeParentCannotBeUpdated(); }
if (this.identifiedBy(newParent.getId())) { throw new CannotUpdateOfficeWithParentOfficeSameAsSelf(this.getId(), newParent.getId()); }
this.parent = newParent;
generateHierarchy();
}
public boolean identifiedBy(final Long id) {
return getId().equals(id);
}
public void generateHierarchy() {
if (parent != null) {
this.hierarchy = this.parent.hierarchyOf(this.getId());
} else {
this.hierarchy = ".";
}
}
private String hierarchyOf(Long id) {
return this.hierarchy + id.toString() + ".";
}
public String getName() {
return this.name;
}
public String getHierarchy() {
return hierarchy;
}
public boolean hasParentOf(final Office office) {
boolean isParent = false;
if (this.parent != null) {
isParent = this.parent.equals(office);
}
return isParent;
}
public boolean doesNotHaveAnOfficeInHierarchyWithId(Long officeId) {
return !this.hasAnOfficeInHierarchyWithId(officeId);
}
private boolean hasAnOfficeInHierarchyWithId(Long officeId) {
boolean match = false;
if (identifiedBy(officeId)) {
match = true;
}
if (!match) {
for (Office child : this.children) {
boolean result = child.hasAnOfficeInHierarchyWithId(officeId);
if (result) {
match = result;
break;
}
}
}
return match;
}
}
@@ -14,6 +14,7 @@ import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
@@ -23,53 +24,54 @@ import org.mifosplatform.useradministration.domain.AppUser;
@Table(name = "m_office_transaction")
public class OfficeTransaction extends AbstractAuditableCustom<AppUser, Long> {
@SuppressWarnings("unused")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "from_office_id")
private Office from;
@SuppressWarnings("unused")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "from_office_id")
private Office from;
@SuppressWarnings("unused")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "to_office_id")
private Office to;
@SuppressWarnings("unused")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "to_office_id")
private Office to;
@SuppressWarnings("unused")
@Column(name = "transaction_date", nullable = false)
@Temporal(TemporalType.DATE)
private Date transactionDate;
@SuppressWarnings("unused")
@Column(name = "transaction_date", nullable = false)
@Temporal(TemporalType.DATE)
private Date transactionDate;
@SuppressWarnings("unused")
@Embedded
private MonetaryCurrency currency;
@SuppressWarnings("unused")
@Embedded
private MonetaryCurrency currency;
@SuppressWarnings("unused")
@Column(name = "transaction_amount", scale = 6, precision = 19, nullable = false)
private BigDecimal transactionAmount;
@SuppressWarnings("unused")
@Column(name = "description", nullable=true, length=100)
private String description;
@SuppressWarnings("unused")
@Column(name = "transaction_amount", scale = 6, precision = 19, nullable = false)
private BigDecimal transactionAmount;
protected OfficeTransaction() {
this.transactionDate = null;
}
@SuppressWarnings("unused")
@Column(name = "description", nullable = true, length = 100)
private String description;
public static OfficeTransaction create(Office fromOffice, Office toOffice, LocalDate transactionLocalDate, Money amount, String description) {
public static OfficeTransaction fromJson(final Office fromOffice, final Office toOffice, final Money amount, final JsonCommand command) {
Date transactionDate = null;
if (transactionLocalDate != null) {
transactionDate = transactionLocalDate.toDate();
}
final LocalDate transactionLocalDate = command.localDateValueOfParameterNamed("transactionDate");
final String description = command.stringValueOfParameterNamed("description");
return new OfficeTransaction(fromOffice, toOffice, transactionDate, amount, description);
}
return new OfficeTransaction(fromOffice, toOffice, transactionLocalDate, amount, description);
}
private OfficeTransaction(final Office fromOffice,final Office toOffice, final Date transactionDate, final Money amount, String description) {
this.from = fromOffice;
this.to = toOffice;
this.transactionDate = transactionDate;
this.currency = amount.getCurrency();
this.transactionAmount = amount.getAmount();
this.description = description;
}
protected OfficeTransaction() {
this.transactionDate = null;
}
private OfficeTransaction(final Office fromOffice, final Office toOffice, final LocalDate transactionLocalDate, final Money amount,
final String description) {
this.from = fromOffice;
this.to = toOffice;
if (transactionLocalDate != null) {
this.transactionDate = transactionLocalDate.toDate();
}
this.currency = amount.getCurrency();
this.transactionAmount = amount.getAmount();
this.description = description;
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.organisation.office.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.organisation.office.service.OfficeWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CreateOfficeCommandHandler implements NewCommandSourceHandler {
private final OfficeWritePlatformService writePlatformService;
@Autowired
public CreateOfficeCommandHandler(final OfficeWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.writePlatformService.createOffice(command);
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.organisation.office.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.organisation.office.service.OfficeWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CreateOfficeTransactionCommandHandler implements NewCommandSourceHandler {
private final OfficeWritePlatformService writePlatformService;
@Autowired
public CreateOfficeTransactionCommandHandler(final OfficeWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.writePlatformService.externalBranchMoneyTransfer(command);
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.organisation.office.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.organisation.office.service.OfficeWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UpdateOfficeCommandHandler implements NewCommandSourceHandler {
private final OfficeWritePlatformService writePlatformService;
@Autowired
public UpdateOfficeCommandHandler(final OfficeWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.writePlatformService.updateOffice(command.resourceId(), command);
}
}
@@ -7,9 +7,10 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.office.command.BranchMoneyTransferCommand;
@@ -35,33 +36,28 @@ public final class BranchMoneyTransferCommandFromApiJsonDeserializer extends Abs
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public BranchMoneyTransferCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper,
final CommandSerializer commandSerializerService) {
super(commandSerializerService);
public BranchMoneyTransferCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
@Override
public BranchMoneyTransferCommand commandFromApiJson(@SuppressWarnings("unused") final Long resourceId, final String json) {
public BranchMoneyTransferCommand commandFromApiJson(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromApiJsonHelper.parse(json);
final Long fromOfficeId = fromApiJsonHelper.extractLongNamed("fromOfficeId", element, parametersPassedInRequest);
final Long toOfficeId = fromApiJsonHelper.extractLongNamed("toOfficeId", element, parametersPassedInRequest);
final LocalDate transactionLocalDate = fromApiJsonHelper.extractLocalDateNamed("transactionDate", element,
parametersPassedInRequest);
final Long fromOfficeId = fromApiJsonHelper.extractLongNamed("fromOfficeId", element);
final Long toOfficeId = fromApiJsonHelper.extractLongNamed("toOfficeId", element);
final LocalDate transactionLocalDate = fromApiJsonHelper.extractLocalDateNamed("transactionDate", element);
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element, parametersPassedInRequest);
final BigDecimal transactionAmountValue = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("transactionAmount", element,
parametersPassedInRequest);
final String description = fromApiJsonHelper.extractStringNamed("description", element, parametersPassedInRequest);
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element);
final BigDecimal transactionAmountValue = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("transactionAmount", element);
final String description = fromApiJsonHelper.extractStringNamed("description", element);
return new BranchMoneyTransferCommand(parametersPassedInRequest, false, fromOfficeId, toOfficeId, transactionLocalDate,
currencyCode, transactionAmountValue, description);
return new BranchMoneyTransferCommand(fromOfficeId, toOfficeId, transactionLocalDate, currencyCode, transactionAmountValue,
description);
}
}
@@ -1,49 +0,0 @@
package org.mifosplatform.organisation.office.serialization;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromCommandJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.office.command.BranchMoneyTransferCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
@Component
public final class BranchMoneyTransferCommandFromCommandJsonDeserializer extends
AbstractFromCommandJsonDeserializer<BranchMoneyTransferCommand> {
private final FromJsonHelper fromJsonHelper;
@Autowired
public BranchMoneyTransferCommandFromCommandJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromJsonHelper = fromApiJsonHelper;
}
@Override
public BranchMoneyTransferCommand commandFromCommandJson(@SuppressWarnings("unused") final Long resourceId, final String commandAsJson,
final boolean makerCheckerApproval) {
if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); }
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromJsonHelper.parse(commandAsJson);
final Long fromOfficeId = fromJsonHelper.extractLongNamed("fromOfficeId", element, parametersPassedInRequest);
final Long toOfficeId = fromJsonHelper.extractLongNamed("toOfficeId", element, parametersPassedInRequest);
final LocalDate transactionLocalDate = fromJsonHelper.extractLocalDateAsArrayNamed("transactionDate", element,
parametersPassedInRequest);
final String currencyCode = fromJsonHelper.extractStringNamed("currencyCode", element, parametersPassedInRequest);
final BigDecimal transactionAmountValue = fromJsonHelper.extractBigDecimalNamed("transactionAmount", element,
parametersPassedInRequest);
final String description = fromJsonHelper.extractStringNamed("description", element, parametersPassedInRequest);
return new BranchMoneyTransferCommand(parametersPassedInRequest, makerCheckerApproval, fromOfficeId, toOfficeId,
transactionLocalDate, currencyCode, transactionAmountValue, description);
}
}
@@ -6,9 +6,10 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.office.command.OfficeCommand;
@@ -28,31 +29,29 @@ public final class OfficeCommandFromApiJsonDeserializer extends AbstractFromApiJ
/**
* The parameters supported for this command.
*/
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("name", "parentId", "openingDate", "externalId", "locale", "dateFormat"));
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("name", "parentId", "openingDate", "externalId",
"locale", "dateFormat"));
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public OfficeCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, final CommandSerializer commandSerializerService) {
super(commandSerializerService);
public OfficeCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
@Override
public OfficeCommand commandFromApiJson(final Long officeId, final String json) {
public OfficeCommand commandFromApiJson(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromApiJsonHelper.parse(json);
final String name = fromApiJsonHelper.extractStringNamed("name", element, parametersPassedInRequest);
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element, parametersPassedInRequest);
final Long parentId = fromApiJsonHelper.extractLongNamed("parentId", element, parametersPassedInRequest);
final LocalDate openingLocalDate = fromApiJsonHelper.extractLocalDateNamed("openingDate", element, parametersPassedInRequest);
final String name = fromApiJsonHelper.extractStringNamed("name", element);
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
final Long parentId = fromApiJsonHelper.extractLongNamed("parentId", element);
final LocalDate openingLocalDate = fromApiJsonHelper.extractLocalDateNamed("openingDate", element);
return new OfficeCommand(parametersPassedInRequest, false, officeId, name, externalId, parentId, openingLocalDate);
return new OfficeCommand(name, externalId, parentId, openingLocalDate);
}
}
@@ -1,42 +0,0 @@
package org.mifosplatform.organisation.office.serialization;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromCommandJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.office.command.OfficeCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
@Component
public final class OfficeCommandFromCommandJsonDeserializer extends AbstractFromCommandJsonDeserializer<OfficeCommand> {
private final FromJsonHelper fromJsonHelper;
@Autowired
public OfficeCommandFromCommandJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromJsonHelper = fromApiJsonHelper;
}
@Override
public OfficeCommand commandFromCommandJson(final Long officeId, final String commandAsJson, final boolean makerCheckerApproval) {
if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); }
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromJsonHelper.parse(commandAsJson);
final String name = fromJsonHelper.extractStringNamed("name", element, parametersPassedInRequest);
final String externalId = fromJsonHelper.extractStringNamed("externalId", element, parametersPassedInRequest);
final Long parentId = fromJsonHelper.extractLongNamed("parentId", element, parametersPassedInRequest);
final LocalDate openingLocalDate = fromJsonHelper.extractLocalDateAsArrayNamed("openingDate", element, parametersPassedInRequest);
return new OfficeCommand(parametersPassedInRequest, makerCheckerApproval, officeId, name, externalId, parentId, openingLocalDate);
}
}
@@ -1,13 +1,13 @@
package org.mifosplatform.organisation.office.service;
import org.mifosplatform.organisation.office.command.BranchMoneyTransferCommand;
import org.mifosplatform.organisation.office.command.OfficeCommand;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface OfficeWritePlatformService {
Long createOffice(OfficeCommand command);
EntityIdentifier createOffice(JsonCommand command);
Long updateOffice(OfficeCommand command);
EntityIdentifier updateOffice(Long officeId, JsonCommand command);
Long externalBranchMoneyTransfer(BranchMoneyTransferCommand command);
EntityIdentifier externalBranchMoneyTransfer(JsonCommand command);
}
@@ -1,5 +1,9 @@
package org.mifosplatform.organisation.office.service;
import java.util.Map;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
@@ -8,7 +12,6 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyReposit
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.monetary.exception.CurrencyNotFoundException;
import org.mifosplatform.organisation.monetary.service.ConfigurationDomainService;
import org.mifosplatform.organisation.office.command.BranchMoneyTransferCommand;
import org.mifosplatform.organisation.office.command.OfficeCommand;
import org.mifosplatform.organisation.office.domain.Office;
@@ -16,7 +19,8 @@ import org.mifosplatform.organisation.office.domain.OfficeRepository;
import org.mifosplatform.organisation.office.domain.OfficeTransaction;
import org.mifosplatform.organisation.office.domain.OfficeTransactionRepository;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.organisation.office.serialization.BranchMoneyTransferCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.office.serialization.OfficeCommandFromApiJsonDeserializer;
import org.mifosplatform.useradministration.domain.AppUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,33 +35,39 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
private final static Logger logger = LoggerFactory.getLogger(OfficeWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
private final OfficeCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final BranchMoneyTransferCommandFromApiJsonDeserializer moneyTransferCommandFromApiJsonDeserializer;
private final OfficeRepository officeRepository;
private final OfficeTransactionRepository officeMonetaryTransferRepository;
private final ApplicationCurrencyRepository applicationCurrencyRepository;
private final ConfigurationDomainService configurationDomainService;
@Autowired
public OfficeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final OfficeRepository officeRepository,
final OfficeTransactionRepository officeMonetaryTransferRepository,
final ApplicationCurrencyRepository applicationCurrencyRepository, final ConfigurationDomainService configurationDomainService) {
public OfficeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final OfficeCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final BranchMoneyTransferCommandFromApiJsonDeserializer moneyTransferCommandFromApiJsonDeserializer,
final OfficeRepository officeRepository, final OfficeTransactionRepository officeMonetaryTransferRepository,
final ApplicationCurrencyRepository applicationCurrencyRepository) {
this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.moneyTransferCommandFromApiJsonDeserializer = moneyTransferCommandFromApiJsonDeserializer;
this.officeRepository = officeRepository;
this.officeMonetaryTransferRepository = officeMonetaryTransferRepository;
this.applicationCurrencyRepository = applicationCurrencyRepository;
this.configurationDomainService = configurationDomainService;
}
@Transactional
@Override
public Long createOffice(final OfficeCommand command) {
public EntityIdentifier createOffice(final JsonCommand command) {
try {
final AppUser currentUser = context.authenticatedUser();
command.validateForCreate();
final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId());
final OfficeCommand officeCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
officeCommand.validateForCreate();
final Office office = Office.createNew(parent, command.getName(), command.getOpeningDate(), command.getExternalId());
final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeCommand.getParentId());
final Office office = Office.fromJson(parent, command);
// pre save to generate id for use in office hierarchy
this.officeRepository.save(office);
@@ -66,90 +76,94 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
this.officeRepository.save(office);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_OFFICE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return office.getId();
return EntityIdentifier.resourceResult(office.getId(), null);
} catch (DataIntegrityViolationException dve) {
handleOfficeDataIntegrityIssues(command, dve);
return Long.valueOf(-1);
return EntityIdentifier.empty();
}
}
@Transactional
@Override
public Long updateOffice(final OfficeCommand command) {
public EntityIdentifier updateOffice(final Long officeId, final JsonCommand command) {
try {
final AppUser currentUser = context.authenticatedUser();
command.validateForUpdate();
final Office office = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getId());
final OfficeCommand officeCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
officeCommand.validateForUpdate();
office.update(command);
final Office office = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeId);
if (command.isParentChanged()) {
final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId());
final Map<String, Object> changes = office.update(command);
if (changes.containsKey("parentId")) {
final Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, officeCommand.getParentId());
office.update(parent);
}
this.officeRepository.save(office);
if (!changes.isEmpty()) {
this.officeRepository.saveAndFlush(office);
}
if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_OFFICE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return office.getId();
return EntityIdentifier.withChanges(office.getId(), changes);
} catch (DataIntegrityViolationException dve) {
handleOfficeDataIntegrityIssues(command, dve);
return Long.valueOf(-1);
return EntityIdentifier.empty();
}
}
@Transactional
@Override
public Long externalBranchMoneyTransfer(final BranchMoneyTransferCommand command) {
public EntityIdentifier externalBranchMoneyTransfer(final JsonCommand command) {
context.authenticatedUser();
command.validateBranchTransfer();
final BranchMoneyTransferCommand moneyTransferCommand = this.moneyTransferCommandFromApiJsonDeserializer.commandFromApiJson(command
.json());
moneyTransferCommand.validateBranchTransfer();
Office fromOffice = null;
if (command.getFromOfficeId() != null) {
fromOffice = this.officeRepository.findOne(command.getFromOfficeId());
if (moneyTransferCommand.getFromOfficeId() != null) {
fromOffice = this.officeRepository.findOne(moneyTransferCommand.getFromOfficeId());
}
Office toOffice = null;
if (command.getToOfficeId() != null) {
toOffice = this.officeRepository.findOne(command.getToOfficeId());
if (moneyTransferCommand.getToOfficeId() != null) {
toOffice = this.officeRepository.findOne(moneyTransferCommand.getToOfficeId());
}
if (fromOffice == null && toOffice == null) { throw new OfficeNotFoundException(command.getToOfficeId()); }
if (fromOffice == null && toOffice == null) { throw new OfficeNotFoundException(moneyTransferCommand.getToOfficeId()); }
final String currencyCode = command.getCurrencyCode();
final String currencyCode = moneyTransferCommand.getCurrencyCode();
final ApplicationCurrency appCurrency = this.applicationCurrencyRepository.findOneByCode(currencyCode);
if (appCurrency == null) { throw new CurrencyNotFoundException(currencyCode); }
final MonetaryCurrency currency = new MonetaryCurrency(appCurrency.getCode(), appCurrency.getDecimalPlaces());
final Money amount = Money.of(currency, command.getTransactionAmount());
final Money amount = Money.of(currency, moneyTransferCommand.getTransactionAmount());
final OfficeTransaction entity = OfficeTransaction.create(fromOffice, toOffice, command.getTransactionDate(), amount,
command.getDescription());
final OfficeTransaction entity = OfficeTransaction.fromJson(fromOffice, toOffice, amount, command);
this.officeMonetaryTransferRepository.save(entity);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_OFFICETRANSACTION") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return entity.getId();
return EntityIdentifier.resourceResult(entity.getId(), null);
}
/*
* Guaranteed to throw an exception no matter what the data integrity issue
* is.
*/
private void handleOfficeDataIntegrityIssues(final OfficeCommand command, DataIntegrityViolationException dve) {
private void handleOfficeDataIntegrityIssues(final JsonCommand command, DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("externalid_org")) {
throw new PlatformDataIntegrityException("error.msg.office.duplicate.externalId", "Office with externalId {0} already exists",
"externalId", command.getExternalId());
} else if (realCause.getMessage().contains("name_org")) { throw new PlatformDataIntegrityException(
"error.msg.office.duplicate.name", "Office with name {0} already exists", "name", command.getName()); }
final String externalId = command.stringValueOfParameterNamed("externalId");
throw new PlatformDataIntegrityException("error.msg.office.duplicate.externalId", "Office with externalId `" + externalId
+ "` already exists", "externalId", externalId);
} else if (realCause.getMessage().contains("name_org")) {
final String name = command.stringValueOfParameterNamed("name");
throw new PlatformDataIntegrityException("error.msg.office.duplicate.name", "Office with name `" + name + "` already exists",
"name", name);
}
logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.office.unknown.data.integrity.issue",
@@ -160,10 +174,11 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP
* used to restrict modifying operations to office that are either the users
* office or lower (child) in the office hierarchy
*/
private Office validateUserPriviledgeOnOfficeAndRetrieve(AppUser currentUser, Long officeId) {
private Office validateUserPriviledgeOnOfficeAndRetrieve(final AppUser currentUser, final Long officeId) {
Office userOffice = this.officeRepository.findOne(currentUser.getOffice().getId());
if (userOffice == null) { throw new OfficeNotFoundException(currentUser.getOffice().getId()); }
final Long userOfficeId = currentUser.getOffice().getId();
final Office userOffice = this.officeRepository.findOne(userOfficeId);
if (userOffice == null) { throw new OfficeNotFoundException(userOfficeId); }
if (userOffice.doesNotHaveAnOfficeInHierarchyWithId(officeId)) { throw new NoAuthorizationException(
"User does not have sufficient priviledges to act on the provided office."); }
@@ -3,7 +3,6 @@ package org.mifosplatform.organisation.staff.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ws.rs.Consumes;
@@ -20,7 +19,6 @@ import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.codes.data.CodeData;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
@@ -29,7 +27,6 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
import org.mifosplatform.organisation.office.data.OfficeLookup;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.organisation.staff.serialization.StaffCommandFromApiJsonDeserializer;
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
@@ -41,7 +38,8 @@ import org.springframework.stereotype.Component;
public class StaffApiResource {
/**
* The set of parameters that are supported in response for {@link CodeData}
* The set of parameters that are supported in response for
* {@link StaffData}.
*/
private final Set<String> RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "firstname", "lastname", "displayName",
"officeId", "officeName", "loanOfficerFlag", "allowedOffices"));
@@ -51,20 +49,18 @@ public class StaffApiResource {
private final PlatformSecurityContext context;
private final StaffReadPlatformService readPlatformService;
private final OfficeReadPlatformService officeReadPlatformService;
private final StaffCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<StaffData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired
public StaffApiResource(final PlatformSecurityContext context, final StaffReadPlatformService readPlatformService,
final OfficeReadPlatformService officeReadPlatformService, final StaffCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<StaffData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final OfficeReadPlatformService officeReadPlatformService, final DefaultToApiJsonSerializer<StaffData> toApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.readPlatformService = readPlatformService;
this.officeReadPlatformService = officeReadPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -90,13 +86,8 @@ public class StaffApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createStaff(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_STAFF");
context.authenticatedUser().validateHasPermissionTo("CREATE_STAFF", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "staff", null,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_STAFF", "CREATE", "staff", null,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -126,13 +117,8 @@ public class StaffApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateStaff(@PathParam("staffId") final Long staffId, final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_STAFF");
context.authenticatedUser().validateHasPermissionTo("UPDATE_STAFF", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(staffId, apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "staff", staffId,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_STAFF", "UPDATE", "staff",
staffId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -2,7 +2,6 @@ package org.mifosplatform.organisation.staff.command;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
@@ -18,61 +17,13 @@ public class StaffCommand {
private final Long officeId;
private final Boolean isLoanOfficer;
private final transient Set<String> parametersPassedInRequest;
private final transient boolean makerCheckerApproval;
private final transient Long id;
public StaffCommand(final Set<String> parametersPassedInRequest, final boolean makerCheckerApproval, final Long id,
final Long officeId, final String firstName, final String lastName, final Boolean isLoanOfficer) {
this.parametersPassedInRequest = parametersPassedInRequest;
this.makerCheckerApproval = makerCheckerApproval;
this.id = id;
public StaffCommand(final Long officeId, final String firstName, final String lastName, final Boolean isLoanOfficer) {
this.firstname = firstName;
this.lastname = lastName;
this.officeId = officeId;
this.isLoanOfficer = isLoanOfficer;
}
public Long getId() {
return id;
}
public String getFirstname() {
return this.firstname;
}
public String getLastname() {
return this.lastname;
}
public Long getOfficeId() {
return officeId;
}
public Boolean getIsLoanOfficer() {
return this.isLoanOfficer;
}
public boolean isFirstnameChanged() {
return this.parametersPassedInRequest.contains("firstname");
}
public boolean isLastnameChanged() {
return this.parametersPassedInRequest.contains("lastname");
}
public boolean isLoanOfficerFlagChanged() {
return this.parametersPassedInRequest.contains("isLoanOfficer");
}
public boolean isOfficeChanged() {
return this.parametersPassedInRequest.contains("officeId");
}
public boolean isApprovedByChecker() {
return this.makerCheckerApproval;
}
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -91,7 +42,6 @@ public class StaffCommand {
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("staff");
baseDataValidator.reset().parameter("id").value(this.id).notNull();
baseDataValidator.reset().parameter("officeId").value(this.officeId).ignoreIfNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("firstname").value(this.firstname).ignoreIfNull().notBlank().notExceedingLengthOf(50);
baseDataValidator.reset().parameter("lastname").value(this.lastname).ignoreIfNull().notBlank().notExceedingLengthOf(50);
@@ -101,6 +51,6 @@ public class StaffCommand {
baseDataValidator.reset().anyOfNotNull(this.firstname, this.lastname, this.officeId, this.isLoanOfficer);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -1,5 +1,8 @@
package org.mifosplatform.organisation.staff.domain;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
@@ -8,9 +11,9 @@ import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.staff.command.StaffCommand;
import org.mifosplatform.useradministration.domain.AppUser;
@Entity
@@ -28,7 +31,6 @@ public class Staff extends AbstractAuditableCustom<AppUser, Long> {
private String displayName;
// Office to which this employee belongs
@SuppressWarnings("unused")
@ManyToOne
@JoinColumn(name = "office_id", nullable = false)
private Office office;
@@ -37,6 +39,20 @@ public class Staff extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "is_loan_officer ", nullable = false)
private boolean loanOfficer;
public static Staff fromJson(final Office staffOffice, final JsonCommand command) {
final String firstnameParamName = "firstname";
String firstname = command.stringValueOfParameterNamed(firstnameParamName);
final String lastnameParamName = "lastname";
String lastname = command.stringValueOfParameterNamed(lastnameParamName);
final String isLoanOfficerParamName = "isLoanOfficer";
final boolean isLoanOfficer = command.booleanPrimitiveValueOfParameterNamed(isLoanOfficerParamName);
return new Staff(staffOffice, firstname, lastname, isLoanOfficer);
}
public static Staff createNew(Office staffOffice, final String firstname, final String lastname, boolean isLoanOfficer) {
return new Staff(staffOffice, firstname, lastname, isLoanOfficer);
}
@@ -53,32 +69,56 @@ public class Staff extends AbstractAuditableCustom<AppUser, Long> {
deriveDisplayName(firstname);
}
public void update(final StaffCommand command, final Office staffOffice) {
if (command.isOfficeChanged()) {
this.office = staffOffice;
}
if (command.isFirstnameChanged()) {
this.firstname = StringUtils.defaultIfEmpty(command.getFirstname(), null);
}
if (command.isLastnameChanged()) {
this.lastname = StringUtils.defaultIfEmpty(command.getLastname(), null);
}
if (command.isLastnameChanged() || command.isFirstnameChanged()) {
deriveDisplayName(firstname);
}
if (command.isLoanOfficerFlagChanged()) {
this.loanOfficer = command.getIsLoanOfficer();
}
public void changeOffice(final Office newOffice) {
this.office = newOffice;
}
public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7);
final String officeIdParamName = "officeId";
if (command.isChangeInLongParameterNamed(officeIdParamName, this.office.getId())) {
final Long newValue = command.longValueOfParameterNamed(officeIdParamName);
actualChanges.put(officeIdParamName, newValue);
}
boolean firstnameChanged = false;
final String firstnameParamName = "firstname";
if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstname)) {
final String newValue = command.stringValueOfParameterNamed(firstnameParamName);
actualChanges.put(firstnameParamName, newValue);
this.firstname = newValue;
firstnameChanged = true;
}
boolean lastnameChanged = false;
final String lastnameParamName = "lastname";
if (command.isChangeInStringParameterNamed(lastnameParamName, this.lastname)) {
final String newValue = command.stringValueOfParameterNamed(lastnameParamName);
actualChanges.put(lastnameParamName, newValue);
this.lastname = newValue;
lastnameChanged = true;
}
if (firstnameChanged || lastnameChanged) {
deriveDisplayName(this.firstname);
}
final String isLoanOfficerParamName = "isLoanOfficer";
if (command.isChangeInBooleanParameterNamed(isLoanOfficerParamName, this.loanOfficer)) {
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(isLoanOfficerParamName);
actualChanges.put(isLoanOfficerParamName, newValue);
this.loanOfficer = newValue;
}
return actualChanges;
}
public boolean isNotLoanOfficer() {
return !isLoanOfficer();
}
public boolean isLoanOfficer() {
return this.loanOfficer;
}
@@ -0,0 +1,27 @@
package org.mifosplatform.organisation.staff.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.organisation.staff.service.StaffWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CreateStaffCommandHandler implements NewCommandSourceHandler {
private final StaffWritePlatformService writePlatformService;
@Autowired
public CreateStaffCommandHandler(final StaffWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.writePlatformService.createStaff(command);
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.organisation.staff.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.organisation.staff.service.StaffWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UpdateStaffCommandHandler implements NewCommandSourceHandler {
private final StaffWritePlatformService writePlatformService;
@Autowired
public UpdateStaffCommandHandler(final StaffWritePlatformService writePlatformService) {
this.writePlatformService = writePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.writePlatformService.updateStaff(command.resourceId(), command);
}
}
@@ -6,20 +6,23 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
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.organisation.staff.command.StaffCommand;
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 StaffCommand}'s.
*/
@Component
public final class StaffCommandFromApiJsonDeserializer implements FromApiJsonDeserializer<StaffCommand> {
public final class StaffCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<StaffCommand> {
/**
* The parameters supported for this command.
@@ -27,42 +30,26 @@ public final class StaffCommandFromApiJsonDeserializer implements FromApiJsonDes
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("firstname", "lastname", "officeId", "isLoanOfficer"));
private final FromJsonHelper fromApiJsonHelper;
private final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final CommandSerializer commandSerializerService;
@Autowired
public StaffCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper,
final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer,
final CommandSerializer commandSerializerService) {
public StaffCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.commandSerializerService = commandSerializerService;
}
@Override
public StaffCommand commandFromApiJson(final String json) {
return commandFromApiJson(null, json);
}
@Override
public StaffCommand commandFromApiJson(final Long roleId, final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
return this.fromCommandJsonDeserializer.commandFromCommandJson(roleId, json);
}
final JsonElement element = fromApiJsonHelper.parse(json);
@Override
public String serializedCommandJsonFromApiJson(final String json) {
final StaffCommand command = commandFromApiJson(json);
return this.commandSerializerService.serializeCommandToJson(command);
}
final String firstname = fromApiJsonHelper.extractStringNamed("firstname", element);
final String lastname = fromApiJsonHelper.extractStringNamed("lastname", element);
final Boolean isLoanOfficer = fromApiJsonHelper.extractBooleanNamed("isLoanOfficer", element);
final Long officeId = fromApiJsonHelper.extractLongNamed("officeId", element);
@Override
public String serializedCommandJsonFromApiJson(final Long roleId, final String json) {
final StaffCommand command = commandFromApiJson(roleId, json);
return this.commandSerializerService.serializeCommandToJson(command);
return new StaffCommand(officeId, firstname, lastname, isLoanOfficer);
}
}
@@ -1,51 +0,0 @@
package org.mifosplatform.organisation.staff.serialization;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.FromCommandJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.organisation.staff.command.StaffCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
@Component
public final class StaffCommandFromCommandJsonDeserializer implements FromCommandJsonDeserializer<StaffCommand> {
private final FromJsonHelper fromJsonHelper;
@Autowired
public StaffCommandFromCommandJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromJsonHelper = fromApiJsonHelper;
}
@Override
public StaffCommand commandFromCommandJson(final String commandAsJson) {
return commandFromCommandJson(null, commandAsJson);
}
@Override
public StaffCommand commandFromCommandJson(final Long staffId, final String commandAsJson) {
return commandFromCommandJson(staffId, commandAsJson, false);
}
@Override
public StaffCommand commandFromCommandJson(final Long staffId, final String commandAsJson, final boolean makerCheckerApproval) {
if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); }
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromJsonHelper.parse(commandAsJson);
final String firstname = fromJsonHelper.extractStringNamed("firstname", element, parametersPassedInRequest);
final String lastname = fromJsonHelper.extractStringNamed("lastname", element, parametersPassedInRequest);
final Boolean isLoanOfficer = fromJsonHelper.extractBooleanNamed("isLoanOfficer", element, parametersPassedInRequest);
final Long officeId = fromJsonHelper.extractLongNamed("officeId", element, parametersPassedInRequest);
return new StaffCommand(parametersPassedInRequest, makerCheckerApproval, staffId, officeId, firstname, lastname, isLoanOfficer);
}
}
@@ -1,10 +1,11 @@
package org.mifosplatform.organisation.staff.service;
import org.mifosplatform.organisation.staff.command.StaffCommand;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface StaffWritePlatformService {
Long createStaff(final StaffCommand command);
EntityIdentifier createStaff(final JsonCommand command);
Long updateStaff(final StaffCommand command);
EntityIdentifier updateStaff(final Long staffId, final JsonCommand command);
}
@@ -1,9 +1,12 @@
package org.mifosplatform.organisation.staff.service;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.service.ConfigurationDomainService;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.office.domain.OfficeRepository;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
@@ -11,7 +14,7 @@ import org.mifosplatform.organisation.staff.command.StaffCommand;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.staff.domain.StaffRepository;
import org.mifosplatform.organisation.staff.exception.StaffNotFoundException;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.organisation.staff.serialization.StaffCommandFromApiJsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -25,72 +28,77 @@ public class StaffWritePlatformServiceJpaRepositoryImpl implements StaffWritePla
private final static Logger logger = LoggerFactory.getLogger(StaffWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
private final StaffCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final StaffRepository staffRepository;
private final OfficeRepository officeRepository;
private final ConfigurationDomainService configurationDomainService;
@Autowired
public StaffWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final StaffRepository staffRepository,
final OfficeRepository officeRepository, final ConfigurationDomainService configurationDomainService) {
public StaffWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final StaffCommandFromApiJsonDeserializer fromApiJsonDeserializer, final StaffRepository staffRepository,
final OfficeRepository officeRepository) {
this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.staffRepository = staffRepository;
this.officeRepository = officeRepository;
this.configurationDomainService = configurationDomainService;
}
@Transactional
@Override
public Long createStaff(final StaffCommand command) {
public EntityIdentifier createStaff(final JsonCommand command) {
try {
context.authenticatedUser();
command.validateForCreate();
final Office staffOffice = this.officeRepository.findOne(command.getOfficeId());
if (staffOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
final StaffCommand staffCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
staffCommand.validateForCreate();
final Staff staff = Staff.createNew(staffOffice, command.getFirstname(), command.getLastname(), command.getIsLoanOfficer());
final Long officeId = command.longValueOfParameterNamed("officeId");
final Office staffOffice = this.officeRepository.findOne(officeId);
if (staffOffice == null) { throw new OfficeNotFoundException(officeId); }
final Staff staff = Staff.fromJson(staffOffice, command);
this.staffRepository.save(staff);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_STAFF") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return staff.getId();
return EntityIdentifier.resourceResult(staff.getId(), null);
} catch (DataIntegrityViolationException dve) {
handleStaffDataIntegrityIssues(command, dve);
return Long.valueOf(-1);
return EntityIdentifier.empty();
}
}
@Transactional
@Override
public Long updateStaff(final StaffCommand command) {
public EntityIdentifier updateStaff(final Long staffId, final JsonCommand command) {
try {
context.authenticatedUser();
command.validateForUpdate();
final Long staffId = command.getId();
Staff staff = this.staffRepository.findOne(staffId);
if (staff == null) { throw new StaffNotFoundException(staffId); }
final StaffCommand staffCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
staffCommand.validateForUpdate();
Office staffOffice = null;
Long officeId = command.getOfficeId();
if (command.isOfficeChanged() && officeId != null) {
staffOffice = this.officeRepository.findOne(officeId);
if (staffOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
Staff staffForUpdate = this.staffRepository.findOne(staffId);
if (staffForUpdate == null) { throw new StaffNotFoundException(staffId); }
final Map<String, Object> changesOnly = staffForUpdate.update(command);
if (changesOnly.containsKey("officeId")) {
final Long officeId = (Long) changesOnly.get("officeId");
final Office newOffice = this.officeRepository.findOne(officeId);
if (newOffice == null) { throw new OfficeNotFoundException(officeId); }
staffForUpdate.changeOffice(newOffice);
}
staff.update(command, staffOffice);
if (!changesOnly.isEmpty()) {
this.staffRepository.save(staffForUpdate);
}
this.staffRepository.save(staff);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_STAFF") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return staff.getId();
return EntityIdentifier.withChanges(staffForUpdate.getId(), changesOnly);
} catch (DataIntegrityViolationException dve) {
handleStaffDataIntegrityIssues(command, dve);
return Long.valueOf(-1);
return EntityIdentifier.empty();
}
}
@@ -98,12 +106,14 @@ public class StaffWritePlatformServiceJpaRepositoryImpl implements StaffWritePla
* Guaranteed to throw an exception no matter what the data integrity issue
* is.
*/
private void handleStaffDataIntegrityIssues(final StaffCommand command, DataIntegrityViolationException dve) {
private void handleStaffDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("display_name")) {
String displayName = command.getLastname();
if (!StringUtils.isBlank(command.getFirstname())) {
displayName = command.getLastname() + ", " + command.getFirstname();
final String lastname = command.stringValueOfParameterNamed("lastname");
String displayName = lastname;
if (!StringUtils.isBlank(displayName)) {
final String firstname = command.stringValueOfParameterNamed("firstname");
displayName = lastname + ", " + firstname;
}
throw new PlatformDataIntegrityException("error.msg.staff.duplicate.displayName", "A staff with the given display name '"
+ displayName + "' already exists", "displayName", displayName);
@@ -3,7 +3,6 @@ package org.mifosplatform.portfolio.charge.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ws.rs.Consumes;
@@ -25,7 +24,6 @@ import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSeriali
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.charge.data.ChargeData;
import org.mifosplatform.portfolio.charge.serialization.ChargeDefinitionCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.charge.service.ChargeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
@@ -46,17 +44,14 @@ public class ChargesApiResource {
private final ChargeReadPlatformService readPlatformService;
private final DefaultToApiJsonSerializer<ChargeData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final ChargeDefinitionCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired
public ChargesApiResource(final PlatformSecurityContext context, final ChargeReadPlatformService readPlatformService,
final ChargeDefinitionCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<ChargeData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.readPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -113,13 +108,8 @@ public class ChargesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createCharge(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "CREATE_CHARGE");
context.authenticatedUser().validateHasPermissionTo("CREATE_CHARGE", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "charges", null,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CHARGE", "CREATE", "charges", null,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -130,14 +120,8 @@ public class ChargesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateCharge(@PathParam("chargeId") final Long chargeId, final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "UPDATE_CHARGE");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CHARGE", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer
.serializedCommandJsonFromApiJson(chargeId, apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "charges", chargeId,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CHARGE", "UPDATE", "charges", chargeId,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -148,10 +132,7 @@ public class ChargesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String deleteCharge(@PathParam("chargeId") final Long chargeId) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER", "DELETE_CHARGE");
context.authenticatedUser().validateHasPermissionTo("DELETE_CHARGE", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "charges", chargeId, "{}");
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CHARGE", "DELETE", "charges", chargeId, "{}");
return this.toApiJsonSerializer.serialize(result);
}
@@ -3,7 +3,6 @@ package org.mifosplatform.portfolio.charge.command;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
@@ -23,30 +22,18 @@ public class ChargeDefinitionCommand {
private final Boolean penalty;
private final Boolean active;
private final transient Set<String> parametersPassedInRequest;
private final transient boolean makerCheckerApproval;
private final transient Long id;
public ChargeDefinitionCommand(final Set<String> parametersPassedInRequest, final boolean makerCheckerApproval, final Long id,
final String name, final BigDecimal amount, final String currencyCode, final Integer chargeTimeType,
public ChargeDefinitionCommand(final String name, final BigDecimal amount, final String currencyCode, final Integer chargeTimeType,
final Integer chargeAppliesTo, final Integer chargeCalculationType, final Boolean penalty, final Boolean active) {
this.makerCheckerApproval = makerCheckerApproval;
this.id = id;
this.name = name;
this.amount = amount;
this.currencyCode = currencyCode;
this.chargeTimeType = chargeTimeType;
this.chargeAppliesTo = chargeAppliesTo;
this.chargeCalculationType = chargeCalculationType;
this.parametersPassedInRequest = parametersPassedInRequest;
this.penalty = penalty;
this.active = active;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
@@ -55,10 +42,6 @@ public class ChargeDefinitionCommand {
return amount;
}
public Set<String> getModifiedParameters() {
return parametersPassedInRequest;
}
public String getCurrencyCode() {
return currencyCode;
}
@@ -87,42 +70,6 @@ public class ChargeDefinitionCommand {
return active;
}
public boolean isNameChanged() {
return this.parametersPassedInRequest.contains("name");
}
public boolean isAmountChanged() {
return this.parametersPassedInRequest.contains("amount");
}
public boolean isCurrencyCodeChanged() {
return this.parametersPassedInRequest.contains("currencyCode");
}
public boolean isChargeTimeTypeChanged() {
return this.parametersPassedInRequest.contains("chargeTimeType");
}
public boolean isChargeAppliesToChanged() {
return this.parametersPassedInRequest.contains("chargeAppliesTo");
}
public boolean isChargeCalculationTypeChanged() {
return this.parametersPassedInRequest.contains("chargeCalculationType");
}
public boolean isPenaltyChanged() {
return this.parametersPassedInRequest.contains("penalty");
}
public boolean isActiveChanged() {
return this.parametersPassedInRequest.contains("active");
}
public boolean isApprovedByChecker() {
return this.makerCheckerApproval;
}
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -148,10 +95,11 @@ public class ChargeDefinitionCommand {
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("charge");
baseDataValidator.reset().parameter("id").value(this.id).notNull();
baseDataValidator.reset().parameter("name").value(this.name).ignoreIfNull().notBlank().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("amount").value(this.amount).ignoreIfNull().positiveAmount();
baseDataValidator.reset().parameter("currencyCode").value(this.currencyCode).ignoreIfNull().notBlank();
// FIXME - kw - need to check if parameter exists in update and if so that its not null
baseDataValidator.reset().parameter("chargeAppliesTo").value(this.chargeAppliesTo).ignoreIfNull().notNull().inMinMaxRange(1, 1);
baseDataValidator.reset().parameter("chargeTimeType").value(this.chargeTimeType).ignoreIfNull().notNull().inMinMaxRange(1, 2);
baseDataValidator.reset().parameter("chargeCalculationType").value(this.chargeCalculationType).ignoreIfNull().notNull()
@@ -1,11 +1,17 @@
package org.mifosplatform.portfolio.charge.domain;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand;
import org.mifosplatform.useradministration.domain.AppUser;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.useradministration.domain.AppUser;
@Entity
@Table(name = "m_charge", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "name") })
@@ -20,7 +26,6 @@ public class Charge extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "currency_code", length = 3)
private String currencyCode;
@SuppressWarnings("unused")
@Column(name = "charge_applies_to_enum", nullable = false)
private Integer chargeAppliesTo;
@@ -39,10 +44,21 @@ public class Charge extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "is_deleted", nullable = false)
private boolean deleted = false;
public static Charge createNew(final String name, final BigDecimal amount, final String currencyCode,
final ChargeAppliesTo chargeAppliesTo, final ChargeTimeType chargeTime, final ChargeCalculationType chargeCalculationType,
final boolean penalty, final boolean active) {
return new Charge(name, amount, currencyCode, chargeAppliesTo, chargeTime, chargeCalculationType, penalty, active);
public static Charge fromJson(final JsonCommand command) {
final String name = command.stringValueOfParameterNamed("name");
final BigDecimal amount = command.bigDecimalValueOfParameterNamed("amount");
final String currencyCode = command.stringValueOfParameterNamed("currencyCode");
final ChargeAppliesTo chargeAppliesTo = ChargeAppliesTo.fromInt(command.integerValueOfParameterNamed("chargeAppliesTo"));
final ChargeTimeType chargeTimeType = ChargeTimeType.fromInt(command.integerValueOfParameterNamed("chargeTimeType"));
final ChargeCalculationType chargeCalculationType = ChargeCalculationType.fromInt(command
.integerValueOfParameterNamed("chargeCalculationType"));
final boolean penalty = command.booleanPrimitiveValueOfParameterNamed("penalty");
final boolean active = command.booleanPrimitiveValueOfParameterNamed("active");
return new Charge(name, amount, currencyCode, chargeAppliesTo, chargeTimeType, chargeCalculationType, penalty, active);
}
protected Charge() {
@@ -93,34 +109,73 @@ public class Charge extends AbstractAuditableCustom<AppUser, Long> {
return deleted;
}
public void update(final ChargeDefinitionCommand command) {
if (command.isNameChanged()) {
this.name = command.getName();
public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7);
final String localeAsInput = command.locale();
final String nameParamName = "name";
if (command.isChangeInStringParameterNamed(nameParamName, this.name)) {
final String newValue = command.stringValueOfParameterNamed(nameParamName);
actualChanges.put(nameParamName, newValue);
this.name = newValue;
}
if (command.isAmountChanged()) {
this.amount = command.getAmount();
final String currencyCodeParamName = "currencyCode";
if (command.isChangeInStringParameterNamed(currencyCodeParamName, this.currencyCode)) {
final String newValue = command.stringValueOfParameterNamed(currencyCodeParamName);
actualChanges.put(currencyCodeParamName, newValue);
this.currencyCode = newValue;
}
if (command.isCurrencyCodeChanged()) {
this.currencyCode = command.getCurrencyCode();
final String amountParamName = "amount";
if (command.isChangeInBigDecimalParameterNamed(amountParamName, this.amount)) {
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountParamName);
actualChanges.put(amountParamName, newValue);
actualChanges.put("locale", localeAsInput);
this.amount = newValue;
}
if (command.isChargeTimeTypeChanged()) {
this.chargeTime = ChargeTimeType.fromInt(command.getChargeTimeType()).getValue();
final String chargeTimeParamName = "chargeTime";
if (command.isChangeInIntegerParameterNamed(chargeTimeParamName, this.chargeTime)) {
final Integer newValue = command.integerValueOfParameterNamed(chargeTimeParamName);
actualChanges.put(chargeTimeParamName, newValue);
actualChanges.put("locale", localeAsInput);
this.chargeTime = ChargeTimeType.fromInt(newValue).getValue();
}
if (command.isChargeAppliesToChanged()) {
this.chargeAppliesTo = ChargeAppliesTo.fromInt(command.getChargeAppliesTo()).getValue();
final String chargeAppliesToParamName = "chargeAppliesTo";
if (command.isChangeInIntegerParameterNamed(chargeAppliesToParamName, this.chargeAppliesTo)) {
final Integer newValue = command.integerValueOfParameterNamed(chargeAppliesToParamName);
actualChanges.put(chargeAppliesToParamName, newValue);
actualChanges.put("locale", localeAsInput);
this.chargeAppliesTo = ChargeAppliesTo.fromInt(newValue).getValue();
}
if (command.isChargeCalculationTypeChanged()) {
this.chargeCalculation = ChargeCalculationType.fromInt(command.getChargeCalculationType()).getValue();
final String chargeCalculationParamName = "chargeCalculation";
if (command.isChangeInIntegerParameterNamed(chargeCalculationParamName, this.chargeCalculation)) {
final Integer newValue = command.integerValueOfParameterNamed(chargeCalculationParamName);
actualChanges.put(chargeCalculationParamName, newValue);
actualChanges.put("locale", localeAsInput);
this.chargeCalculation = ChargeCalculationType.fromInt(newValue).getValue();
}
if (command.isActiveChanged()) {
this.active = command.isActive();
final String penaltyParamName = "penalty";
if (command.isChangeInBooleanParameterNamed(penaltyParamName, this.penalty)) {
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(penaltyParamName);
actualChanges.put(penaltyParamName, newValue);
this.penalty = newValue;
}
final String activeParamName = "active";
if (command.isChangeInBooleanParameterNamed(activeParamName, this.active)) {
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(activeParamName);
actualChanges.put(activeParamName, newValue);
this.active = newValue;
}
return actualChanges;
}
/**
@@ -0,0 +1,27 @@
package org.mifosplatform.portfolio.charge.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.portfolio.charge.service.ChargeWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CreateChargeDefinitionCommandHandler implements NewCommandSourceHandler {
private final ChargeWritePlatformService clientWritePlatformService;
@Autowired
public CreateChargeDefinitionCommandHandler(final ChargeWritePlatformService clientWritePlatformService) {
this.clientWritePlatformService = clientWritePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.clientWritePlatformService.createCharge(command);
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.portfolio.charge.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.portfolio.charge.service.ChargeWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class DeleteChargeDefinitionCommandHandler implements NewCommandSourceHandler {
private final ChargeWritePlatformService clientWritePlatformService;
@Autowired
public DeleteChargeDefinitionCommandHandler(final ChargeWritePlatformService clientWritePlatformService) {
this.clientWritePlatformService = clientWritePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.clientWritePlatformService.deleteCharge(command.resourceId());
}
}
@@ -0,0 +1,27 @@
package org.mifosplatform.portfolio.charge.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.portfolio.charge.service.ChargeWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UpdateChargeDefinitionCommandHandler implements NewCommandSourceHandler {
private final ChargeWritePlatformService clientWritePlatformService;
@Autowired
public UpdateChargeDefinitionCommandHandler(final ChargeWritePlatformService clientWritePlatformService) {
this.clientWritePlatformService = clientWritePlatformService;
}
@Transactional
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
return this.clientWritePlatformService.updateCharge(command.resourceId(), command);
}
}
@@ -1,59 +0,0 @@
package org.mifosplatform.portfolio.charge.serialization;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.FromCommandJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
@Component
public final class ChargeCommandFromCommandJsonDeserializer implements FromCommandJsonDeserializer<ChargeDefinitionCommand> {
private final FromJsonHelper fromJsonHelper;
@Autowired
public ChargeCommandFromCommandJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromJsonHelper = fromApiJsonHelper;
}
@Override
public ChargeDefinitionCommand commandFromCommandJson(final String commandAsJson) {
return commandFromCommandJson(null, commandAsJson);
}
@Override
public ChargeDefinitionCommand commandFromCommandJson(final Long chargeDefinitionId, final String commandAsJson) {
return commandFromCommandJson(chargeDefinitionId, commandAsJson, false);
}
@Override
public ChargeDefinitionCommand commandFromCommandJson(final Long chargeDefinitionId, final String commandAsJson,
final boolean makerCheckerApproval) {
if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); }
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromJsonHelper.parse(commandAsJson);
final String name = fromJsonHelper.extractStringNamed("name", element, parametersPassedInRequest);
final String currencyCode = fromJsonHelper.extractStringNamed("currencyCode", element, parametersPassedInRequest);
final BigDecimal amount = fromJsonHelper.extractBigDecimalNamed("amount", element.getAsJsonObject(), parametersPassedInRequest);
final Integer chargeTimeType = fromJsonHelper.extractIntegerNamed("chargeTimeType", element, parametersPassedInRequest);
final Integer chargeAppliesTo = fromJsonHelper.extractIntegerNamed("chargeAppliesTo", element, parametersPassedInRequest);
final Integer chargeCalculationType = fromJsonHelper.extractIntegerNamed("chargeCalculationType", element,
parametersPassedInRequest);
final Boolean penalty = fromJsonHelper.extractBooleanNamed("penalty", element, parametersPassedInRequest);
final Boolean active = fromJsonHelper.extractBooleanNamed("active", element, parametersPassedInRequest);
return new ChargeDefinitionCommand(parametersPassedInRequest, makerCheckerApproval, chargeDefinitionId, name, amount, currencyCode,
chargeTimeType, chargeAppliesTo, chargeCalculationType, penalty, active);
}
}
@@ -7,7 +7,9 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
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.charge.command.ChargeDefinitionCommand;
@@ -22,7 +24,7 @@ import com.google.gson.reflect.TypeToken;
* Implementation of {@link FromApiJsonDeserializer} for {@link FundCommand}'s.
*/
@Component
public final class ChargeDefinitionCommandFromApiJsonDeserializer implements FromApiJsonDeserializer<ChargeDefinitionCommand> {
public final class ChargeDefinitionCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<ChargeDefinitionCommand> {
/**
* The parameters supported for this command.
@@ -32,59 +34,33 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer implements Fro
"active"));
private final FromJsonHelper fromApiJsonHelper;
private final CommandSerializer commandSerializerService;
@Autowired
public ChargeDefinitionCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper,
final CommandSerializer commandSerializerService) {
public ChargeDefinitionCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
this.commandSerializerService = commandSerializerService;
}
@Override
public ChargeDefinitionCommand commandFromApiJson(final String json) {
return commandFromApiJson(null, json);
}
@Override
public ChargeDefinitionCommand commandFromApiJson(final Long chargeId, final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromApiJsonHelper.parse(json);
final String name = fromApiJsonHelper.extractStringNamed("name", element, parametersPassedInRequest);
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element, parametersPassedInRequest);
final BigDecimal amount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("amount", element.getAsJsonObject(),
parametersPassedInRequest);
final String name = fromApiJsonHelper.extractStringNamed("name", element);
final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element);
final BigDecimal amount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("amount", element.getAsJsonObject());
final Integer chargeTimeType = fromApiJsonHelper
.extractIntegerWithLocaleNamed("chargeTimeType", element, parametersPassedInRequest);
final Integer chargeAppliesTo = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeAppliesTo", element,
parametersPassedInRequest);
final Integer chargeCalculationType = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeCalculationType", element,
parametersPassedInRequest);
final Integer chargeTimeType = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeTimeType", element);
final Integer chargeAppliesTo = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeAppliesTo", element);
final Integer chargeCalculationType = fromApiJsonHelper.extractIntegerWithLocaleNamed("chargeCalculationType", element);
final Boolean penalty = fromApiJsonHelper.extractBooleanNamed("penalty", element, parametersPassedInRequest);
final Boolean active = fromApiJsonHelper.extractBooleanNamed("active", element, parametersPassedInRequest);
final Boolean penalty = fromApiJsonHelper.extractBooleanNamed("penalty", element);
final Boolean active = fromApiJsonHelper.extractBooleanNamed("active", element);
return new ChargeDefinitionCommand(parametersPassedInRequest, false, chargeId, name, amount, currencyCode, chargeTimeType,
chargeAppliesTo, chargeCalculationType, penalty, active);
}
@Override
public String serializedCommandJsonFromApiJson(final String json) {
final ChargeDefinitionCommand command = commandFromApiJson(json);
return this.commandSerializerService.serializeCommandToJson(command);
}
@Override
public String serializedCommandJsonFromApiJson(final Long roleId, final String json) {
final ChargeDefinitionCommand command = commandFromApiJson(roleId, json);
return this.commandSerializerService.serializeCommandToJson(command);
return new ChargeDefinitionCommand(name, amount, currencyCode, chargeTimeType, chargeAppliesTo, chargeCalculationType, penalty,
active);
}
}
@@ -1,12 +1,13 @@
package org.mifosplatform.portfolio.charge.service;
import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
public interface ChargeWritePlatformService {
Long createCharge(ChargeDefinitionCommand command);
EntityIdentifier createCharge(JsonCommand command);
Long updateCharge(ChargeDefinitionCommand command);
EntityIdentifier updateCharge(Long chargeId, JsonCommand command);
Long deleteCharge(ChargeDefinitionCommand command);
EntityIdentifier deleteCharge(Long chargeId);
}
@@ -1,16 +1,16 @@
package org.mifosplatform.portfolio.charge.service;
import java.util.Map;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.service.ConfigurationDomainService;
import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand;
import org.mifosplatform.portfolio.charge.domain.Charge;
import org.mifosplatform.portfolio.charge.domain.ChargeAppliesTo;
import org.mifosplatform.portfolio.charge.domain.ChargeCalculationType;
import org.mifosplatform.portfolio.charge.domain.ChargeRepository;
import org.mifosplatform.portfolio.charge.domain.ChargeTimeType;
import org.mifosplatform.portfolio.charge.exception.ChargeNotFoundException;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.portfolio.charge.serialization.ChargeDefinitionCommandFromApiJsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,73 +24,69 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP
private final static Logger logger = LoggerFactory.getLogger(ChargeWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
private final ChargeDefinitionCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final ChargeRepository chargeRepository;
private final ConfigurationDomainService configurationDomainService;
@Autowired
public ChargeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ChargeRepository chargeRepository, final ConfigurationDomainService configurationDomainService) {
public ChargeWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final ChargeDefinitionCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final ChargeRepository chargeRepository) {
this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.chargeRepository = chargeRepository;
this.configurationDomainService = configurationDomainService;
}
@Transactional
@Override
public Long createCharge(final ChargeDefinitionCommand command) {
public EntityIdentifier createCharge(final JsonCommand command) {
try {
this.context.authenticatedUser();
command.validateForCreate();
final ChargeAppliesTo chargeAppliesTo = ChargeAppliesTo.fromInt(command.getChargeAppliesTo());
final ChargeTimeType chargeTimeType = ChargeTimeType.fromInt(command.getChargeTimeType());
final ChargeCalculationType chargeCalculationType = ChargeCalculationType.fromInt(command.getChargeCalculationType());
final Charge charge = Charge.createNew(command.getName(), command.getAmount(), command.getCurrencyCode(), chargeAppliesTo,
chargeTimeType, chargeCalculationType, command.isPenalty(), command.isActive());
final ChargeDefinitionCommand chargeDefinitionCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
chargeDefinitionCommand.validateForCreate();
final Charge charge = Charge.fromJson(command);
this.chargeRepository.save(charge);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_CHARGE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return charge.getId();
return EntityIdentifier.resourceResult(charge.getId(), null);
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve);
return Long.valueOf(-1);
return EntityIdentifier.empty();
}
}
@Transactional
@Override
public Long updateCharge(final ChargeDefinitionCommand command) {
public EntityIdentifier updateCharge(final Long chargeId, final JsonCommand command) {
try {
this.context.authenticatedUser();
command.validateForUpdate();
final ChargeDefinitionCommand chargeDefinitionCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
chargeDefinitionCommand.validateForUpdate();
final Long chargeId = command.getId();
final Charge chargeForUpdate = this.chargeRepository.findOne(chargeId);
if (chargeForUpdate == null) { throw new ChargeNotFoundException(chargeId); }
chargeForUpdate.update(command);
final Map<String, Object> changes = chargeForUpdate.update(command);
this.chargeRepository.save(chargeForUpdate);
if (!changes.isEmpty()) {
this.chargeRepository.save(chargeForUpdate);
}
if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_CHARGE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return chargeForUpdate.getId();
return EntityIdentifier.withChanges(chargeForUpdate.getId(), changes);
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve);
return Long.valueOf(-1);
return EntityIdentifier.empty();
}
}
@Transactional
@Override
public Long deleteCharge(final ChargeDefinitionCommand command) {
public EntityIdentifier deleteCharge(final Long chargeId) {
this.context.authenticatedUser();
final Long chargeId = command.getId();
final Charge chargeForDelete = this.chargeRepository.findOne(chargeId);
if (chargeForDelete == null || chargeForDelete.isDeleted()) { throw new ChargeNotFoundException(chargeId); }
@@ -98,20 +94,20 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP
chargeRepository.save(chargeForDelete);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("DELETE_CHARGE") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return chargeForDelete.getId();
return EntityIdentifier.resourceResult(chargeForDelete.getId(), null);
}
/*
* Guaranteed to throw an exception no matter what the data integrity issue
* is.
*/
private void handleDataIntegrityIssues(final ChargeDefinitionCommand command, final DataIntegrityViolationException dve) {
private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("name")) { throw new PlatformDataIntegrityException("error.msg.charge.duplicate.name",
"Charge with name {0} already exists", "name", command.getName()); }
if (realCause.getMessage().contains("name")) {
final String name = command.stringValueOfParameterNamed("name");
throw new PlatformDataIntegrityException("error.msg.charge.duplicate.name",
"Charge with name `" + name +"` already exists", "name", name); }
logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.charge.unknown.data.integrity.issue",
@@ -3,7 +3,6 @@ package org.mifosplatform.portfolio.client.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ws.rs.Consumes;
@@ -29,7 +28,6 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.data.ClientIdentifierData;
import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException;
import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
@@ -48,7 +46,6 @@ public class ClientIdentifiersApiResource {
private final PlatformSecurityContext context;
private final ClientReadPlatformService clientReadPlatformService;
private final CodeValueReadPlatformService codeValueReadPlatformService;
private final ClientIdentifierCommandFromApiJsonDeserializer commandFromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<ClientIdentifierData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@@ -56,14 +53,12 @@ public class ClientIdentifiersApiResource {
@Autowired
public ClientIdentifiersApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
final CodeValueReadPlatformService codeValueReadPlatformService,
final ClientIdentifierCommandFromApiJsonDeserializer commandFromApiJsonDeserializer,
final DefaultToApiJsonSerializer<ClientIdentifierData> toApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.clientReadPlatformService = readPlatformService;
this.codeValueReadPlatformService = codeValueReadPlatformService;
this.commandFromApiJsonDeserializer = commandFromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -103,16 +98,8 @@ public class ClientIdentifiersApiResource {
public String createClientIdentifier(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) {
try {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"CREATE_CLIENTIDENTIFIER");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENTIDENTIFIER", allowedPermissions);
final String commandSerializedAsJson = this.commandFromApiJsonDeserializer.serializedCommandJsonFromApiJsonWithSubResource(
apiRequestBodyAsJson, clientId);
final String resourceUrl = "clients/" + clientId + "/identifiers";
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", resourceUrl, null,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CLIENTIDENTIFIER", "CREATE",
"clients", clientId, "identifiers", null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
} catch (DuplicateClientIdentifierException e) {
@@ -156,16 +143,8 @@ public class ClientIdentifiersApiResource {
@PathParam("identifierId") final Long clientIdentifierId, final String apiRequestBodyAsJson) {
try {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"UPDATE_CLIENTIDENTIFIER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENTIDENTIFIER", allowedPermissions);
final String commandSerializedAsJson = this.commandFromApiJsonDeserializer.serializedCommandJsonFromApiJsonWithSubResource(
clientIdentifierId, apiRequestBodyAsJson, clientId);
final String resourceUrl = "clients/" + clientId + "/identifiers";
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", resourceUrl,
clientIdentifierId, commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CLIENTIDENTIFIER", "UPDATE",
"clients", clientId, "identifiers", clientIdentifierId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
} catch (DuplicateClientIdentifierException e) {
@@ -187,13 +166,8 @@ public class ClientIdentifiersApiResource {
public String deleteClientIdentifier(@PathParam("clientId") final Long clientId,
@PathParam("identifierId") final Long clientIdentifierId) {
final List<String> allowedPermissions = Arrays
.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "DELETE_CLIENTIDENTIFIER");
context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENTIDENTIFIER", allowedPermissions);
final String resourceUrl = "clients/" + clientId + "/identifiers";
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", resourceUrl, clientIdentifierId,
"{}");
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CLIENTIDENTIFIER", "DELETE",
"clients", clientId, "identifiers", clientIdentifierId, "{}");
return this.toApiJsonSerializer.serialize(result);
}
@@ -3,7 +3,6 @@ package org.mifosplatform.portfolio.client.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ws.rs.Consumes;
@@ -24,7 +23,6 @@ import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSeriali
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.serialization.ClientNoteCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
@@ -40,19 +38,16 @@ public class ClientNotesApiResource {
private final PlatformSecurityContext context;
private final ClientReadPlatformService clientReadPlatformService;
private final ClientNoteCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<NoteData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired
public ClientNotesApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
final ClientNoteCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<NoteData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.clientReadPlatformService = readPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
@@ -76,14 +71,8 @@ public class ClientNotesApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String addNewClientNote(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENTNOTE");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENTNOTE", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJsonWithSubResource(apiRequestBodyAsJson, clientId);
final String resourceUrl = "clients/" + clientId + "/notes";
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", resourceUrl, null,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CLIENTNOTE", "CREATE",
"clients", clientId, "notes", null, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -110,14 +99,8 @@ public class ClientNotesApiResource {
public String updateClientNote(@PathParam("clientId") final Long clientId, @PathParam("noteId") final Long noteId,
final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENTNOTE");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENTNOTE", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJsonWithSubResource(noteId, apiRequestBodyAsJson, clientId);
final String resourceUrl = "clients/" + clientId + "/notes";
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", resourceUrl, noteId,
commandSerializedAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CLIENTNOTE", "UPDATE",
"clients", clientId, "notes", noteId, apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -213,10 +213,7 @@ public class ClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String createClient(final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENT");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENT", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "clients", null,
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE_CLIENT", "CREATE", "clients", null,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -228,10 +225,7 @@ public class ClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String updateClient(@PathParam("clientId") final Long clientId, final String apiRequestBodyAsJson) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENT");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId,
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE_CLIENT", "UPDATE", "clients", clientId,
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
@@ -243,10 +237,7 @@ public class ClientsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String deleteClient(@PathParam("clientId") final Long clientId) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "DELETE_CLIENT");
context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENT", allowedPermissions);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE", "clients", clientId, "{}");
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("DELETE_CLIENT", "DELETE", "clients", clientId, "{}");
return this.toApiJsonSerializer.serialize(result);
}
@@ -1,42 +1,27 @@
package org.mifosplatform.portfolio.client.command;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
/**
* Immutable command for creating or updating details of a client identifier.
*/
public class ClientIdentifierCommand {
private final Long clientId;
private final Long documentTypeId;
private final String documentKey;
private final String description;
private final transient Set<String> modifiedParameters;
private final transient boolean makerCheckerApproval;
private final transient Long id;
public static ClientIdentifierCommand clientSubResource(final ClientIdentifierCommand command, final Long providedClientId) {
return new ClientIdentifierCommand(command.modifiedParameters, command.makerCheckerApproval, command.id, providedClientId, command.documentTypeId, command.documentKey, command.description);
}
public ClientIdentifierCommand(final Set<String> modifiedParameters, final boolean makerCheckerApproval, final Long id, final Long clientId, final Long documentTypeId,
final String documentKey, final String description) {
this.modifiedParameters = modifiedParameters;
this.makerCheckerApproval = makerCheckerApproval;
this.id = id;
this.clientId = clientId;
public ClientIdentifierCommand(final Long documentTypeId, final String documentKey, final String description) {
this.documentTypeId = documentTypeId;
this.documentKey = documentKey;
this.description = description;
}
public Long getId() {
return id;
}
public Long getDocumentTypeId() {
return documentTypeId;
}
@@ -49,27 +34,33 @@ public class ClientIdentifierCommand {
return description;
}
public Set<String> getModifiedParameters() {
return modifiedParameters;
}
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
public Long getClientId() {
return clientId;
}
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("clientIdentifier");
public boolean isDocumentTypeChanged() {
return this.modifiedParameters.contains("documentTypeId");
}
baseDataValidator.reset().parameter("documentTypeId").value(this.documentTypeId).notNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("documentKey").value(this.documentKey).notBlank();
public boolean isDocumentKeyChanged() {
return this.modifiedParameters.contains("documentKey");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
public boolean isDescriptionChanged() {
return this.modifiedParameters.contains("description");
}
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("clientIdentifier");
public boolean isApprovedByChecker() {
return this.makerCheckerApproval;
baseDataValidator.reset().parameter("documentKey").value(this.documentKey).ignoreIfNull().notBlank();
// FIXME - kw
// if (command.isDocumentTypeChanged()) {
// baseDataValidator.reset().parameter("documentTypeId").value(command.getDocumentTypeId()).notNull().integerGreaterThanZero();
// }
baseDataValidator.reset().anyOfNotNull(this.documentTypeId, this.documentKey);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -1,47 +0,0 @@
package org.mifosplatform.portfolio.client.command;
import java.util.ArrayList;
import java.util.List;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
public class ClientIdentifierCommandValidator {
private final ClientIdentifierCommand command;
public ClientIdentifierCommandValidator(ClientIdentifierCommand command) {
this.command = command;
}
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("clientIdentifier");
baseDataValidator.reset().parameter("documentKey").value(command.getDocumentKey()).ignoreIfNull().notBlank();
if (command.isDocumentTypeChanged()) {
baseDataValidator.reset().parameter("documentTypeId").value(command.getDocumentTypeId()).notNull().integerGreaterThanZero();
}
baseDataValidator.reset().anyOfNotNull(command.getDocumentTypeId(), command.getDocumentKey());
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("clientIdentifier");
baseDataValidator.reset().parameter("documentTypeId").value(command.getDocumentTypeId()).notNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("clientId").value(command.getClientId()).notNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("documentKey").value(command.getDocumentKey()).notBlank();
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -1,40 +1,16 @@
package org.mifosplatform.portfolio.client.command;
import java.util.Set;
/**
* Immutable command used for create or update of notes.
*/
public class ClientNoteCommand {
private final Long clientId;
private final String note;
private final transient Long id;
private final transient Set<String> parametersPassedInRequest;
private final transient boolean makerCheckerApproval;
public static ClientNoteCommand clientSubResource(final ClientNoteCommand command, final Long providedClientId) {
return new ClientNoteCommand(command.parametersPassedInRequest, command.makerCheckerApproval, command.id, providedClientId, command.note);
}
public ClientNoteCommand(final Set<String> parametersPassedInRequest, final boolean makerCheckerApproval, final Long id, Long clientId,
final String note) {
this.parametersPassedInRequest = parametersPassedInRequest;
this.makerCheckerApproval = makerCheckerApproval;
this.id = id;
this.clientId = clientId;
public ClientNoteCommand(final String note) {
this.note = note;
}
public Long getId() {
return id;
}
public Long getClientId() {
return clientId;
}
public String getNote() {
return note;
}
@@ -134,6 +134,17 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
final LocalDate newValue = command.localDateValueOfParameterNamed(joiningDateParamName);
this.joinedDate = newValue.toDate();
}
final String clientOrBusinessNameParamName = "clientOrBusinessName";
final String lastnameParamName = "lastname";
if (command.isChangeInStringParameterNamed(lastnameParamName, getLastnameIfNotClientOrBusinessName())) {
final String newValue = command.stringValueOfParameterNamed(lastnameParamName);
actualChanges.put(lastnameParamName, newValue);
if (StringUtils.isNotBlank(getClientOrBusinessName())) {
actualChanges.put(clientOrBusinessNameParamName, "");
}
this.lastName = newValue;
}
final String firstnameParamName = "firstname";
if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstName)) {
@@ -142,14 +153,7 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
this.firstName = newValue;
}
final String lastnameParamName = "lastname";
if (command.isChangeInStringParameterNamed(lastnameParamName, this.lastName)) {
final String newValue = command.stringValueOfParameterNamed(lastnameParamName);
actualChanges.put(lastnameParamName, newValue);
this.lastName = newValue;
}
final String clientOrBusinessNameParamName = "clientOrBusinessName";
if (command.isChangeInStringParameterNamed(clientOrBusinessNameParamName, getClientOrBusinessName())) {
final String newValue = command.stringValueOfParameterNamed(clientOrBusinessNameParamName);
actualChanges.put(clientOrBusinessNameParamName, newValue);
@@ -183,6 +187,18 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
}
return joiningLocalDate;
}
/*
*
*/
private String getLastnameIfNotClientOrBusinessName() {
String lastname = null;
if (StringUtils.isNotBlank(this.firstName) && StringUtils.isNotBlank(this.lastName)) {
lastname = this.lastName;
}
return lastname;
}
private String getClientOrBusinessName() {
String clientOrBusinessName = null;

Some files were not shown because too many files have changed in this diff Show More